diff --git a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
index aeb5e9f..44990ff 100644
--- a/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
+++ b/src/com/android/settings/fuelgauge/BatteryBackupHelper.java
@@ -16,21 +16,33 @@
 
 package com.android.settings.fuelgauge;
 
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.app.backup.BackupDataInputStream;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupHelper;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
 import android.os.IDeviceIdleController;
 import android.os.RemoteException;
 import android.os.ParcelFileDescriptor;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settings.fuelgauge.BatteryOptimizeUtils.AppUsageState;
+
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /** An implementation to backup and restore battery configurations. */
 public final class BatteryBackupHelper implements BackupHelper {
@@ -39,13 +51,24 @@
     private static final String DEVICE_IDLE_SERVICE = "deviceidle";
     private static final boolean DEBUG = false;
 
-    @VisibleForTesting
-    static final CharSequence DELIMITER = ":";
-    @VisibleForTesting
+    // Only the owner can see all apps.
+    private static final int RETRIEVE_FLAG_ADMIN =
+            PackageManager.MATCH_ANY_USER |
+            PackageManager.MATCH_DISABLED_COMPONENTS |
+            PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+    private static final int RETRIEVE_FLAG =
+            PackageManager.MATCH_DISABLED_COMPONENTS |
+            PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+
+    static final CharSequence DELIMITER = ",";
+    static final CharSequence DELIMITER_MODE = "|";
     static final String KEY_FULL_POWER_LIST = "full_power_list";
+    static final String KEY_OPTIMIZATION_LIST = "optimization_mode_list";
 
     @VisibleForTesting
     IDeviceIdleController mIDeviceIdleController;
+    @VisibleForTesting
+    IPackageManager mIPackageManager;
 
     private final Context mContext;
 
@@ -57,10 +80,13 @@
     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
             ParcelFileDescriptor newState) {
         if (!isOwner()) {
-            Log.w(TAG, "ignore the backup process for non-owner");
+            Log.w(TAG, "ignore performBackup() for non-owner");
             return;
         }
-        backupFullPowerList(getIDeviceIdleController(), data);
+        final List<String> allowlistedApps = backupFullPowerList(data);
+        if (allowlistedApps != null) {
+            backupOptimizationMode(data, allowlistedApps);
+        }
     }
 
     @Override
@@ -72,33 +98,57 @@
     public void writeNewStateDescription(ParcelFileDescriptor newState) {
     }
 
