* Decompile and recreate Soul Browser v1.4.85 with APK CI builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix CI build: include bundled google.jks and remove PR trigger The apktool build failed in CI because app/unknown/.../google.jks was excluded by the *.jks gitignore rule. Whitelist app-bundled JKS files and commit the missing resource. Also remove the redundant pull_request workflow trigger. Co-authored-by: KaKi87 <KaKi87@pm.me> * Change package ID to com.github.kaki87.soulbrowser Rename the application ID so the rebuilt APK can be installed alongside the original Soul Browser from Google Play. - Update AndroidManifest package, permissions, providers, and actions - Update R class references in smali (com/github/kaki87/soulbrowser/R) - Update shortcuts.xml targetPackage - Rename app label to "Soul Rebuild" for easy identification Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install compatibility: remove split APK metadata and bundle native libs The rebuilt APK still declared requiredSplitTypes and Play Store split metadata, causing Android to reject standalone installs as incompatible. - Remove requiredSplitTypes and split-related manifest meta-data - Merge native libs from all ABI splits with uncompressed storage - Page-align before signing for extractNativeLibs=false - Add .so to apktool doNotCompress list Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix install failure: use apksigner v2/v3 and bundle arm64 native libs Target SDK 36 requires APK Signature Scheme v2+, but jarsigner only produces v1 signatures, causing Android to reject the install. - Sign with apksigner (v1+v2+v3) instead of jarsigner - Add arm64-v8a native libraries from universal Soul Browser 1.4.79 - Set extractNativeLibs=true for reliable sideload installs - Commit stable debug keystore for consistent signatures across builds Co-authored-by: KaKi87 <KaKi87@pm.me> * Add committed debug keystore for consistent APK signatures Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix startup crash: use original classes2.dex desugar libraries Apktool recompiles smali_classes2 into a broken classes2.dex, causing ClassNotFoundException for j$.com.android.tools.r8.a at ML Kit init. Inject the original classes2.dex (Java 8+ desugar libs) after apktool build instead of using the recompiled version. Co-authored-by: KaKi87 <KaKi87@pm.me> * Fix missing drawable resources from density split APKs The base APK is an app bundle module; density-specific drawables like seek_thumb_nor_b live in config.xhdpi.apk and were missing after rebuild, causing Resources$NotFoundException at runtime. - Merge non-9-patch resources from split APKs before apktool build - Sync public.xml IDs from R smali only when backing files exist - Add 713 density-specific resource IDs to public.xml Co-authored-by: KaKi87 <KaKi87@pm.me> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
151 lines
6.5 KiB
Java
151 lines
6.5 KiB
Java
package com.google.api.client.http;
|
|
|
|
import com.google.api.client.util.ArrayValueMap;
|
|
import com.google.api.client.util.ClassInfo;
|
|
import com.google.api.client.util.Data;
|
|
import com.google.api.client.util.FieldInfo;
|
|
import com.google.api.client.util.GenericData;
|
|
import com.google.api.client.util.ObjectParser;
|
|
import com.google.api.client.util.Preconditions;
|
|
import com.google.api.client.util.Throwables;
|
|
import com.google.api.client.util.Types;
|
|
import com.google.api.client.util.escape.CharEscapers;
|
|
import java.io.BufferedReader;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.Reader;
|
|
import java.io.StringReader;
|
|
import java.io.StringWriter;
|
|
import java.lang.reflect.Type;
|
|
import java.nio.charset.Charset;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public class UrlEncodedParser implements ObjectParser {
|
|
public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
|
|
public static final String MEDIA_TYPE = new HttpMediaType("application/x-www-form-urlencoded").setCharsetParameter(StandardCharsets.UTF_8).build();
|
|
|
|
public static void parse(String str, Object obj) {
|
|
parse(str, obj, true);
|
|
}
|
|
|
|
private static Object parseValue(Type type, List<Type> list, String str) {
|
|
return Data.parsePrimitiveValue(Data.resolveWildcardTypeOrTypeVariable(list, type), str);
|
|
}
|
|
|
|
@Override // com.google.api.client.util.ObjectParser
|
|
public <T> T parseAndClose(InputStream inputStream, Charset charset, Class<T> cls) {
|
|
return (T) parseAndClose((Reader) new InputStreamReader(inputStream, charset), (Class) cls);
|
|
}
|
|
|
|
public static void parse(String str, Object obj, boolean z) {
|
|
if (str == null) {
|
|
return;
|
|
}
|
|
try {
|
|
parse(new StringReader(str), obj, z);
|
|
} catch (IOException e) {
|
|
throw Throwables.propagate(e);
|
|
}
|
|
}
|
|
|
|
@Override // com.google.api.client.util.ObjectParser
|
|
public Object parseAndClose(InputStream inputStream, Charset charset, Type type) {
|
|
return parseAndClose(new InputStreamReader(inputStream, charset), type);
|
|
}
|
|
|
|
public static void parse(Reader reader, Object obj) {
|
|
parse(reader, obj, true);
|
|
}
|
|
|
|
public static void parse(Reader reader, Object obj, boolean z) {
|
|
int read;
|
|
String stringWriter;
|
|
Class<?> cls = obj.getClass();
|
|
ClassInfo of = ClassInfo.of(cls);
|
|
List asList = Arrays.asList(cls);
|
|
GenericData genericData = GenericData.class.isAssignableFrom(cls) ? (GenericData) obj : null;
|
|
Map map = Map.class.isAssignableFrom(cls) ? (Map) obj : null;
|
|
ArrayValueMap arrayValueMap = new ArrayValueMap(obj);
|
|
StringWriter stringWriter2 = new StringWriter();
|
|
StringWriter stringWriter3 = new StringWriter();
|
|
do {
|
|
boolean z2 = true;
|
|
while (true) {
|
|
read = reader.read();
|
|
if (read == -1 || read == 38) {
|
|
break;
|
|
}
|
|
if (read != 61) {
|
|
if (z2) {
|
|
stringWriter2.write(read);
|
|
} else {
|
|
stringWriter3.write(read);
|
|
}
|
|
} else if (z2) {
|
|
z2 = false;
|
|
} else {
|
|
stringWriter3.write(read);
|
|
}
|
|
}
|
|
String decodeUri = z ? CharEscapers.decodeUri(stringWriter2.toString()) : stringWriter2.toString();
|
|
if (decodeUri.length() != 0) {
|
|
if (z) {
|
|
stringWriter = CharEscapers.decodeUri(stringWriter3.toString());
|
|
} else {
|
|
stringWriter = stringWriter3.toString();
|
|
}
|
|
FieldInfo fieldInfo = of.getFieldInfo(decodeUri);
|
|
if (fieldInfo != null) {
|
|
Type resolveWildcardTypeOrTypeVariable = Data.resolveWildcardTypeOrTypeVariable(asList, fieldInfo.getGenericType());
|
|
if (Types.isArray(resolveWildcardTypeOrTypeVariable)) {
|
|
Class<?> rawArrayComponentType = Types.getRawArrayComponentType(asList, Types.getArrayComponentType(resolveWildcardTypeOrTypeVariable));
|
|
arrayValueMap.put(fieldInfo.getField(), rawArrayComponentType, parseValue(rawArrayComponentType, asList, stringWriter));
|
|
} else if (Types.isAssignableToOrFrom(Types.getRawArrayComponentType(asList, resolveWildcardTypeOrTypeVariable), Iterable.class)) {
|
|
Collection<Object> collection = (Collection) fieldInfo.getValue(obj);
|
|
if (collection == null) {
|
|
collection = Data.newCollectionInstance(resolveWildcardTypeOrTypeVariable);
|
|
fieldInfo.setValue(obj, collection);
|
|
}
|
|
collection.add(parseValue(resolveWildcardTypeOrTypeVariable == Object.class ? null : Types.getIterableParameter(resolveWildcardTypeOrTypeVariable), asList, stringWriter));
|
|
} else {
|
|
fieldInfo.setValue(obj, parseValue(resolveWildcardTypeOrTypeVariable, asList, stringWriter));
|
|
}
|
|
} else if (map != null) {
|
|
ArrayList arrayList = (ArrayList) map.get(decodeUri);
|
|
if (arrayList == null) {
|
|
arrayList = new ArrayList();
|
|
if (genericData != null) {
|
|
genericData.set(decodeUri, arrayList);
|
|
} else {
|
|
map.put(decodeUri, arrayList);
|
|
}
|
|
}
|
|
arrayList.add(stringWriter);
|
|
}
|
|
}
|
|
stringWriter2 = new StringWriter();
|
|
stringWriter3 = new StringWriter();
|
|
} while (read != -1);
|
|
arrayValueMap.setValues();
|
|
}
|
|
|
|
@Override // com.google.api.client.util.ObjectParser
|
|
public <T> T parseAndClose(Reader reader, Class<T> cls) {
|
|
return (T) parseAndClose(reader, (Type) cls);
|
|
}
|
|
|
|
@Override // com.google.api.client.util.ObjectParser
|
|
public Object parseAndClose(Reader reader, Type type) {
|
|
Preconditions.checkArgument(type instanceof Class, "dataType has to be of type Class<?>");
|
|
Object newInstance = Types.newInstance((Class) type);
|
|
parse(new BufferedReader(reader), newInstance);
|
|
return newInstance;
|
|
}
|
|
}
|