Repo cloned
This commit is contained in:
commit
496ae75f58
7988 changed files with 1451097 additions and 0 deletions
22
core-gms/base/build.gradle.kts
Normal file
22
core-gms/base/build.gradle.kts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
plugins {
|
||||
id("signal-library")
|
||||
}
|
||||
|
||||
val gmsVersionCode = 12451000
|
||||
|
||||
android {
|
||||
namespace = "com.google.android.gms"
|
||||
|
||||
buildFeatures {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
buildConfigField("int", "GMS_VERSION_CODE", gmsVersionCode.toString())
|
||||
resValue("integer", "google_play_services_version", gmsVersionCode.toString())
|
||||
}
|
||||
|
||||
lint {
|
||||
disable += setOf("LogNotSignal")
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public class ConnectionResult {
|
||||
public static final int UNKNOWN = -1;
|
||||
public static final int SUCCESS = 0;
|
||||
public static final int SERVICE_MISSING = 1;
|
||||
public static final int SERVICE_VERSION_UPDATE_REQUIRED = 2;
|
||||
public static final int SERVICE_DISABLED = 3;
|
||||
public static final int NETWORK_ERROR = 7;
|
||||
public static final int SERVICE_INVALID = 9;
|
||||
public static final int API_UNAVAILABLE = 16;
|
||||
public static final int SERVICE_UPDATING = 18;
|
||||
public static final int SERVICE_MISSING_PERMISSION = 19;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public final class GoogleApiAvailability extends GoogleApiAvailabilityLight {
|
||||
|
||||
private static final class InstanceHolder {
|
||||
private static final GoogleApiAvailability instance = new GoogleApiAvailability();
|
||||
}
|
||||
|
||||
private GoogleApiAvailability() {}
|
||||
|
||||
public static GoogleApiAvailability getInstance() {
|
||||
return InstanceHolder.instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.BuildConfig;
|
||||
|
||||
@Keep
|
||||
public class GoogleApiAvailabilityLight {
|
||||
|
||||
public static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms";
|
||||
public static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending";
|
||||
|
||||
public static final int GOOGLE_PLAY_SERVICES_VERSION_CODE = BuildConfig.GMS_VERSION_CODE;
|
||||
|
||||
public int isGooglePlayServicesAvailable(@NonNull Context context) {
|
||||
return isGooglePlayServicesAvailable(context, GOOGLE_PLAY_SERVICES_VERSION_CODE);
|
||||
}
|
||||
|
||||
public int isGooglePlayServicesAvailable(@NonNull Context context, int minApkVersion) {
|
||||
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context, minApkVersion);
|
||||
|
||||
if (GooglePlayServicesUtil.isPlayServicesPossiblyUpdating(context, status)) {
|
||||
return ConnectionResult.SERVICE_UPDATING;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PendingIntent getErrorResolutionPendingIntent(@NonNull Context context, int errorCode, int requestCode) {
|
||||
Intent intent = getErrorResolutionIntent(errorCode);
|
||||
if (intent == null) {
|
||||
return null;
|
||||
}
|
||||
return PendingIntent.getActivity(
|
||||
context, requestCode, intent,
|
||||
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Intent getErrorResolutionIntent(int errorCode) {
|
||||
switch (errorCode) {
|
||||
case ConnectionResult.SERVICE_MISSING:
|
||||
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
|
||||
return new Intent(Intent.ACTION_VIEW)
|
||||
.setData(Uri.parse("market://details?id=" + GOOGLE_PLAY_SERVICES_PACKAGE))
|
||||
.setPackage(GOOGLE_PLAY_STORE_PACKAGE)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
|
||||
case ConnectionResult.SERVICE_DISABLED:
|
||||
return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||
.setData(Uri.fromParts("package", GOOGLE_PLAY_SERVICES_PACKAGE, null));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import static com.google.android.gms.common.GoogleApiAvailability.GOOGLE_PLAY_SERVICES_VERSION_CODE;
|
||||
|
||||
@Keep
|
||||
public final class GooglePlayServicesIncorrectManifestValueException extends GooglePlayServicesManifestException {
|
||||
|
||||
public GooglePlayServicesIncorrectManifestValueException(int actualVersion) {
|
||||
super(actualVersion, getString(actualVersion));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static String getString(int actualVersion) {
|
||||
return "The meta-data tag in your app's AndroidManifest.xml does not have the right value. " +
|
||||
" Expected " + GOOGLE_PLAY_SERVICES_VERSION_CODE + " but found " + actualVersion + ". " +
|
||||
"You must have the following declaration within the <application> element: " +
|
||||
"<meta-data android:name=\"com.google.android.gms.version\" " +
|
||||
"android:value=\"@integer/google_play_services_version\" />";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import static com.google.android.gms.common.GoogleApiAvailability.GOOGLE_PLAY_SERVICES_VERSION_CODE;
|
||||
|
||||
@Keep
|
||||
public class GooglePlayServicesManifestException extends IllegalStateException {
|
||||
|
||||
private final int actualVersion;
|
||||
|
||||
public GooglePlayServicesManifestException(int actualVersion, String message) {
|
||||
super(message);
|
||||
this.actualVersion = actualVersion;
|
||||
}
|
||||
|
||||
public int getActualVersion() {
|
||||
return actualVersion;
|
||||
}
|
||||
|
||||
public int getExpectedVersion() {
|
||||
return GOOGLE_PLAY_SERVICES_VERSION_CODE;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public final class GooglePlayServicesMissingManifestValueException extends GooglePlayServicesManifestException {
|
||||
|
||||
private static final String ERROR_MESSAGE =
|
||||
"A required meta-data tag in your app's AndroidManifest.xml does not exist. " +
|
||||
"You must have the following declaration within the <application> element: " +
|
||||
"<meta-data android:name=\"com.google.android.gms.version\" " +
|
||||
"android:value=\"@integer/google_play_services_version\" />";
|
||||
|
||||
public GooglePlayServicesMissingManifestValueException() {
|
||||
super(0, ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public final class GooglePlayServicesNotAvailableException extends Exception {
|
||||
|
||||
public final int errorCode;
|
||||
|
||||
public GooglePlayServicesNotAvailableException(int errorCode) {
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class GooglePlayServicesRepairableException extends UserRecoverableException {
|
||||
|
||||
public final int connectionStatusCode;
|
||||
|
||||
public GooglePlayServicesRepairableException(int connectionStatusCode, @NonNull String msg, @NonNull Intent intent) {
|
||||
super(msg, intent);
|
||||
this.connectionStatusCode = connectionStatusCode;
|
||||
}
|
||||
|
||||
public int getConnectionStatusCode() {
|
||||
return connectionStatusCode;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.Preconditions;
|
||||
import com.google.android.gms.common.wrappers.PackageManagerWrapper;
|
||||
import com.google.android.gms.common.wrappers.Wrappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.android.gms.common.GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE;
|
||||
import static com.google.android.gms.common.GoogleApiAvailability.GOOGLE_PLAY_SERVICES_VERSION_CODE;
|
||||
|
||||
@Keep
|
||||
public class GooglePlayServicesUtil {
|
||||
|
||||
private static final String TAG = "GooglePlayServicesUtil";
|
||||
|
||||
GooglePlayServicesUtil() {}
|
||||
|
||||
public static int isGooglePlayServicesAvailable(@NonNull Context context) {
|
||||
return isGooglePlayServicesAvailable(context, GOOGLE_PLAY_SERVICES_VERSION_CODE);
|
||||
}
|
||||
|
||||
public static int isGooglePlayServicesAvailable(@NonNull Context context, int minApkVersion) {
|
||||
Preconditions.checkArgument(minApkVersion >= 0, "minApkVersion must be non-negative");
|
||||
|
||||
int manifestVersion = PlayServicesOptions.getVersionCodeFromResource(context);
|
||||
if (manifestVersion == 0) {
|
||||
throw new GooglePlayServicesMissingManifestValueException();
|
||||
}
|
||||
if (manifestVersion != GOOGLE_PLAY_SERVICES_VERSION_CODE) {
|
||||
throw new GooglePlayServicesIncorrectManifestValueException(manifestVersion);
|
||||
}
|
||||
|
||||
final PackageManagerWrapper pm = Wrappers.packageManager(context);
|
||||
|
||||
PackageInfo gmsInfo;
|
||||
try {
|
||||
gmsInfo = pm.getPackageInfo(GOOGLE_PLAY_SERVICES_PACKAGE, PackageManager.GET_SIGNATURES);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, context.getPackageName() + " requires Google Play services, but they are missing.");
|
||||
return ConnectionResult.SERVICE_MISSING;
|
||||
}
|
||||
|
||||
if (!GoogleSignatureVerifier.isGooglePublicSignedPackage(gmsInfo)) {
|
||||
Log.w(TAG, context.getPackageName() + " requires Google Play services, but their signature is invalid.");
|
||||
return ConnectionResult.SERVICE_INVALID;
|
||||
}
|
||||
|
||||
if (normalizeVersionCode(gmsInfo.versionCode) < normalizeVersionCode(minApkVersion)) {
|
||||
Log.w(TAG, context.getPackageName() + " requires Google Play services version " +
|
||||
minApkVersion + ", but found " + gmsInfo.versionCode);
|
||||
return ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED;
|
||||
}
|
||||
|
||||
if (gmsInfo.applicationInfo == null || !gmsInfo.applicationInfo.enabled) {
|
||||
return ConnectionResult.SERVICE_DISABLED;
|
||||
}
|
||||
|
||||
return ConnectionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public static boolean isPlayServicesPossiblyUpdating(@NonNull Context context, int status) {
|
||||
return switch (status) {
|
||||
case ConnectionResult.SERVICE_UPDATING -> true;
|
||||
case ConnectionResult.SERVICE_MISSING -> isUpdatingOrEnabled(context);
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private static boolean isUpdatingOrEnabled(Context context) {
|
||||
final PackageManagerWrapper pm = Wrappers.packageManager(context);
|
||||
|
||||
try {
|
||||
List<PackageInstaller.SessionInfo> sessions =
|
||||
pm.getPackageInstaller().getAllSessions();
|
||||
|
||||
for (PackageInstaller.SessionInfo session : sessions) {
|
||||
if (GOOGLE_PLAY_SERVICES_PACKAGE.equals(session.getAppPackageName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
try {
|
||||
return pm.getApplicationInfo(GOOGLE_PLAY_SERVICES_PACKAGE, 0).enabled;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static int normalizeVersionCode(int versionCode) {
|
||||
return versionCode == -1 ? -1 : versionCode / 1000;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.Signature;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.util.Hex;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
class GoogleSignatureVerifier {
|
||||
|
||||
private static final String TAG = "GoogleSignatureVerifier";
|
||||
|
||||
/**
|
||||
* SHA-1: 38918a453d07199354f8b19af05ec6562ced5788
|
||||
* SHA-256: f0fd6c5b410f25cb25c3b53346c8972fae30f8ee7411df910480ad6b2d60db83
|
||||
* Certificate: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
|
||||
*/
|
||||
private static final byte[] GMS_PRIMARY_SIGNATURE_SHA256 = new byte[] {
|
||||
(byte) 0xf0, (byte) 0xfd, (byte) 0x6c, (byte) 0x5b, (byte) 0x41, (byte) 0x0f, (byte) 0x25, (byte) 0xcb,
|
||||
(byte) 0x25, (byte) 0xc3, (byte) 0xb5, (byte) 0x33, (byte) 0x46, (byte) 0xc8, (byte) 0x97, (byte) 0x2f,
|
||||
(byte) 0xae, (byte) 0x30, (byte) 0xf8, (byte) 0xee, (byte) 0x74, (byte) 0x11, (byte) 0xdf, (byte) 0x91,
|
||||
(byte) 0x04, (byte) 0x80, (byte) 0xad, (byte) 0x6b, (byte) 0x2d, (byte) 0x60, (byte) 0xdb, (byte) 0x83
|
||||
};
|
||||
|
||||
/**
|
||||
* SHA-1: 2169eddb5fbb1fdf241c262681024692c4fc1ecb
|
||||
* SHA-256: 5f2391277b1dbd489000467e4c2fa6af802430080457dce2f618992e9dfb5402
|
||||
* Certificate: CN=Android, OU=Android, O=Google Inc., L=Mountain View, ST=California, C=US
|
||||
*/
|
||||
private static final byte[] GMS_SECONDARY_SIGNATURE_SHA256 = new byte[] {
|
||||
(byte) 0x5f, (byte) 0x23, (byte) 0x91, (byte) 0x27, (byte) 0x7b, (byte) 0x1d, (byte) 0xbd, (byte) 0x48,
|
||||
(byte) 0x90, (byte) 0x00, (byte) 0x46, (byte) 0x7e, (byte) 0x4c, (byte) 0x2f, (byte) 0xa6, (byte) 0xaf,
|
||||
(byte) 0x80, (byte) 0x24, (byte) 0x30, (byte) 0x08, (byte) 0x04, (byte) 0x57, (byte) 0xdc, (byte) 0xe2,
|
||||
(byte) 0xf6, (byte) 0x18, (byte) 0x99, (byte) 0x2e, (byte) 0x9d, (byte) 0xfb, (byte) 0x54, (byte) 0x02
|
||||
};
|
||||
|
||||
private static final byte[][] VALID_GMS_SIGNATURES = {
|
||||
GMS_PRIMARY_SIGNATURE_SHA256,
|
||||
GMS_SECONDARY_SIGNATURE_SHA256
|
||||
};
|
||||
|
||||
private GoogleSignatureVerifier() {}
|
||||
|
||||
public static boolean isGooglePublicSignedPackage(@NonNull PackageInfo packageInfo) {
|
||||
if (packageInfo.signatures != null) {
|
||||
if (packageInfo.signatures.length > 1) {
|
||||
Log.w(TAG, "Package has more than one signature.");
|
||||
return false;
|
||||
}
|
||||
return verifyGoogleSignature(packageInfo.signatures[0]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean verifyGoogleSignature(@NonNull Signature signature) {
|
||||
try {
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
byte[] hash = sha256.digest(signature.toByteArray());
|
||||
for (byte[] valid : VALID_GMS_SIGNATURES) {
|
||||
if (Arrays.equals(hash, valid)) return true;
|
||||
}
|
||||
Log.w(TAG, "Unrecognized GMS signature: " + Hex.bytesToStringLowercase(hash));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.wrappers.Wrappers;
|
||||
|
||||
final class PlayServicesOptions {
|
||||
|
||||
public static final String GMS_VERSION_RESOURCE_NAME = "com.google.android.gms.version";
|
||||
|
||||
@Nullable
|
||||
private static Integer gmsVersion;
|
||||
|
||||
private PlayServicesOptions() {}
|
||||
|
||||
public static int getVersionCodeFromResource(@NonNull Context context) {
|
||||
if (gmsVersion == null) {
|
||||
try {
|
||||
ApplicationInfo appInfo
|
||||
= Wrappers.packageManager(context)
|
||||
.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
|
||||
Bundle metaData = appInfo.metaData;
|
||||
gmsVersion = metaData != null ? metaData.getInt(GMS_VERSION_RESOURCE_NAME, 0) : 0;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return gmsVersion;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.google.android.gms.common;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class UserRecoverableException extends Exception {
|
||||
|
||||
private final Intent intent;
|
||||
|
||||
public UserRecoverableException(@NonNull String msg, @NonNull Intent intent) {
|
||||
super(msg);
|
||||
this.intent = intent;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Intent getIntent() {
|
||||
return new Intent(intent);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.google.android.gms.common.annotation;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Keep
|
||||
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR })
|
||||
@Documented
|
||||
public @interface KeepForSdk {
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
package com.google.android.gms.common.api.internal;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Application;
|
||||
import android.content.ComponentCallbacks2;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.util.ProcessUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@Keep
|
||||
public final class BackgroundDetector implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
|
||||
|
||||
private final AtomicBoolean inBackground = new AtomicBoolean();
|
||||
private final AtomicBoolean evaluated = new AtomicBoolean();
|
||||
|
||||
private final List<BackgroundStateChangeListener> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
private BackgroundDetector() {}
|
||||
|
||||
private static final class InstanceHolder {
|
||||
private static final BackgroundDetector instance = new BackgroundDetector();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static BackgroundDetector getInstance() {
|
||||
return InstanceHolder.instance;
|
||||
}
|
||||
|
||||
public static void initialize(@NonNull Application application) {
|
||||
BackgroundDetector instance = getInstance();
|
||||
if (instance.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (instance) {
|
||||
if (instance.initialized) {
|
||||
return;
|
||||
}
|
||||
instance.initialized = true;
|
||||
application.registerActivityLifecycleCallbacks(instance);
|
||||
application.registerComponentCallbacks(instance);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean readCurrentStateIfPossible(boolean isInBackgroundDefault) {
|
||||
if (!evaluated.get()) {
|
||||
if (ProcessUtils.isIsolatedProcess()) {
|
||||
return isInBackgroundDefault;
|
||||
}
|
||||
|
||||
ActivityManager.RunningAppProcessInfo info =
|
||||
new ActivityManager.RunningAppProcessInfo();
|
||||
ActivityManager.getMyMemoryState(info);
|
||||
|
||||
boolean firstEval = !evaluated.getAndSet(true);
|
||||
if (firstEval && info.importance > ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
|
||||
inBackground.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
return isInBackground();
|
||||
}
|
||||
|
||||
public boolean isInBackground() {
|
||||
return inBackground.get();
|
||||
}
|
||||
|
||||
public void addListener(@NonNull BackgroundStateChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
|
||||
if (initialized) {
|
||||
listener.onBackgroundStateChanged(inBackground.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
|
||||
enterForeground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(@NonNull Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(@NonNull Activity activity) {
|
||||
enterForeground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(@NonNull Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(@NonNull Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(@NonNull Activity activity) {}
|
||||
|
||||
@Override
|
||||
public void onTrimMemory(int level) {
|
||||
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
|
||||
enterBackground();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {}
|
||||
|
||||
private void enterForeground() {
|
||||
boolean stateChanged = inBackground.compareAndSet(true, false);
|
||||
evaluated.set(true);
|
||||
if (stateChanged) {
|
||||
notifyListeners(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void enterBackground() {
|
||||
boolean stateChanged = inBackground.compareAndSet(false, true);
|
||||
evaluated.set(true);
|
||||
if (stateChanged) {
|
||||
notifyListeners(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(boolean nowBackground) {
|
||||
for (BackgroundStateChangeListener listener : listeners) {
|
||||
listener.onBackgroundStateChanged(nowBackground);
|
||||
}
|
||||
}
|
||||
|
||||
public interface BackgroundStateChangeListener {
|
||||
void onBackgroundStateChanged(boolean isInBackground);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.google.android.gms.common.internal;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Keep
|
||||
public final class Objects {
|
||||
|
||||
private Objects() {}
|
||||
|
||||
public static boolean equal(Object a, Object b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
public static int hashCode(Object... objects) {
|
||||
return Arrays.hashCode(objects);
|
||||
}
|
||||
|
||||
public static boolean checkBundlesEquality(Bundle a, Bundle b) {
|
||||
if (a == null || b == null) {
|
||||
return a == b;
|
||||
}
|
||||
if (a.size() != b.size()) {
|
||||
return false;
|
||||
}
|
||||
Set<String> keys = a.keySet();
|
||||
if (!keys.containsAll(b.keySet())) {
|
||||
return false;
|
||||
}
|
||||
for (String k : keys) {
|
||||
if (!equal(a.get(k), b.get(k))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static final class ToStringHelper {
|
||||
|
||||
private final Object target;
|
||||
private final List<String> parts;
|
||||
|
||||
private ToStringHelper(@NonNull Object target) {
|
||||
this.target = target;
|
||||
this.parts = new ArrayList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ToStringHelper add(@NonNull String name, Object value) {
|
||||
parts.add(name + "=" + value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
String name = target.getClass().getSimpleName();
|
||||
|
||||
StringBuilder sb = new StringBuilder(name.length() * 2);
|
||||
sb.append(name);
|
||||
sb.append('{');
|
||||
|
||||
for (int i = 0; i < parts.size(); i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(parts.get(i));
|
||||
}
|
||||
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
public static ToStringHelper toStringHelper(@NonNull Object target) {
|
||||
return new ToStringHelper(target);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
package com.google.android.gms.common.internal;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Keep
|
||||
public class Preconditions {
|
||||
|
||||
private Preconditions() {}
|
||||
|
||||
public static double checkArgumentInRange(double value, double lower, double upper, @NonNull String valueName) {
|
||||
if (value < lower) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%f, %f] (too low)", valueName, lower, upper)
|
||||
);
|
||||
} else if (value > upper) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%f, %f] (too high)", valueName, lower, upper)
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static float checkArgumentInRange(float value, float lower, float upper, @NonNull String valueName) {
|
||||
if (value < lower) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%f, %f] (too low)", valueName, lower, upper)
|
||||
);
|
||||
} else if (value > upper) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%f, %f] (too high)", valueName, lower, upper)
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int checkArgumentInRange(int value, int lower, int upper, @NonNull String valueName) {
|
||||
if (value < lower) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%d, %d] (too low)", valueName, lower, upper)
|
||||
);
|
||||
} else if (value > upper) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%d, %d] (too high)", valueName, lower, upper)
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int requireNonZero(int value) {
|
||||
if (value == 0) {
|
||||
throw new IllegalArgumentException("Value must not be zero");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int requireNonZero(int value, Object errorMessage) {
|
||||
if (value == 0) {
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long checkArgumentInRange(long value, long lower, long upper, @NonNull String valueName) {
|
||||
if (value < lower) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%d, %d] (too low)", valueName, lower, upper)
|
||||
);
|
||||
} else if (value > upper) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s is out of range of [%d, %d] (too high)", valueName, lower, upper)
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long requireNonZero(long value) {
|
||||
if (value == 0L) {
|
||||
throw new IllegalArgumentException("Value must not be zero");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static long requireNonZero(long value, @NonNull Object errorMessage) {
|
||||
if (value == 0L) {
|
||||
throw new IllegalArgumentException(errorMessage.toString());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static <T> T checkNotNull(@Nullable T reference) {
|
||||
Objects.requireNonNull(reference);
|
||||
return reference;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static <T> T checkNotNull(@Nullable T reference, @NonNull Object errorMessage) {
|
||||
Objects.requireNonNull(reference, String.valueOf(errorMessage));
|
||||
return reference;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String checkNotEmpty(@Nullable String string) {
|
||||
if (TextUtils.isEmpty(string)) {
|
||||
throw new IllegalArgumentException("String must not be null or empty");
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String checkNotEmpty(@Nullable String string, @NonNull Object errorMessage) {
|
||||
if (TextUtils.isEmpty(string)) {
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean expression) {
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean expression, @NonNull Object errorMessage) {
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean expression, @NonNull String errorMessage, @NonNull Object... errorMessageArgs) {
|
||||
if (!expression) {
|
||||
throw new IllegalArgumentException(String.format(errorMessage, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkMainThread() {
|
||||
checkMainThread("Must be called on the main thread");
|
||||
}
|
||||
|
||||
public static void checkMainThread(@NonNull String errorMessage) {
|
||||
if (!isOnMainThread()) {
|
||||
throw new IllegalStateException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNotGoogleApiHandlerThread() {
|
||||
checkNotGoogleApiHandlerThread("Must not be called on GoogleApiHandler thread.");
|
||||
}
|
||||
|
||||
public static void checkNotGoogleApiHandlerThread(@NonNull String errorMessage) {
|
||||
Looper looper = Looper.myLooper();
|
||||
if (looper != null) {
|
||||
String threadName = looper.getThread().getName();
|
||||
if ("GoogleApiHandler".equals(threadName)) {
|
||||
throw new IllegalStateException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkNotMainThread() {
|
||||
checkNotMainThread("Must not be called on the main thread");
|
||||
}
|
||||
|
||||
public static void checkNotMainThread(@NonNull String errorMessage) {
|
||||
if (isOnMainThread()) {
|
||||
throw new IllegalStateException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression) {
|
||||
if (!expression) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression, @NonNull Object errorMessage) {
|
||||
if (!expression) {
|
||||
throw new IllegalStateException(String.valueOf(errorMessage));
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression, @NonNull String errorMessage, @NonNull Object... errorMessageArgs) {
|
||||
if (!expression) {
|
||||
throw new IllegalStateException(String.format(errorMessage, errorMessageArgs));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOnMainThread() {
|
||||
return Looper.getMainLooper() == Looper.myLooper();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.google.android.gms.common.internal;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.R;
|
||||
|
||||
@Keep
|
||||
public class StringResourceValueReader {
|
||||
|
||||
private final Resources resources;
|
||||
private final String namespace;
|
||||
|
||||
public StringResourceValueReader(@NonNull Context context) {
|
||||
resources = context.getResources();
|
||||
namespace = resources.getResourcePackageName(R.integer.google_play_services_version);
|
||||
}
|
||||
|
||||
@SuppressLint("DiscouragedApi")
|
||||
@Nullable
|
||||
public String getString(@NonNull String name) {
|
||||
int resId = resources.getIdentifier(name, "string", namespace);
|
||||
return resId == 0 ? null : resources.getString(resId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.google.android.gms.common.stats;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.wrappers.Wrappers;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Keep
|
||||
public class ConnectionTracker {
|
||||
|
||||
private static final String TAG = "ConnectionTracker";
|
||||
|
||||
private final Map<ServiceConnection, ServiceConnection> tracked = new ConcurrentHashMap<>();
|
||||
|
||||
private ConnectionTracker() {}
|
||||
|
||||
private static final class InstanceHolder {
|
||||
private static final ConnectionTracker instance = new ConnectionTracker();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ConnectionTracker getInstance() {
|
||||
return InstanceHolder.instance;
|
||||
}
|
||||
|
||||
public boolean bindService(@NonNull Context context,
|
||||
@NonNull Intent intent,
|
||||
@NonNull ServiceConnection conn,
|
||||
int flags)
|
||||
{
|
||||
return bindInternal(context, context.getClass().getName(), intent, conn, flags);
|
||||
}
|
||||
|
||||
public void unbindService(@NonNull Context context, @NonNull ServiceConnection conn) {
|
||||
ServiceConnection current = tracked.remove(conn);
|
||||
try {
|
||||
context.unbindService(Objects.requireNonNullElse(current, conn));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
|
||||
private boolean bindInternal(@NonNull Context context,
|
||||
@NonNull String callerName,
|
||||
@NonNull Intent intent,
|
||||
@NonNull ServiceConnection conn,
|
||||
int flags)
|
||||
{
|
||||
ComponentName component = intent.getComponent();
|
||||
if (component != null) {
|
||||
String pkg = component.getPackageName();
|
||||
if (isStoppedPackage(context, pkg)) {
|
||||
Log.w(TAG, "Attempted to bind to a service in a STOPPED package.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ServiceConnection previous = tracked.putIfAbsent(conn, conn);
|
||||
if (previous != null && conn != previous) {
|
||||
Log.w(TAG, String.format(
|
||||
"Duplicate binding with the same ServiceConnection: %s, %s, %s.",
|
||||
conn, callerName, intent.getAction())
|
||||
);
|
||||
}
|
||||
|
||||
boolean bound = false;
|
||||
try {
|
||||
bound = context.bindService(intent, conn, flags);
|
||||
} finally {
|
||||
if (!bound) {
|
||||
tracked.remove(conn, conn);
|
||||
}
|
||||
}
|
||||
return bound;
|
||||
}
|
||||
|
||||
private static boolean isStoppedPackage(Context context, String packageName) {
|
||||
try {
|
||||
ApplicationInfo ai =
|
||||
Wrappers.packageManager(context).getApplicationInfo(packageName, 0);
|
||||
return (ai.flags & ApplicationInfo.FLAG_STOPPED) != 0;
|
||||
} catch (PackageManager.NameNotFoundException ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.Signature;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.wrappers.Wrappers;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@Keep
|
||||
public class AndroidUtilsLight {
|
||||
|
||||
AndroidUtilsLight() {}
|
||||
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public static byte[] getPackageCertificateHashBytes(@NonNull Context context, @NonNull String packageName)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
PackageInfo pkgInfo =
|
||||
Wrappers.packageManager(context)
|
||||
.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
|
||||
|
||||
Signature[] signatures = pkgInfo.signatures;
|
||||
if (signatures != null && signatures.length == 1) {
|
||||
try {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
||||
return sha1.digest(signatures[0].toByteArray());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public final class Base64Utils {
|
||||
|
||||
private Base64Utils() {}
|
||||
|
||||
@NonNull
|
||||
public static String encode(@NonNull byte[] data) {
|
||||
return Base64.encodeToString(data, Base64.DEFAULT);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String encodeUrlSafe(@NonNull byte[] data) {
|
||||
return Base64.encodeToString(data, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String encodeUrlSafeNoPadding(@NonNull byte[] data) {
|
||||
return Base64.encodeToString(data, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static byte[] decode(@NonNull String encodedData) {
|
||||
return Base64.decode(encodedData, Base64.DEFAULT);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static byte[] decodeUrlSafe(@NonNull String encodedData) {
|
||||
return Base64.decode(encodedData, Base64.URL_SAFE | Base64.NO_WRAP);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static byte[] decodeUrlSafeNoPadding(@NonNull String encodedData) {
|
||||
return Base64.decode(encodedData, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public interface BiConsumer<T, U> {
|
||||
void accept(T t, U u);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public interface Clock {
|
||||
long currentTimeMillis();
|
||||
|
||||
long nanoTime();
|
||||
|
||||
long currentThreadTimeMillis();
|
||||
|
||||
long elapsedRealtime();
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class DefaultClock implements Clock {
|
||||
|
||||
private DefaultClock() {}
|
||||
|
||||
private static final class InstanceHolder {
|
||||
private static final DefaultClock instance = new DefaultClock();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Clock getInstance() {
|
||||
return InstanceHolder.instance;
|
||||
}
|
||||
|
||||
public final long currentTimeMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public final long nanoTime() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
public final long currentThreadTimeMillis() {
|
||||
return SystemClock.currentThreadTimeMillis();
|
||||
}
|
||||
|
||||
public final long elapsedRealtime() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class Hex {
|
||||
|
||||
private Hex() {}
|
||||
|
||||
@NonNull
|
||||
public static String bytesToStringLowercase(@NonNull byte[] bytes) {
|
||||
StringBuilder sb = new StringBuilder(bytes.length * 2);
|
||||
for (byte b : bytes) {
|
||||
sb.append(String.format("%02x", b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String bytesToStringUppercase(@NonNull byte[] bytes) {
|
||||
return bytesToStringUppercase(bytes, false);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String bytesToStringUppercase(@NonNull byte[] bytes, boolean zeroTerminated) {
|
||||
int len = bytes.length;
|
||||
StringBuilder sb = new StringBuilder(len * 2);
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (zeroTerminated && i == len - 1 && bytes[i] == 0) {
|
||||
break;
|
||||
}
|
||||
sb.append(String.format("%02X", bytes[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static byte[] stringToBytes(String hex) throws IllegalArgumentException {
|
||||
int len = hex.length();
|
||||
if (len % 2 != 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
byte[] bytes = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
bytes[i / 2] = (byte) Integer.parseInt(hex.substring(i, i + 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.os.Build.VERSION;
|
||||
|
||||
import androidx.annotation.ChecksSdkIntAtLeast;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.core.os.BuildCompat;
|
||||
|
||||
@Keep
|
||||
public final class PlatformVersion {
|
||||
|
||||
private PlatformVersion() {}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 11)
|
||||
public static boolean isAtLeastHoneycomb() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 12)
|
||||
public static boolean isAtLeastHoneycombMR1() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 14)
|
||||
public static boolean isAtLeastIceCreamSandwich() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 15)
|
||||
public static boolean isAtLeastIceCreamSandwichMR1() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 16)
|
||||
public static boolean isAtLeastJellyBean() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 17)
|
||||
public static boolean isAtLeastJellyBeanMR1() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 18)
|
||||
public static boolean isAtLeastJellyBeanMR2() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 19)
|
||||
public static boolean isAtLeastKitKat() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 20)
|
||||
public static boolean isAtLeastKitKatWatch() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 21)
|
||||
public static boolean isAtLeastLollipop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 22)
|
||||
public static boolean isAtLeastLollipopMR1() {
|
||||
return VERSION.SDK_INT >= 22;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 23)
|
||||
public static boolean isAtLeastM() {
|
||||
return VERSION.SDK_INT >= 23;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 24)
|
||||
public static boolean isAtLeastN() {
|
||||
return VERSION.SDK_INT >= 24;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 26)
|
||||
public static boolean isAtLeastO() {
|
||||
return VERSION.SDK_INT >= 26;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 28)
|
||||
public static boolean isAtLeastP() {
|
||||
return VERSION.SDK_INT >= 28;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 29)
|
||||
public static boolean isAtLeastQ() {
|
||||
return VERSION.SDK_INT >= 29;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 30)
|
||||
public static boolean isAtLeastR() {
|
||||
return VERSION.SDK_INT >= 30;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 31)
|
||||
public static boolean isAtLeastS() {
|
||||
return VERSION.SDK_INT >= 31;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 32)
|
||||
public static boolean isAtLeastSv2() {
|
||||
return VERSION.SDK_INT >= 32;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 33)
|
||||
public static boolean isAtLeastT() {
|
||||
return VERSION.SDK_INT >= 33;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 34)
|
||||
public static boolean isAtLeastU() {
|
||||
return VERSION.SDK_INT >= 34;
|
||||
}
|
||||
|
||||
@ChecksSdkIntAtLeast(api = 35)
|
||||
public static boolean isAtLeastV() {
|
||||
return BuildCompat.isAtLeastV();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@Keep
|
||||
public class ProcessUtils {
|
||||
|
||||
@Nullable
|
||||
private static Boolean cachedIsolated;
|
||||
|
||||
private ProcessUtils() {}
|
||||
|
||||
@NonNull
|
||||
public static String getMyProcessName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public static boolean isIsolatedProcess() {
|
||||
if (cachedIsolated == null) {
|
||||
if (PlatformVersion.isAtLeastP()) {
|
||||
cachedIsolated = Process.isIsolated();
|
||||
} else {
|
||||
cachedIsolated = reflectIsIsolated();
|
||||
}
|
||||
}
|
||||
return cachedIsolated;
|
||||
}
|
||||
|
||||
private static Boolean reflectIsIsolated() {
|
||||
try {
|
||||
return (Boolean) Process.class.getMethod("isIsolated").invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@Keep
|
||||
public class Strings {
|
||||
|
||||
private Strings() {}
|
||||
|
||||
@Nullable
|
||||
public static String emptyToNull(String string) {
|
||||
return TextUtils.isEmpty(string) ? null : string;
|
||||
}
|
||||
|
||||
public static boolean isEmptyOrWhitespace(String string) {
|
||||
return string == null || string.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.google.android.gms.common.util;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
@Keep
|
||||
public @interface VisibleForTesting {
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.google.android.gms.common.util.concurrent;
|
||||
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
@Keep
|
||||
public class NamedThreadFactory implements ThreadFactory {
|
||||
|
||||
private final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
|
||||
|
||||
private final String name;
|
||||
|
||||
public NamedThreadFactory(@NonNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable runnable) {
|
||||
Runnable wrapper = () -> {
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
|
||||
runnable.run();
|
||||
};
|
||||
|
||||
Thread thread = defaultFactory.newThread(wrapper);
|
||||
thread.setName(name);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.google.android.gms.common.wrappers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.util.Pair;
|
||||
|
||||
@Keep
|
||||
public class PackageManagerWrapper {
|
||||
|
||||
private final PackageManager packageManager;
|
||||
private final Context appContext;
|
||||
|
||||
public PackageManagerWrapper(@NonNull Context context) {
|
||||
this.packageManager = context.getPackageManager();
|
||||
this.appContext = context.getApplicationContext();
|
||||
}
|
||||
|
||||
public int checkCallingOrSelfPermission(@NonNull String permission) {
|
||||
return appContext.checkCallingOrSelfPermission(permission);
|
||||
}
|
||||
|
||||
public int checkPermission(@NonNull String permission, @NonNull String packageName) {
|
||||
return packageManager.checkPermission(permission, packageName);
|
||||
}
|
||||
|
||||
public boolean isCallerInstantApp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean hasSystemFeature(@NonNull String featureName) {
|
||||
return packageManager.hasSystemFeature(featureName);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ApplicationInfo getApplicationInfo(@NonNull String packageName, int flags)
|
||||
throws PackageManager.NameNotFoundException
|
||||
{
|
||||
return packageManager.getApplicationInfo(packageName, flags);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PackageInfo getPackageInfo(@NonNull String packageName, int flags)
|
||||
throws PackageManager.NameNotFoundException
|
||||
{
|
||||
return packageManager.getPackageInfo(packageName, flags);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Pair<CharSequence, Drawable> getApplicationLabelAndIcon(@NonNull String packageName)
|
||||
throws PackageManager.NameNotFoundException
|
||||
{
|
||||
ApplicationInfo info = getApplicationInfo(packageName, 0);
|
||||
CharSequence label = packageManager.getApplicationLabel(info);
|
||||
Drawable icon = packageManager.getApplicationIcon(info);
|
||||
return Pair.create(label, icon);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public CharSequence getApplicationLabel(@NonNull String packageName)
|
||||
throws PackageManager.NameNotFoundException
|
||||
{
|
||||
ApplicationInfo info = getApplicationInfo(packageName, 0);
|
||||
return packageManager.getApplicationLabel(info);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PackageInstaller getPackageInstaller() {
|
||||
return packageManager.getPackageInstaller();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.google.android.gms.common.wrappers;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class Wrappers {
|
||||
|
||||
private static volatile PackageManagerWrapper packageManagerWrapper;
|
||||
|
||||
private Wrappers() {}
|
||||
|
||||
public static PackageManagerWrapper packageManager(@NonNull Context context) {
|
||||
PackageManagerWrapper wrapper = packageManagerWrapper;
|
||||
if (wrapper == null) {
|
||||
synchronized (Wrappers.class) {
|
||||
wrapper = packageManagerWrapper;
|
||||
if (wrapper == null) {
|
||||
wrapper = new PackageManagerWrapper(context);
|
||||
packageManagerWrapper = wrapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.google.android.gms.security;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
|
||||
import com.google.android.gms.common.GooglePlayServicesRepairableException;
|
||||
|
||||
@Keep
|
||||
public class ProviderInstaller {
|
||||
|
||||
public static void installIfNeeded(Context context) throws GooglePlayServicesRepairableException, GooglePlayServicesNotAvailableException {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
public static void installIfNeededAsync(Context context, ProviderInstaller.ProviderInstallListener listener) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
public interface ProviderInstallListener {
|
||||
void onProviderInstallFailed(int errorCode, @Nullable Intent recoveryIntent);
|
||||
|
||||
void onProviderInstalled();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.google.android.gms.stats;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@Keep
|
||||
public class WakeLock {
|
||||
|
||||
private final PowerManager.WakeLock pmWakeLock;
|
||||
|
||||
public WakeLock(@NonNull Context context, int levelAndFlags, @NonNull String wakeLockName) {
|
||||
this.pmWakeLock = createWakeLock(context.getApplicationContext(), levelAndFlags, wakeLockName);
|
||||
}
|
||||
|
||||
private static PowerManager.WakeLock createWakeLock(@NonNull Context context, int levelAndFlags, @NonNull String tag) {
|
||||
final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
return pm.newWakeLock(levelAndFlags, tag);
|
||||
}
|
||||
|
||||
public void setReferenceCounted(boolean value) {
|
||||
pmWakeLock.setReferenceCounted(value);
|
||||
}
|
||||
|
||||
public void acquire(long timeoutMillis) {
|
||||
pmWakeLock.acquire(timeoutMillis);
|
||||
}
|
||||
|
||||
public void release() {
|
||||
pmWakeLock.release();
|
||||
}
|
||||
|
||||
public boolean isHeld() {
|
||||
return pmWakeLock.isHeld();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue