Merge "Adding alarms and reminders activity" into sc-dev
diff --git a/res/layout/enable_accessibility_service_dialog_content.xml b/res/layout/enable_accessibility_service_dialog_content.xml
index 59cb6dd..6b3220b 100644
--- a/res/layout/enable_accessibility_service_dialog_content.xml
+++ b/res/layout/enable_accessibility_service_dialog_content.xml
@@ -134,6 +134,11 @@
                 android:text="@string/accessibility_dialog_button_deny"
                 style="@style/AccessibilityDialogButton" />
 
+            <Button
+                android:id="@+id/permission_enable_uninstall_button"
+                android:text="@string/uninstall_text"
+                android:visibility="gone"
+                style="@style/AccessibilityDialogButton" />
         </LinearLayout>
     </LinearLayout>
 
diff --git a/res/layout/preference_widget_dialog_summary.xml b/res/layout/preference_widget_dialog_summary.xml
index 2978efb..e37be71 100644
--- a/res/layout/preference_widget_dialog_summary.xml
+++ b/res/layout/preference_widget_dialog_summary.xml
@@ -18,7 +18,6 @@
 
 <TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:text="@string/bluetooth_select_a2dp_codec_type_help_info"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginTop="@dimen/developer_option_dialog_margin_top"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3c4e5ef..9dd44ef 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4981,6 +4981,8 @@
     <string name="captions_category_title">Captions</string>
     <!-- Title for the accessibility preference category of audio services and settings. [CHAR LIMIT=50] -->
     <string name="audio_category_title">Audio</string>
+    <!-- Title for the accessibility preference category of general services and settings. [CHAR LIMIT=50] -->
+    <string name="general_category_title">General</string>
     <!-- Title for the accessibility preference category of display services and settings. [CHAR LIMIT=50] -->
     <string name="display_category_title">Display</string>
     <!-- Title for the accessibility text options page. [CHAR LIMIT=50] -->
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index 67b1211..1743f9b 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -128,8 +128,9 @@
 
     </PreferenceCategory>
 
-    <!-- TODO(b/174829936): Add title for shortcuts settings category. -->
-    <PreferenceCategory android:persistent="false">
+    <PreferenceCategory
+        android:persistent="false"
+        android:title="@string/general_category_title">
 
         <Preference
             android:fragment="com.android.settings.accessibility.ShortcutsSettingsFragment"
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index 7331058..7a79136 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -22,16 +22,10 @@
     settings:keywords="@string/keywords_location">
 
     <PreferenceCategory
-        android:key="recent_location_requests"
-        android:title="@string/location_category_recent_location_requests"
-        settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
-
-    <Preference
-        android:key="recent_location_requests_see_all_button"
-        android:title="@string/location_recent_location_requests_see_all"
-        android:icon="@drawable/ic_chevron_right_24dp"
-        android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
-        settings:searchable="false"/>
+        android:key="recent_location_access"
+        android:title="@string/location_category_recent_location_access"
+        settings:controller=
+            "com.android.settings.location.RecentLocationAccessPreferenceController"/>
 
     <PreferenceCategory
         android:key="location_advanced_settings"
diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml
index 2226a2c..2e1cb7e 100644
--- a/res/xml/location_settings_personal.xml
+++ b/res/xml/location_settings_personal.xml
@@ -25,14 +25,8 @@
     <PreferenceCategory
         android:key="recent_location_requests"
         android:title="@string/location_category_recent_location_requests"
-        settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
-
-    <Preference
-        android:key="recent_location_requests_see_all_button"
-        android:title="@string/location_recent_location_requests_see_all"
-        android:icon="@drawable/ic_chevron_right_24dp"
-        android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
-        settings:searchable="false"/>
+        settings:controller=
+            "com.android.settings.location.RecentLocationAccessPreferenceController"/>
 
     <!-- This preference category gets removed if new_recent_location_ui is disabled -->
     <Preference
diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml
index f15c8d8..f6f2d96 100644
--- a/res/xml/location_settings_workprofile.xml
+++ b/res/xml/location_settings_workprofile.xml
@@ -25,16 +25,8 @@
     <PreferenceCategory
         android:key="recent_location_requests"
         android:title="@string/location_category_recent_location_requests"
