Reset app preferences does not trigger backup for App battery usages

Bug: 328712606
Fix: 328712606
Test: UT && Verify logcat when change/reset App battery usages
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ef8a51fac85eedee8f9509b9f7c002281c1ae093)
Merged-In: Ia3917c8dc2654185f5f048c048362fd47379b7d1
Change-Id: Ia3917c8dc2654185f5f048c048362fd47379b7d1
diff --git a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
index 6ef5aa8..42e6d9c 100644
--- a/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetail.java
@@ -52,7 +52,6 @@
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.instrumentation.Instrumentable;
-import com.android.settingslib.datastore.ChangeReason;
 import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.ArrayList;
@@ -272,7 +271,6 @@
     public void onPause() {
         super.onPause();
 
-        notifyBackupManager();
         final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode();
         mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode);
         logMetricCategory(currentOptimizeMode);
@@ -290,13 +288,6 @@
     }
 
     @VisibleForTesting
-    void notifyBackupManager() {
-        if (mOptimizationMode != mBatteryOptimizeUtils.getAppOptimizationMode()) {
-            BatterySettingsStorage.get(getContext()).notifyChange(ChangeReason.UPDATE);
-        }
-    }
-
-    @VisibleForTesting
     void initHeader() {
         final View appSnippet = mHeaderPreference.findViewById(R.id.entity_header);
         final Activity context = getActivity();
diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
index dc4aade..001876c3 100644
--- a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
@@ -33,6 +33,7 @@
 
 import com.android.settings.R;
 import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
+import com.android.settingslib.datastore.ChangeReason;
 import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
 
 import java.lang.annotation.Retention;
@@ -222,6 +223,10 @@
             return;
         }
 
+        // App preferences are already clear when code reach here, and there may be no
+        // setAppUsageStateInternal call to notifyChange. So always trigger notifyChange here.
+        BatterySettingsStorage.get(context).notifyChange(ChangeReason.DELETE);
+
         allowlistBackend.refreshList();
         // Resets optimization mode for each application.
         for (ApplicationInfo info : applications) {
@@ -351,6 +356,9 @@
         }
         BatteryOptimizeLogUtils.writeLog(
                 context, action, packageNameKey, createLogEvent(appStandbyMode, allowListed));
+        if (action != Action.RESET) { // reset has been notified in resetAppOptimizationMode
+            BatterySettingsStorage.get(context).notifyChange(toChangeReason(action));
+        }
     }
 
     private static String createLogEvent(int appStandbyMode, boolean allowListed) {
@@ -362,4 +370,8 @@
                         allowListed,
                         getAppOptimizationMode(appStandbyMode, allowListed));
     }
