Merge changes from topic "location settings"

* changes:
  Display app stats for location permission
  Display recent location access in the widget
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3b84755..1aaa374 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -827,8 +827,15 @@
     <string name="location_settings_title">Location</string>
     <!-- Used in the location settings to control turning on/off the feature entirely -->
     <string name="location_settings_master_switch_title">Use location</string>
-    <!-- Summary for Location settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
-    <string name="location_settings_summary">Scanning, location history</string>
+    <!-- Summary for Location settings when location is off [CHAR LIMIT=NONE] -->
+    <string name="location_settings_summary_location_off">Off</string>
+    <!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]-->
+    <plurals name="location_settings_summary_location_on">
+        <item quantity="one">On - <xliff:g id="count">%1$d</xliff:g> app can access location</item>
+        <item quantity="other">On - <xliff:g id="count">%1$d</xliff:g> apps can access location</item>
+    </plurals>
+    <!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] -->
+    <string name="location_settings_loading_app_permission_stats">Loading\u2026</string>
 
     <!-- Main Settings screen setting option title for the item to take you to the accounts screen [CHAR LIMIT=22] -->
     <string name="account_settings_title">Accounts</string>
@@ -3630,15 +3637,28 @@
     <string name="managed_profile_location_switch_title">Location for work profile</string>
     <!-- [CHAR LIMIT=30] Location settings screen. It's a link that directs the user to a page that
       shows the location permission setting for each installed app -->
-    <string name="location_app_level_permissions">App-level permissions</string>
-    <!-- [CHAR LIMIT=42] Location settings screen, sub category for recent location requests -->
-    <string name="location_category_recent_location_requests">Recent location requests</string>
-    <!-- Location settings screen, displayed when there're more than three recent location requests -->
-    <string name="location_recent_location_requests_see_all">See all</string>
+    <string name="location_app_level_permissions">App permission</string>
+    <!-- Summary for app permission on Location settings page when location is off [CHAR LIMIT=NONE] -->
+    <string name="location_app_permission_summary_location_off">Location is off</string>
+    <!-- Summary for Location settings when location is on, explaining how many apps have location permission [CHAR LIMIT=NONE]-->
+    <plurals name="location_app_permission_summary_location_on">
+        <item quantity="one">
+            <xliff:g id="background_location_app_count">%1$d</xliff:g>
+            of
+            <xliff:g id="total_location_app_count">%2$d</xliff:g>
+            app has unlimited access</item>
+        <item quantity="other">
+            <xliff:g id="background_location_app_count">%1$d</xliff:g>
+            of
+            <xliff:g id="total_location_app_count">%2$d</xliff:g>
+            apps have unlimited access</item>
+    </plurals>
+    <!-- [CHAR LIMIT=50] Location settings screen, sub category for recent location access -->
+    <string name="location_category_recent_location_access">Recent location access</string>
+    <!-- [CHAR LIMIT=30] Location settings screen, button to bring the user to view the details of recent location access -->
+    <string name="location_recent_location_access_view_details">View details</string>
     <!-- Location settings screen, displayed when there's no recent app accessing location -->
     <string name="location_no_recent_apps">No apps have requested location recently</string>
-    <!-- [CHAR LIMIT=30] Location settings screen, sub category for location services -->
-    <string name="location_category_location_services">Location services</string>
     <!-- [CHAR LIMIT=30] Location settings screen, recent location requests high battery use-->
     <string name="location_high_battery_use">High battery use</string>
     <!-- [CHAR LIMIT=30] Location settings screen, recent location requests low battery use-->
diff --git a/res/xml/location_recent_requests_see_all.xml b/res/xml/location_recent_requests_see_all.xml
deleted file mode 100644
index 38db142..0000000
--- a/res/xml/location_recent_requests_see_all.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/location_category_recent_location_requests"
-        android:key="recent_location_requests_see_all">
-
-        <PreferenceCategory
-            android:key="all_recent_location_requests"/>
-</PreferenceScreen>
\ No newline at end of file
diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml
index b53e986..f1c13cf 100644
--- a/res/xml/location_settings.xml
+++ b/res/xml/location_settings.xml
@@ -20,21 +20,14 @@
         android:title="@string/location_settings_title"
         settings:keywords="@string/keywords_location">
 