-        settings:controller="com.android.settings.location.RecentLocationRequestPreferenceController"/>
-
-    <Preference
-        android:key="recent_location_requests_see_all_button"
-        android:title="@string/location_recent_location_requests_see_all"
-        android:icon="@drawable/ic_chevron_right_24dp"
-        android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
-        settings:controller="com.android.settings.core.WorkPreferenceController"
-        settings:forWork="true"
-        settings:searchable="false"/>
+        settings:controller=
+            "com.android.settings.location.RecentLocationAccessPreferenceController"/>
 
     <com.android.settingslib.RestrictedSwitchPreference
         android:key="managed_profile_location_switch"
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 2c628f6..0c1ace9 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -57,6 +57,8 @@
 import com.android.settingslib.search.Indexable;
 import com.android.settingslib.widget.LayoutPreference;
 
+import com.google.android.material.appbar.AppBarLayout;
+
 import java.util.UUID;
 
 /**
@@ -112,9 +114,8 @@
 
     @VisibleForTesting
     ViewGroup mPinnedHeaderFrameLayout;
-
+    private AppBarLayout mAppBarLayout;
     private LayoutPreference mHeader;
-
     private View mEmptyView;
     private LinearLayoutManager mLayoutManager;
     private ArrayMap<String, Preference> mPreferenceCache;
@@ -145,6 +146,7 @@
             Bundle savedInstanceState) {
         final View root = super.onCreateView(inflater, container, savedInstanceState);
         mPinnedHeaderFrameLayout = root.findViewById(R.id.pinned_header);
+        mAppBarLayout = getActivity().findViewById(R.id.app_bar);
         return root;
     }
 
@@ -250,7 +252,7 @@
             return;
         }
         if (mAdapter != null) {
-            mAdapter.requestHighlight(getView(), getListView());
+            mAdapter.requestHighlight(getView(), getListView(), mAppBarLayout);
         }
     }
 
diff --git a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
index 2206e81..dcf7897 100644
--- a/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
+++ b/src/com/android/settings/accessibility/AccessibilityServiceWarning.java
@@ -35,6 +35,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 import androidx.core.content.ContextCompat;
 
@@ -60,11 +61,19 @@
         return false;
     };
 
+    /**
+     * The interface to execute the uninstallation action.
+     */
+    interface UninstallActionPerformer {
+        void uninstallPackage();
+    }
+
     /** Returns a {@link Dialog} to be shown to confirm that they want to enable a service. */
-    public static Dialog createCapabilitiesDialog(Context context,
-            AccessibilityServiceInfo info, View.OnClickListener listener) {
+    public static Dialog createCapabilitiesDialog(@NonNull Context context,
+            @NonNull AccessibilityServiceInfo info, @NonNull View.OnClickListener listener,
+            @NonNull UninstallActionPerformer performer) {
         final AlertDialog ad = new AlertDialog.Builder(context)
-                .setView(createEnableDialogContentView(context, info, listener))
+                .setView(createEnableDialogContentView(context, info, listener, performer))
                 .create();
 
         Window window = ad.getWindow();
@@ -88,7 +97,8 @@
     }
 
     private static View createEnableDialogContentView(Context context,
-            AccessibilityServiceInfo info, View.OnClickListener listener) {
+            @NonNull AccessibilityServiceInfo info, View.OnClickListener listener,
+            UninstallActionPerformer performer) {
         LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
@@ -129,6 +139,14 @@
         permissionAllowButton.setOnTouchListener(filterTouchListener);
         permissionDenyButton.setOnClickListener(listener);
 
+        final Button uninstallButton = content.findViewById(
+                R.id.permission_enable_uninstall_button);
+        // Shows an uninstall button to help users quickly remove the non-system App due to the
+        // required permissions.
+        if (!AccessibilityUtil.isSystemApp(info)) {
+            uninstallButton.setVisibility(View.VISIBLE);
+            uninstallButton.setOnClickListener(v -> performer.uninstallPackage());
+        }
         return content;
     }
 
diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java
index eb202b5..f547209 100644
--- a/src/com/android/settings/accessibility/AccessibilityUtil.java
+++ b/src/com/android/settings/accessibility/AccessibilityUtil.java
@@ -381,4 +381,13 @@
         return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp,
                 resources.getDisplayMetrics()));
     }
+
+    /**
+     * Indicates if the accessibility service belongs to a system App.
+     * @param info AccessibilityServiceInfo
+     * @return {@code true} if the App is a system App.
+     */
+    public static boolean isSystemApp(@NonNull AccessibilityServiceInfo info) {
+        return info.getResolveInfo().serviceInfo.applicationInfo.isSystemApp();
+    }
 }
diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
index 02016e5..7902ec6 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -24,10 +24,14 @@
 import android.app.Dialog;
 import android.app.admin.DevicePolicyManager;
 import android.app.settings.SettingsEnums;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
@@ -37,12 +41,14 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.View;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Switch;
 
+import androidx.annotation.Nullable;
 import androidx.preference.Preference;
 
 import com.android.internal.widget.LockPatternUtils;
@@ -59,7 +65,8 @@
 public class ToggleAccessibilityServicePreferenceFragment extends
         ToggleFeaturePreferenceFragment {
 
-    public static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
+    private static final String TAG = "ToggleAccessibilityServicePreferenceFragment";
+    private static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
     private LockPatternUtils mLockPatternUtils;
     private AtomicBoolean mIsDialogShown = new AtomicBoolean(/* initialValue= */ false);
 
@@ -74,6 +81,7 @@
             };
 
     private Dialog mDialog;
+    private BroadcastReceiver mPackageRemovedReceiver;
 
     @Override
     public int getMetricsCategory() {
@@ -94,6 +102,17 @@
     }
 
     @Override
+    public void onStart() {
+        super.onStart();
+        final AccessibilityServiceInfo serviceInfo = getAccessibilityServiceInfo();
+        if (serviceInfo == null) {
+            getActivity().finishAndRemoveTask();
+        } else if (!AccessibilityUtil.isSystemApp(serviceInfo)) {
+            registerPackageRemoveReceiver();
+        }
+    }
+
+    @Override
     public void onResume() {
         super.onResume();
         updateSwitchBarToggleSwitch();
@@ -111,6 +130,7 @@
     // capabilities. For
     // example, before JellyBean MR2 the user was granting the explore by touch
     // one.
+    @Nullable
     AccessibilityServiceInfo getAccessibilityServiceInfo() {
         final List<AccessibilityServiceInfo> infos = AccessibilityManager.getInstance(
                 getPrefContext()).getInstalledAccessibilityServiceList();
@@ -136,7 +156,8 @@
                 }
                 mDialog = AccessibilityServiceWarning
                         .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromEnableToggleClicked);
+                                this::onDialogButtonFromEnableToggleClicked,
+                                this::onDialogButtonFromUninstallClicked);
                 break;
             }
             case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: {
@@ -146,7 +167,8 @@
                 }
                 mDialog = AccessibilityServiceWarning
                         .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromShortcutToggleClicked);
+                                this::onDialogButtonFromShortcutToggleClicked,
+                                this::onDialogButtonFromUninstallClicked);
                 break;
             }
             case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: {
@@ -156,7 +178,8 @@
                 }
                 mDialog = AccessibilityServiceWarning
                         .createCapabilitiesDialog(getPrefContext(), info,
-                                this::onDialogButtonFromShortcutClicked);
+                                this::onDialogButtonFromShortcutClicked,
+                                this::onDialogButtonFromUninstallClicked);
                 break;
             }
             case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: {
@@ -246,6 +269,32 @@
         }
     }
 
+    private void registerPackageRemoveReceiver() {
+        if (mPackageRemovedReceiver != null || getContext() == null) {
+            return;
+        }
+        mPackageRemovedReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                final String packageName = intent.getData().getSchemeSpecificPart();
+                if (TextUtils.equals(mComponentName.getPackageName(), packageName)) {
+                    getActivity().finishAndRemoveTask();
+                }
+            }
+        };
+        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addDataScheme("package");
+        getContext().registerReceiver(mPackageRemovedReceiver, filter);
+    }
+
+    private void unregisterPackageRemoveReceiver() {
+        if (mPackageRemovedReceiver == null || getContext() == null) {
+            return;
+        }
+        getContext().unregisterReceiver(mPackageRemovedReceiver);
+        mPackageRemovedReceiver = null;
+    }
+
     private boolean isServiceSupportAccessibilityButton() {
         final AccessibilityManager ams = getPrefContext().getSystemService(
                 AccessibilityManager.class);
@@ -378,6 +427,35 @@
         }
     }
 
