soul-browser/sources/java/com/google/android/gms/common/GoogleApiAvailability.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

394 lines
18 KiB
Java

package com.google.android.gms.common;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.support.v4.media.a;
import android.util.Log;
import android.util.TypedValue;
import android.widget.ProgressBar;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.IntentSenderRequest;
import androidx.annotation.GuardedBy;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.google.android.gms.ads.RequestConfiguration;
import com.google.android.gms.common.annotation.KeepForSdk;
import com.google.android.gms.common.api.GoogleApi;
import com.google.android.gms.common.api.GoogleApiActivity;
import com.google.android.gms.common.api.HasApiKey;
import com.google.android.gms.common.api.internal.GoogleApiManager;
import com.google.android.gms.common.api.internal.LifecycleFragment;
import com.google.android.gms.common.api.internal.zabr;
import com.google.android.gms.common.api.internal.zabs;
import com.google.android.gms.common.api.internal.zabx;
import com.google.android.gms.common.internal.HideFirstParty;
import com.google.android.gms.common.internal.Preconditions;
import com.google.android.gms.common.internal.ShowFirstParty;
import com.google.android.gms.common.internal.zag;
import com.google.android.gms.common.util.DeviceProperties;
import com.google.android.gms.common.util.PlatformVersion;
import com.google.android.gms.common.wrappers.InstantApps;
import com.google.android.gms.internal.base.zak;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import java.util.ArrayList;
import java.util.Arrays;
/* loaded from: classes.dex */
public class GoogleApiAvailability extends GoogleApiAvailabilityLight {
@NonNull
public static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms";
@GuardedBy
private String zac;
private static final Object zaa = new Object();
private static final GoogleApiAvailability zab = new GoogleApiAvailability();
public static final int GOOGLE_PLAY_SERVICES_VERSION_CODE = GoogleApiAvailabilityLight.GOOGLE_PLAY_SERVICES_VERSION_CODE;
@NonNull
public static GoogleApiAvailability getInstance() {
return zab;
}
@NonNull
public static final Task zai(@NonNull HasApiKey hasApiKey, @NonNull HasApiKey... hasApiKeyArr) {
Preconditions.checkNotNull(hasApiKey, "Requested API must not be null.");
for (HasApiKey hasApiKey2 : hasApiKeyArr) {
Preconditions.checkNotNull(hasApiKey2, "Requested API must not be null.");
}
ArrayList arrayList = new ArrayList(hasApiKeyArr.length + 1);
arrayList.add(hasApiKey);
arrayList.addAll(Arrays.asList(hasApiKeyArr));
return GoogleApiManager.zab().zah(arrayList);
}
@NonNull
public Task<Void> checkApiAvailability(@NonNull GoogleApi<?> googleApi, @NonNull GoogleApi<?>... googleApiArr) {
return zai(googleApi, googleApiArr).q(zab.zaa);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@ShowFirstParty
@KeepForSdk
public int getClientVersion(@NonNull Context context) {
return super.getClientVersion(context);
}
@Nullable
public Dialog getErrorDialog(@NonNull Activity activity, int i, int i2) {
return getErrorDialog(activity, i, i2, (DialogInterface.OnCancelListener) null);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@Nullable
@ShowFirstParty
@KeepForSdk
public Intent getErrorResolutionIntent(@Nullable Context context, int i, @Nullable String str) {
return super.getErrorResolutionIntent(context, i, str);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@Nullable
public PendingIntent getErrorResolutionPendingIntent(@NonNull Context context, int i, int i2) {
return super.getErrorResolutionPendingIntent(context, i, i2);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@NonNull
public final String getErrorString(int i) {
return super.getErrorString(i);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@HideFirstParty
public int isGooglePlayServicesAvailable(@NonNull Context context) {
return super.isGooglePlayServicesAvailable(context);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
public final boolean isUserResolvableError(int i) {
return super.isUserResolvableError(i);
}
@NonNull
@MainThread
public Task<Void> makeGooglePlayServicesAvailable(@NonNull Activity activity) {
int i = GOOGLE_PLAY_SERVICES_VERSION_CODE;
Preconditions.checkMainThread("makeGooglePlayServicesAvailable must be called from the main thread");
int isGooglePlayServicesAvailable = isGooglePlayServicesAvailable(activity, i);
if (isGooglePlayServicesAvailable == 0) {
return Tasks.e(null);
}
zabx zaa2 = zabx.zaa(activity);
zaa2.zaf(new ConnectionResult(isGooglePlayServicesAvailable, null), 0);
return zaa2.zab();
}
@TargetApi(26)
public void setDefaultNotificationChannelId(@NonNull Context context, @NonNull String str) {
if (PlatformVersion.isAtLeastO()) {
Preconditions.checkNotNull(((NotificationManager) Preconditions.checkNotNull(context.getSystemService("notification"))).getNotificationChannel(str));
}
synchronized (zaa) {
this.zac = str;
}
}
public boolean showErrorDialogFragment(@NonNull Activity activity, int i, int i2) {
return showErrorDialogFragment(activity, i, i2, (DialogInterface.OnCancelListener) null);
}
public void showErrorNotification(@NonNull Context context, int i) {
zac(context, i, null, getErrorResolutionPendingIntent(context, i, 0, "n"));
}
/* JADX WARN: Multi-variable type inference failed */
@Nullable
public final Dialog zaa(@NonNull Context context, int i, @Nullable zag zagVar, @Nullable DialogInterface.OnCancelListener onCancelListener, @Nullable DialogInterface.OnClickListener onClickListener) {
AlertDialog.Builder builder = null;
if (i == 0) {
return null;
}
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.alertDialogTheme, typedValue, true);
if ("Theme.Dialog.Alert".equals(context.getResources().getResourceEntryName(typedValue.resourceId))) {
builder = new AlertDialog.Builder(context, 5);
}
if (builder == null) {
builder = new AlertDialog.Builder(context);
}
builder.setMessage(com.google.android.gms.common.internal.zac.zac(context, i));
if (onCancelListener != null) {
builder.setOnCancelListener(onCancelListener);
}
String zae = com.google.android.gms.common.internal.zac.zae(context, i);
if (zae != null) {
if (zagVar == null) {
zagVar = onClickListener;
}
builder.setPositiveButton(zae, zagVar);
}
String zaa2 = com.google.android.gms.common.internal.zac.zaa(context, i);
if (zaa2 != null) {
builder.setTitle(zaa2);
}
Log.w("GoogleApiAvailability", a.e(i, "Creating dialog for Google Play services availability issue. ConnectionResult="), new IllegalArgumentException());
return builder.create();
}
public final boolean zab(@NonNull Activity activity, @NonNull LifecycleFragment lifecycleFragment, int i, int i2, @Nullable DialogInterface.OnCancelListener onCancelListener) {
Dialog zaa2 = zaa(activity, i, zag.zad(lifecycleFragment, getErrorResolutionIntent(activity, i, "d"), 2), onCancelListener, null);
if (zaa2 == null) {
return false;
}
zag(activity, zaa2, GooglePlayServicesUtil.GMS_ERROR_DIALOG, onCancelListener);
return true;
}
/* JADX WARN: Multi-variable type inference failed */
/* JADX WARN: Type inference failed for: r11v6, types: [java.lang.Object, androidx.core.app.NotificationCompat$Style, androidx.core.app.NotificationCompat$BigTextStyle] */
@TargetApi(20)
public final void zac(Context context, int i, @Nullable String str, @Nullable PendingIntent pendingIntent) {
int i2;
String str2;
Log.w("GoogleApiAvailability", a.f(i, "GMS core API Availability. ConnectionResult=", ", tag=null"), new IllegalArgumentException());
if (i == 18) {
zah(context);
return;
}
if (pendingIntent == null) {
if (i == 6) {
Log.w("GoogleApiAvailability", "Missing resolution for ConnectionResult.RESOLUTION_REQUIRED. Call GoogleApiAvailability#showErrorNotification(Context, ConnectionResult) instead.");
return;
}
return;
}
String zab2 = com.google.android.gms.common.internal.zac.zab(context, i);
String zad = com.google.android.gms.common.internal.zac.zad(context, i);
Resources resources = context.getResources();
NotificationManager notificationManager = (NotificationManager) Preconditions.checkNotNull(context.getSystemService("notification"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null);
builder.p = true;
builder.d(16);
builder.e = NotificationCompat.Builder.c(zab2);
?? obj = new Object();
obj.b = NotificationCompat.Builder.c(zad);
builder.g(obj);
boolean isWearable = DeviceProperties.isWearable(context);
int i3 = android.R.drawable.stat_sys_warning;
if (isWearable) {
Preconditions.checkState(PlatformVersion.isAtLeastKitKatWatch());
int i4 = context.getApplicationInfo().icon;
if (i4 != 0) {
i3 = i4;
}
builder.u.icon = i3;
builder.i = 2;
if (DeviceProperties.isWearableWithoutPlayStore(context)) {
builder.b.add(new NotificationCompat.Action(com.google.android.gms.base.R.drawable.common_full_open_on_phone, resources.getString(com.google.android.gms.base.R.string.common_open_on_phone), pendingIntent));
} else {
builder.g = pendingIntent;
}
} else {
builder.u.icon = android.R.drawable.stat_sys_warning;
String string = resources.getString(com.google.android.gms.base.R.string.common_google_play_services_notification_ticker);
builder.u.tickerText = NotificationCompat.Builder.c(string);
builder.u.when = System.currentTimeMillis();
builder.g = pendingIntent;
builder.f = NotificationCompat.Builder.c(zad);
}
if (PlatformVersion.isAtLeastO()) {
Preconditions.checkState(PlatformVersion.isAtLeastO());
synchronized (zaa) {
str2 = this.zac;
}
if (str2 == null) {
str2 = "com.google.android.gms.availability";
NotificationChannel notificationChannel = notificationManager.getNotificationChannel("com.google.android.gms.availability");
String string2 = context.getResources().getString(com.google.android.gms.base.R.string.common_google_play_services_notification_channel_name);
if (notificationChannel == null) {
notificationManager.createNotificationChannel(new NotificationChannel("com.google.android.gms.availability", string2, 4));
} else if (!string2.contentEquals(notificationChannel.getName())) {
notificationChannel.setName(string2);
notificationManager.createNotificationChannel(notificationChannel);
}
}
builder.s = str2;
}
Notification b = builder.b();
if (i != 1 && i != 2 && i != 3) {
i2 = 39789;
} else {
GooglePlayServicesUtilLight.sCanceledAvailabilityNotification.set(false);
i2 = 10436;
}
notificationManager.notify(i2, b);
}
public final boolean zad(@NonNull Context context, @NonNull ConnectionResult connectionResult, int i) {
PendingIntent errorResolutionPendingIntent;
if (InstantApps.isInstantApp(context) || (errorResolutionPendingIntent = getErrorResolutionPendingIntent(context, connectionResult)) == null) {
return false;
}
zac(context, connectionResult.getErrorCode(), null, PendingIntent.getActivity(context, 0, GoogleApiActivity.zaa(context, errorResolutionPendingIntent, i, true), zak.f9599a | 134217728));
return true;
}
@NonNull
public final Dialog zae(@NonNull Activity activity, @NonNull DialogInterface.OnCancelListener onCancelListener) {
ProgressBar progressBar = new ProgressBar(activity, null, android.R.attr.progressBarStyleLarge);
progressBar.setIndeterminate(true);
progressBar.setVisibility(0);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setView(progressBar);
builder.setMessage(com.google.android.gms.common.internal.zac.zac(activity, 18));
builder.setPositiveButton(RequestConfiguration.MAX_AD_CONTENT_RATING_UNSPECIFIED, (DialogInterface.OnClickListener) null);
AlertDialog create = builder.create();
zag(activity, create, "GooglePlayServicesUpdatingDialog", onCancelListener);
return create;
}
@Nullable
public final zabs zaf(Context context, zabr zabrVar) {
IntentFilter intentFilter = new IntentFilter("android.intent.action.PACKAGE_ADDED");
intentFilter.addDataScheme("package");
zabs zabsVar = new zabs(zabrVar);
ContextCompat.f(context, zabsVar, intentFilter, null, 2);
zabsVar.zaa(context);
if (!isUninstalledAppPossiblyUpdating(context, "com.google.android.gms")) {
zabrVar.zaa();
zabsVar.zab();
return null;
}
return zabsVar;
}
public final void zag(Activity activity, Dialog dialog, String str, @Nullable DialogInterface.OnCancelListener onCancelListener) {
try {
if (activity instanceof FragmentActivity) {
SupportErrorDialogFragment.newInstance(dialog, onCancelListener).show(((FragmentActivity) activity).T(), str);
return;
}
} catch (NoClassDefFoundError unused) {
}
ErrorDialogFragment.newInstance(dialog, onCancelListener).show(activity.getFragmentManager(), str);
}
public final void zah(Context context) {
new zad(this, context).sendEmptyMessageDelayed(1, 120000L);
}
@Nullable
public Dialog getErrorDialog(@NonNull Activity activity, int i, int i2, @Nullable DialogInterface.OnCancelListener onCancelListener) {
return zaa(activity, i, zag.zab(activity, getErrorResolutionIntent(activity, i, "d"), i2), onCancelListener, null);
}
@Nullable
public PendingIntent getErrorResolutionPendingIntent(@NonNull Context context, @NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
return connectionResult.getResolution();
}
return getErrorResolutionPendingIntent(context, connectionResult.getErrorCode(), 0);
}
@Override // com.google.android.gms.common.GoogleApiAvailabilityLight
@ShowFirstParty
@KeepForSdk
public int isGooglePlayServicesAvailable(@NonNull Context context, int i) {
return super.isGooglePlayServicesAvailable(context, i);
}
public boolean showErrorDialogFragment(@NonNull Activity activity, int i, int i2, @Nullable DialogInterface.OnCancelListener onCancelListener) {
Dialog errorDialog = getErrorDialog(activity, i, i2, onCancelListener);
if (errorDialog == null) {
return false;
}
zag(activity, errorDialog, GooglePlayServicesUtil.GMS_ERROR_DIALOG, onCancelListener);
return true;
}
@NonNull
public Task<Void> checkApiAvailability(@NonNull HasApiKey<?> hasApiKey, @NonNull HasApiKey<?>... hasApiKeyArr) {
return zai(hasApiKey, hasApiKeyArr).q(zac.zaa);
}
public void showErrorNotification(@NonNull Context context, @NonNull ConnectionResult connectionResult) {
zac(context, connectionResult.getErrorCode(), null, getErrorResolutionPendingIntent(context, connectionResult));
}
@Nullable
public Dialog getErrorDialog(@NonNull Fragment fragment, int i, int i2) {
return getErrorDialog(fragment, i, i2, (DialogInterface.OnCancelListener) null);
}
public boolean showErrorDialogFragment(@NonNull Activity activity, int i, @NonNull ActivityResultLauncher<IntentSenderRequest> activityResultLauncher, @Nullable DialogInterface.OnCancelListener onCancelListener) {
Dialog zaa2 = zaa(activity, i, null, onCancelListener, new zaa(this, activity, i, activityResultLauncher));
if (zaa2 == null) {
return false;
}
zag(activity, zaa2, GooglePlayServicesUtil.GMS_ERROR_DIALOG, onCancelListener);
return true;
}
@Nullable
public Dialog getErrorDialog(@NonNull Fragment fragment, int i, int i2, @Nullable DialogInterface.OnCancelListener onCancelListener) {
return zaa(fragment.requireContext(), i, zag.zac(fragment, getErrorResolutionIntent(fragment.requireContext(), i, "d"), i2), onCancelListener, null);
}
}