soul-browser/sources/java/com/google/android/gms/internal/cast/zzr.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

258 lines
10 KiB
Java

package com.google.android.gms.internal.cast;
import android.content.SharedPreferences;
import android.os.Looper;
import android.text.TextUtils;
import androidx.annotation.MainThread;
import com.google.android.gms.cast.internal.Logger;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.internal.Preconditions;
import com.google.android.gms.common.util.Clock;
import com.google.android.gms.common.util.DefaultClock;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@MainThread
/* loaded from: classes.dex */
public final class zzr {
public static final Logger j = new Logger("FeatureUsageAnalytics", null);
public static final String k = "22.2.0";
public static zzr l;
/* renamed from: a, reason: collision with root package name */
public final zzj f9830a;
public final SharedPreferences b;
/* renamed from: c, reason: collision with root package name */
public final String f9831c;
public long i;
public final Clock h = DefaultClock.getInstance();
public final HashSet f = new HashSet();
public final HashSet g = new HashSet();
public final zzfk e = new zzfk(Looper.getMainLooper());
public final Runnable d = new Runnable() { // from class: com.google.android.gms.internal.cast.zzq
@Override // java.lang.Runnable
public final void run() {
long j2;
zzr zzrVar = zzr.this;
SharedPreferences sharedPreferences = zzrVar.b;
HashSet hashSet = zzrVar.f;
if (!hashSet.isEmpty()) {
HashSet hashSet2 = zzrVar.g;
if (true != hashSet2.equals(hashSet)) {
j2 = 86400000;
} else {
j2 = 172800000;
}
long currentTimeMillis = ((Clock) Preconditions.checkNotNull(zzrVar.h)).currentTimeMillis();
long j3 = zzrVar.i;
if (j3 != 0 && currentTimeMillis - j3 < j2) {
return;
}
zzr.j.b("Upload the feature usage report.", new Object[0]);
zzqb n = zzqc.n();
String str = zzr.k;
n.c();
((zzqc) n.f).p(str);
String str2 = zzrVar.f9831c;
n.c();
((zzqc) n.f).o(str2);
zzqc zzqcVar = (zzqc) n.e();
ArrayList arrayList = new ArrayList();
arrayList.addAll(hashSet);
zzpv n2 = zzpw.n();
n2.c();
((zzpw) n2.f).p(arrayList);
n2.c();
((zzpw) n2.f).o(zzqcVar);
zzpw zzpwVar = (zzpw) n2.e();
zzqq o = zzqr.o();
o.c();
((zzqr) o.f).A(zzpwVar);
zzrVar.f9830a.b(243, (zzqr) o.e());
SharedPreferences.Editor edit = sharedPreferences.edit();
if (!hashSet2.equals(hashSet)) {
hashSet2.clear();
hashSet2.addAll(hashSet);
Iterator it = hashSet2.iterator();
while (it.hasNext()) {
String num = Integer.toString(((zzpm) it.next()).f9824c);
String C = android.support.v4.media.a.C("feature_usage_timestamp_reported_feature_", num);
if (!sharedPreferences.contains(C)) {
C = android.support.v4.media.a.C("feature_usage_timestamp_detected_feature_", num);
}
String C2 = android.support.v4.media.a.C("feature_usage_timestamp_reported_feature_", num);
if (!TextUtils.equals(C, C2)) {
long j4 = sharedPreferences.getLong(C, 0L);
edit.remove(C);
if (j4 != 0) {
edit.putLong(C2, j4);
}
}
}
}
zzrVar.i = currentTimeMillis;
edit.putLong("feature_usage_last_report_time", currentTimeMillis).apply();
}
}
};
public zzr(SharedPreferences sharedPreferences, zzj zzjVar, String str) {
this.b = sharedPreferences;
this.f9830a = zzjVar;
this.f9831c = str;
}
public static void a(zzpm zzpmVar) {
zzr zzrVar;
if (zzj.m && (zzrVar = l) != null) {
SharedPreferences sharedPreferences = zzrVar.b;
String num = Integer.toString(zzpmVar.f9824c);
SharedPreferences.Editor edit = sharedPreferences.edit();
String C = android.support.v4.media.a.C("feature_usage_timestamp_reported_feature_", num);
if (!sharedPreferences.contains(C)) {
C = android.support.v4.media.a.C("feature_usage_timestamp_detected_feature_", num);
}
edit.putLong(C, ((Clock) Preconditions.checkNotNull(zzrVar.h)).currentTimeMillis()).apply();
zzrVar.f.add(zzpmVar);
zzrVar.e.post(zzrVar.d);
}
}
public static zzpm c(String str) {
zzpm zzpmVar = zzpm.DEVELOPER_FEATURE_FLAG_UNKNOWN;
switch (Integer.parseInt(str)) {
case 0:
return zzpmVar;
case 1:
return zzpm.CAF_CAST_BUTTON;
case 2:
return zzpm.CAF_EXPANDED_CONTROLLER;
case 3:
return zzpm.CAF_MINI_CONTROLLER;
case 4:
return zzpm.CAF_CONTAINER_CONTROLLER;
case 5:
return zzpm.CAST_CONTEXT;
case 6:
return zzpm.IMAGE_CACHE;
case 7:
return zzpm.IMAGE_PICKER;
case 8:
return zzpm.AD_BREAK_PARSER;
case 9:
return zzpm.UI_STYLE;
case 10:
return zzpm.HARDWARE_VOLUME_BUTTON;
case 11:
return zzpm.NON_CAST_DEVICE_PROVIDER;
case 12:
return zzpm.PAUSE_CONTROLLER;
case 13:
return zzpm.SEEK_CONTROLLER;
case 14:
return zzpm.STREAM_VOLUME;
case 15:
return zzpm.UI_MEDIA_CONTROLLER;
case 16:
return zzpm.PLAYBACK_RATE_CONTROLLER;
case 17:
return zzpm.PRECACHE;
case 18:
return zzpm.INSTRUCTIONS_VIEW;
case 19:
return zzpm.OPTION_SUSPEND_SESSIONS_WHEN_BACKGROUNDED;
case 20:
return zzpm.OPTION_STOP_RECEIVER_APPLICATION_WHEN_ENDING_SESSION;
case 21:
return zzpm.OPTION_DISABLE_DISCOVERY_AUTOSTART;
case 22:
return zzpm.OPTION_DISABLE_ANALYTICS_LOGGING;
case ConnectionResult.API_DISABLED /* 23 */:
return zzpm.OPTION_PHYSICAL_VOLUME_BUTTONS_WILL_CONTROL_DEVICE_VOLUME;
case ConnectionResult.API_DISABLED_FOR_CONNECTION /* 24 */:
return zzpm.CAF_EXPANDED_CONTROLLER_HIDE_STREAM_POSITION_CONTROLS_FOR_LIVE_CONTENT;
case 25:
return zzpm.CAF_EXPANDED_CONTROLLER_WITH_LIVE_CONTENT;
case 26:
return zzpm.REMOTE_MEDIA_CLIENT_LOAD_MEDIA_WITH_OPTIONS;
case 27:
return zzpm.REMOTE_MEDIA_CLIENT_QUEUE_LOAD_ITEMS_WITH_OPTIONS;
case 28:
return zzpm.REMOTE_MEDIA_CLIENT_LOAD_MEDIA_WITH_LOAD_REQUEST_DATA;
case 29:
return zzpm.LAUNCH_OPTION_ANDROID_RECEIVER_COMPATIBLE;
case 30:
return zzpm.CAST_CONTEXT_SET_LAUNCH_CREDENTIALS_DATA;
case 31:
return zzpm.START_DISCOVERY_AFTER_FIRST_TAP_ON_CAST_BUTTON;
case 32:
return zzpm.CAST_UNAVAILABLE_BUTTON_VISIBLE;
case 33:
return zzpm.CAST_DEFAULT_MEDIA_ROUTER_DIALOG;
case 34:
return zzpm.CAST_CUSTOM_MEDIA_ROUTER_DIALOG;
case 35:
return zzpm.CAST_OUTPUT_SWITCHER_ENABLED;
case 36:
return zzpm.CAST_TRANSFER_TO_LOCAL_ENABLED;
case 37:
return zzpm.CAST_BUTTON_IS_TRIGGERED_DEFAULT_CAST_DIALOG_FALSE;
case 38:
return zzpm.CAST_BUTTON_DELEGATE;
case 39:
return zzpm.CAST_BUTTON_DELEGATE_PRESENT_LNA_PERMISSION_CUSTOM_DIALOG;
case 40:
return zzpm.CAST_BUTTON_DELEGATE_PRESENT_CAST_STATE_CUSTOM_DIALOG;
case 41:
return zzpm.CAST_TRANSFER_TO_LOCAL_USED;
case 42:
return zzpm.MEDIA_REQUEST_ITEM_MAP_HLS_SEGMENT_FORMAT_TO_STRING;
case 43:
return zzpm.MEDIA_REQUEST_ITEM_MAP_HLS_SEGMENT_FORMAT_STRING_TO_ENUM;
case 44:
return zzpm.HLS_SEGMENT_MAP_HLS_SEGMENT_FORMAT_TO_STRING;
case 45:
return zzpm.HLS_SEGMENT_MAP_HLS_SEGMENT_FORMAT_STRING_TO_ENUM;
case 46:
return zzpm.HLS_VIDEO_SEGMENT_MAP_HLS_VIDEO_SEGMENT_FORMAT_TO_STRING;
case 47:
return zzpm.HLS_VIDEO_SEGMENT_MAP_HLS_VIDEO_SEGMENT_FORMAT_STRING_TO_ENUM;
case 48:
return zzpm.CAST_SLIDER_SET_AD_BLOCK_POSITIONS;
case 49:
return zzpm.CAF_NOTIFICATION_SERVICE;
case 50:
return zzpm.HARDWARE_VOLUME_BUTTON_PRESS;
case 51:
return zzpm.CAST_SDK_DEFAULT_DEVICE_DIALOG;
case 52:
return zzpm.CAST_SDK_CUSTOM_DEVICE_DIALOG;
case 53:
return zzpm.PERSISTENT_CAST_BUTTON_DISCOVERY_DISABLED_WITH_CONFLICT_TYPES;
case 54:
return zzpm.CAST_DEVICE_DIALOG_FACTORY_INSTANTIATED;
case 55:
return zzpm.CAF_MEDIA_NOTIFICATION_PROXY;
case 56:
return zzpm.REMOTE_CONNECTION_MANAGER_ACQUIRED;
case 57:
return zzpm.REMOTE_CONNECTION_CALLBACK_SET;
default:
return null;
}
}
public final void b(HashSet hashSet) {
if (hashSet.isEmpty()) {
return;
}
SharedPreferences.Editor edit = this.b.edit();
Iterator it = hashSet.iterator();
while (it.hasNext()) {
edit.remove((String) it.next());
}
edit.apply();
}
}