+    private void onDialogButtonFromUninstallClicked() {
+        mDialog.dismiss();
+        final Intent uninstallIntent = createUninstallPackageActivityIntent();
+        if (uninstallIntent == null) {
+            return;
+        }
+        startActivity(uninstallIntent);
+    }
+
+    @Nullable
+    private Intent createUninstallPackageActivityIntent() {
+        final AccessibilityServiceInfo a11yServiceInfo = getAccessibilityServiceInfo();
+        if (a11yServiceInfo == null) {
+            Log.w(TAG, "createUnInstallIntent -- invalid a11yServiceInfo");
+            return null;
+        }
+        final ApplicationInfo appInfo =
+                a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo;
+        final Uri packageUri = Uri.parse("package:" + appInfo.packageName);
+        final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
+        return uninstallIntent;
+    }
+
+    @Override
+    public void onStop() {
+        super.onStop();
+        unregisterPackageRemoveReceiver();
+    }
+
     private void onAllowButtonFromEnableToggleClicked() {
         if (isFullDiskEncrypted()) {
             final String title = createConfirmCredentialReasonMessage();
diff --git a/src/com/android/settings/development/bluetooth/BaseBluetoothDialogPreference.java b/src/com/android/settings/development/bluetooth/BaseBluetoothDialogPreference.java
index 08a450b..39e2276 100644
--- a/src/com/android/settings/development/bluetooth/BaseBluetoothDialogPreference.java
+++ b/src/com/android/settings/development/bluetooth/BaseBluetoothDialogPreference.java
@@ -97,10 +97,14 @@
             radioButton.setText(mRadioButtonStrings.get(i));
             radioButton.setEnabled(selectableIndex.contains(i));
         }
-        // View will be invisible when all options are enabled.
+        // Initial help information text view
+        final TextView helpTextView = view.findViewById(R.id.bluetooth_audio_codec_help_info);
         if (selectableIndex.size() == mRadioButtonIds.size()) {
-            final TextView helpTextView = view.findViewById(R.id.bluetooth_audio_codec_help_info);
+            // View will be invisible when all options are enabled.
             helpTextView.setVisibility(View.GONE);
+        } else {
+            helpTextView.setText(R.string.bluetooth_select_a2dp_codec_type_help_info);
+            helpTextView.setVisibility(View.VISIBLE);
         }
     }
 
diff --git a/src/com/android/settings/fuelgauge/OWNERS b/src/com/android/settings/fuelgauge/OWNERS
index ab3da89..d68dc98 100644
--- a/src/com/android/settings/fuelgauge/OWNERS
+++ b/src/com/android/settings/fuelgauge/OWNERS
@@ -2,3 +2,6 @@
 tifn@google.com
 wesleycwwang@google.com
 ykhung@google.com
+
+# BatteryStats
+per-file FakeUid.java = file:platform/frameworks/base:/BATTERY_STATS_OWNERS
diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java
index 31ca0ae..38b7c4a 100644
--- a/src/com/android/settings/location/LocationPersonalSettings.java
+++ b/src/com/android/settings/location/LocationPersonalSettings.java
@@ -55,8 +55,8 @@
         use(LocationFooterPreferenceController.class).init(this);
 
         final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
-        final RecentLocationRequestPreferenceController controller = use(
-                RecentLocationRequestPreferenceController.class);
+        final RecentLocationAccessPreferenceController controller = use(
+                RecentLocationAccessPreferenceController.class);
         controller.init(this);
         controller.setProfileType(profileType);
     }
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 8d862d4..9a61b31 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -82,7 +82,7 @@
         super.onAttach(context);
 
         use(AppLocationPermissionPreferenceController.class).init(this);
-        use(RecentLocationRequestPreferenceController.class).init(this);
+        use(RecentLocationAccessPreferenceController.class).init(this);
         use(LocationFooterPreferenceController.class).init(this);
         use(LocationForWorkPreferenceController.class).init(this);
         use(LocationServiceForWorkPreferenceController.class).init(this);
diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java
index 2bf5f98..601ec23 100644
--- a/src/com/android/settings/location/LocationWorkProfileSettings.java
+++ b/src/com/android/settings/location/LocationWorkProfileSettings.java
@@ -55,8 +55,8 @@
         use(LocationForWorkPreferenceController.class).init(this);
 
         final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE);
