Merge changes Iced0fa59,Ic354ac91,I0b4cb6ca,I9c1d3761 into sc-dev

* changes:
  Add footer to app usage page
  Update app usage page with 3 radio button control
  Add 3 controller for app usage page radio buttons
  Add utils class for app usage operation
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8a5539b..4059b80 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2425,6 +2425,7 @@
 
         <activity android:name="Settings$ChooseAccountActivity"
             android:label="@string/header_add_an_account"
+                  android:theme="@style/Theme.SubSettings"
             android:configChanges="orientation|keyboardHidden|screenSize">
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                        android:value="com.android.settings.accounts.ChooseAccountFragment" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2a20727..16c7e18 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -11814,9 +11814,9 @@
     <string name="storage_percent_full">used</string>
 
     <!-- Summary of a single storage volume used space. [CHAR LIMIT=24] -->
-    <string name="storage_usage_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g></string>
+    <string name="storage_usage_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g> used</string>
     <!-- Summary of a single storage volume total space. [CHAR LIMIT=24] -->
-    <string name="storage_total_summary"><xliff:g id="percentage" example="54%">%1$s</xliff:g> used of <xliff:g id="number" example="128">%2$s</xliff:g> <xliff:g id="unit" example="KB">%3$s</xliff:g></string>
+    <string name="storage_total_summary"><xliff:g id="number" example="128">%1$s</xliff:g> <xliff:g id="unit" example="KB">%2$s</xliff:g> total</string>
 
     <!-- Label for button allow user to remove the instant app from the device. -->
     <string name="clear_instant_app_data">Clear app</string>
diff --git a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
index 03a7b97..e7f5ba6 100644
--- a/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
+++ b/src/com/android/settings/deviceinfo/StorageDashboardFragment.java
@@ -336,8 +336,7 @@
         final Activity activity = getActivity();
         EntityHeaderController.newInstance(activity, this /*fragment*/,
                 null /* header view */)
-                .setRecyclerView(getListView(), getSettingsLifecycle())
-                .styleActionBar(activity);
+                .setRecyclerView(getListView(), getSettingsLifecycle());
     }
 
     @Override
diff --git a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
index ec51db6..6b06daf 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageUsageProgressBarPreferenceController.java
@@ -26,7 +26,6 @@
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.settingslib.widget.UsageProgressBarPreference;
@@ -108,23 +107,16 @@
 
     @Override
     public void updateState(Preference preference) {
-        final Formatter.BytesResult usedResult = getBytesResult(mUsedBytes);
         mUsageProgressBarPreference.setUsageSummary(
-                mContext.getString(R.string.storage_usage_summary,
-                usedResult.value, usedResult.units));
-
-        final String percentageString = mTotalBytes == 0L
-                ? Utils.formatPercentage(0)
-                : Utils.formatPercentage((mUsedBytes * 100) / mTotalBytes, true /* round */);
-        final Formatter.BytesResult totalResult = getBytesResult(mTotalBytes);
+                getStorageSummary(R.string.storage_usage_summary, mUsedBytes));
         mUsageProgressBarPreference.setTotalSummary(
-                mContext.getString(R.string.storage_total_summary, percentageString,
-                totalResult.value, totalResult.units));
-
+                getStorageSummary(R.string.storage_total_summary, mTotalBytes));
         mUsageProgressBarPreference.setPercent(mUsedBytes, mTotalBytes);
     }
 
-    private Formatter.BytesResult getBytesResult(long bytes) {
-        return Formatter.formatBytes(mContext.getResources(), bytes, Formatter.FLAG_SHORTER);
+    private String getStorageSummary(int resId, long bytes) {
+        final Formatter.BytesResult result = Formatter.formatBytes(mContext.getResources(),
+                bytes, Formatter.FLAG_SHORTER);
+        return mContext.getString(resId, result.value, result.units);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
index cc7f8455..eca2bf3 100644
--- a/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryChartPreferenceController.java
@@ -18,6 +18,10 @@
 package com.android.settings.fuelgauge;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
@@ -38,6 +42,7 @@
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -63,6 +68,11 @@
     private final String mPreferenceKey;
     private final SettingsActivity mActivity;
     private final InstrumentedPreferenceFragment mFragment;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+    // Preference cache to avoid create new instance each time.
+    @VisibleForTesting
+    final Map<String, Preference> mPreferenceCache = new HashMap<>();
 
     public BatteryChartPreferenceController(
             Context context, String preferenceKey,
@@ -86,6 +96,8 @@
         if (mActivity.isChangingConfigurations()) {
             BatteryDiffEntry.clearCache();
         }
+        mHandler.removeCallbacksAndMessages(/*token=*/ null);
+        mPreferenceCache.clear();
     }
 
     @Override
@@ -93,6 +105,7 @@
         super.displayPreference(screen);
         mPrefContext = screen.getContext();
         mAppListPrefGroup = screen.findPreference(mPreferenceKey);
+        mAppListPrefGroup.setOrderingAsAdded(false);
     }
 
     @Override
@@ -116,7 +129,13 @@
         refreshUi(trapezoidIndex, /*isForce=*/ false);
     }
 
