Hook up hibernation eligibility to exemption toggle
Use hibernation eligibility API to determine whether toggle should be
enabled or disabled for an app. For apps that are already exempt from
hibernation by the system, the toggle is disabled and unchecked.
Bug: 200087723
Test: manual
Test: atest AppHibernationIntegrationTest
Change-Id: I36a1eafc2bb90a92bcbdc4bf32041426d6377fd4
diff --git a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
index d922867..f0b3329 100644
--- a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
@@ -20,6 +20,8 @@
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED;
+import static android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM;
+import static android.permission.PermissionControllerManager.HIBERNATION_ELIGIBILITY_UNKNOWN;
import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
@@ -29,6 +31,7 @@
import android.apphibernation.AppHibernationManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.permission.PermissionControllerManager;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.Slog;
@@ -51,7 +54,10 @@
private static final String TAG = "HibernationSwitchPrefController";
private String mPackageName;
private final AppOpsManager mAppOpsManager;
+ private final PermissionControllerManager mPermissionControllerManager;
private int mPackageUid;
+ private boolean mHibernationEligibilityLoaded;
+ private int mHibernationEligibility = HIBERNATION_ELIGIBILITY_UNKNOWN;
@VisibleForTesting
boolean mIsPackageSet;
private boolean mIsPackageExemptByDefault;
@@ -60,6 +66,7 @@
String preferenceKey) {
super(context, preferenceKey);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class);
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@@ -109,10 +116,27 @@
}
}
+ private boolean isAppEligibleForHibernation() {
+ return mHibernationEligibilityLoaded
+ && mHibernationEligibility != HIBERNATION_ELIGIBILITY_EXEMPT_BY_SYSTEM
+ && mHibernationEligibility != HIBERNATION_ELIGIBILITY_UNKNOWN;
+ }
+
@Override
public void updateState(Preference preference) {
super.updateState(preference);
- ((SwitchPreference) preference).setChecked(!isPackageHibernationExemptByUser());
+ ((SwitchPreference) preference).setChecked(isAppEligibleForHibernation()
+ && !isPackageHibernationExemptByUser());
+ preference.setEnabled(isAppEligibleForHibernation());
+ if (!mHibernationEligibilityLoaded) {
+ mPermissionControllerManager.getHibernationEligibility(mPackageName,
+ mContext.getMainExecutor(),
+ eligibility -> {
+ mHibernationEligibility = eligibility;
+ mHibernationEligibilityLoaded = true;
+ updateState(preference);
+ });
+ }
}
@VisibleForTesting
diff --git a/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java b/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
index 567594c..825a9b6 100644
--- a/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceControllerTest.java
@@ -27,6 +27,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.spy;
@@ -43,6 +45,7 @@
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,6 +71,7 @@
private HibernationSwitchPreferenceController mController;
private Context mContext;
+ private String mOriginalPreSFlagValue;
@Before
public void setUp() throws PackageManager.NameNotFoundException {
@@ -89,6 +93,16 @@
"true", true /* makeDefault */);
mController = new HibernationSwitchPreferenceController(mContext, KEY);
when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+
+ mOriginalPreSFlagValue = DeviceConfig.getProperty(NAMESPACE_APP_HIBERNATION,
+ PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS);
+ }
+
+ @After
+ public void cleanUp() {
+ // Restore original device config values.
+ DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS,
+ mOriginalPreSFlagValue, true /* makeDefault */);
}
@Test
@@ -124,43 +138,37 @@
}
@Test
- public void updateState_exemptedByDefaultPackage_shouldNotCheck() {
+ public void isPackageHibernationExemptByUser_preSAppShouldBeExemptByDefault() {
when(mAppOpsManager.unsafeCheckOpNoThrow(
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(EXEMPTED_PACKAGE_NAME)))
.thenReturn(MODE_DEFAULT);
mController.setPackage(EXEMPTED_PACKAGE_NAME);
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(false);
+ assertTrue(mController.isPackageHibernationExemptByUser());
}
@Test
- public void updateState_exemptedPackageOverrideByUser_shouldCheck() {
+ public void isPackageHibernationExemptByUser_preSAppShouldNotBeExemptWithUserSetting() {
when(mAppOpsManager.unsafeCheckOpNoThrow(
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(EXEMPTED_PACKAGE_NAME)))
.thenReturn(MODE_ALLOWED);
mController.setPackage(EXEMPTED_PACKAGE_NAME);
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(true);
+ assertFalse(mController.isPackageHibernationExemptByUser());
}
@Test
- public void updateState_unexemptedPackageOverrideByUser_shouldNotCheck() {
+ public void isPackageHibernationExemptByUser_SAppShouldBeExemptWithUserSetting() {
when(mAppOpsManager.unsafeCheckOpNoThrow(
eq(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED), anyInt(), eq(UNEXEMPTED_PACKAGE_NAME)))
.thenReturn(MODE_IGNORED);
mController.setPackage(UNEXEMPTED_PACKAGE_NAME);
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(false);
+ assertTrue(mController.isPackageHibernationExemptByUser());
}
@Test
- public void updateState_exemptedByDefaultPackageOverriddenByPreSFlag_shouldCheck() {
+ public void isPackageHibernationExemptByUser_preSAppShouldNotBeExemptByDefaultWithPreSFlag() {
DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_HIBERNATION_TARGETS_PRE_S_APPS,
"true", true /* makeDefault */);
when(mAppOpsManager.unsafeCheckOpNoThrow(
@@ -168,8 +176,6 @@
.thenReturn(MODE_DEFAULT);
mController.setPackage(EXEMPTED_PACKAGE_NAME);
- mController.updateState(mPreference);
-
- verify(mPreference).setChecked(true);
+ assertFalse(mController.isPackageHibernationExemptByUser());
}
}