soul-browser/sources/java/com/google/api/client/http/UriTemplate.java
KaKi87 550ddb0413
Decompile and recreate Soul Browser v1.4.85 with APK CI builds (#1)
* 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>
2026-08-10 16:07:14 +02:00

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();
}
}