-    void setBatteryHistoryMap(Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
+    void setBatteryHistoryMap(
+            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
+        mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
+    }
+
+    private void setBatteryHistoryMapInner(
+            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
         // Resets all battery history data relative variables.
         if (batteryHistoryMap == null) {
             mBatteryIndexedMap = null;
@@ -163,7 +182,11 @@
             Arrays.toString(mBatteryHistoryLevels)));
     }
 
-    void setBatteryChartView(BatteryChartView batteryChartView) {
+    void setBatteryChartView(final BatteryChartView batteryChartView) {
+        mHandler.post(() -> setBatteryChartViewInner(batteryChartView));
+    }
+
+    private void setBatteryChartViewInner(final BatteryChartView batteryChartView) {
         mBatteryChartView = batteryChartView;
         mBatteryChartView.setOnSelectListener(this);
         forceRefreshUi();
@@ -174,6 +197,9 @@
             mTrapezoidIndex == BatteryChartView.SELECTED_INDEX_INVALID
                 ? BatteryChartView.SELECTED_INDEX_ALL
                 : mTrapezoidIndex;
+        if (mBatteryChartView != null) {
+            mBatteryChartView.setLevels(mBatteryHistoryLevels);
+        }
         refreshUi(refreshIndex, /*isForce=*/ true);
     }
 
@@ -185,12 +211,89 @@
                 || (mTrapezoidIndex == trapezoidIndex && !isForce)) {
             return false;
         }
-        mTrapezoidIndex = trapezoidIndex;
         Log.d(TAG, String.format("refreshUi: index=%d batteryIndexedMap.size=%d",
             mTrapezoidIndex, mBatteryIndexedMap.size()));
+
+        mTrapezoidIndex = trapezoidIndex;
+        mHandler.post(() -> {
+            removeAndCacheAllPrefs();
+            addAllPreferences();
+        });
         return true;
     }
 