-        final RecentLocationRequestPreferenceController controller = use(
-                RecentLocationRequestPreferenceController.class);
+        final RecentLocationAccessPreferenceController controller = use(
+                RecentLocationAccessPreferenceController.class);
         controller.init(this);
         controller.setProfileType(profileType);
     }
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
index c835a51..245118d 100644
--- a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -13,114 +13,141 @@
  */
 package com.android.settings.location;
 
-import static java.util.concurrent.TimeUnit.DAYS;
+import static android.Manifest.permission_group.LOCATION;
 
-import android.Manifest;
 import android.content.Context;
 import android.content.Intent;
-import android.icu.text.RelativeDateTimeFormatter;
-import android.provider.DeviceConfig;
-import android.view.View;
+import android.os.UserHandle;
+import android.os.UserManager;
 
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
 import com.android.settingslib.location.RecentLocationAccesses;
-import com.android.settingslib.utils.StringUtil;
-import com.android.settingslib.widget.AppEntitiesHeaderController;
-import com.android.settingslib.widget.AppEntityInfo;
-import com.android.settingslib.widget.LayoutPreference;
+import com.android.settingslib.widget.AppPreference;
 
+import java.util.ArrayList;
 import java.util.List;
 
-public class RecentLocationAccessPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin {
-    /** Key for the recent location apps dashboard */
-    private static final String KEY_APPS_DASHBOARD = "apps_dashboard";
-    private final RecentLocationAccesses mRecentLocationAccesses;
-    private AppEntitiesHeaderController mController;
-    private static final int MAXIMUM_APP_COUNT = 3;
+/**
+ * Preference controller that handles the display of apps that access locations.
+ */
+public class RecentLocationAccessPreferenceController extends LocationBasePreferenceController {
+    @VisibleForTesting
+    RecentLocationAccesses mRecentLocationApps;
+    private PreferenceCategory mCategoryRecentLocationRequests;
+    private int mType = ProfileSelectFragment.ProfileType.ALL;
 
-    public RecentLocationAccessPreferenceController(Context context) {
-        this(context, new RecentLocationAccesses(context));
+    private static class PackageEntryClickedListener implements
+            Preference.OnPreferenceClickListener {
+        private final Context mContext;
+        private final String mPackage;
+        private final UserHandle mUserHandle;
+
+        PackageEntryClickedListener(Context context, String packageName,
+                UserHandle userHandle) {
+            mContext = context;
+            mPackage = packageName;
+            mUserHandle = userHandle;
+        }
+
+        @Override
+        public boolean onPreferenceClick(Preference preference) {
+            final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
+            intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, LOCATION);
+            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackage);
+            intent.putExtra(Intent.EXTRA_USER, mUserHandle);
+            mContext.startActivity(intent);
+            return true;
+        }
+    }
+
+    public RecentLocationAccessPreferenceController(Context context, String key) {
+        this(context, key, new RecentLocationAccesses(context));
     }
 
     @VisibleForTesting
-    RecentLocationAccessPreferenceController(Context context,
-            RecentLocationAccesses recentAccesses) {
-        super(context);
-        mRecentLocationAccesses = recentAccesses;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_APPS_DASHBOARD;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return Boolean.parseBoolean(
-                DeviceConfig.getProperty(DeviceConfig.NAMESPACE_PRIVACY,
-                        Utils.PROPERTY_PERMISSIONS_HUB_ENABLED));
+    public RecentLocationAccessPreferenceController(Context context, String key,
+            RecentLocationAccesses recentLocationApps) {
+        super(context, key);
+        mRecentLocationApps = recentLocationApps;
     }
 
     @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
-        final LayoutPreference preference = screen.findPreference(KEY_APPS_DASHBOARD);
-        final View view = preference.findViewById(R.id.app_entities_header);
-        mController = AppEntitiesHeaderController.newInstance(mContext, view)
-                .setHeaderTitleRes(R.string.location_category_recent_location_access)
-                .setHeaderDetailsRes(R.string.location_recent_location_access_view_details)
-                .setHeaderEmptyRes(R.string.location_no_recent_accesses)
-                .setHeaderDetailsClickListener((View v) -> {
-                    final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
-                    intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
-                            Manifest.permission.ACCESS_FINE_LOCATION);
-                    intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
-                    mContext.startActivity(intent);
-                });
+        mCategoryRecentLocationRequests = screen.findPreference(getPreferenceKey());
+        final Context prefContext = mCategoryRecentLocationRequests.getContext();
+        final List<RecentLocationAccesses.Access> recentLocationAccesses = new ArrayList<>();
+        final UserManager userManager = UserManager.get(mContext);
+        for (RecentLocationAccesses.Access access : mRecentLocationApps.getAppListSorted()) {
+            if (isRequestMatchesProfileType(userManager, access, mType)) {
+                recentLocationAccesses.add(access);
+            }
+        }
+
+        if (recentLocationAccesses.size() > 0) {
+            // Add preferences to container in original order (already sorted by recency).
+            for (RecentLocationAccesses.Access access : recentLocationAccesses) {
+                mCategoryRecentLocationRequests.addPreference(
+                        createAppPreference(prefContext, access, mFragment));
+            }
+        } else {
+            // If there's no item to display, add a "No recent apps" item.
+            final Preference banner = new AppPreference(prefContext);
+            banner.setTitle(R.string.location_no_recent_accesses);
+            banner.setSelectable(false);
+            mCategoryRecentLocationRequests.addPreference(banner);
+        }
     }
 
     @Override
