Merge "Update location app stats" into qt-dev

This commit is contained in:
TreeHugger Robot
2019-04-30 02:50:58 +00:00
committed by Android (Google) Code Review
4 changed files with 110 additions and 54 deletions

View File

@@ -842,8 +842,8 @@
<string name="location_settings_summary_location_off">Off</string> <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]--> <!-- 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"> <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="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 can access location</item> <item quantity="other">On - <xliff:g id="count">%1$d</xliff:g> apps have access to location</item>
</plurals> </plurals>
<!-- Location settings, loading the number of apps which have location permission [CHAR LIMIT=30] --> <!-- 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> <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] --> <!-- 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> <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 Summary for Location settings when location is on, explaining how many apps have location
location permission. 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).
Please note that the distinction between singular and plural of this sentence only depends on 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. "total_location_app_count" is almost always greater than 1, so "apps" is always in plural form.
[CHAR LIMIT=NONE]--> [CHAR LIMIT=NONE]-->
<plurals name="location_app_permission_summary_location_on"> <plurals name="location_app_permission_summary_location_on">
<item quantity="one"> <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 of
<xliff:g id="total_location_app_count">%2$d</xliff:g> <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"> <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 of
<xliff:g id="total_location_app_count">%2$d</xliff:g> <xliff:g id="total_location_app_count">%2$d</xliff:g>
apps have unlimited access</item> apps have access to location</item>
</plurals> </plurals>
<!-- [CHAR LIMIT=50] Location settings screen, sub category for recent location access --> <!-- [CHAR LIMIT=50] Location settings screen, sub category for recent location access -->
<string name="location_category_recent_location_access">Recent location access</string> <string name="location_category_recent_location_access">Recent location access</string>

View File

@@ -1,11 +1,12 @@
package com.android.settings.location; 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_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import android.content.Context; import android.content.Context;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager; import android.permission.PermissionControllerManager;
import android.provider.Settings; import android.provider.Settings;
@@ -13,11 +14,12 @@ import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public class AppLocationPermissionPreferenceController extends public class AppLocationPermissionPreferenceController extends
@@ -29,7 +31,12 @@ public class AppLocationPermissionPreferenceController extends
int mNumTotal = -1; int mNumTotal = -1;
/** Total number of apps that has background location permission. */ /** Total number of apps that has background location permission. */
@VisibleForTesting @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 final LocationManager mLocationManager;
private Preference mPreference; private Preference mPreference;
@@ -52,52 +59,76 @@ public class AppLocationPermissionPreferenceController extends
@Override @Override
public CharSequence getSummary() { public CharSequence getSummary() {
if (mLocationManager.isLocationEnabled()) { 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.getString(R.string.location_settings_loading_app_permission_stats);
} }
return mContext.getResources().getQuantityString( return mContext.getResources().getQuantityString(
R.plurals.location_app_permission_summary_location_on, mNumBackground, R.plurals.location_app_permission_summary_location_on, mNumHasLocation,
mNumBackground, mNumTotal); mNumHasLocation, mNumTotal);
} else { } else {
return mContext.getString(R.string.location_app_permission_summary_location_off); 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 @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
super.updateState(preference); super.updateState(preference);
mPreference = preference; mPreference = preference;
final AtomicInteger loadingInProgress = new AtomicInteger(2);
refreshSummary(preference); refreshSummary(preference);
// Bail out if location has been disabled. // Bail out if location has been disabled, or there's another loading request in progress.
if (!mLocationManager.isLocationEnabled()) { if (!mLocationManager.isLocationEnabled() ||
loadingInProgress.get() != 0) {
return; return;
} }
PermissionControllerManager permController = mNumTotalLoading = 0;
mContext.getSystemService(PermissionControllerManager.class); mNumHasLocationLoading = 0;
permController.countPermissionApps( // Retrieve a list of users inside the current user profile group.
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), 0, final List<UserHandle> users = mContext.getSystemService(
(numApps) -> { UserManager.class).getUserProfiles();
mNumTotal = numApps; 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) { if (loadingInProgress.decrementAndGet() == 0) {
refreshSummary(preference); setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
} }
}, null); }
continue;
permController.countPermissionApps( }
Collections.singletonList(ACCESS_BACKGROUND_LOCATION), final PermissionControllerManager permController =
PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED, userContext.getSystemService(PermissionControllerManager.class);
(numApps) -> { permController.countPermissionApps(
mNumBackground = numApps; Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), 0,
if (loadingInProgress.decrementAndGet() == 0) { (numApps) -> {
refreshSummary(preference); mNumTotalLoading += numApps;
} if (loadingInProgress.decrementAndGet() == 0) {
}, null); setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
}
}, null);
permController.countPermissionApps(
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION),
PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED,
(numApps) -> {
mNumHasLocationLoading += numApps;
if (loadingInProgress.decrementAndGet() == 0) {
setAppCounts(mNumTotalLoading, mNumHasLocationLoading);
}
}, null);
}
} }
@Override @Override
public void onLocationModeChanged(int mode, boolean restricted) { public void onLocationModeChanged(int mode, boolean restricted) {
// 'null' is checked inside updateState(), so no need to check here. if (mPreference != null) {
updateState(mPreference); updateState(mPreference);
}
} }
} }

View File

@@ -8,18 +8,23 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionControllerManager; import android.permission.PermissionControllerManager;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class TopLevelLocationPreferenceController extends BasePreferenceController implements public class TopLevelLocationPreferenceController extends BasePreferenceController implements
LifecycleObserver, OnStart, OnStop { LifecycleObserver, OnStart, OnStop {
@@ -28,8 +33,10 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
private final LocationManager mLocationManager; private final LocationManager mLocationManager;
/** Total number of apps that has location permission. */ /** Total number of apps that has location permission. */
private int mNumTotal = -1; private int mNumTotal = -1;
private int mNumTotalLoading = 0;
private BroadcastReceiver mReceiver; private BroadcastReceiver mReceiver;
private Preference mPreference; private Preference mPreference;
private AtomicInteger loadingInProgress = new AtomicInteger(0);
public TopLevelLocationPreferenceController(Context context, String preferenceKey) { public TopLevelLocationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
@@ -66,16 +73,37 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
super.updateState(preference); super.updateState(preference);
mPreference = preference; mPreference = preference;
refreshSummary(preference); refreshSummary(preference);
// Bail out if location has been disabled. // Bail out if location has been disabled, or there's another loading request in progress.
if (!mLocationManager.isLocationEnabled()) { if (!mLocationManager.isLocationEnabled() ||
loadingInProgress.get() != 0) {
return; return;
} }
mContext.getSystemService(PermissionControllerManager.class).countPermissionApps( mNumTotalLoading = 0;
Arrays.asList(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION), // Retrieve a list of users inside the current user profile group.
PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED, final List<UserHandle> users = mContext.getSystemService(
(numApps) -> { UserManager.class).getUserProfiles();
setLocationAppCount(numApps); loadingInProgress.set(users.size());
}, null); 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) -> {
mNumTotalLoading += numApps;
if (loadingInProgress.decrementAndGet() == 0) {
setLocationAppCount(mNumTotalLoading);
}
}, null);
}
} }
@Override @Override
@@ -98,7 +126,8 @@ public class TopLevelLocationPreferenceController extends BasePreferenceControll
} }
private void refreshLocationMode() { private void refreshLocationMode() {
// 'null' is checked inside updateState(), so no need to check here. if (mPreference != null) {
updateState(mPreference); updateState(mPreference);
}
} }
} }

View File

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