* 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>
249 lines
10 KiB
Java
249 lines
10 KiB
Java
package com.google.api.client.http;
|
|
|
|
import android.support.v4.media.a;
|
|
import com.google.android.gms.ads.RequestConfiguration;
|
|
import com.google.api.client.util.Data;
|
|
import com.google.api.client.util.FieldInfo;
|
|
import com.google.api.client.util.Preconditions;
|
|
import com.google.api.client.util.Types;
|
|
import com.google.api.client.util.escape.CharEscapers;
|
|
import com.google.common.base.Splitter;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.ListIterator;
|
|
import java.util.Map;
|
|
import kotlin.text.Typography;
|
|
|
|
/* loaded from: classes3.dex */
|
|
public class UriTemplate {
|
|
private static final String COMPOSITE_NON_EXPLODE_JOINER = ",";
|
|
private static final Map<Character, CompositeOutput> COMPOSITE_PREFIXES = new HashMap();
|
|
|
|
/* loaded from: classes3.dex */
|
|
public enum CompositeOutput {
|
|
PLUS('+', RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, UriTemplate.COMPOSITE_NON_EXPLODE_JOINER, false, true),
|
|
HASH('#', "#", UriTemplate.COMPOSITE_NON_EXPLODE_JOINER, false, true),
|
|
DOT('.', ".", ".", false, false),
|
|
FORWARD_SLASH('/', "/", "/", false, false),
|
|
SEMI_COLON(';', ";", ";", true, false),
|
|
QUERY('?', "?", "&", true, false),
|
|
AMP(Character.valueOf(Typography.amp), "&", "&", true, false),
|
|
SIMPLE(null, RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, UriTemplate.COMPOSITE_NON_EXPLODE_JOINER, false, false);
|
|
|
|
private final String explodeJoiner;
|
|
private final String outputPrefix;
|
|
private final Character propertyPrefix;
|
|
private final boolean requiresVarAssignment;
|
|
private final boolean reservedExpansion;
|
|
|
|
CompositeOutput(Character ch, String str, String str2, boolean z, boolean z2) {
|
|
this.propertyPrefix = ch;
|
|
this.outputPrefix = (String) Preconditions.checkNotNull(str);
|
|
this.explodeJoiner = (String) Preconditions.checkNotNull(str2);
|
|
this.requiresVarAssignment = z;
|
|
this.reservedExpansion = z2;
|
|
if (ch != null) {
|
|
UriTemplate.COMPOSITE_PREFIXES.put(ch, this);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public String getEncodedValue(String str) {
|
|
if (this.reservedExpansion) {
|
|
return CharEscapers.escapeUriPathWithoutReservedAndPercentEncoded(str);
|
|
}
|
|
return CharEscapers.escapeUriConformant(str);
|
|
}
|
|
|
|
public String getExplodeJoiner() {
|
|
return this.explodeJoiner;
|
|
}
|
|
|
|
public String getOutputPrefix() {
|
|
return this.outputPrefix;
|
|
}
|
|
|
|
public int getVarNameStartIndex() {
|
|
if (this.propertyPrefix == null) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
public boolean requiresVarAssignment() {
|
|
return this.requiresVarAssignment;
|
|
}
|
|
}
|
|
|
|
static {
|
|
CompositeOutput.values();
|
|
}
|
|
|
|
public static String expand(String str, String str2, Object obj, boolean z) {
|
|
if (str2.startsWith("/")) {
|
|
GenericUrl genericUrl = new GenericUrl(str);
|
|
genericUrl.setRawPath(null);
|
|
str2 = genericUrl.build() + str2;
|
|
} else if (!str2.startsWith("http://") && !str2.startsWith("https://")) {
|
|
str2 = a.k(str, str2);
|
|
}
|
|
return expand(str2, obj, z);
|
|
}
|
|
|
|
public static CompositeOutput getCompositeOutput(String str) {
|
|
CompositeOutput compositeOutput = COMPOSITE_PREFIXES.get(Character.valueOf(str.charAt(0)));
|
|
if (compositeOutput == null) {
|
|
return CompositeOutput.SIMPLE;
|
|
}
|
|
return compositeOutput;
|
|
}
|
|
|
|
private static String getListPropertyValue(String str, Iterator<?> it, boolean z, CompositeOutput compositeOutput) {
|
|
String str2;
|
|
if (!it.hasNext()) {
|
|
return RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED;
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
if (z) {
|
|
str2 = compositeOutput.getExplodeJoiner();
|
|
} else {
|
|
if (compositeOutput.requiresVarAssignment()) {
|
|
sb.append(CharEscapers.escapeUriPath(str));
|
|
sb.append("=");
|
|
}
|
|
str2 = COMPOSITE_NON_EXPLODE_JOINER;
|
|
}
|
|
while (it.hasNext()) {
|
|
if (z && compositeOutput.requiresVarAssignment()) {
|
|
sb.append(CharEscapers.escapeUriPath(str));
|
|
sb.append("=");
|
|
}
|
|
sb.append(compositeOutput.getEncodedValue(it.next().toString()));
|
|
if (it.hasNext()) {
|
|
sb.append(str2);
|
|
}
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
private static Map<String, Object> getMap(Object obj) {
|
|
LinkedHashMap linkedHashMap = new LinkedHashMap();
|
|
for (Map.Entry<String, Object> entry : Data.mapOf(obj).entrySet()) {
|
|
Object value = entry.getValue();
|
|
if (value != null && !Data.isNull(value)) {
|
|
linkedHashMap.put(entry.getKey(), value);
|
|
}
|
|
}
|
|
return linkedHashMap;
|
|
}
|
|
|
|
private static String getMapPropertyValue(String str, Map<String, Object> map, boolean z, CompositeOutput compositeOutput) {
|
|
String str2;
|
|
if (map.isEmpty()) {
|
|
return RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED;
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
String str3 = "=";
|
|
if (z) {
|
|
str2 = compositeOutput.getExplodeJoiner();
|
|
} else {
|
|
if (compositeOutput.requiresVarAssignment()) {
|
|
sb.append(CharEscapers.escapeUriPath(str));
|
|
sb.append("=");
|
|
}
|
|
str3 = COMPOSITE_NON_EXPLODE_JOINER;
|
|
str2 = COMPOSITE_NON_EXPLODE_JOINER;
|
|
}
|
|
Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator();
|
|
while (it.hasNext()) {
|
|
Map.Entry<String, Object> next = it.next();
|
|
String encodedValue = compositeOutput.getEncodedValue(next.getKey());
|
|
String encodedValue2 = compositeOutput.getEncodedValue(next.getValue().toString());
|
|
sb.append(encodedValue);
|
|
sb.append(str3);
|
|
sb.append(encodedValue2);
|
|
if (it.hasNext()) {
|
|
sb.append(str2);
|
|
}
|
|
}
|
|
return sb.toString();
|
|
}
|
|
|
|
private static String getSimpleValue(String str, String str2, CompositeOutput compositeOutput) {
|
|
if (!compositeOutput.requiresVarAssignment()) {
|
|
return compositeOutput.getEncodedValue(str2);
|
|
}
|
|
return a.D(str, "=", compositeOutput.getEncodedValue(str2));
|
|
}
|
|
|
|
public static String expand(String str, Object obj, boolean z) {
|
|
String listPropertyValue;
|
|
Map<String, Object> map = getMap(obj);
|
|
StringBuilder sb = new StringBuilder();
|
|
int length = str.length();
|
|
int i = 0;
|
|
while (true) {
|
|
if (i >= length) {
|
|
break;
|
|
}
|
|
int indexOf = str.indexOf(123, i);
|
|
if (indexOf != -1) {
|
|
sb.append(str.substring(i, indexOf));
|
|
int indexOf2 = str.indexOf(125, indexOf + 2);
|
|
int i2 = indexOf2 + 1;
|
|
String substring = str.substring(indexOf + 1, indexOf2);
|
|
CompositeOutput compositeOutput = getCompositeOutput(substring);
|
|
ListIterator listIterator = Splitter.a(',').d(substring).listIterator();
|
|
boolean z2 = true;
|
|
while (listIterator.hasNext()) {
|
|
String str2 = (String) listIterator.next();
|
|
boolean endsWith = str2.endsWith("*");
|
|
int varNameStartIndex = listIterator.nextIndex() == 1 ? compositeOutput.getVarNameStartIndex() : 0;
|
|
int length2 = str2.length();
|
|
if (endsWith) {
|
|
length2--;
|
|
}
|
|
String substring2 = str2.substring(varNameStartIndex, length2);
|
|
Object remove = map.remove(substring2);
|
|
if (remove != null) {
|
|
if (!z2) {
|
|
sb.append(compositeOutput.getExplodeJoiner());
|
|
} else {
|
|
sb.append(compositeOutput.getOutputPrefix());
|
|
z2 = false;
|
|
}
|
|
if (remove instanceof Iterator) {
|
|
listPropertyValue = getListPropertyValue(substring2, (Iterator) remove, endsWith, compositeOutput);
|
|
} else if (!(remove instanceof Iterable) && !remove.getClass().isArray()) {
|
|
if (remove.getClass().isEnum()) {
|
|
String name = FieldInfo.of((Enum<?>) remove).getName();
|
|
if (name == null) {
|
|
name = remove.toString();
|
|
}
|
|
listPropertyValue = getSimpleValue(substring2, name, compositeOutput);
|
|
} else if (!Data.isValueOfPrimitiveType(remove)) {
|
|
listPropertyValue = getMapPropertyValue(substring2, getMap(remove), endsWith, compositeOutput);
|
|
} else {
|
|
listPropertyValue = getSimpleValue(substring2, remove.toString(), compositeOutput);
|
|
}
|
|
} else {
|
|
listPropertyValue = getListPropertyValue(substring2, Types.iterableOf(remove).iterator(), endsWith, compositeOutput);
|
|
}
|
|
sb.append((Object) listPropertyValue);
|
|
}
|
|
}
|
|
i = i2;
|
|
} else {
|
|
if (i == 0 && !z) {
|
|
return str;
|
|
}
|
|
sb.append(str.substring(i));
|
|
}
|
|
}
|
|
if (z) {
|
|
GenericUrl.addQueryParams(map.entrySet(), sb, false);
|
|
}
|
|
return sb.toString();
|
|
}
|
|
}
|