-    public void updateState(Preference preference) {
-        updateRecentApps();
+    public void onLocationModeChanged(int mode, boolean restricted) {
+        mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
     }
 
-    private void updateRecentApps() {
-        final List<RecentLocationAccesses.Access> recentLocationAccesses =
-                mRecentLocationAccesses.getAppListSorted();
-        if (recentLocationAccesses.size() > 0) {
-            // Display the top 3 preferences to container in original order.
-            int i = 0;
-            for (; i < Math.min(recentLocationAccesses.size(), MAXIMUM_APP_COUNT); i++) {
-                final RecentLocationAccesses.Access access = recentLocationAccesses.get(i);
-                final AppEntityInfo appEntityInfo = new AppEntityInfo.Builder()
-                        .setIcon(access.icon)
-                        .setTitle(access.label)
-                        .setSummary(StringUtil.formatRelativeTime(mContext,
-                                System.currentTimeMillis() - access.accessFinishTime, false,
-                                RelativeDateTimeFormatter.Style.SHORT))
-                        .setOnClickListener((v) -> {
-                            final Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
-                            intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
-                                    Manifest.permission.ACCESS_FINE_LOCATION);
-                            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, access.packageName);
-                            intent.putExtra(Intent.EXTRA_USER, access.userHandle);
-                            mContext.startActivity(intent);
-                        })
-                        .build();
-                mController.setAppEntity(i, appEntityInfo);
-            }
-            for (; i < MAXIMUM_APP_COUNT; i++) {
-                mController.removeAppEntity(i);
-            }
+    /**
+     * Initialize {@link ProfileSelectFragment.ProfileType} of the controller
+     *
+     * @param type {@link ProfileSelectFragment.ProfileType} of the controller.
+     */
+    public void setProfileType(@ProfileSelectFragment.ProfileType int type) {
+        mType = type;
+    }
+
+    /**
+     * Create a {@link AppPreference}
+     */
+    public static AppPreference createAppPreference(Context prefContext,
+            RecentLocationAccesses.Access access, DashboardFragment fragment) {
+        final AppPreference pref = new AppPreference(prefContext);
+        pref.setIcon(access.icon);
+        pref.setTitle(access.label);
+        pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
+                fragment.getContext(), access.packageName, access.userHandle));
+        return pref;
+    }
+
+    /**
+     * Return if the {@link RecentLocationAccesses.Access} matches current UI
+     * {@ProfileSelectFragment.ProfileType}
+     */
+    public static boolean isRequestMatchesProfileType(UserManager userManager,
+            RecentLocationAccesses.Access access, @ProfileSelectFragment.ProfileType int type) {
+
+        final boolean isWorkProfile = userManager.isManagedProfile(
+                access.userHandle.getIdentifier());
+        if (isWorkProfile && (type & ProfileSelectFragment.ProfileType.WORK) != 0) {
+            return true;
         }
-        mController.apply();
+        if (!isWorkProfile && (type & ProfileSelectFragment.ProfileType.PERSONAL) != 0) {
+            return true;
+        }
+        return false;
     }
 }
diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
index e89e793..b3ae609 100644
--- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
+++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java
@@ -39,10 +39,14 @@
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 
+import com.google.android.material.appbar.AppBarLayout;
+
 public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {
 
     private static final String TAG = "HighlightableAdapter";
     @VisibleForTesting
+    static final long DELAY_COLLAPSE_DURATION_MILLIS = 300L;
+    @VisibleForTesting
     static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 600L;
     private static final long HIGHLIGHT_DURATION = 15000L;
     private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L;
@@ -115,7 +119,7 @@
         View v = holder.itemView;
         if (position == mHighlightPosition
                 && (mHighlightKey != null
-                        && TextUtils.equals(mHighlightKey, getItem(position).getKey()))) {
+                && TextUtils.equals(mHighlightKey, getItem(position).getKey()))) {
             // This position should be highlighted. If it's highlighted before - skip animation.
             addHighlightBackground(v, !mFadeInAnimated);
         } else if (Boolean.TRUE.equals(v.getTag(R.id.preference_highlighted))) {
@@ -124,15 +128,26 @@
         }
     }
 
-    public void requestHighlight(View root, RecyclerView recyclerView) {
+    /**
+     * A function can highlight a specific setting in recycler view.
+     * note: Before highlighting a setting, screen collapses tool bar with an animation.
+     */
+    public void requestHighlight(View root, RecyclerView recyclerView, AppBarLayout appBarLayout) {
         if (mHighlightRequested || recyclerView == null || TextUtils.isEmpty(mHighlightKey)) {
             return;
         }
+        final int position = getPreferenceAdapterPosition(mHighlightKey);
+        if (position < 0) {
+            return;
+        }
+
+        if (appBarLayout != null) {
+            root.postDelayed(() -> {
+                appBarLayout.setExpanded(false, true);
+            }, DELAY_COLLAPSE_DURATION_MILLIS);
+        }
+
         root.postDelayed(() -> {
-            final int position = getPreferenceAdapterPosition(mHighlightKey);
-            if (position < 0) {
-                return;
-            }
             mHighlightRequested = true;
             recyclerView.smoothScrollToPosition(position);
             mHighlightPosition = position;
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
index 71a80de..5feee60 100644
--- a/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/RecentLocationAccessPreferenceControllerTest.java
@@ -24,19 +24,17 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.provider.DeviceConfig;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.preference.PreferenceCategory;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
-import com.android.settings.Utils;
+import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.testutils.shadow.ShadowDeviceConfig;
 import com.android.settingslib.location.RecentLocationAccesses;
-import com.android.settingslib.widget.LayoutPreference;
 
 import org.junit.After;
 import org.junit.Before;
@@ -55,11 +53,14 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = {ShadowDeviceConfig.class})
 public class RecentLocationAccessPreferenceControllerTest {
+    private static final String PREFERENCE_KEY = "test_preference_key";
     @Mock
-    private LayoutPreference mLayoutPreference;
+    private PreferenceCategory mLayoutPreference;
     @Mock
     private PreferenceScreen mScreen;
     @Mock
+    private DashboardFragment mDashboardFragment;
+    @Mock
     private RecentLocationAccesses mRecentLocationApps;
 
     private Context mContext;
@@ -71,15 +72,16 @@
         MockitoAnnotations.initMocks(this);
         mContext = spy(RuntimeEnvironment.application);
         mController = spy(
-                new RecentLocationAccessPreferenceController(mContext, mRecentLocationApps));
+                new RecentLocationAccessPreferenceController(mContext, PREFERENCE_KEY,
+                        mRecentLocationApps));
+        mController.init(mDashboardFragment);
         final String key = mController.getPreferenceKey();
         mAppEntitiesHeaderView = LayoutInflater.from(mContext).inflate(
                 R.layout.app_entities_header, null /* root */);
         when(mScreen.findPreference(key)).thenReturn(mLayoutPreference);
         when(mLayoutPreference.getKey()).thenReturn(key);
         when(mLayoutPreference.getContext()).thenReturn(mContext);
-        when(mLayoutPreference.findViewById(R.id.app_entities_header)).thenReturn(
-                mAppEntitiesHeaderView);
+        when(mDashboardFragment.getContext()).thenReturn(mContext);
     }
 
     @After
@@ -88,16 +90,7 @@
     }
 
     @Test
-    public void isAvailable_permissionHubNotSet_shouldReturnFalse() {
-        // We have not yet set the property to show the Permissions Hub.
-        assertThat(mController.isAvailable()).isEqualTo(false);
-    }
-
-    @Test
-    public void isAvailable_permissionHubEnabled_shouldReturnTrue() {
-        DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
-                Utils.PROPERTY_PERMISSIONS_HUB_ENABLED, "true", true);
-
+    public void isAvailable_shouldReturnTrue() {
         assertThat(mController.isAvailable()).isEqualTo(true);
     }
 
@@ -118,39 +111,6 @@
         assertThat(details.hasOnClickListeners()).isTrue();
     }
 
