Skip to content
This repository has been archived by the owner on Oct 26, 2024. It is now read-only.

Commit

Permalink
fix(YouTube - GmsCore support): Prompt to disable battery optimizatio…
Browse files Browse the repository at this point in the history
…ns, if not done already (#601)

Co-authored-by: oSumAtrIX <[email protected]>
  • Loading branch information
LisoUseInAIKyrios and oSumAtrIX authored Apr 6, 2024
1 parent fedace0 commit c5c9de5
Showing 1 changed file with 46 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package app.revanced.integrations.shared;

import static app.revanced.integrations.shared.StringRef.str;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;

import androidx.annotation.RequiresApi;

import java.net.MalformedURLException;
import java.net.URL;

import static app.revanced.integrations.shared.StringRef.str;

/**
* @noinspection unused
*/
Expand Down Expand Up @@ -45,27 +49,19 @@ private static void open(String queryOrLink) {
System.exit(0);
}

private static void showToastOrDialog(Context context, String toastMessageKey, String dialogMessageKey, String link) {
if (!(context instanceof Activity)) {
// Context is for the application and cannot show a dialog using it.
Utils.showToastLong(str(toastMessageKey));
open(link);
return;
}

private static void showBatteryOptimizationDialog(Activity context,
String dialogMessageRef,
String positiveButtonStringRef,
DialogInterface.OnClickListener onPositiveClickListener) {
// 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.
Utils.runOnMainThreadDelayed(() -> {
new AlertDialog.Builder(context)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setTitle(str("gms_core_dialog_title"))
.setMessage(str(dialogMessageKey))
.setPositiveButton(str("gms_core_dialog_ok_button_text"), (dialog, id) -> {
open(link);
})
// 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)
.setMessage(str(dialogMessageRef))
.setPositiveButton(str(positiveButtonStringRef), onPositiveClickListener)
.setCancelable(false)
.show();
}, 100);
}
Expand All @@ -74,47 +70,62 @@ private static void showToastOrDialog(Context context, String toastMessageKey, S
* Injection point.
*/
@RequiresApi(api = Build.VERSION_CODES.N)
public static void checkGmsCore(Context context) {
public static void checkGmsCore(Activity context) {
try {
// Verify GmsCore is installed.
try {
PackageManager manager = context.getPackageManager();
manager.getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES);
} 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,
// 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"));
open(getGmsCoreDownload());
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.
try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) {
if (client == null) {
Logger.printDebug(() -> "GmsCore is not running in the background");
showToastOrDialog(context,
"gms_core_toast_not_whitelisted_message",
Logger.printInfo(() -> "GmsCore is not running in the background");

showBatteryOptimizationDialog(context,
"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) {
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() {
final var vendorGroupId = getGmsCoreVendorGroupId();
//noinspection SwitchStatementWithTooFewBranches
Expand Down

0 comments on commit c5c9de5

Please sign in to comment.