-        <PreferenceCategory
-            android:key="recent_location_requests"
-            android:title="@string/location_category_recent_location_requests"/>
-
-        <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:selectable="true"
-            android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
-            settings:searchable="false"/>
+        <com.android.settingslib.widget.LayoutPreference
+            android:key="apps_dashboard"
+            android:layout="@layout/app_entities_header"
+            settings:allowDividerBelow="true" />
 
         <PreferenceCategory
             android:key="location_advanced_settings"
-            settings:initialExpandedChildrenCount="1">
+            settings:initialExpandedChildrenCount="0">
 
             <!-- This preference category gets removed if new_recent_location_ui is disabled -->
             <Preference
@@ -60,8 +53,7 @@
                 android:selectable="true" />
 
             <PreferenceCategory
-                android:key="location_services"
-                android:title="@string/location_category_location_services"/>
+                android:key="location_services" />
         </PreferenceCategory>
 
         <PreferenceCategory
diff --git a/res/xml/top_level_settings.xml b/res/xml/top_level_settings.xml
index 03e32dc..9f4f902 100644
--- a/res/xml/top_level_settings.xml
+++ b/res/xml/top_level_settings.xml
@@ -93,10 +93,11 @@
     <Preference
         android:key="top_level_location"
         android:title="@string/location_settings_title"
-        android:summary="@string/location_settings_summary"
+        android:summary="@string/location_settings_loading_app_permission_stats"
         android:icon="@drawable/ic_homepage_location"
         android:order="-50"
-        android:fragment="com.android.settings.location.LocationSettings"/>
+        android:fragment="com.android.settings.location.LocationSettings"
+        settings:controller="com.android.settings.location.TopLevelLocationPreferenceController"/>
 
     <Preference
         android:key="top_level_security"
@@ -149,4 +150,4 @@
         android:order="100"
         settings:controller="com.android.settings.support.SupportPreferenceController"/>
 
-</PreferenceScreen>
\ No newline at end of file
+</PreferenceScreen>
diff --git a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
index f920fdc..5bfc584 100644
--- a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
+++ b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
@@ -1,18 +1,38 @@
 package com.android.settings.location;
 
+import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
 import android.content.Context;
+import android.location.LocationManager;
+import android.permission.RuntimePermissionPresenter;
 import android.provider.Settings;
 
+import androidx.preference.Preference;
+
+import com.android.settings.R;
 import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class AppLocationPermissionPreferenceController extends
-        AbstractPreferenceController implements PreferenceControllerMixin {
+        LocationBasePreferenceController implements PreferenceControllerMixin {
 
     private static final String KEY_APP_LEVEL_PERMISSIONS = "app_level_permissions";
+    /** Total number of apps that has location permission. */
+    private int mNumTotal = -1;
+    /** Total number of apps that has background location permission. */
+    private int mNumBackground = -1;
+    private final LocationManager mLocationManager;
+    private Preference mPreference;
 
-    public AppLocationPermissionPreferenceController(Context context) {
-        super(context);
+    public AppLocationPermissionPreferenceController(Context context, Lifecycle lifecycle) {
+        super(context, lifecycle);
+        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
     }
 
     @Override
@@ -25,4 +45,53 @@
         return Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, 1) == 1;
     }
+
+    @Override
+    public CharSequence getSummary() {
+        if (mLocationManager.isLocationEnabled()) {
+            if (mNumTotal == -1 || mNumBackground == -1) {
+                return mContext.getString(R.string.location_settings_loading_app_permission_stats);
+            }
+            return mContext.getResources().getQuantityString(
+                    R.plurals.location_app_permission_summary_location_on, mNumBackground,
+                    mNumBackground, mNumTotal);
+        } else {
+            return mContext.getString(R.string.location_app_permission_summary_location_off);
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        mPreference = preference;
+        final AtomicInteger loadingInProgress = new AtomicInteger(2);
+        refreshSummary(preference);
+        // Bail out if location has been disabled.
+        if (!mLocationManager.isLocationEnabled()) {
+            return;
+        }
+        RuntimePermissionPresenter.getInstance(mContext).countPermissionApps(
+                Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), false, false,
+                (numApps) -> {
+                    mNumTotal = numApps;
+                    if (loadingInProgress.decrementAndGet() == 0) {
+                        refreshSummary(preference);
+                    }
+                }, null);
+
+        RuntimePermissionPresenter.getInstance(mContext).countPermissionApps(
+                Collections.singletonList(ACCESS_BACKGROUND_LOCATION), true, false,
+                (numApps) -> {
+                    mNumBackground = numApps;
+                    if (loadingInProgress.decrementAndGet() == 0) {
+                        refreshSummary(preference);
+                    }
+                }, null);
+    }
+
+    @Override
+    public void onLocationModeChanged(int mode, boolean restricted) {
+        // 'null' is checked inside updateState(), so no need to check here.
+        updateState(mPreference);
+    }
 }