+
+    private static @ChangeReason int toChangeReason(Action action) {
+        return action == Action.RESTORE ? ChangeReason.RESTORE : ChangeReason.UPDATE;
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
index 56702cf..b662d3e 100644
--- a/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerBackgroundUsageDetail.java
@@ -41,7 +41,6 @@
 import com.android.settingslib.applications.AppUtils;
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.datastore.ChangeReason;
 import com.android.settingslib.widget.FooterPreference;
 import com.android.settingslib.widget.LayoutPreference;
 import com.android.settingslib.widget.MainSwitchPreference;
@@ -116,7 +115,6 @@
     public void onPause() {
         super.onPause();
 
-        notifyBackupManager();
         final int currentOptimizeMode = mBatteryOptimizeUtils.getAppOptimizationMode();
         mLogStringBuilder.append(", onPause mode = ").append(currentOptimizeMode);
         logMetricCategory(currentOptimizeMode);
@@ -184,13 +182,6 @@
     }
 
     @VisibleForTesting
-    void notifyBackupManager() {
-        if (mOptimizationMode != mBatteryOptimizeUtils.getAppOptimizationMode()) {
-            BatterySettingsStorage.get(getContext()).notifyChange(ChangeReason.UPDATE);
-        }
-    }
-
-    @VisibleForTesting
     int getSelectedPreference() {
         if (!mMainSwitchPreference.isChecked()) {
             return BatteryOptimizeUtils.MODE_RESTRICTED;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
index 0648de4..80739e9 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/AdvancedPowerUsageDetailTest.java
@@ -60,12 +60,8 @@
 import com.android.settingslib.applications.ApplicationsState;
 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.datastore.ChangeReason;
-import com.android.settingslib.datastore.Observer;
 import com.android.settingslib.widget.LayoutPreference;
 
-import com.google.common.util.concurrent.MoreExecutors;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -119,10 +115,8 @@
     @Mock private AppOpsManager mAppOpsManager;
     @Mock private LoaderManager mLoaderManager;
     @Mock private BatteryOptimizeUtils mBatteryOptimizeUtils;
-    @Mock private Observer mObserver;
 
     private Context mContext;
-    private BatterySettingsStorage mBatterySettingsStorage;
     private PrimarySwitchPreference mAllowBackgroundUsagePreference;
     private AdvancedPowerUsageDetail mFragment;
     private SettingsActivity mTestActivity;
@@ -134,7 +128,6 @@
     @Before
     public void setUp() {
         mContext = spy(ApplicationProvider.getApplicationContext());
-        mBatterySettingsStorage = BatterySettingsStorage.get(mContext);
         when(mContext.getPackageName()).thenReturn("foo");
         mFeatureFactory = FakeFeatureFactory.setupForTest();
         mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
@@ -448,28 +441,4 @@
         TimeUnit.SECONDS.sleep(1);
         verifyNoInteractions(mMetricsFeatureProvider);
     }
-
-    @Test
-    public void notifyBackupManager_optimizationModeIsNotChanged_notInvokeDataChanged() {
-        mBatterySettingsStorage.addObserver(mObserver, MoreExecutors.directExecutor());
-        final int mode = BatteryOptimizeUtils.MODE_RESTRICTED;
-        mFragment.mOptimizationMode = mode;
-        when(mBatteryOptimizeUtils.getAppOptimizationMode()).thenReturn(mode);
-
-        mFragment.notifyBackupManager();
-
-        verifyNoInteractions(mObserver);
-    }
-
-    @Test
-    public void notifyBackupManager_optimizationModeIsChanged_invokeDataChanged() {
-        mBatterySettingsStorage.addObserver(mObserver, MoreExecutors.directExecutor());
-        mFragment.mOptimizationMode = BatteryOptimizeUtils.MODE_RESTRICTED;
-        when(mBatteryOptimizeUtils.getAppOptimizationMode())
-                .thenReturn(BatteryOptimizeUtils.MODE_UNRESTRICTED);
-
-        mFragment.notifyBackupManager();
-
-        verify(mObserver).onChanged(ChangeReason.UPDATE);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
index 3551eeb..6085b9a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryOptimizeUtilsTest.java
@@ -49,8 +49,12 @@
 import android.util.ArraySet;
 
 import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
+import com.android.settingslib.datastore.ChangeReason;
+import com.android.settingslib.datastore.Observer;
 import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
 
+import com.google.common.util.concurrent.MoreExecutors;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -74,14 +78,18 @@
     @Mock private PowerAllowlistBackend mMockBackend;
     @Mock private IPackageManager mMockIPackageManager;
     @Mock private UserManager mMockUserManager;
+    @Mock private Observer mObserver;
 
     private Context mContext;
     private BatteryOptimizeUtils mBatteryOptimizeUtils;
+    private BatterySettingsStorage mBatterySettingsStorage;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        mBatterySettingsStorage = BatterySettingsStorage.get(mContext);
+        mBatterySettingsStorage.addObserver(mObserver, MoreExecutors.directExecutor());
         mBatteryOptimizeUtils = spy(new BatteryOptimizeUtils(mContext, UID, PACKAGE_NAME));
         mBatteryOptimizeUtils.mAppOpsManager = mMockAppOpsManager;
         mBatteryOptimizeUtils.mBatteryUtils = mMockBatteryUtils;
@@ -156,6 +164,7 @@
         TimeUnit.SECONDS.sleep(1);
 
         verifySetAppOptimizationMode(AppOpsManager.MODE_IGNORED, /* allowListed */ false);
+        verify(mObserver).onChanged(ChangeReason.UPDATE);
     }
 
     @Test
@@ -169,6 +178,7 @@
         TimeUnit.SECONDS.sleep(1);
 
         verifySetAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ true);
+        verify(mObserver).onChanged(ChangeReason.UPDATE);
     }
 
     @Test
@@ -182,6 +192,7 @@
         TimeUnit.SECONDS.sleep(1);
 
         verifySetAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ false);
+        verify(mObserver).onChanged(ChangeReason.UPDATE);
     }
 
     @Test
@@ -197,6 +208,7 @@
         verify(mMockBatteryUtils, never()).setForceAppStandby(anyInt(), anyString(), anyInt());
         verify(mMockBackend, never()).addApp(anyString());
         verify(mMockBackend, never()).removeApp(anyString());
+        verifyNoInteractions(mObserver);
     }
 
     @Test
@@ -288,6 +300,7 @@
         inOrder.verify(mMockBackend).isAllowlisted(PACKAGE_NAME, UID);
         inOrder.verify(mMockBackend).isSysAllowlisted(PACKAGE_NAME);
         verifyNoMoreInteractions(mMockBackend);
+        verify(mObserver).onChanged(ChangeReason.DELETE);
     }
 
     @Test
@@ -298,6 +311,7 @@
                 /* isSystemOrDefaultApp */ false);
 
         verifySetAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ false);
+        verify(mObserver).onChanged(ChangeReason.DELETE);
     }
 
     @Test
@@ -308,6 +322,7 @@
                 /* isSystemOrDefaultApp */ false);
 
         verifySetAppOptimizationMode(AppOpsManager.MODE_ALLOWED, /* allowListed */ false);
+        verify(mObserver).onChanged(ChangeReason.DELETE);
     }
 
     private void runTestForResetWithMode(