summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/location
diff options
context:
space:
mode:
authorLifu Tang <lifu@google.com>2018-12-11 13:50:34 -0800
committerLifu Tang <lifu@google.com>2018-12-17 21:13:08 -0800
commit3da8f8d31dc78f39cc598cce6b0c9012da1e64af (patch)
tree85563ad36c5dc439d361326603f231e1245f2d21 /src/com/android/settings/location
parent811d95c373f94c0aef9795634fa9de2283465165 (diff)
downloadpackages_apps_Settings-3da8f8d31dc78f39cc598cce6b0c9012da1e64af.tar.gz
packages_apps_Settings-3da8f8d31dc78f39cc598cce6b0c9012da1e64af.tar.bz2
packages_apps_Settings-3da8f8d31dc78f39cc598cce6b0c9012da1e64af.zip
Display app stats for location permission
Bug: 120221631 Test: manually Change-Id: I53f43079807759c50eeb62029bb0d8d1f84e1118
Diffstat (limited to 'src/com/android/settings/location')
-rw-r--r--src/com/android/settings/location/AppLocationPermissionPreferenceController.java77
-rw-r--r--src/com/android/settings/location/LocationEnabler.java16
-rw-r--r--src/com/android/settings/location/LocationSettings.java2
-rw-r--r--src/com/android/settings/location/TopLevelLocationPreferenceController.java99
4 files changed, 179 insertions, 15 deletions
diff --git a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java
index f920fdc7dc..5bfc58447e 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 @@ public class AppLocationPermissionPreferenceController extends
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 20c228024f..e1bdf162ef 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.RestrictedLockUtils;
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 @@ public class LocationEnabler implements LifecycleObserver, OnResume, OnPause {
}
@Override
- public void onResume() {
+ public void onStart() {
if (mReceiver == null) {
mReceiver = new BroadcastReceiver() {
@Override
@@ -90,12 +90,8 @@ public class LocationEnabler implements LifecycleObserver, OnResume, OnPause {
}
@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 8a92f4706e..4112340203 100644
--- a/src/com/android/settings/location/LocationSettings.java
+++ b/src/com/android/settings/location/LocationSettings.java
@@ -122,7 +122,7 @@ public class LocationSettings extends DashboardFragment {
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 RecentLocationAccessPreferenceController(context));
controllers.add(new LocationScanningPreferenceController(context));
diff --git a/src/com/android/settings/location/TopLevelLocationPreferenceController.java b/src/com/android/settings/location/TopLevelLocationPreferenceController.java
new file mode 100644
index 0000000000..d0bd9a9284
--- /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);
+ }
+}