diff --git a/src/com/android/settings/location/LocationEnabler.java b/src/com/android/settings/location/LocationEnabler.java
index 20c2280..e1bdf16 100644
--- a/src/com/android/settings/location/LocationEnabler.java
+++ b/src/com/android/settings/location/LocationEnabler.java
@@ -35,15 +35,15 @@
 import com.android.settingslib.RestrictedLockUtilsInternal;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnPause;
-import com.android.settingslib.core.lifecycle.events.OnResume;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
 
 
 /**
  * A class that listens to location settings change and modifies location settings
  * settings.
  */
-public class LocationEnabler implements LifecycleObserver, OnResume, OnPause {
+public class LocationEnabler implements LifecycleObserver, OnStart, OnStop {
 
     private static final String TAG = "LocationEnabler";
     @VisibleForTesting
@@ -73,7 +73,7 @@
     }
 
     @Override
-    public void onResume() {
+    public void onStart() {
         if (mReceiver == null) {
             mReceiver = new BroadcastReceiver() {
                 @Override
@@ -90,12 +90,8 @@
     }
 
     @Override
-    public void onPause() {
-        try {
-            mContext.unregisterReceiver(mReceiver);
-        } catch (RuntimeException e) {
-            // Ignore exceptions caused by race condition
-        }
+    public void onStop() {
+        mContext.unregisterReceiver(mReceiver);
     }
 
     void refreshLocationMode() {
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java
index 53076e8..4112340 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -35,7 +35,7 @@
 import com.android.settings.widget.SwitchBar;
 import com.android.settingslib.core.AbstractPreferenceController;
 import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
+import com.android.settingslib.location.RecentLocationAccesses;
 import com.android.settingslib.search.SearchIndexable;
 
 import java.util.ArrayList;
@@ -52,7 +52,7 @@
  *         <li>In switch bar: location master switch. Used to toggle location on and off.
  *         </li>
  *     </ul>
- *     <li>Recent location requests: automatically populated by {@link RecentLocationApps}</li>
+ *     <li>Recent location requests: automatically populated by {@link RecentLocationAccesses}</li>
  *     <li>Location services: multi-app settings provided from outside the Android framework. Each
  *     is injected by a system-partition app via the {@link SettingInjectorService} API.</li>
  * </ul>
@@ -122,13 +122,11 @@
     private static List<AbstractPreferenceController> buildPreferenceControllers(
             Context context, LocationSettings fragment, Lifecycle lifecycle) {
         final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(new AppLocationPermissionPreferenceController(context));
+        controllers.add(new AppLocationPermissionPreferenceController(context, lifecycle));
         controllers.add(new LocationForWorkPreferenceController(context, lifecycle));
-        controllers.add(
-                new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
+        controllers.add(new RecentLocationAccessPreferenceController(context));
         controllers.add(new LocationScanningPreferenceController(context));
-        controllers.add(
-                new LocationServicePreferenceController(context, fragment, lifecycle));
+        controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle));
         controllers.add(new LocationFooterPreferenceController(context, lifecycle));
         return controllers;
     }
diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
new file mode 100644
index 0000000..0d5cca5
--- /dev/null
+++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.settings.location;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.Intent;
+import android.view.View;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.location.RecentLocationAccesses;
+import com.android.settingslib.widget.AppEntitiesHeaderController;
+import com.android.settingslib.widget.LayoutPreference;
+
+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;
+
+    public RecentLocationAccessPreferenceController(Context context) {
+        this(context, 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 true;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        final LayoutPreference preference = (LayoutPreference) 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)
+                .setHeaderDetailsClickListener((View v) -> {
+                    final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
+                    intent.putExtra(Intent.EXTRA_PERMISSION_NAME,
+                            Manifest.permission.ACCESS_FINE_LOCATION);
+                    mContext.startActivity(intent);
+                });
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        updateRecentApps();
+    }
+
+    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);
+                mController.setAppEntity(i, access.icon, access.label, access.contentDescription);
+            }
+            for (; i < MAXIMUM_APP_COUNT; i++) {
+                mController.removeAppEntity(i);
+            }
+        } else {
+            // If there's no item to display, add a "No recent apps" item.
+        }
+        mController.apply();
+    }
+}
diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
deleted file mode 100644
index 60374eb..0000000
--- a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-package com.android.settings.location;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-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.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settings.core.SubSettingLauncher;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
-import com.android.settingslib.widget.apppreference.AppPreference;
-
-import java.util.List;
-
-public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController {
-
-    /** Key for preference category "Recent location requests" */
-    private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests";
-    @VisibleForTesting
-    static final String KEY_SEE_ALL_BUTTON = "recent_location_requests_see_all_button";
-    private final LocationSettings mFragment;
-    private final RecentLocationApps mRecentLocationApps;
-    private PreferenceCategory mCategoryRecentLocationRequests;
-    private Preference mSeeAllButton;
-
-    /** Used in this class and {@link RecentLocationRequestSeeAllPreferenceController} */
-    static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener {
-        private final DashboardFragment mFragment;
-        private final String mPackage;
-        private final UserHandle mUserHandle;
-
-        public PackageEntryClickedListener(DashboardFragment fragment, String packageName,
-                UserHandle userHandle) {
-            mFragment = fragment;
-            mPackage = packageName;
-            mUserHandle = userHandle;
-        }
-
-        @Override
-        public boolean onPreferenceClick(Preference preference) {
-            // start new fragment to display extended information
-            final Bundle args = new Bundle();
-            args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage);
-
-            new SubSettingLauncher(mFragment.getContext())
-                    .setDestination(AppInfoDashboardFragment.class.getName())
-                    .setArguments(args)
-                    .setTitleRes(R.string.application_info_label)
-                    .setUserHandle(mUserHandle)
-                    .setSourceMetricsCategory(mFragment.getMetricsCategory())
-                    .launch();
-            return true;
-        }
-    }
-
-    public RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
-            Lifecycle lifecycle) {
-        this(context, fragment, lifecycle, new RecentLocationApps(context));
-    }
-
-    @VisibleForTesting
-    RecentLocationRequestPreferenceController(Context context, LocationSettings fragment,
-            Lifecycle lifecycle, RecentLocationApps recentApps) {
-        super(context, lifecycle);
-        mFragment = fragment;
-        mRecentLocationApps = recentApps;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_RECENT_LOCATION_REQUESTS;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mCategoryRecentLocationRequests =
-                (PreferenceCategory) screen.findPreference(KEY_RECENT_LOCATION_REQUESTS);
-        mSeeAllButton = screen.findPreference(KEY_SEE_ALL_BUTTON);
-
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        mCategoryRecentLocationRequests.removeAll();
-        mSeeAllButton.setVisible(false);
-
-        final Context prefContext = preference.getContext();
-        final List<RecentLocationApps.Request> recentLocationRequests =
-                mRecentLocationApps.getAppListSorted();
-
-        if (recentLocationRequests.size() > 3) {
-            // Display the top 3 preferences to container in original order.
-            for (int i = 0; i < 3; i++) {
-                mCategoryRecentLocationRequests.addPreference(
-                        createAppPreference(prefContext, recentLocationRequests.get(i)));
-            }
-            // Display a button to list all requests
-            mSeeAllButton.setVisible(true);
-        } else if (recentLocationRequests.size() > 0) {
-            // Add preferences to container in original order (already sorted by recency).
-            for (RecentLocationApps.Request request : recentLocationRequests) {
-                mCategoryRecentLocationRequests.addPreference(
-                        createAppPreference(prefContext, request));
-            }
-        } else {
-            // If there's no item to display, add a "No recent apps" item.
-            final Preference banner = createAppPreference(prefContext);
-            banner.setTitle(R.string.location_no_recent_apps);
-            banner.setSelectable(false);
-            mCategoryRecentLocationRequests.addPreference(banner);
-        }
-    }
-
-    @Override
-    public void onLocationModeChanged(int mode, boolean restricted) {
-        mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
-    }
-
-    @VisibleForTesting
-    AppPreference createAppPreference(Context prefContext) {
-        return new AppPreference(prefContext);
-    }
-
-    @VisibleForTesting
-    AppPreference createAppPreference(Context prefContext, RecentLocationApps.Request request) {
-        final AppPreference pref = createAppPreference(prefContext);
-        pref.setSummary(request.contentDescription);
-        pref.setIcon(request.icon);
-        pref.setTitle(request.label);
-        pref.setOnPreferenceClickListener(new PackageEntryClickedListener(
-                mFragment, request.packageName, request.userHandle));
-        return pref;
-    }
-}
diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java
deleted file mode 100644
index d256b9b..0000000
--- a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-
-import android.content.Context;
-import android.provider.SearchIndexableResource;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settingslib.core.AbstractPreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.search.SearchIndexable;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/** Dashboard Fragment to display all recent location requests, sorted by recency. */
-@SearchIndexable
-public class RecentLocationRequestSeeAllFragment extends DashboardFragment {
-
-    private static final String TAG = "RecentLocationReqAll";
-
-    public static final String PATH =
-            "com.android.settings.location.RecentLocationRequestSeeAllFragment";
-
-    @Override
-    public int getMetricsCategory() {
-      return MetricsEvent.RECENT_LOCATION_REQUESTS_ALL;
-    }
-
-    @Override
-    protected int getPreferenceScreenResId() {
-        return R.xml.location_recent_requests_see_all;
-    }
-
-    @Override
-    protected String getLogTag() {
-      return TAG;
-    }
-
-    @Override
-    protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
-        return buildPreferenceControllers(context, getSettingsLifecycle(), this);
-    }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(
-            Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) {
-        final List<AbstractPreferenceController> controllers = new ArrayList<>();
-        controllers.add(
-                new RecentLocationRequestSeeAllPreferenceController(context, lifecycle, fragment));
-        return controllers;
-    }
-
-    /**
-     * For Search.
-     */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.location_recent_requests_see_all;
-                    return Arrays.asList(sir);
-                }
-
-                @Override
-                public List<AbstractPreferenceController> getPreferenceControllers(Context
-                        context) {
-                    return buildPreferenceControllers(
-                            context, /* lifecycle = */ null, /* fragment = */ null);
-                }
-            };
-}
diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java
deleted file mode 100644
index 3fa0f00..0000000
--- a/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-import android.content.Context;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
-import com.android.settingslib.widget.apppreference.AppPreference;
-
-import java.util.List;
-
-/** Preference controller for preference category displaying all recent location requests. */
-public class RecentLocationRequestSeeAllPreferenceController
-        extends LocationBasePreferenceController {
-
-    /** Key for preference category "All recent location requests" */
-    private static final String KEY_ALL_RECENT_LOCATION_REQUESTS = "all_recent_location_requests";
-    private final RecentLocationRequestSeeAllFragment mFragment;
-    private PreferenceCategory mCategoryAllRecentLocationRequests;
-    private RecentLocationApps mRecentLocationApps;
-
-    public RecentLocationRequestSeeAllPreferenceController(
-            Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) {
-        this(context, lifecycle, fragment, new RecentLocationApps(context));
-    }
-
-    @VisibleForTesting
-    RecentLocationRequestSeeAllPreferenceController(
-            Context context,
-            Lifecycle lifecycle,
-            RecentLocationRequestSeeAllFragment fragment,
-            RecentLocationApps recentLocationApps) {
-        super(context, lifecycle);
-        mFragment = fragment;
-        mRecentLocationApps = recentLocationApps;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_ALL_RECENT_LOCATION_REQUESTS;
-    }
-
-    @Override
-    public void onLocationModeChanged(int mode, boolean restricted) {
-        mCategoryAllRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode));
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mCategoryAllRecentLocationRequests =
-                (PreferenceCategory) screen.findPreference(KEY_ALL_RECENT_LOCATION_REQUESTS);
-
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        mCategoryAllRecentLocationRequests.removeAll();
-        List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppListSorted();
-        for (RecentLocationApps.Request request : requests) {
-            Preference appPreference = createAppPreference(preference.getContext(), request);
-            mCategoryAllRecentLocationRequests.addPreference(appPreference);
-        }
-    }
-
-    @VisibleForTesting
-    AppPreference createAppPreference(
-            Context prefContext, RecentLocationApps.Request request) {
-        final AppPreference pref = new AppPreference(prefContext);
-        pref.setSummary(request.contentDescription);
-        pref.setIcon(request.icon);
-        pref.setTitle(request.label);
-        pref.setOnPreferenceClickListener(
-                new RecentLocationRequestPreferenceController.PackageEntryClickedListener(
-                        mFragment, request.packageName, request.userHandle));
-        return pref;
-    }
-}
diff --git a/src/com/android/settings/location/TopLevelLocationPreferenceController.java b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
new file mode 100644
index 0000000..d0bd9a9
--- /dev/null
+++ b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
@@ -0,0 +1,99 @@
+package com.android.settings.location;
+
+import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.location.LocationManager;
+import android.permission.RuntimePermissionPresenter;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+import com.android.settingslib.core.lifecycle.events.OnStop;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+public class TopLevelLocationPreferenceController extends BasePreferenceController implements
+        LifecycleObserver, OnStart, OnStop {
+    private static final IntentFilter INTENT_FILTER_LOCATION_MODE_CHANGED =
+            new IntentFilter(LocationManager.MODE_CHANGED_ACTION);
+    private final LocationManager mLocationManager;
+    /** Total number of apps that has location permission. */
+    private int mNumTotal = -1;
+    private BroadcastReceiver mReceiver;
+    private Preference mPreference;
+
+    public TopLevelLocationPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+        mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public CharSequence getSummary() {
+        if (mLocationManager.isLocationEnabled()) {
+            if (mNumTotal == -1) {
+                return mContext.getString(R.string.location_settings_loading_app_permission_stats);
+            }
+            return mContext.getResources().getQuantityString(
+                    R.plurals.location_settings_summary_location_on,
+                    mNumTotal, mNumTotal);
+        } else {
+            return mContext.getString(R.string.location_settings_summary_location_off);
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        mPreference = preference;
+        refreshSummary(preference);
+        // Bail out if location has been disabled.
+        if (!mLocationManager.isLocationEnabled()) {
+            return;
+        }
+        RuntimePermissionPresenter.getInstance(mContext).countPermissionApps(
+                Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), false, false,
+                (numApps) -> {
+                    mNumTotal = numApps;
+                    refreshSummary(preference);
+                }, null);
+    }
+
+    @Override
+    public void onStart() {
+        if (mReceiver == null) {
+            mReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    refreshLocationMode();
+                }
+            };
+        }
+        mContext.registerReceiver(mReceiver, INTENT_FILTER_LOCATION_MODE_CHANGED);
+        refreshLocationMode();
+    }
+
+    @Override
+    public void onStop() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
+    private void refreshLocationMode() {
+        // 'null' is checked inside updateState(), so no need to check here.
+        updateState(mPreference);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
index eff5d43..6379e44 100644
--- a/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java
@@ -5,6 +5,10 @@
 import android.content.Context;
 import android.provider.Settings;
 
+import androidx.lifecycle.LifecycleOwner;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -21,11 +25,16 @@
     @Mock
     private Context mContext;
 
+    private LifecycleOwner mLifecycleOwner;
+    private Lifecycle mLifecycle;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mController = new AppLocationPermissionPreferenceController(mContext);
+        mLifecycleOwner = () -> mLifecycle;
+        mLifecycle = new Lifecycle(mLifecycleOwner);
+        mController = new AppLocationPermissionPreferenceController(mContext, mLifecycle);
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
index e380830..806e2ec 100644
--- a/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationEnablerTest.java
@@ -84,30 +84,31 @@
     }
 
     @Test
