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

Commit 5bfa4b24 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update location app stats" into qt-dev

parents 9efd0c96 d3a6d5e8
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -842,8 +842,8 @@
    <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>
        <item quantity="one">On - <xliff:g id="count">%1$d</xliff:g> app has access to location</item>
        <item quantity="other">On - <xliff:g id="count">%1$d</xliff:g> apps have access to 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>
@@ -3838,29 +3838,25 @@
    <!-- 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 unlimited
    location permission.
    "Unlimited access" means the app can access the device location even when it's not being used
    (on background), while "limited" means the app can only access the device location when the user
    is using it (foreground only).
    Summary for Location settings when location is on, explaining how many apps have location
    permission.
    Please note that the distinction between singular and plural of this sentence only depends on
    the quantity of "background_location_app_count" ("has" vs "have"). The quantity of
    the quantity of "permitted_location_app_count" ("has" vs "have"). The quantity of
    "total_location_app_count" is almost always greater than 1, so "apps" is always in plural form.
    [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>
            <xliff:g id="permitted_location_app_count">%1$d</xliff:g>
            of
            <xliff:g id="total_location_app_count">%2$d</xliff:g>
            apps has unlimited access</item>
            apps has access to location</item>
        <item quantity="other">
            <xliff:g id="background_location_app_count">%1$d</xliff:g>
            <xliff:g id="permitted_location_app_count">%1$d</xliff:g>
            of
            <xliff:g id="total_location_app_count">%2$d</xliff:g>
            apps have unlimited access</item>
            apps have access to location</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>
+60 −29
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.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager;
import android.provider.Settings;

@@ -13,11 +14,12 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class AppLocationPermissionPreferenceController extends
@@ -29,7 +31,12 @@ public class AppLocationPermissionPreferenceController extends
    int mNumTotal = -1;
    /** Total number of apps that has background location permission. */
    @VisibleForTesting
    int mNumBackground = -1;
    int mNumHasLocation = -1;

    final AtomicInteger loadingInProgress = new AtomicInteger(0);
    private int mNumTotalLoading = 0;
    private int mNumHasLocationLoading = 0;

    private final LocationManager mLocationManager;
    private Preference mPreference;

@@ -52,52 +59,76 @@ public class AppLocationPermissionPreferenceController extends
    @Override
    public CharSequence getSummary() {
        if (mLocationManager.isLocationEnabled()) {
            if (mNumTotal == -1 || mNumBackground == -1) {
            if (mNumTotal == -1 || mNumHasLocation == -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);
                    R.plurals.location_app_permission_summary_location_on, mNumHasLocation,
                    mNumHasLocation, mNumTotal);
        } else {
            return mContext.getString(R.string.location_app_permission_summary_location_off);
        }
    }

    private void setAppCounts(int numTotal, int numHasLocation) {
        mNumTotal = numTotal;
        mNumHasLocation = numHasLocation;
        refreshSummary(mPreference);
    }

    @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()) {
        // Bail out if location has been disabled, or there's another loading request in progress.
        if (!mLocationManager.isLocationEnabled() ||
                loadingInProgress.get() != 0) {
            return;
        }
        PermissionControllerManager permController =
                mContext.getSystemService(PermissionControllerManager.class);
        mNumTotalLoading = 0;
        mNumHasLocationLoading = 0;
        // Retrieve a list of users inside the current user profile group.
        final List<UserHandle> users = mContext.getSystemService(
                UserManager.class).getUserProfiles();
        loadingInProgress.set(2 * users.size());
        for (UserHandle user : users) {
            final Context userContext = Utils.createPackageContextAsUser(mContext,
                    user.getIdentifier());
            if (userContext == null) {
                for (int i = 0; i < 2; ++i) {
                    if (loadingInProgress.decrementAndGet() == 0) {
                        setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
                    }
                }
                continue;
            }
            final PermissionControllerManager permController =
                    userContext.getSystemService(PermissionControllerManager.class);
            permController.countPermissionApps(
                    Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), 0,
                    (numApps) -> {
                    mNumTotal = numApps;
                        mNumTotalLoading += numApps;
                        if (loadingInProgress.decrementAndGet() == 0) {
                        refreshSummary(preference);
                            setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
                        }
                    }, null);

            permController.countPermissionApps(
                Collections.singletonList(ACCESS_BACKGROUND_LOCATION),
                    Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
                    PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED,
                    (numApps) -> {
                    mNumBackground = numApps;
                        mNumHasLocationLoading += numApps;
                        if (loadingInProgress.decrementAndGet() == 0) {
                        refreshSummary(preference);
                            setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
                        }
                    }, null);
        }
    }

    @Override
    public void onLocationModeChanged(int mode, boolean restricted) {
        // 'null' is checked inside updateState(), so no need to check here.
        if (mPreference != null) {
            updateState(mPreference);
        }
    }
}
+39 −10
Original line number Diff line number Diff line
@@ -8,18 +8,23 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager;