-    private void backupFullPowerList(
-            IDeviceIdleController deviceIdleService, BackupDataOutput data) {
+    private List<String> backupFullPowerList(BackupDataOutput data) {
         final long timestamp = System.currentTimeMillis();
         String[] allowlistedApps;
         try {
-            allowlistedApps = deviceIdleService.getFullPowerWhitelist();
+            allowlistedApps = getIDeviceIdleController().getFullPowerWhitelist();
         } catch (RemoteException e) {
             Log.e(TAG, "backupFullPowerList() failed", e);
-            return;
+            return null;
         }
         // Ignores unexpected emptty result case.
         if (allowlistedApps == null || allowlistedApps.length == 0) {
             Log.w(TAG, "no data found in the getFullPowerList()");
-            return;
+            return new ArrayList<>();
         }
+
         debugLog("allowlistedApps:" + Arrays.toString(allowlistedApps));
         final String allowedApps = String.join(DELIMITER, allowlistedApps);
-        final byte[] allowedAppsBytes = allowedApps.getBytes();
-        try {
-            data.writeEntityHeader(KEY_FULL_POWER_LIST, allowedAppsBytes.length);
-            data.writeEntityData(allowedAppsBytes, allowedAppsBytes.length);
-        } catch (IOException e) {
-            Log.e(TAG, "backup getFullPowerList() failed", e);
-            return;
-        }
+        writeBackupData(data, KEY_FULL_POWER_LIST, allowedApps);
         Log.d(TAG, String.format("backup getFullPowerList() size=%d in %d/ms",
                 allowlistedApps.length, (System.currentTimeMillis() - timestamp)));
+        return Arrays.asList(allowlistedApps);
+    }
+
+    @VisibleForTesting
+    void backupOptimizationMode(BackupDataOutput data, List<String> allowlistedApps) {
+        final long timestamp = System.currentTimeMillis();
+        final List<ApplicationInfo> applications = getInstalledApplications();
+        if (applications == null || applications.isEmpty()) {
+            Log.w(TAG, "no data found in the getInstalledApplications()");
+            return;
+        }
+        final StringBuilder builder = new StringBuilder();
+        final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+        // Converts application into the AppUsageState.
+        for (ApplicationInfo info : applications) {
+            final int mode = appOps.checkOpNoThrow(
+                    AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
+            final AppUsageState state = BatteryOptimizeUtils.getAppUsageState(
+                    mode, allowlistedApps.contains(info.packageName));
+            // Ignores default optimized or unknown state.
+            if (state == AppUsageState.OPTIMIZED || state == AppUsageState.UNKNOWN) {
+                continue;
+            }
+            final String packageOptimizeMode = info.packageName + DELIMITER_MODE + state;
+            builder.append(packageOptimizeMode + DELIMITER);
+            debugLog(packageOptimizeMode);
+        }
+
+        writeBackupData(data, KEY_OPTIMIZATION_LIST, builder.toString());
+        Log.d(TAG, String.format("backup getInstalledApplications() size=%d in %d/ms",
+                applications.size(), (System.currentTimeMillis() - timestamp)));
     }
 
     // Provides an opportunity to inject mock IDeviceIdleController for testing.
@@ -111,10 +161,58 @@
         return mIDeviceIdleController;
     }
 
+    private IPackageManager getIPackageManager() {
+        if (mIPackageManager != null) {
+            return mIPackageManager;
+        }
+        mIPackageManager = AppGlobals.getPackageManager();
+        return mIPackageManager;
+    }
+
+    private List<ApplicationInfo> getInstalledApplications() {
+        final List<ApplicationInfo> applications = new ArrayList<>();
+        final UserManager um = mContext.getSystemService(UserManager.class);
+        for (UserInfo userInfo : um.getProfiles(UserHandle.myUserId())) {
+            try {
+                @SuppressWarnings("unchecked")
+                final ParceledListSlice<ApplicationInfo> infoList =
+                        getIPackageManager().getInstalledApplications(
+                                userInfo.isAdmin() ? RETRIEVE_FLAG_ADMIN : RETRIEVE_FLAG,
+                                userInfo.id);
+                if (infoList != null) {
+                    applications.addAll(infoList.getList());
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "getInstalledApplications() is failed", e);
+                return null;
+            }
+        }
+        // Removes the application which is disabled by the system.
+        for (int index = applications.size() - 1; index >= 0; index--) {
+            final ApplicationInfo info = applications.get(index);
+            if (info.enabledSetting != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
+                    && !info.enabled) {
+                applications.remove(index);
+            }
+        }
+        return applications;
+    }
+
     private void debugLog(String debugContent) {
         if (DEBUG) Log.d(TAG, debugContent);
     }
 
+    private static void writeBackupData(
+            BackupDataOutput data, String dataKey, String dataContent) {
+        final byte[] dataContentBytes = dataContent.getBytes();
+        try {
+            data.writeEntityHeader(dataKey, dataContentBytes.length);
+            data.writeEntityData(dataContentBytes, dataContentBytes.length);
+        } catch (IOException e) {
+            Log.e(TAG, "writeBackupData() is failed for " + dataKey, e);
+        }
+    }
+
     private static boolean isOwner() {
         return UserHandle.myUserId() == UserHandle.USER_OWNER;
     }
diff --git a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
index 4a56040..0be9060 100644
--- a/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryOptimizeUtils.java
@@ -59,20 +59,25 @@
         mAllowListed = mPowerAllowListBackend.isAllowlisted(mPackageName);
     }
 
