soul-browser/sources/java/com/mycompany/app/vpn/VpnAdapter.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

155 lines
5.9 KiB
Java

package com.mycompany.app.vpn;
import android.content.Context;
import android.content.res.Resources;
import android.net.VpnService;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.text.TextUtils;
import backend.Backend;
import backend.DoHServer;
import backend.Session;
import com.google.android.gms.common.ConnectionResult;
import com.mycompany.app.pref.PrefTts;
import com.mycompany.app.soulbrowser.R;
import java.io.IOException;
/* loaded from: classes3.dex */
public class VpnAdapter {
/* renamed from: a, reason: collision with root package name */
public final VpnSvc f19051a;
public VpnListener b = new Object();
/* renamed from: c, reason: collision with root package name */
public ParcelFileDescriptor f19052c;
public Session d;
/* loaded from: classes3.dex */
public static class VpnItem {
/* renamed from: a, reason: collision with root package name */
public String f19053a;
public String b;
}
/* JADX WARN: Type inference failed for: r0v0, types: [com.mycompany.app.vpn.VpnListener, java.lang.Object] */
public VpnAdapter(VpnSvc vpnSvc) {
this.f19051a = vpnSvc;
ParcelFileDescriptor parcelFileDescriptor = null;
if (vpnSvc != null) {
try {
VpnService.Builder allowBypass = new VpnService.Builder(vpnSvc).setSession("Soul DNS").setMtu(ConnectionResult.DRIVE_EXTERNAL_STORAGE_REQUIRED).addAddress("10.111.222.1", 24).addRoute("0.0.0.0", 0).addDnsServer("10.111.222.3").addAllowedApplication(vpnSvc.getPackageName()).allowBypass();
if (Build.VERSION.SDK_INT >= 29) {
allowBypass.setMetered(false);
}
parcelFileDescriptor = allowBypass.establish();
} catch (Exception unused) {
}
}
this.f19052c = parcelFileDescriptor;
}
/* JADX WARN: Type inference failed for: r0v2, types: [com.mycompany.app.vpn.VpnAdapter$VpnItem, java.lang.Object] */
/* JADX WARN: Type inference failed for: r0v5, types: [com.mycompany.app.vpn.VpnAdapter$VpnItem, java.lang.Object] */
/* JADX WARN: Type inference failed for: r8v4, types: [com.mycompany.app.vpn.VpnAdapter$VpnItem, java.lang.Object] */
/* JADX WARN: Type inference failed for: r8v5, types: [com.mycompany.app.vpn.VpnAdapter$VpnItem, java.lang.Object] */
public static VpnItem c(Context context) {
String[] split2;
if (PrefTts.z == -1 && !TextUtils.isEmpty(PrefTts.A) && !TextUtils.isEmpty(PrefTts.B)) {
?? obj = new Object();
obj.f19053a = PrefTts.A;
String str = PrefTts.B;
String str2 = null;
if (!TextUtils.isEmpty(str) && (split2 = str.split(",")) != null && split2.length == 4) {
StringBuilder sb = null;
for (int i = 0; i < 4; i++) {
String str3 = split2[i];
if (!TextUtils.isEmpty(str3) && !"x".equals(str3)) {
if (sb == null) {
sb = new StringBuilder();
} else {
sb.append(",");
}
sb.append(str3);
}
}
if (sb != null) {
str2 = sb.toString();
}
}
obj.b = str2;
return obj;
}
Resources resources = context.getResources();
int i2 = PrefTts.z;
if (i2 >= 0 && i2 < 18) {
String[] stringArray = resources.getStringArray(R.array.urls);
String[] stringArray2 = resources.getStringArray(R.array.ips);
if (stringArray != null && stringArray2 != null && stringArray.length == 18 && stringArray2.length == 18) {
?? obj2 = new Object();
int i3 = PrefTts.z;
obj2.f19053a = stringArray[i3];
obj2.b = stringArray2[i3];
return obj2;
}
?? obj3 = new Object();
obj3.f19053a = resources.getString(R.string.url0);
obj3.b = resources.getString(R.string.ips0);
return obj3;
}
PrefTts.z = 0;
?? obj4 = new Object();
obj4.f19053a = resources.getString(R.string.url0);
obj4.b = resources.getString(R.string.ips0);
return obj4;
}
public final synchronized void a() {
try {
Session session = this.d;
if (session != null) {
session.disconnect();
this.d = null;
}
ParcelFileDescriptor parcelFileDescriptor = this.f19052c;
if (parcelFileDescriptor != null) {
try {
parcelFileDescriptor.close();
} catch (IOException unused) {
}
this.f19052c = null;
}
this.b = null;
} catch (Throwable th) {
throw th;
}
}
public final boolean b() {
DoHServer doHServer;
if (this.f19052c != null) {
if (this.d == null) {
VpnSvc vpnSvc = this.f19051a;
try {
VpnItem c2 = c(vpnSvc);
doHServer = new DoHServer(c2.f19053a, c2.b, vpnSvc, this.b);
} catch (Exception | UnsatisfiedLinkError unused) {
doHServer = null;
}
DoHServer doHServer2 = doHServer;
if (doHServer2 != null) {
try {
this.d = Backend.connectSession(this.f19052c.getFd(), "10.111.222.3:53", doHServer2, this.f19051a, this.b);
return true;
} catch (Exception | UnsatisfiedLinkError unused2) {
return false;
}
}
return false;
}
return true;
}
return false;
}
}