Merge "Implement UnitsBasePreferenceController with application to UnitsTemperaturePreferenceController" into pi-car-dev
diff --git a/res/drawable/ic_audio_navi.xml b/res/drawable/ic_audio_navi.xml
index afc8a61..4919d18 100644
--- a/res/drawable/ic_audio_navi.xml
+++ b/res/drawable/ic_audio_navi.xml
@@ -21,7 +21,8 @@
     android:height="@dimen/icon_size"
     android:viewportHeight="24.0"
     android:viewportWidth="24.0">
+    <!-- Use solid fillColor for mask. Icon tint color will be applied after icon is loaded. -->
     <path
-        android:fillColor="?attr/iconColor"
+        android:fillColor="#FF000000"
         android:pathData="M18.92,5.01C18.72,4.42 18.16,4 17.5,4h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,11v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,15c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,12 6.5,12s1.5,0.67 1.5,1.5S7.33,15 6.5,15zM17.5,15c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,10l1.5,-4.5h11L19,10L5,10z"/>
 </vector>
diff --git a/res/values/config.xml b/res/values/config.xml
index 939d08c..9a31b51 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -27,7 +27,7 @@
     <!-- Whether premium SMS should be shown or not. -->
     <bool name="config_show_premium_sms">true</bool>
     <!-- Whether exit button in settings' root action bar should be shown or not -->
-    <bool name="config_show_settings_root_exit_icon">false</bool>
+    <bool name="config_show_settings_root_exit_icon">true</bool>
     <!-- Whether all preferences should always ignore UX Restrictions -->
     <bool name="config_always_ignore_ux_restrictions">false</bool>
     <!-- Array of Preference Keys that ignore UX Restrictions -->
diff --git a/res/values/preference_keys.xml b/res/values/preference_keys.xml
index 3959717..fc9c2d7 100644
--- a/res/values/preference_keys.xml
+++ b/res/values/preference_keys.xml
@@ -229,6 +229,8 @@
 
     <!-- Storage -->
     <string name="pk_storage_music_audio" translatable="false">storage_music_audio</string>
+    <string name="pk_storage_music_audio_files" translatable="false">storage_music_audio_files
+    </string>
     <string name="pk_storage_music_audio_details" translatable="false">storage_music_audio_details
     </string>
     <string name="pk_storage_other_apps" translatable="false">storage_other_apps</string>