-    @Test
-    public void updateState_whenAppListMoreThanThree_shouldDisplayTopThreeApps() {
-        final List<RecentLocationAccesses.Access> accesses = createMockAccesses(6);
-        doReturn(accesses).when(mRecentLocationApps).getAppListSorted();
-        mController.displayPreference(mScreen);
-        mController.updateState(mLayoutPreference);
-
-        // The widget can display the top 3 apps from the list when there're more than 3.
-        final View app1View = mAppEntitiesHeaderView.findViewById(R.id.app1_view);
-        final ImageView appIconView1 = app1View.findViewById(R.id.app_icon);
-        final TextView appTitle1 = app1View.findViewById(R.id.app_title);
-
-        assertThat(app1View.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(appIconView1.getDrawable()).isNotNull();
-        assertThat(appTitle1.getText()).isEqualTo("appTitle0");
-
-        final View app2View = mAppEntitiesHeaderView.findViewById(R.id.app2_view);
-        final ImageView appIconView2 = app2View.findViewById(R.id.app_icon);
-        final TextView appTitle2 = app2View.findViewById(R.id.app_title);
-
-        assertThat(app2View.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(appIconView2.getDrawable()).isNotNull();
-        assertThat(appTitle2.getText()).isEqualTo("appTitle1");
-
-        final View app3View = mAppEntitiesHeaderView.findViewById(R.id.app3_view);
-        final ImageView appIconView3 = app3View.findViewById(R.id.app_icon);
-        final TextView appTitle3 = app3View.findViewById(R.id.app_title);
-
-        assertThat(app3View.getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(appIconView3.getDrawable()).isNotNull();
-        assertThat(appTitle3.getText()).isEqualTo("appTitle2");
-    }
-
     private List<RecentLocationAccesses.Access> createMockAccesses(int count) {
         final List<RecentLocationAccesses.Access> accesses = new ArrayList<>();
         for (int i = 0; i < count; i++) {
diff --git a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
index 23b7edc..f5e2a50 100644
--- a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -43,6 +44,8 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.SettingsPreferenceFragment;
 
+import com.google.android.material.appbar.AppBarLayout;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -85,9 +88,12 @@
 
     @Test
     public void requestHighlight_hasKey_notHighlightedBefore_shouldRequest() {
-        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+        when(mAdapter.getPreferenceAdapterPosition(anyString())).thenReturn(1);
+        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class));
 
         verify(mRoot).postDelayed(any(),
+                eq(HighlightablePreferenceGroupAdapter.DELAY_COLLAPSE_DURATION_MILLIS));
+        verify(mRoot).postDelayed(any(),
                 eq(HighlightablePreferenceGroupAdapter.DELAY_HIGHLIGHT_DURATION_MILLIS));
     }
 
@@ -95,21 +101,21 @@
     public void requestHighlight_noKey_highlightedBefore_noRecyclerView_shouldNotRequest() {
         ReflectionHelpers.setField(mAdapter, "mHighlightKey", null);
         ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false);
-        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class),  mock(AppBarLayout.class));
 
         ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY);
         ReflectionHelpers.setField(mAdapter, "mHighlightRequested", true);
-        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class));
+        mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class));
 
         ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY);
         ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false);
-        mAdapter.requestHighlight(mRoot, null /* recyclerView */);
+        mAdapter.requestHighlight(mRoot, null /* recyclerView */,  mock(AppBarLayout.class));
 
         verifyZeroInteractions(mRoot);
     }
 
     @Test
-    public void adjustInitialExpandedChildCount_invalidInput_shouldNotadjust() {
+    public void adjustInitialExpandedChildCount_invalidInput_shouldNotAdjust() {
         HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(null /* host */);
         HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(mFragment);
         final Bundle args = new Bundle();