Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3da8f8d3 authored by Lifu Tang's avatar Lifu Tang
Browse files

Display app stats for location permission

Bug: 120221631
Test: manually
Change-Id: I53f43079807759c50eeb62029bb0d8d1f84e1118
parent 811d95c3
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -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,7 +3637,22 @@
    <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>
    <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 -->
+4 −3
Original line number Diff line number Diff line
@@ -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"
+73 −4
Original line number Diff line number Diff line
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);
    }
}
+6 −10
Original line number Diff line number Diff line
@@ -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 {
    public void onStop() {
        mContext.unregisterReceiver(mReceiver);
        } catch (RuntimeException e) {
            // Ignore exceptions caused by race condition
        }
    }

    void refreshLocationMode() {
+1 −1
Original line number Diff line number Diff line
@@ -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));
Loading