fix(YouTube - GmsCore support): Prompt to disable battery optimizations, if not done already (#601)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
LisoUseInAIKyrios 2024-04-06 22:46:07 +04:00 committed by GitHub
parent fedace02fd
commit c5c9de500d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,21 +1,25 @@
package app.revanced.integrations.shared; package app.revanced.integrations.shared;
import static app.revanced.integrations.shared.StringRef.str;
import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.PowerManager; import android.os.PowerManager;
import android.provider.Settings;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import static app.revanced.integrations.shared.StringRef.str;
/** /**
* @noinspection unused * @noinspection unused
*/ */
@ -45,27 +49,19 @@ public class GmsCoreSupport {
System.exit(0); System.exit(0);
} }
private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) { private static void showBatteryOptimizationDialog(Activity context,
if (!(context instanceof Activity)) { String dialogMessageRef,
// Context is for the application and cannot show a dialog using it. String positiveButtonStringRef,
Utils.showToastLong(str(toastMessageKey)); DialogInterface.OnClickListener onPositiveClickListener) {
open(link);
return;
}
// Use a delay to allow the activity to finish initializing. // Use a delay to allow the activity to finish initializing.
// Otherwise, if device is in dark mode the dialog is shown with wrong color scheme. // Otherwise, if device is in dark mode the dialog is shown with wrong color scheme.
Utils.runOnMainThreadDelayed(() -> { Utils.runOnMainThreadDelayed(() -> {
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setIconAttribute(android.R.attr.alertDialogIcon) .setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(str("gms_core_dialog_title")) .setTitle(str("gms_core_dialog_title"))
.setMessage(str(dialogMessageKey)) .setMessage(str(dialogMessageRef))
.setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> { .setPositiveButton(str(positiveButtonStringRef), onPositiveClickListener)
open(link); .setCancelable(false)
})
// Manually allow using the back button to dismiss the dialog with the back button,
// if troubleshooting and somehow the GmsCore verification checks always fail.
.setCancelable(true)
.show(); .show();
}, 100); }, 100);
} }
@ -74,47 +70,62 @@ public class GmsCoreSupport {
* Injection point. * Injection point.
*/ */
@RequiresApi(api = Build.VERSION_CODES.N) @RequiresApi(api = Build.VERSION_CODES.N)
public static void checkGmsCore(Context context) { public static void checkGmsCore(Activity context) {
try { try {
// Verify GmsCore is installed. // Verify GmsCore is installed.
try { try {
PackageManager manager = context.getPackageManager(); PackageManager manager = context.getPackageManager();
manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException exception) { } catch (PackageManager.NameNotFoundException exception) {
Logger.printDebug(() -> "GmsCore was not found"); Logger.printInfo(() -> "GmsCore was not found");
// Cannot show a dialog and must show a toast, // Cannot show a dialog and must show a toast,
// because on some installations the app crashes before the dialog can display. // because on some installations the app crashes before a dialog can be displayed.
Utils.showToastLong(str("gms_core_toast_not_installed_message")); Utils.showToastLong(str("gms_core_toast_not_installed_message"));
open(getGmsCoreDownload()); open(getGmsCoreDownload());
return; return;
} }
// Check if GmsCore is whitelisted from battery optimizations.
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME)) {
Logger.printDebug(() -> "GmsCore is not whitelisted from battery optimizations");
showToastOrDialog(context,
"gms_core_toast_not_whitelisted_message",
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
DONT_KILL_MY_APP_LINK);
return;
}
// Check if GmsCore is running in the background. // Check if GmsCore is running in the background.
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
if (client == null) { if (client == null) {
Logger.printDebug(() -> "GmsCore is not running in the background"); Logger.printInfo(() -> "GmsCore is not running in the background");
showToastOrDialog(context,
"gms_core_toast_not_whitelisted_message", showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_not_allowed_in_background_message", "gms_core_dialog_not_whitelisted_not_allowed_in_background_message",
DONT_KILL_MY_APP_LINK); "gms_core_dialog_open_website_text",
(dialog, id) -> open(DONT_KILL_MY_APP_LINK));
return;
} }
} }
// Check if GmsCore is whitelisted from battery optimizations.
if (batteryOptimizationsEnabled(context)) {
Logger.printInfo(() -> "GmsCore is not whitelisted from battery optimizations");
showBatteryOptimizationDialog(context,
"gms_core_dialog_not_whitelisted_using_battery_optimizations_message",
"gms_core_dialog_continue_text",
(dialog, id) -> openGmsCoreDisableBatteryOptimizationsIntent(context));
}
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "checkGmsCore failure", ex); Logger.printException(() -> "checkGmsCore failure", ex);
} }
} }
@SuppressLint("BatteryLife") // Permission is part of GmsCore
private static void openGmsCoreDisableBatteryOptimizationsIntent(Activity activity) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.fromParts("package", GMS_CORE_PACKAGE_NAME, null));
activity.startActivityForResult(intent, 0);
}
/**
* @return If GmsCore is not whitelisted from battery optimizations.
*/
private static boolean batteryOptimizationsEnabled(Context context) {
var powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return !powerManager.isIgnoringBatteryOptimizations(GMS_CORE_PACKAGE_NAME);
}
private static String getGmsCoreDownload() { private static String getGmsCoreDownload() {
final var vendorGroupId = getGmsCoreVendorGroupId(); final var vendorGroupId = getGmsCoreVendorGroupId();
//noinspection SwitchStatementWithTooFewBranches //noinspection SwitchStatementWithTooFewBranches