diff --git a/src/com/android/car/settings/accounts/SyncPreference.java b/src/com/android/car/settings/accounts/SyncPreference.java
index 76e3f2a..612a739 100644
--- a/src/com/android/car/settings/accounts/SyncPreference.java
+++ b/src/com/android/car/settings/accounts/SyncPreference.java
@@ -69,15 +69,15 @@
         switch (mSyncState) {
             case ACTIVE:
                 setIcon(R.drawable.ic_sync_anim);
-                getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+                getIcon().setTintList(Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
                 break;
             case PENDING:
                 setIcon(R.drawable.ic_sync);
-                getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+                getIcon().setTintList(Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
                 break;
             case FAILED:
                 setIcon(R.drawable.ic_sync_problem);
-                getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+                getIcon().setTintList(Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
                 break;
             default:
                 setIcon(null);
diff --git a/src/com/android/car/settings/applications/specialaccess/AppOpsFragment.java b/src/com/android/car/settings/applications/AppListFragment.java
similarity index 73%
rename from src/com/android/car/settings/applications/specialaccess/AppOpsFragment.java
rename to src/com/android/car/settings/applications/AppListFragment.java
index 165dbb8..c56ab7b 100644
--- a/src/com/android/car/settings/applications/specialaccess/AppOpsFragment.java
+++ b/src/com/android/car/settings/applications/AppListFragment.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.car.settings.applications.specialaccess;
+package com.android.car.settings.applications;
 
 import android.os.Bundle;
 import android.widget.Button;
@@ -25,11 +25,10 @@
 import com.android.car.settings.common.SettingsFragment;
 
 /**
- * Fragment which hosts an {@link AppOpsPreferenceController} to display a list of controls to
- * allow/disallow app operations. There is a toggle in the app bar for showing/hiding system
- * applications. The semantics of what constitues a system app is left up to the controller.
+ * Fragment base class for use in cases where a list of applications is displayed with the option to
+ * show/hide system apps in the list.
  */
-public abstract class AppOpsFragment extends SettingsFragment {
+public abstract class AppListFragment extends SettingsFragment {
 
     private static final String KEY_SHOW_SYSTEM = "showSystem";
 
@@ -41,15 +40,11 @@
         return R.layout.action_bar_with_button;
     }
 
-    /** Returns the {@link AppOpsPreferenceController} via {@link #use(Class, int)} lookup. */
-    protected abstract AppOpsPreferenceController lookupAppOpsPreferenceController();
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         if (savedInstanceState != null) {
             mShowSystem = savedInstanceState.getBoolean(KEY_SHOW_SYSTEM, false);
-            lookupAppOpsPreferenceController().setShowSystem(mShowSystem);
         }
     }
 
@@ -60,11 +55,25 @@
         setButtonText(toggleShowSystem);
         toggleShowSystem.setOnClickListener(v -> {
             mShowSystem = !mShowSystem;
-            lookupAppOpsPreferenceController().setShowSystem(mShowSystem);
+            onToggleShowSystemApps(mShowSystem);
             setButtonText(toggleShowSystem);
         });
     }
 
+    @Override
+    public void onStart() {
+        super.onStart();
+        onToggleShowSystemApps(mShowSystem);
+    }
+
+    /** Called when a user toggles the option to show system applications in the list. */
+    protected abstract void onToggleShowSystemApps(boolean showSystem);
+
+    /** Returns {@code true} if system applications should be shown in the list. */
+    protected final boolean shouldShowSystemApps() {
+        return mShowSystem;
+    }
+
     private void setButtonText(Button button) {
         // Show text to reverse the current state.
         button.setText(mShowSystem ? R.string.hide_system : R.string.show_system);
diff --git a/src/com/android/car/settings/applications/ApplicationListItemManager.java b/src/com/android/car/settings/applications/ApplicationListItemManager.java
index 7293539..8f7f95b 100644
--- a/src/com/android/car/settings/applications/ApplicationListItemManager.java
+++ b/src/com/android/car/settings/applications/ApplicationListItemManager.java
@@ -20,6 +20,7 @@
 
 import androidx.lifecycle.Lifecycle;
 
+import com.android.car.settings.common.Logger;
 import com.android.settingslib.applications.ApplicationsState;
 
 import java.util.ArrayList;
@@ -29,6 +30,7 @@
 /**
  * Class used to load the applications installed on the system with their metadata.
  */
+// TODO: consolidate with AppEntryListManager.
 public class ApplicationListItemManager implements ApplicationsState.Callbacks {
     /**
      * Callback that is called once the list of applications are loaded.
@@ -41,6 +43,8 @@
         void onDataLoaded(ArrayList<ApplicationsState.AppEntry> apps);
     }
 
+    private static final Logger LOG = new Logger(ApplicationListItemManager.class);
+
     private final VolumeInfo mVolumeInfo;
     private final Lifecycle mLifecycle;
     private final ApplicationsState mAppState;
@@ -90,18 +94,33 @@
     /**
      * Starts the new session and start loading the list of installed applications on the device.
      * This list will be filtered out based on the {@link ApplicationsState.AppFilter} provided.
-     * Once the list is ready {@link AppListItemListener#onDataLoaded} method will be called.
+     * Once the list is ready, {@link AppListItemListener#onDataLoaded} will be called.
      *
-     * @param appFilter based on which the list of applications will be filtered before returning.
+     * @param appFilter          based on which the list of applications will be filtered before
+     *                           returning.
      * @param appEntryComparator comparator based on which the application list will be sorted.
      */
     public void startLoading(ApplicationsState.AppFilter appFilter,
             Comparator<ApplicationsState.AppEntry> appEntryComparator) {
+        if (mSession != null) {
+            LOG.w("Loading already started but restart attempted.");
+            return; // Prevent leaking sessions.
+        }
         mAppFilter = appFilter;
         mAppEntryComparator = appEntryComparator;
         mSession = mAppState.newSession(this, mLifecycle);
     }
 
+    /**
+     * Rebuilds the list of applications using the provided {@link ApplicationsState.AppFilter}.
+     * The filter will be used for all subsequent loading. Once the list is ready, {@link
+     * AppListItemListener#onDataLoaded} will be called.
+     */
+    public void rebuildWithFilter(ApplicationsState.AppFilter appFilter) {
+        mAppFilter = appFilter;
+        rebuild();
+    }
+
     @Override
     public void onPackageIconChanged() {
         rebuild();
@@ -176,8 +195,6 @@
         if (compositeFilter != null) {
             filterObj = new ApplicationsState.CompoundFilter(filterObj, compositeFilter);
         }
-        filterObj = new ApplicationsState.CompoundFilter(filterObj,
-                ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT);
         ApplicationsState.AppFilter finalFilterObj = filterObj;
         mSession.rebuild(finalFilterObj, mAppEntryComparator, /* foreground= */ false);
     }
diff --git a/src/com/android/car/settings/applications/ApplicationsSettingsFragment.java b/src/com/android/car/settings/applications/ApplicationsSettingsFragment.java
index c736e5d..0dce6be 100644
--- a/src/com/android/car/settings/applications/ApplicationsSettingsFragment.java
+++ b/src/com/android/car/settings/applications/ApplicationsSettingsFragment.java
@@ -25,13 +25,12 @@
 import android.os.storage.VolumeInfo;
 
 import com.android.car.settings.R;
-import com.android.car.settings.common.SettingsFragment;
 import com.android.settingslib.applications.ApplicationsState;
 
 /**
  * Lists all installed applications and their summary.
  */
-public class ApplicationsSettingsFragment extends SettingsFragment {
+public class ApplicationsSettingsFragment extends AppListFragment {
 
     private ApplicationListItemManager mAppListItemManager;
 
@@ -57,7 +56,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mAppListItemManager.startLoading(/* AppFilter= */ null, ApplicationsState.ALPHA_COMPARATOR);
+        mAppListItemManager.startLoading(getAppFilter(), ApplicationsState.ALPHA_COMPARATOR);
     }
 
     @Override
@@ -71,4 +70,14 @@
         super.onStop();
         mAppListItemManager.onFragmentStop();
     }
+
+    @Override
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        mAppListItemManager.rebuildWithFilter(getAppFilter());
+    }
+
+    private ApplicationsState.AppFilter getAppFilter() {
+        return shouldShowSystemApps() ? null
+                : ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT;
+    }
 }
diff --git a/src/com/android/car/settings/applications/specialaccess/ModifySystemSettingsFragment.java b/src/com/android/car/settings/applications/specialaccess/ModifySystemSettingsFragment.java
index bd3955d..fae0522 100644
--- a/src/com/android/car/settings/applications/specialaccess/ModifySystemSettingsFragment.java
+++ b/src/com/android/car/settings/applications/specialaccess/ModifySystemSettingsFragment.java
@@ -23,11 +23,12 @@
 import androidx.annotation.XmlRes;
 
 import com.android.car.settings.R;
+import com.android.car.settings.applications.AppListFragment;
 
 /**
  * Displays apps which have requested to modify system settings and their current allowed status.
  */
-public class ModifySystemSettingsFragment extends AppOpsFragment {
+public class ModifySystemSettingsFragment extends AppListFragment {
 
     @Override
     @XmlRes
@@ -38,13 +39,15 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        lookupAppOpsPreferenceController().init(AppOpsManager.OP_WRITE_SETTINGS,
+        use(AppOpsPreferenceController.class, R.string.pk_modify_system_settings).init(
+                AppOpsManager.OP_WRITE_SETTINGS,
                 Manifest.permission.WRITE_SETTINGS,
                 AppOpsManager.MODE_ERRORED);
     }
 
     @Override
-    protected AppOpsPreferenceController lookupAppOpsPreferenceController() {
-        return use(AppOpsPreferenceController.class, R.string.pk_modify_system_settings);
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        use(AppOpsPreferenceController.class, R.string.pk_modify_system_settings).setShowSystem(
+                showSystem);
     }
 }
diff --git a/src/com/android/car/settings/applications/specialaccess/UsageAccessFragment.java b/src/com/android/car/settings/applications/specialaccess/UsageAccessFragment.java
index c44e870..266afd8 100644
--- a/src/com/android/car/settings/applications/specialaccess/UsageAccessFragment.java
+++ b/src/com/android/car/settings/applications/specialaccess/UsageAccessFragment.java
@@ -23,11 +23,12 @@
 import androidx.annotation.XmlRes;
 
 import com.android.car.settings.R;
+import com.android.car.settings.applications.AppListFragment;
 
 /**
  * Displays apps which have requested to access usage data and their current allowed status.
  */
-public class UsageAccessFragment extends AppOpsFragment {
+public class UsageAccessFragment extends AppListFragment {
 
     @Override
     @XmlRes
@@ -38,13 +39,14 @@
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
-        lookupAppOpsPreferenceController().init(AppOpsManager.OP_GET_USAGE_STATS,
+        use(AppOpsPreferenceController.class, R.string.pk_usage_access).init(
+                AppOpsManager.OP_GET_USAGE_STATS,
                 Manifest.permission.PACKAGE_USAGE_STATS,
                 AppOpsManager.MODE_IGNORED);
     }
 
     @Override
-    protected AppOpsPreferenceController lookupAppOpsPreferenceController() {
-        return use(AppOpsPreferenceController.class, R.string.pk_usage_access);
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        use(AppOpsPreferenceController.class, R.string.pk_usage_access).setShowSystem(showSystem);
     }
 }
diff --git a/src/com/android/car/settings/applications/specialaccess/WifiControlFragment.java b/src/com/android/car/settings/applications/specialaccess/WifiControlFragment.java
index eff706c..87b7728 100644
--- a/src/com/android/car/settings/applications/specialaccess/WifiControlFragment.java
+++ b/src/com/android/car/settings/applications/specialaccess/WifiControlFragment.java
@@ -19,11 +19,12 @@
 import androidx.annotation.XmlRes;
 
 import com.android.car.settings.R;
+import com.android.car.settings.applications.AppListFragment;
 
 /**
  * Displays apps which have requested to control Wi-Fi settings and their current allowed status.
  */
-public class WifiControlFragment extends AppOpsFragment {
+public class WifiControlFragment extends AppListFragment {
 
     @Override
     @XmlRes
@@ -32,7 +33,8 @@
     }
 
     @Override
-    protected AppOpsPreferenceController lookupAppOpsPreferenceController() {
-        return use(WifiControlPreferenceController.class, R.string.pk_wifi_control);
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        use(WifiControlPreferenceController.class, R.string.pk_wifi_control).setShowSystem(
+                showSystem);
     }
 }
diff --git a/src/com/android/car/settings/bluetooth/BluetoothDeviceNamePreferenceController.java b/src/com/android/car/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
index 9ca375a..afb7db5 100644
--- a/src/com/android/car/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
+++ b/src/com/android/car/settings/bluetooth/BluetoothDeviceNamePreferenceController.java
@@ -75,7 +75,8 @@
         }
         preference.setTitle(cachedDevice.getName());
         preference.setIcon(pair.first);
-        preference.getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+        preference.getIcon().setTintList(
+                Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
         preference.setSummary(summaryJoiner.toString());
     }
 
diff --git a/src/com/android/car/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/car/settings/bluetooth/BluetoothDevicePreference.java
index 4748e01..66274c9 100644
--- a/src/com/android/car/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/car/settings/bluetooth/BluetoothDevicePreference.java
@@ -82,7 +82,7 @@
                 .getBtClassDrawableWithDescription(getContext(), mCachedDevice);
         if (pair.first != null) {
             setIcon(pair.first);
-            getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+            getIcon().setTintList(Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
         }
 
         setEnabled(!mCachedDevice.isBusy());
diff --git a/src/com/android/car/settings/common/ExtraSettingsLoader.java b/src/com/android/car/settings/common/ExtraSettingsLoader.java
index 6d81060..1f51496 100644
--- a/src/com/android/car/settings/common/ExtraSettingsLoader.java
+++ b/src/com/android/car/settings/common/ExtraSettingsLoader.java
@@ -137,7 +137,8 @@
             preference.setSummary(summary);
             if (icon != null) {
                 preference.setIcon(icon.loadDrawable(mContext));
-                preference.getIcon().setTint(Themes.getAttrColor(mContext, R.attr.iconColor));
+                preference.getIcon().setTintList(
+                        Themes.getAttrColorStateList(mContext, R.attr.iconColor));
             }
             preference.setIntent(extraSettingIntent);
             mPreferenceBundleMap.put(preference, metaData);
diff --git a/src/com/android/car/settings/sound/VolumeSettingsPreferenceController.java b/src/com/android/car/settings/sound/VolumeSettingsPreferenceController.java
index 4e92c0d..fae748e 100644
--- a/src/com/android/car/settings/sound/VolumeSettingsPreferenceController.java
+++ b/src/com/android/car/settings/sound/VolumeSettingsPreferenceController.java
@@ -142,7 +142,8 @@
         SeekBarPreference preference = new SeekBarPreference(getContext());
         preference.setTitle(getContext().getString(titleId));
         preference.setIcon(getContext().getDrawable(iconResId));
-        preference.getIcon().setTint(Themes.getAttrColor(getContext(), R.attr.iconColor));
+        preference.getIcon().setTintList(
+                Themes.getAttrColorStateList(getContext(), R.attr.iconColor));
         try {
             preference.setValue(mCarAudioManager.getGroupVolume(volumeGroupId));
             preference.setMin(mCarAudioManager.getGroupMinVolume(volumeGroupId));
diff --git a/src/com/android/car/settings/storage/StorageApplicationListPreferenceController.java b/src/com/android/car/settings/storage/StorageApplicationListPreferenceController.java
index 53ed01c..e403998 100644
--- a/src/com/android/car/settings/storage/StorageApplicationListPreferenceController.java
+++ b/src/com/android/car/settings/storage/StorageApplicationListPreferenceController.java
@@ -49,22 +49,14 @@
 
     @Override
     public void onDataLoaded(ArrayList<ApplicationsState.AppEntry> apps) {
+        getPreference().removeAll();
         for (ApplicationsState.AppEntry appEntry : apps) {
-            addOrUpdatePreference(appEntry);
+            getPreference().addPreference(
+                    createPreference(appEntry.label, appEntry.sizeStr, appEntry.icon,
+                            appEntry.info.packageName));
         }
     }
 
-    private void addOrUpdatePreference(ApplicationsState.AppEntry appEntry) {
-        Preference preference = getPreference().findPreference(appEntry.info.packageName);
-        if (preference != null) {
-            preference.setSummary(appEntry.sizeStr);
-            return;
-        }
-        getPreference().addPreference(
-                createPreference(appEntry.label, appEntry.sizeStr, appEntry.icon,
-                        appEntry.info.packageName));
-    }
-
     protected Preference createPreference(String title, String summary, Drawable icon,
             String key) {
         Preference preference = new Preference(getContext());
diff --git a/src/com/android/car/settings/storage/StorageMediaCategoryDetailFragment.java b/src/com/android/car/settings/storage/StorageMediaCategoryDetailFragment.java
index 66919d1..f7af597 100644
--- a/src/com/android/car/settings/storage/StorageMediaCategoryDetailFragment.java
+++ b/src/com/android/car/settings/storage/StorageMediaCategoryDetailFragment.java
@@ -26,14 +26,14 @@
 import android.os.storage.VolumeInfo;
 
 import com.android.car.settings.R;
+import com.android.car.settings.applications.AppListFragment;
 import com.android.car.settings.applications.ApplicationListItemManager;
-import com.android.car.settings.common.SettingsFragment;
 import com.android.settingslib.applications.ApplicationsState;
 
 /**
  * Lists all installed applications with category audio and their summary.
  */
-public class StorageMediaCategoryDetailFragment extends SettingsFragment {
+public class StorageMediaCategoryDetailFragment extends AppListFragment {
 
     private ApplicationListItemManager mAppListItemManager;
 
@@ -70,8 +70,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mAppListItemManager.startLoading(ApplicationsState.FILTER_AUDIO,
-                ApplicationsState.SIZE_COMPARATOR);
+        mAppListItemManager.startLoading(getAppFilter(), ApplicationsState.SIZE_COMPARATOR);
     }
 
     @Override
@@ -85,4 +84,18 @@
         super.onStop();
         mAppListItemManager.onFragmentStop();
     }
+
+    @Override
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        mAppListItemManager.rebuildWithFilter(getAppFilter());
+    }
+
+    private ApplicationsState.AppFilter getAppFilter() {
+        ApplicationsState.AppFilter filter = ApplicationsState.FILTER_AUDIO;
+        if (!shouldShowSystemApps()) {
+            filter = new ApplicationsState.CompoundFilter(filter,
+                    ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT);
+        }
+        return filter;
+    }
 }
diff --git a/src/com/android/car/settings/storage/StorageMediaCategoryDetailPreferenceController.java b/src/com/android/car/settings/storage/StorageMediaCategoryDetailPreferenceController.java
index 548faa2..7c81ff7 100644
--- a/src/com/android/car/settings/storage/StorageMediaCategoryDetailPreferenceController.java
+++ b/src/com/android/car/settings/storage/StorageMediaCategoryDetailPreferenceController.java
@@ -35,7 +35,6 @@
         StorageApplicationListPreferenceController {
 
     private long mExternalAudioBytes;
-    private boolean mIsStorageAudioPreferenceAdded;
 
     public StorageMediaCategoryDetailPreferenceController(Context context,
             String preferenceKey, FragmentController fragmentController,
@@ -46,18 +45,15 @@
     @Override
     public void onDataLoaded(ArrayList<ApplicationsState.AppEntry> apps) {
         super.onDataLoaded(apps);
-        if (mIsStorageAudioPreferenceAdded) {
-            return;
-        }
         Preference preference = createPreference(
                 getContext().getString(R.string.storage_audio_files_title),
                 Long.toString(mExternalAudioBytes),
-                getContext().getDrawable(R.drawable.ic_headset), /* key= */ null);
+                getContext().getDrawable(R.drawable.ic_headset),
+                getContext().getString(R.string.pk_storage_music_audio_files));
         // remove the onClickListener which was set above with null key. This preference should
         // do nothing on click.
         preference.setOnPreferenceClickListener(null);
         getPreference().addPreference(preference);
-        mIsStorageAudioPreferenceAdded = true;
     }
 
     /**
diff --git a/src/com/android/car/settings/storage/StorageOtherCategoryDetailFragment.java b/src/com/android/car/settings/storage/StorageOtherCategoryDetailFragment.java
index ac71912..6aec796 100644
--- a/src/com/android/car/settings/storage/StorageOtherCategoryDetailFragment.java
+++ b/src/com/android/car/settings/storage/StorageOtherCategoryDetailFragment.java
@@ -24,14 +24,14 @@
 import android.os.storage.VolumeInfo;
 
 import com.android.car.settings.R;
+import com.android.car.settings.applications.AppListFragment;
 import com.android.car.settings.applications.ApplicationListItemManager;
-import com.android.car.settings.common.SettingsFragment;
 import com.android.settingslib.applications.ApplicationsState;
 
 /**
  * Lists all installed applications with no category defined and their summary.
  */
-public class StorageOtherCategoryDetailFragment extends SettingsFragment {
+public class StorageOtherCategoryDetailFragment extends AppListFragment {
 
     private ApplicationListItemManager mAppListItemManager;
 
@@ -56,8 +56,7 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        mAppListItemManager.startLoading(ApplicationsState.FILTER_OTHER_APPS,
-                ApplicationsState.SIZE_COMPARATOR);
+        mAppListItemManager.startLoading(getAppFilter(), ApplicationsState.SIZE_COMPARATOR);
     }
 
     @Override
@@ -71,4 +70,18 @@
         super.onStop();
         mAppListItemManager.onFragmentStop();
     }
+
+    @Override
+    protected void onToggleShowSystemApps(boolean showSystem) {
+        mAppListItemManager.rebuildWithFilter(getAppFilter());
+    }
+
+    private ApplicationsState.AppFilter getAppFilter() {
+        ApplicationsState.AppFilter filter = ApplicationsState.FILTER_OTHER_APPS;
+        if (!shouldShowSystemApps()) {
+            filter = new ApplicationsState.CompoundFilter(filter,
+                    ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER_AND_INSTANT);
+        }
+        return filter;
+    }
 }
diff --git a/tests/robotests/res/values/config.xml b/tests/robotests/res/values/config.xml
index 0b52270..8e168b0 100644
--- a/tests/robotests/res/values/config.xml
+++ b/tests/robotests/res/values/config.xml
@@ -20,4 +20,6 @@
     <string name="config_settings_hierarchy_root_fragment" translatable="false">com.android.car.settings.testutils.DummyFragment</string>
     <!-- explicitly set to unset string for testing purpose -->
     <string name="config_defaultAssistantComponentName" translatable="false">#+UNSET</string>
+    <!-- Whether exit button in settings' root action bar should be shown or not -->
+    <bool name="config_show_settings_root_exit_icon">true</bool>
 </resources>