import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;

import com.android.settings.R;
import com.android.settings.Utils;
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.List;
import java.util.concurrent.atomic.AtomicInteger;

public class TopLevelLocationPreferenceController extends BasePreferenceController implements
        LifecycleObserver, OnStart, OnStop {
@@ -28,8 +33,10 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
    private final LocationManager mLocationManager;
    /** Total number of apps that has location permission. */
    private int mNumTotal = -1;
    private int mNumTotalLoading = 0;
    private BroadcastReceiver mReceiver;
    private Preference mPreference;
    private AtomicInteger loadingInProgress = new AtomicInteger(0);

    public TopLevelLocationPreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey);
@@ -66,17 +73,38 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
        super.updateState(preference);
        mPreference = preference;
        refreshSummary(preference);
        // Bail out if location has been disabled.
        if (!mLocationManager.isLocationEnabled()) {
        // Bail out if location has been disabled, or there's another loading request in progress.
        if (!mLocationManager.isLocationEnabled() ||
                loadingInProgress.get() != 0) {
            return;
        }
        mContext.getSystemService(PermissionControllerManager.class).countPermissionApps(
        mNumTotalLoading = 0;
        // Retrieve a list of users inside the current user profile group.
        final List<UserHandle> users = mContext.getSystemService(
                UserManager.class).getUserProfiles();
        loadingInProgress.set(users.size());
        for (UserHandle user : users) {
            final Context userContext = Utils.createPackageContextAsUser(mContext,
                    user.getIdentifier());
            if (userContext == null) {
                if (loadingInProgress.decrementAndGet() == 0) {
                    setLocationAppCount(mNumTotalLoading);
                }
                continue;
            }
            final PermissionControllerManager permController =
                    userContext.getSystemService(PermissionControllerManager.class);
            permController.countPermissionApps(
                    Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
                    PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED,
                    (numApps) -> {
                    setLocationAppCount(numApps);
                        mNumTotalLoading += numApps;
                        if (loadingInProgress.decrementAndGet() == 0) {
                            setLocationAppCount(mNumTotalLoading);
                        }
                    }, null);
        }
    }

    @Override
    public void onStart() {
@@ -98,7 +126,8 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
    }

    private void refreshLocationMode() {
        // 'null' is checked inside updateState(), so no need to check here.
        if (mPreference != null) {
            updateState(mPreference);
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ public class AppLocationPermissionPreferenceControllerTest {
    @Test
    public void getSummary_whenLocationAppCountIsOne_shouldShowSingularString() {
        mLocationManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle());
        mController.mNumBackground = 1;
        mController.mNumHasLocation = 1;
        mController.mNumTotal = 1;

        assertThat(mController.getSummary()).isEqualTo(mContext.getResources().getQuantityString(
@@ -86,7 +86,7 @@ public class AppLocationPermissionPreferenceControllerTest {
    @Test
    public void getSummary_whenLocationAppCountIsGreaterThanOne_shouldShowPluralString() {
        mLocationManager.setLocationEnabledForUser(true, android.os.Process.myUserHandle());
        mController.mNumBackground = 5;
        mController.mNumHasLocation = 5;
        mController.mNumTotal = 10;

        assertThat(mController.getSummary()).isEqualTo(mContext.getResources().getQuantityString(