+    private void addAllPreferences() {
+        final List<BatteryDiffEntry> entries =
+            mBatteryIndexedMap.get(Integer.valueOf(mTrapezoidIndex));
+        if (entries == null) {
+            Log.w(TAG, "cannot find BatteryDiffEntry for:" + mTrapezoidIndex);
+            return;
+        }
+        // Separates data into two groups and sort them individually.
+        final List<BatteryDiffEntry> appEntries = new ArrayList<>();
+        final List<BatteryDiffEntry> systemEntries = new ArrayList<>();
+        entries.forEach(entry -> {
+            if (entry.isSystemEntry()) {
+                systemEntries.add(entry);
+            } else {
+                appEntries.add(entry);
+            }
+        });
+        Collections.sort(appEntries, BatteryDiffEntry.COMPARATOR);
+        Collections.sort(systemEntries, BatteryDiffEntry.COMPARATOR);
+        Log.d(TAG, String.format("addAllPreferences() app=%d system=%d",
+            appEntries.size(), systemEntries.size()));
+        addPreferenceToScreen(appEntries);
+        addPreferenceToScreen(systemEntries);
+    }
+
+    @VisibleForTesting
+    void addPreferenceToScreen(List<BatteryDiffEntry> entries) {
+        if (mAppListPrefGroup == null || entries.isEmpty()) {
+            return;
+        }
+        int prefIndex = mAppListPrefGroup.getPreferenceCount();
+        for (BatteryDiffEntry entry : entries) {
+            final String appLabel = entry.getAppLabel();
+            final Drawable appIcon = entry.getAppIcon();
+            if (TextUtils.isEmpty(appLabel) || appIcon == null) {
+                Log.w(TAG, "cannot find app resource:" + entry.mBatteryHistEntry);
+                continue;
+            }
+            final String prefKey = entry.mBatteryHistEntry.getKey();
+            PowerGaugePreference pref =
+                (PowerGaugePreference) mPreferenceCache.get(prefKey);
+            // Creates new innstance if cached preference is not found.
+            if (pref == null) {
+                pref = new PowerGaugePreference(mPrefContext);
+                pref.setKey(prefKey);
+                mPreferenceCache.put(prefKey, pref);
+            }
+            pref.setIcon(appIcon);
+            pref.setTitle(appLabel);
+            pref.setOrder(prefIndex);
+            pref.setPercent(entry.getPercentOfTotal());
+            mAppListPrefGroup.addPreference(pref);
+            prefIndex++;
+        }
+    }
+
+    private void removeAndCacheAllPrefs() {
+        if (mAppListPrefGroup == null
+                || mAppListPrefGroup.getPreferenceCount() == 0) {
+            return;
+        }
+        final int prefsCount = mAppListPrefGroup.getPreferenceCount();
+        for (int index = 0; index < prefsCount; index++) {
+            final Preference pref = mAppListPrefGroup.getPreference(index);
+            if (TextUtils.isEmpty(pref.getKey())) {
+                continue;
+            }
+            mPreferenceCache.put(pref.getKey(), pref);
+        }
+        mAppListPrefGroup.removeAll();
+    }
+
     private static String utcToLocalTime(long[] timestamps) {
         final StringBuilder builder = new StringBuilder();
         for (int index = 0; index < timestamps.length; index++) {
diff --git a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
index 7c27d7d..652b54c 100644
--- a/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryDiffEntry.java
@@ -34,7 +34,7 @@
 import java.util.Map;
 
 /** A container class to carry battery data in a specific time slot. */
-public final class BatteryDiffEntry {
+public class BatteryDiffEntry {
     private static final String TAG = "BatteryDiffEntry";
 
     static Locale sCurrentLocale = null;
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
index 5a92f53..e895e9a 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceController.java
@@ -105,8 +105,7 @@
     @Override
     public void onStart() {
         EntityHeaderController.newInstance(mActivity, mHost, null /* header view */)
-                .setRecyclerView(mHost.getListView(), mLifecycle)
-                .styleActionBar(mActivity);
+                .setRecyclerView(mHost.getListView(), mLifecycle);
     }
 
     private CharSequence generateLabel(BatteryInfo info) {
diff --git a/src/com/android/settings/fuelgauge/BatteryHistEntry.java b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
index 9611de1..41fd55f 100644
--- a/src/com/android/settings/fuelgauge/BatteryHistEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryHistEntry.java
@@ -21,7 +21,7 @@
 import java.util.TimeZone;
 
 /** A container class to carry data from {@link ContentValues}. */
-public final class BatteryHistEntry {
+public class BatteryHistEntry {
     private static final String TAG = "BatteryHistEntry";
 
     /** Keys for accessing {@link ContentValues} or {@link Cursor}. */
diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
index 96e5011..99a72ab 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java
@@ -57,6 +57,7 @@
     final BatteryHistoryLoaderCallbacks mBatteryHistoryLoaderCallbacks =
             new BatteryHistoryLoaderCallbacks();
 
+    private boolean mIsChartDataLoaded = false;
     private boolean mIsChartGraphEnabled = false;
     private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
     private BatteryChartPreferenceController mBatteryChartPreferenceController;
@@ -145,10 +146,11 @@
         final Bundle bundle = new Bundle();
         bundle.putInt(KEY_REFRESH_TYPE, refreshType);
         // Uses customized battery history loader if chart design is enabled.
-        if (mIsChartGraphEnabled) {
+        if (mIsChartGraphEnabled && !mIsChartDataLoaded) {
+            mIsChartDataLoaded = true;
             getLoaderManager().restartLoader(LOADER_BATTERY_USAGE_STATS, bundle,
-                    mBatteryHistoryLoaderCallbacks);
-        } else {
+                mBatteryHistoryLoaderCallbacks);
+        } else if (!mIsChartGraphEnabled) {
             super.restartBatteryStatsLoader(refreshType);
         }
     }
diff --git a/src/com/android/settings/network/SubscriptionsChangeListener.java b/src/com/android/settings/network/SubscriptionsChangeListener.java
index 192ee53..e13f85c 100644
--- a/src/com/android/settings/network/SubscriptionsChangeListener.java
+++ b/src/com/android/settings/network/SubscriptionsChangeListener.java
@@ -27,12 +27,15 @@
 import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
+import android.util.Log;
 
 import com.android.internal.telephony.TelephonyIntents;
 
 /** Helper class for listening to changes in availability of telephony subscriptions */
 public class SubscriptionsChangeListener extends ContentObserver {
 
+    private static final String TAG = "SubscriptionsChangeListener";
+
     public interface SubscriptionsChangeListenerClient {
         void onAirplaneModeChanged(boolean airplaneModeEnabled);
         void onSubscriptionsChanged();
@@ -44,6 +47,7 @@
     private OnSubscriptionsChangedListener mSubscriptionsChangedListener;
     private Uri mAirplaneModeSettingUri;
     private BroadcastReceiver mBroadcastReceiver;
+    private boolean mRunning = false;
 
     public SubscriptionsChangeListener(Context context, SubscriptionsChangeListenerClient client) {
         super(new Handler(Looper.getMainLooper()));
@@ -75,12 +79,19 @@
         final IntentFilter radioTechnologyChangedFilter = new IntentFilter(
                 TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
         mContext.registerReceiver(mBroadcastReceiver, radioTechnologyChangedFilter);
+        mRunning = true;
     }
 
     public void stop() {
-        mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionsChangedListener);
-        mContext.getContentResolver().unregisterContentObserver(this);
-        mContext.unregisterReceiver(mBroadcastReceiver);
+        if (mRunning) {
+            mSubscriptionManager.removeOnSubscriptionsChangedListener(
+                    mSubscriptionsChangedListener);
+            mContext.getContentResolver().unregisterContentObserver(this);
+            mContext.unregisterReceiver(mBroadcastReceiver);
+            mRunning = false;
+        } else {
+            Log.d(TAG, "Stop has been called without associated Start.");
+        }
     }
 
     public boolean isAirplaneModeOn() {
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index a88be03..cd6b4ff 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -26,6 +26,7 @@
 import android.os.SystemProperties;
 import android.text.Editable;
 import android.text.TextWatcher;
+import android.util.Log;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -40,6 +41,7 @@
 import com.android.internal.net.VpnProfile;
 import com.android.net.module.util.ProxyUtils;
 import com.android.settings.R;
+import com.android.settings.Utils;
 import com.android.settings.utils.AndroidKeystoreAliasLoader;
 
 import java.net.InetAddress;
@@ -64,6 +66,8 @@
 
     private boolean mEditing;
     private boolean mExists;
+    private List<String> mTotalTypes;
+    private List<String> mAllowedTypes;
 
     private View mView;
 
@@ -134,7 +138,13 @@
         // Second, copy values from the profile.
         mName.setText(mProfile.name);
         setTypesByFeature(mType);
-        mType.setSelection(mProfile.type);
+        // Not all types will be available to the user. Find the index corresponding to the
+        // string of the profile's type.
+        if (mAllowedTypes != null && mTotalTypes != null) {
+            mType.setSelection(mAllowedTypes.indexOf(mTotalTypes.get(mProfile.type)));
+        } else {
+            Log.w(TAG, "Allowed or Total vpn types not initialized when setting initial selection");
+        }
         mServer.setText(mProfile.server);
         if (mProfile.saveLogin) {
             mUsername.setText(mProfile.username);
@@ -276,7 +286,10 @@
     @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
         if (parent == mType) {
-            changeType(position);
+            // Because the spinner may not display all available types,
+            // convert the selected position into the actual vpn profile type integer.
+            final int profileType = convertAllowedIndexToProfileType(position);
+            changeType(profileType);
         } else if (parent == mProxySettings) {
             updateProxyFieldsVisibility(position);
         }
@@ -371,7 +384,7 @@
             // Configure networking option visibility
             // TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
             final int visibility =
-                    isLegacyType(mType.getSelectedItemPosition()) ? View.VISIBLE : View.GONE;
+                    isLegacyType(getSelectedVpnType()) ? View.VISIBLE : View.GONE;
             mView.findViewById(R.id.network_options).setVisibility(visibility);
         } else {
             mView.findViewById(R.id.options).setVisibility(View.GONE);
@@ -431,7 +444,7 @@
             return false;
         }
 
-        final int type = mType.getSelectedItemPosition();
+        final int type = getSelectedVpnType();
         if (!editing && requiresUsernamePassword(type)) {
             return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
         }
@@ -503,6 +516,8 @@
 
     private void setTypesByFeature(Spinner typeSpinner) {
         String[] types = getContext().getResources().getStringArray(R.array.vpn_types);
+        mTotalTypes = new ArrayList<>(Arrays.asList(types));
+        mAllowedTypes = new ArrayList<>(Arrays.asList(types));
         if (!getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_IPSEC_TUNNELS)) {
             final List<String> typesList = new ArrayList<>(Arrays.asList(types));
@@ -513,6 +528,26 @@
             typesList.remove(VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS);
 
             types = typesList.toArray(new String[0]);
+        } else if (Utils.isProviderModelEnabled(getContext())) {
+            // If the provider mode is enabled and the vpn is new or is not already a legacy type,
+            // don't allow the user to set the type to a legacy option.
+
+            // Set the mProfile.type to TYPE_IKEV2_IPSEC_USER_PASS if the VPN not exist
+            if (!mExists) {
+                mProfile.type = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
+            }
+
+            // Remove all types which are legacy types from the typesList
+            if (!VpnProfile.isLegacyType(mProfile.type)) {
+                for (int i = mAllowedTypes.size() - 1; i >= 0; i--) {
+                    // This must be removed from back to front in order to ensure index consistency
+                    if (VpnProfile.isLegacyType(i)) {
+                        mAllowedTypes.remove(i);
+                    }
+                }
+
+                types = mAllowedTypes.toArray(new String[0]);
+            }
         }
         final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                 getContext(), android.R.layout.simple_spinner_item, types);
@@ -577,7 +612,7 @@
         // First, save common fields.
         VpnProfile profile = new VpnProfile(mProfile.key);
         profile.name = mName.getText().toString();
-        profile.type = mType.getSelectedItemPosition();
+        profile.type = getSelectedVpnType();
         profile.server = mServer.getText().toString().trim();
         profile.username = mUsername.getText().toString();
         profile.password = mPassword.getText().toString();
@@ -652,4 +687,19 @@
         return ProxyUtils.validate(host, port, "") == ProxyUtils.PROXY_VALID;
     }
 
+    private int getSelectedVpnType() {
+        return convertAllowedIndexToProfileType(mType.getSelectedItemPosition());
+    }
+
+    private int convertAllowedIndexToProfileType(int allowedSelectedPosition) {
+        if (mAllowedTypes != null && mTotalTypes != null) {
+            final String typeString = mAllowedTypes.get(allowedSelectedPosition);
+            final int profileType = mTotalTypes.indexOf(typeString);
+            return profileType;
+        } else {
+            Log.w(TAG, "Allowed or Total vpn types not initialized when converting protileType");
+            return allowedSelectedPosition;
+        }
+    }
+
 }
diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
index 197fdff..c5ea21f 100644
--- a/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetailsTest.java
@@ -34,7 +34,6 @@
 
 import com.google.common.collect.ImmutableList;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -80,7 +79,6 @@
     }
 
     @Test
-    @Ignore
     public void getPreferenceSummary_appOpNotAllowed_returnsNotAllowed() {
         shadowOf(mUserManager).addUser(
                 PERSONAL_PROFILE_ID, "personal-profile"/* name */, 0/* flags */);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
index 7d64960..66ef2d2 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryChartPreferenceControllerTest.java
@@ -18,14 +18,18 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.ContentValues;
 import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
 
 import androidx.preference.PreferenceGroup;
 
@@ -55,9 +59,13 @@
     @Mock private SettingsActivity mSettingsActivity;
     @Mock private PreferenceGroup mAppListGroup;
     @Mock private PackageManager mPackageManager;
+    @Mock private Drawable mDrawable;
+    @Mock private BatteryHistEntry mBatteryHistEntry;
     @Mock private BatteryChartView mBatteryChartView;
+    @Mock private PowerGaugePreference mPowerGaugePreference;
 
     private Context mContext;
+    private BatteryDiffEntry mBatteryDiffEntry;
     private BatteryChartPreferenceController mBatteryChartPreferenceController;
 
     @Before
@@ -71,6 +79,13 @@
         mBatteryChartPreferenceController.mPrefContext = mContext;
         mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
         mBatteryChartPreferenceController.mBatteryChartView = mBatteryChartView;
+        mBatteryDiffEntry = new BatteryDiffEntry(
+            mContext,
+            /*foregroundUsageTimeInMs=*/ 1,
+            /*backgroundUsageTimeInMs=*/ 2,
+            /*consumePower=*/ 3,
+            mBatteryHistEntry);
+        mBatteryDiffEntry = spy(mBatteryDiffEntry);
         // Adds fake testing data.
         BatteryDiffEntry.sResourceCache.put(
             "fakeBatteryDiffEntryKey",
@@ -100,6 +115,19 @@
     }
 
     @Test
+    public void testOnDestroy_clearPreferenceCache() {
+        final String prefKey = "preference fake key";
+        // Ensures the testing environment is correct.
+        mBatteryChartPreferenceController.mPreferenceCache.put(
+            prefKey, mPowerGaugePreference);
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).hasSize(1);
+
+        mBatteryChartPreferenceController.onDestroy();
+        // Verifies the result after onDestroy.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+    }
+
+    @Test
     public void testSetBatteryHistoryMap_createExpectedKeysAndLevels() {
         mBatteryChartPreferenceController.setBatteryHistoryMap(
             createBatteryHistoryMap(/*size=*/ 5));
@@ -176,11 +204,70 @@
         mBatteryChartPreferenceController.setBatteryHistoryMap(
             createBatteryHistoryMap(/*size=*/ 25));
 
-
         assertThat(mBatteryChartPreferenceController.mTrapezoidIndex)
             .isEqualTo(BatteryChartView.SELECTED_INDEX_ALL);
     }
 
+    @Test
+    public void testRemoveAndCacheAllPrefs_emptyContent_ignoreRemoveAll() {
+        final int trapezoidIndex = 1;
+        doReturn(0).when(mAppListGroup).getPreferenceCount();
+
+        mBatteryChartPreferenceController.refreshUi(
+            trapezoidIndex, /*isForce=*/ true);
+        verify(mAppListGroup, never()).removeAll();
+    }
+
+    @Test
+    public void testRemoveAndCacheAllPrefs_buildCacheAndRemoveAllPreference() {
+        final int trapezoidIndex = 1;
+        final String prefKey = "preference fake key";
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mPowerGaugePreference).when(mAppListGroup).getPreference(0);
+        doReturn(prefKey).when(mPowerGaugePreference).getKey();
+        // Ensures the testing data is correct.
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache).isEmpty();
+
+        mBatteryChartPreferenceController.refreshUi(
+            trapezoidIndex, /*isForce=*/ true);
+
+        assertThat(mBatteryChartPreferenceController.mPreferenceCache.get(prefKey))
+            .isEqualTo(mPowerGaugePreference);
+        verify(mAppListGroup).removeAll();
+    }
+
+    @Test
+    public void testAddPreferenceToScreen_emptyContent_ignoreAddPreference() {
+        mBatteryChartPreferenceController.addPreferenceToScreen(
+            new ArrayList<BatteryDiffEntry>());
+        verify(mAppListGroup, never()).addPreference(any());
+    }
+
+    @Test
+    public void testAddPreferenceToScreen_addPreferenceIntoScreen() {
+        final String prefKey = "preference fake key";
+        final String appLabel = "fake app label";
+        doReturn(1).when(mAppListGroup).getPreferenceCount();
+        doReturn(mDrawable).when(mBatteryDiffEntry).getAppIcon();
+        doReturn(appLabel).when(mBatteryDiffEntry).getAppLabel();
+        doReturn(prefKey).when(mBatteryHistEntry).getKey();
+
+        mBatteryChartPreferenceController.addPreferenceToScreen(
+            Arrays.asList(mBatteryDiffEntry));
+
+        // Verifies the preference cache.
+        final PowerGaugePreference pref =
+            (PowerGaugePreference) mBatteryChartPreferenceController.mPreferenceCache
+                .get(prefKey);
+        assertThat(pref).isNotNull();
+        // Verifies the added preference configuration.
+        verify(mAppListGroup).addPreference(pref);
+        assertThat(pref.getKey()).isEqualTo(prefKey);
+        assertThat(pref.getTitle()).isEqualTo(appLabel);
+        assertThat(pref.getIcon()).isEqualTo(mDrawable);
+        assertThat(pref.getOrder()).isEqualTo(1);
+    }
+
     private Map<Long, List<BatteryHistEntry>> createBatteryHistoryMap(int size) {
         final Map<Long, List<BatteryHistEntry>> batteryHistoryMap = new HashMap<>();
         for (int index = 0; index < size; index++) {