-    public void onResume_shouldSetActiveAndRegisterListener() {
-        mEnabler.onResume();
+    public void onStart_shouldSetActiveAndRegisterListener() {
+        mEnabler.onStart();
 
         verify(mContext).registerReceiver(eq(mEnabler.mReceiver),
                 eq(LocationEnabler.INTENT_FILTER_LOCATION_MODE_CHANGED));
     }
 
     @Test
-    public void onResume_shouldRefreshLocationMode() {
-        mEnabler.onResume();
+    public void onStart_shouldRefreshLocationMode() {
+        mEnabler.onStart();
 
         verify(mEnabler).refreshLocationMode();
     }
 
     @Test
-    public void onPause_shouldUnregisterListener() {
-        mEnabler.onPause();
+    public void onStop_shouldUnregisterListener() {
+        mEnabler.onStart();
+        mEnabler.onStop();
 
         verify(mContext).unregisterReceiver(mEnabler.mReceiver);
     }
 
     @Test
     public void onReceive_shouldRefreshLocationMode() {
-        mEnabler.onResume();
+        mEnabler.onStart();
         reset(mListener);
         mEnabler.mReceiver.onReceive(mContext, new Intent());
 
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
deleted file mode 100644
index d4b4ac3..0000000
--- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.location;
-
-import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-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.Intent;
-import android.provider.Settings;
-import android.text.TextUtils;
-
-import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.applications.appinfo.AppInfoDashboardFragment;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
-import com.android.settingslib.location.RecentLocationApps.Request;
-import com.android.settingslib.widget.apppreference.AppPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-public class RecentLocationRequestPreferenceControllerTest {
-
-    @Mock
-    private LocationSettings mFragment;
-    @Mock
-    private PreferenceCategory mCategory;
-    @Mock
-    private PreferenceScreen mScreen;
-    @Mock
-    private RecentLocationApps mRecentLocationApps;
-    @Mock
-    private Preference mSeeAllButton;
-
-    private Context mContext;
-    private RecentLocationRequestPreferenceController mController;
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = spy(new RecentLocationRequestPreferenceController(
-                mContext, mFragment, mLifecycle, mRecentLocationApps));
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory);
-        when(mScreen.findPreference(mController.KEY_SEE_ALL_BUTTON)).thenReturn(mSeeAllButton);
-        final String key = mController.getPreferenceKey();
-        when(mCategory.getKey()).thenReturn(key);
-        when(mCategory.getContext()).thenReturn(mContext);
-    }
-
-    @Test
-    public void onLocationModeChanged_LocationOn_shouldEnablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false);
-
-        verify(mCategory).setEnabled(true);
-    }
-
-    @Test
-    public void onLocationModeChanged_LocationOff_shouldDisablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false);
-
-        verify(mCategory).setEnabled(false);
-    }
-
-    @Test
-    public void updateState_noRecentRequest_shouldRemoveAllAndAddBanner() {
-        doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppListSorted();
-        mController.displayPreference(mScreen);
-
-        mController.updateState(mCategory);
-
-        verify(mCategory).removeAll();
-        final String title = mContext.getString(R.string.location_no_recent_apps);
-        verify(mCategory).addPreference(argThat(titleMatches(title)));
-    }
-
-    @Test
-    public void updateState_hasRecentRequest_shouldRemoveAllAndAddInjectedSettings() {
-        List<Request> requests = createMockRequests(2);
-        doReturn(requests).when(mRecentLocationApps).getAppListSorted();
-
-        mController.displayPreference(mScreen);
-        mController.updateState(mCategory);
-
-        verify(mCategory).removeAll();
-        // Verifies two preferences are added in original order
-        InOrder inOrder = Mockito.inOrder(mCategory);
-        inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0")));
-        inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1")));
-    }
-
-    @Test
-    public void updateState_hasOverThreeRequests_shouldDisplaySeeAllButton() {
-        List<Request> requests = createMockRequests(6);
-        when(mRecentLocationApps.getAppListSorted()).thenReturn(requests);
-
-        mController.displayPreference(mScreen);
-        mController.updateState(mCategory);
-
-        verify(mCategory).removeAll();
-        // Verifies the first three preferences are added
-        InOrder inOrder = Mockito.inOrder(mCategory);
-        inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0")));
-        inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1")));
-        inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle2")));
-        verify(mCategory, never()).addPreference(argThat(titleMatches("appTitle3")));
-        // Verifies the "See all" preference is visible
-        verify(mSeeAllButton).setVisible(true);
-    }
-
-    @Test
-    public void createAppPreference_shouldAddClickListener() {
-        final Request request = mock(Request.class);
-        final AppPreference preference = mock(AppPreference.class);
-        doReturn(preference).when(mController).createAppPreference(any(Context.class));
-
-        mController.createAppPreference(mContext, request);
-
-        verify(preference).setOnPreferenceClickListener(
-                any(RecentLocationRequestPreferenceController.PackageEntryClickedListener.class));
-    }
-
-    @Test
-    public void onPreferenceClick_shouldLaunchAppDetails() {
-        final Context context = mock(Context.class);
-        when(mFragment.getContext()).thenReturn(context);
-
-        final List<RecentLocationApps.Request> requests = new ArrayList<>();
-        final Request request = mock(Request.class);
-        requests.add(request);
-        doReturn(requests).when(mRecentLocationApps).getAppListSorted();
-        final AppPreference preference = new AppPreference(mContext);
-        doReturn(preference).when(mController).createAppPreference(any(Context.class));
-        mController.displayPreference(mScreen);
-        mController.updateState(mCategory);
-
-        final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
-
-        preference.performClick();
-
-        verify(context).startActivity(intent.capture());
-
-        assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT))
-                .isEqualTo(AppInfoDashboardFragment.class.getName());
-    }
-
-    private static ArgumentMatcher<Preference> titleMatches(String expected) {
-        return preference -> TextUtils.equals(expected, preference.getTitle());
-    }
-
-    private List<RecentLocationApps.Request> createMockRequests(int count) {
-        List<RecentLocationApps.Request> requests = new ArrayList<>();
-        for (int i = 0; i < count; i++) {
-            // Add mock requests
-            Request req = mock(Request.class, "request" + i);
-            requests.add(req);
-            // Map mock AppPreferences with mock requests
-            String title = "appTitle" + i;
-            AppPreference appPreference = mock(AppPreference.class, "AppPreference" + i);
-            doReturn(title).when(appPreference).getTitle();
-            doReturn(appPreference)
-                    .when(mController).createAppPreference(any(Context.class), eq(req));
-        }
-        return requests;
-    }
-}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java
deleted file mode 100644
index 7411afe..0000000
--- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.location;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.provider.Settings.Secure;
-
-import androidx.lifecycle.LifecycleOwner;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
-import com.android.settingslib.location.RecentLocationApps.Request;
-import com.android.settingslib.widget.apppreference.AppPreference;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/** Unit tests for {@link RecentLocationRequestSeeAllPreferenceController} */
-@RunWith(RobolectricTestRunner.class)
-public class RecentLocationRequestSeeAllPreferenceControllerTest {
-
-    @Mock
-    RecentLocationRequestSeeAllFragment mFragment;
-    @Mock
-    private PreferenceScreen mScreen;
-    @Mock
-    private PreferenceCategory mCategory;
-    @Mock
-    private RecentLocationApps mRecentLocationApps;
-
-    private Context mContext;
-    private LifecycleOwner mLifecycleOwner;
-    private Lifecycle mLifecycle;
-    private RecentLocationRequestSeeAllPreferenceController mController;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = spy(RuntimeEnvironment.application);
-        mLifecycleOwner = () -> mLifecycle;
-        mLifecycle = new Lifecycle(mLifecycleOwner);
-        mController = spy(
-                new RecentLocationRequestSeeAllPreferenceController(
-                        mContext, mLifecycle, mFragment, mRecentLocationApps));
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory);
-        final String key = mController.getPreferenceKey();
-        when(mCategory.getKey()).thenReturn(key);
-        when(mCategory.getContext()).thenReturn(mContext);
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOn_shouldEnablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Secure.LOCATION_MODE_HIGH_ACCURACY, false);
-
-        verify(mCategory).setEnabled(true);
-    }
-
-    @Test
-    public void onLocationModeChanged_locationOff_shouldDisablePreference() {
-        mController.displayPreference(mScreen);
-
-        mController.onLocationModeChanged(Secure.LOCATION_MODE_OFF, false);
-
-        verify(mCategory).setEnabled(false);
-    }
-
-    @Test
-    public void updateState_shouldRemoveAll() {
-        doReturn(Collections.EMPTY_LIST).when(mRecentLocationApps).getAppListSorted();
-
-        mController.displayPreference(mScreen);
-        mController.updateState(mCategory);
-
-        verify(mCategory).removeAll();
-    }
-
-    @Test
-    public void updateState_hasRecentLocationRequest_shouldAddPreference() {
-        Request request = mock(Request.class);
-        AppPreference appPreference = mock(AppPreference.class);
-        doReturn(appPreference)
-                .when(mController).createAppPreference(any(Context.class), eq(request));
-        when(mRecentLocationApps.getAppListSorted())
-                .thenReturn(new ArrayList<>(Collections.singletonList(request)));
-
-        mController.displayPreference(mScreen);
-        mController.updateState(mCategory);
-
-        verify(mCategory).removeAll();
-        verify(mCategory).addPreference(appPreference);
-    }
-}