-    public AppUsageState getAppUsageState() {
-        refreshState();
-        if (!mAllowListed && mMode == AppOpsManager.MODE_IGNORED) {
+    /** Gets the {@link AppUsageState} based on mode and allowed list. */
+    public static AppUsageState getAppUsageState(int mode, boolean isAllowListed) {
+        if (!isAllowListed && mode == AppOpsManager.MODE_IGNORED) {
             return AppUsageState.RESTRICTED;
-        } else if (mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
+        } else if (isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
             return AppUsageState.UNRESTRICTED;
-        } else if (!mAllowListed && mMode == AppOpsManager.MODE_ALLOWED) {
+        } else if (!isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
             return AppUsageState.OPTIMIZED;
         } else {
-            Log.d(TAG, "get unknown app usage state.");
             return AppUsageState.UNKNOWN;
         }
     }
 
+    /** Gets the current {@link AppUsageState}. */
+    public AppUsageState getAppUsageState() {
+        refreshState();
+        return getAppUsageState(mMode, mAllowListed);
+    }
+
     public void setAppUsageState(AppUsageState state) {
         switch (state) {
             case RESTRICTED:
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
index 87aa812..47fa59e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryBackupHelperTest.java
@@ -27,11 +27,21 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.AppOpsManager;
 import android.app.backup.BackupDataOutput;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.UserInfo;
 import android.os.IDeviceIdleController;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
+
+import java.util.Arrays;
+import java.util.List;
 
 import org.junit.After;
 import org.junit.Before;
@@ -57,13 +67,23 @@
     private BackupDataOutput mBackupDataOutput;
     @Mock
     private IDeviceIdleController mDeviceController;
+    @Mock
+    private IPackageManager mIPackageManager;
+    @Mock
+    private AppOpsManager mAppOpsManager;
+    @Mock
+    private UserManager mUserManager;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
+        doReturn(mContext).when(mContext).getApplicationContext();
+        doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
+        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
         mBatteryBackupHelper = new BatteryBackupHelper(mContext);
         mBatteryBackupHelper.mIDeviceIdleController = mDeviceController;
+        mBatteryBackupHelper.mIPackageManager = mIPackageManager;
     }
 
     @After
@@ -135,6 +155,78 @@
         verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
     }
 
+    @Test
+    public void backupOptimizationMode_nullInstalledApps_ignoreBackupOptimization()
+            throws Exception {
+        final UserInfo userInfo =
+                new UserInfo(/*userId=*/ 0, /*userName=*/ "google", /*flag=*/ 0);
+        doReturn(Arrays.asList(userInfo)).when(mUserManager).getProfiles(anyInt());
+        doThrow(new RuntimeException())
+                .when(mIPackageManager)
+                .getInstalledApplications(anyInt(), anyInt());
+
+        mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, null);
+
+        verify(mBackupDataOutput, never()).writeEntityHeader(anyString(), anyInt());
+    }
+
+    @Test
+    public void backupOptimizationMode_backupOptimizationMode() throws Exception {
+        final String packageName1 = "com.android.testing.1";
+        final String packageName2 = "com.android.testing.2";
+        final String packageName3 = "com.android.testing.3";
+        final List<String> allowlistedApps = Arrays.asList(packageName1);
+        createTestingData(packageName1, packageName2, packageName3);
+
+        mBatteryBackupHelper.backupOptimizationMode(mBackupDataOutput, allowlistedApps);
+
+        final String expectedResult =
+                packageName1 + "|UNRESTRICTED," + packageName2 + "|RESTRICTED,";
+        final byte[] expectedBytes = expectedResult.getBytes();
+        verify(mBackupDataOutput).writeEntityHeader(
+                BatteryBackupHelper.KEY_OPTIMIZATION_LIST, expectedBytes.length);
+        verify(mBackupDataOutput).writeEntityData(expectedBytes, expectedBytes.length);
+    }
+
+    private void createTestingData(
+            String packageName1, String packageName2, String packageName3) throws Exception {
+        // Sets the getInstalledApplications() method for testing.
+        final UserInfo userInfo =
+                new UserInfo(/*userId=*/ 0, /*userName=*/ "google", /*flag=*/ 0);
+        doReturn(Arrays.asList(userInfo)).when(mUserManager).getProfiles(anyInt());
+        final ApplicationInfo applicationInfo1 = new ApplicationInfo();
+        applicationInfo1.enabled = true;
+        applicationInfo1.uid = 1;
+        applicationInfo1.packageName = packageName1;
+        final ApplicationInfo applicationInfo2 = new ApplicationInfo();
+        applicationInfo2.enabled = false;
+        applicationInfo2.uid = 2;
+        applicationInfo2.packageName = packageName2;
+        applicationInfo2.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
+        final ApplicationInfo applicationInfo3 = new ApplicationInfo();
+        applicationInfo3.enabled = false;
+        applicationInfo3.uid = 3;
+        applicationInfo3.packageName = packageName3;
+        applicationInfo3.enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+        doReturn(new ParceledListSlice<ApplicationInfo>(
+                Arrays.asList(applicationInfo1, applicationInfo2, applicationInfo3)))
+            .when(mIPackageManager)
+            .getInstalledApplications(anyInt(), anyInt());
+        // Sets the AppOpsManager for checkOpNoThrow() method.
+        doReturn(AppOpsManager.MODE_ALLOWED)
+                .when(mAppOpsManager)
+                .checkOpNoThrow(
+                        AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+                        applicationInfo1.uid,
+                        applicationInfo1.packageName);
+        doReturn(AppOpsManager.MODE_IGNORED)
+                .when(mAppOpsManager)
+                .checkOpNoThrow(
+                        AppOpsManager.OP_RUN_ANY_IN_BACKGROUND,
+                        applicationInfo2.uid,
+                        applicationInfo2.packageName);
+    }
+
     @Implements(UserHandle.class)
     public static class ShadowUserHandle {
         // Sets the default as thte OWNER role.
