Snap for 5537346 from 65a258e2a2 to qt-release

Change-Id: Ic766576e1a1923494b547faea52a46cbf97744f6
This commit is contained in:
android-build-team Robot
2019-05-07 03:04:44 +00:00
11 changed files with 161 additions and 238 deletions

View File

@@ -16,38 +16,50 @@ package com.android.settings.applications;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.icu.text.ListFormatter;
import android.util.ArraySet;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.applications.PermissionsSummaryHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class AppPermissionsPreferenceController extends BasePreferenceController {
private static final String TAG = "AppPermissionPrefCtrl";
private static final String[] PERMISSION_GROUPS = new String[]{
"android.permission-group.LOCATION",
"android.permission-group.MICROPHONE",
"android.permission-group.CAMERA",
"android.permission-group.SMS",
"android.permission-group.CONTACTS",
"android.permission-group.PHONE"};
private static int NUM_PACKAGE_TO_CHECK = 3;
private static final int NUM_PERMISSION_TO_USE = 3;
@VisibleForTesting
static int NUM_PERMISSIONS_TO_SHOW = 3;
private final PackageManager mPackageManager;
private final Set<CharSequence> mPermissionGroups;
private final PermissionsSummaryHelper.PermissionsResultCallback mPermissionsCallback =
new PermissionsSummaryHelper.PermissionsResultCallback() {
@Override
public void onPermissionSummaryResult(int standardGrantedPermissionCount,
int requestedPermissionCount, int additionalGrantedPermissionCount,
List<CharSequence> grantedGroupLabels) {
updateSummary(grantedGroupLabels);
}
};
@VisibleForTesting
int mNumPackageChecked;
private Preference mPreference;
public AppPermissionsPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mPackageManager = context.getPackageManager();
mPermissionGroups = new ArraySet<>();
}
@Override
@@ -55,72 +67,45 @@ public class AppPermissionsPreferenceController extends BasePreferenceController
return AVAILABLE;
}
/*
Summary text looks like: Apps using Permission1, Permission2, Permission3
The 3 permissions are the first three from the list which any app has granted:
Location, Microphone, Camera, Sms, Contacts, and Phone
*/
@Override
public CharSequence getSummary() {
final Set<String> permissions = getAllPermissionsInGroups();
Set<String> grantedPermissionGroups = getGrantedPermissionGroups(permissions);
int count = 0;
final List<String> summaries = new ArrayList<>();
for (String group : PERMISSION_GROUPS) {
if (!grantedPermissionGroups.contains(group)) {
continue;
}
summaries.add(getPermissionGroupLabel(group).toString().toLowerCase());
if (++count >= NUM_PERMISSION_TO_USE) {
break;
}
}
return count > 0 ? mContext.getString(R.string.app_permissions_summary,
ListFormatter.getInstance().format(summaries)) : null;
public void updateState(Preference preference) {
mPreference = preference;
mNumPackageChecked = 0;
queryPermissionSummary();
}
private Set<String> getGrantedPermissionGroups(Set<String> permissions) {
ArraySet<String> grantedPermissionGroups = new ArraySet<>();
List<PackageInfo> installedPackages =
@VisibleForTesting
void queryPermissionSummary() {
final List<PackageInfo> installedPackages =
mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for (PackageInfo installedPackage : installedPackages) {
if (installedPackage.permissions == null) {
continue;
// Here we only get the first three apps and check their permissions.
final List<PackageInfo> packagesWithPermission = installedPackages.stream()
.filter(pInfo -> pInfo.permissions != null)
.limit(NUM_PACKAGE_TO_CHECK)
.collect(Collectors.toList());
for (PackageInfo installedPackage : packagesWithPermission) {
PermissionsSummaryHelper.getPermissionSummary(mContext,
installedPackage.packageName, mPermissionsCallback);
}
for (PermissionInfo permissionInfo : installedPackage.permissions) {
if (permissions.contains(permissionInfo.name)
&& !grantedPermissionGroups.contains(permissionInfo.group)) {
grantedPermissionGroups.add(permissionInfo.group);
}
}
}
return grantedPermissionGroups;
}
private CharSequence getPermissionGroupLabel(String group) {
try {
final PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo(group, 0);
return groupInfo.loadLabel(mPackageManager);
} catch (NameNotFoundException e) {
Log.e(TAG, "Error getting permissions label.", e);
}
return group;
@VisibleForTesting
void updateSummary(List<CharSequence> grantedGroupLabels) {
mPermissionGroups.addAll(grantedGroupLabels);
mNumPackageChecked++;
if (mNumPackageChecked < NUM_PACKAGE_TO_CHECK) {
return;
}
private Set<String> getAllPermissionsInGroups() {
ArraySet<String> result = new ArraySet<>();
for (String group : PERMISSION_GROUPS) {
try {
final List<PermissionInfo> permissions =
mPackageManager.queryPermissionsByGroup(group, 0);
for (PermissionInfo permissionInfo : permissions) {
result.add(permissionInfo.name);
}
} catch (NameNotFoundException e) {
Log.e(TAG, "Error getting permissions in group " + group, e);
}
}
return result;
final List<CharSequence> permissionsToShow = mPermissionGroups.stream()
.limit(NUM_PERMISSIONS_TO_SHOW)
.collect(Collectors.toList());
final CharSequence summary = !permissionsToShow.isEmpty()
? mContext.getString(R.string.app_permissions_summary,
ListFormatter.getInstance().format(permissionsToShow).toLowerCase())
: null;
mPreference.setSummary(summary);
}
}

View File

@@ -18,9 +18,9 @@ package com.android.settings.homepage.contextualcards.conditional;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.display.NightDisplaySettings;

View File

@@ -16,14 +16,11 @@
package com.android.settings.homepage.contextualcards.slices;
import android.annotation.ColorInt;
import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;

View File

@@ -26,6 +26,7 @@ import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.PendingIntent;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
@@ -44,7 +45,6 @@ import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SubSettings;
import com.android.settings.Utils;
@@ -215,7 +215,7 @@ public class NotificationChannelSlice implements CustomSliceable {
.setDestination(AppNotificationSettings.class.getName())
.setTitleRes(R.string.notifications_title)
.setArguments(args)
.setSourceMetricsCategory(MetricsProto.MetricsEvent.SLICE)
.setSourceMetricsCategory(SettingsEnums.SLICE)
.toIntent();
}
@@ -263,7 +263,7 @@ public class NotificationChannelSlice implements CustomSliceable {
.setDestination(ChannelNotificationSettings.class.getName())
.setArguments(channelArgs)
.setTitleRes(R.string.notification_channel_title)
.setSourceMetricsCategory(MetricsProto.MetricsEvent.SLICE)
.setSourceMetricsCategory(SettingsEnums.SLICE)
.toIntent();
return SliceAction.createDeeplink(
@@ -439,7 +439,7 @@ public class NotificationChannelSlice implements CustomSliceable {
return SliceBuilderUtils.buildSearchResultPageIntent(mContext,
AppAndNotificationDashboardFragment.class.getName(), "" /* key */,
screenTitle,
MetricsProto.MetricsEvent.SLICE)
SettingsEnums.SLICE)
.setClassName(mContext.getPackageName(), SubSettings.class.getName())
.setData(getUri());
}

View File

@@ -29,8 +29,8 @@ import com.android.settings.homepage.contextualcards.CardDatabaseHelper;
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardController;
import com.android.settings.homepage.contextualcards.ContextualCardFeedbackDialog;
import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUtils;
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;

View File

@@ -19,7 +19,6 @@ package com.android.settings.homepage.contextualcards.slices;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slice.Slice;

View File

@@ -34,6 +34,7 @@ import android.util.Log;
import com.android.internal.telephony.OperatorInfo;
import java.util.List;
import java.util.stream.Collectors;
/**
* Add static Utility functions to get information from the CellInfo object.
@@ -161,4 +162,21 @@ public final class CellInfoUtil {
String plmn = CellInfoUtil.getOperatorInfoFromCellInfo(cellInfo).getOperatorNumeric();
return forbiddenPlmns != null && forbiddenPlmns.contains(plmn);
}
/** Convert a list of cellInfos to readable string without sensitive info. */
public static String cellInfoListToString(List<CellInfo> cellInfos) {
return cellInfos.stream()
.map(cellInfo -> cellInfoToString(cellInfo))
.collect(Collectors.joining(", "));
}
/** Convert {@code cellInfo} to a readable string without sensitive info. */
public static String cellInfoToString(CellInfo cellInfo) {
String cellType = cellInfo.getClass().getSimpleName();
CellIdentity cid = cellInfo.getCellIdentity();
return String.format(
"{CellType = %s, isRegistered = %b, mcc = %s, mnc = %s, alphaL = %s, alphaS = %s}",
cellType, cellInfo.isRegistered(), cid.getMccString(), cid.getMncString(),
cid.getOperatorAlphaLong(), cid.getOperatorAlphaShort());
}
}

View File

@@ -45,7 +45,6 @@ import java.util.stream.Collectors;
*/
public class NetworkScanHelper {
public static final String TAG = "NetworkScanHelper";
private static final boolean DBG = false;
/**
* Callbacks interface to inform the network scan results.
@@ -184,7 +183,6 @@ public class NetworkScanHelper {
mExecutor.execute(new NetworkScanSyncTask(
mTelephonyManager, (SettableFuture) mNetworkScanFuture));
} else if (type == NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS) {
if (DBG) Log.d(TAG, "start network scan async");
mNetworkScanRequester = mTelephonyManager.requestNetworkScan(
NETWORK_SCAN_REQUEST,
mExecutor,
@@ -240,17 +238,18 @@ public class NetworkScanHelper {
private final class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
public void onResults(List<CellInfo> results) {
if (DBG) Log.d(TAG, "async scan onResults() results = " + results);
Log.d(TAG, "Async scan onResults() results = "
+ CellInfoUtil.cellInfoListToString(results));
NetworkScanHelper.this.onResults(results);
}
public void onComplete() {
if (DBG) Log.d(TAG, "async scan onComplete()");
Log.d(TAG, "async scan onComplete()");
NetworkScanHelper.this.onComplete();
}
public void onError(@NetworkScan.ScanErrorCode int errCode) {
if (DBG) Log.d(TAG, "async scan onError() errorCode = " + errCode);
Log.d(TAG, "async scan onError() errorCode = " + errCode);
NetworkScanHelper.this.onError(errCode);
}
}
@@ -267,19 +266,21 @@ public class NetworkScanHelper {
@Override
public void run() {
if (DBG) Log.d(TAG, "sync scan start");
CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
final CellNetworkScanResult result = mTelephonyManager.getAvailableNetworks();
if (result.getStatus() == CellNetworkScanResult.STATUS_SUCCESS) {
List<CellInfo> cellInfos = result.getOperators()
final List<CellInfo> cellInfos = result.getOperators()
.stream()
.map(operatorInfo
-> CellInfoUtil.convertOperatorInfoToCellInfo(operatorInfo))
.collect(Collectors.toList());
if (DBG) Log.d(TAG, "sync scan complete");
Log.d(TAG, "Sync network scan completed, cellInfos = "
+ CellInfoUtil.cellInfoListToString(cellInfos));
mCallback.set(cellInfos);
} else {
mCallback.setException(new Throwable(
Integer.toString(convertToScanErrorCode(result.getStatus()))));
final Throwable error = new Throwable(
Integer.toString(convertToScanErrorCode(result.getStatus())));
mCallback.setException(error);
Log.d(TAG, "Sync network scan error, ex = " + error);
}
}
}

View File

@@ -31,6 +31,7 @@ import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import androidx.annotation.VisibleForTesting;
@@ -230,6 +231,8 @@ public class NetworkSelectSettings extends DashboardFragment {
break;
case EVENT_NETWORK_SCAN_RESULTS:
List<CellInfo> results = aggregateCellInfoList((List<CellInfo>) msg.obj);
Log.d(TAG, "CellInfoList after aggregation: "
+ CellInfoUtil.cellInfoListToString(results));
mCellInfoList = new ArrayList<>(results);
if (mCellInfoList != null && mCellInfoList.size() != 0) {
updateAllPreferenceCategory();

View File

@@ -16,30 +16,24 @@
package com.android.settings.applications;
import static com.android.settings.applications.AppPermissionsPreferenceController.NUM_PERMISSIONS_TO_SHOW;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
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.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import androidx.preference.Preference;
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;
@@ -49,99 +43,14 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class)
public class AppPermissionsPreferenceControllerTest {
private static final String PERM_LOCATION = "android.permission-group.LOCATION";
private static final String PERM_MICROPHONE = "android.permission-group.MICROPHONE";
private static final String PERM_CAMERA = "android.permission-group.CAMERA";
private static final String PERM_SMS = "android.permission-group.SMS";
private static final String PERM_CONTACTS = "android.permission-group.CONTACTS";
private static final String PERM_PHONE = "android.permission-group.PHONE";
private static final String LABEL_LOCATION = "Location";
private static final String LABEL_MICROPHONE = "Microphone";
private static final String LABEL_CAMERA = "Camera";
private static final String LABEL_SMS = "Sms";
private static final String LABEL_CONTACTS = "Contacts";
private static final String LABEL_PHONE = "Phone";
@Mock
private Preference mPreference;
@Mock
private PackageManager mPackageManager;
@Mock
private PermissionGroupInfo mGroupLocation;
@Mock
private PermissionGroupInfo mGroupMic;
@Mock
private PermissionGroupInfo mGroupCamera;
@Mock
private PermissionGroupInfo mGroupSms;
@Mock
private PermissionGroupInfo mGroupContacts;
@Mock
private PermissionGroupInfo mGroupPhone;
private Context mContext;
private AppPermissionsPreferenceController mController;
private PermissionInfo mPermLocation;
private PermissionInfo mPermMic;
private PermissionInfo mPermCamera;
private PermissionInfo mPermSms;
private PermissionInfo mPermContacts;
private PermissionInfo mPermPhone;
private Preference mPreference;
@Before
public void setUp() throws NameNotFoundException {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
// create permission groups
when(mPackageManager.getPermissionGroupInfo(eq(PERM_LOCATION), anyInt()))
.thenReturn(mGroupLocation);
when(mGroupLocation.loadLabel(mPackageManager)).thenReturn(LABEL_LOCATION);
when(mPackageManager.getPermissionGroupInfo(eq(PERM_MICROPHONE), anyInt()))
.thenReturn(mGroupMic);
when(mGroupMic.loadLabel(mPackageManager)).thenReturn(LABEL_MICROPHONE);
when(mPackageManager.getPermissionGroupInfo(eq(PERM_CAMERA), anyInt()))
.thenReturn(mGroupCamera);
when(mGroupCamera.loadLabel(mPackageManager)).thenReturn(LABEL_CAMERA);
when(mPackageManager.getPermissionGroupInfo(eq(PERM_SMS), anyInt())).thenReturn(mGroupSms);
when(mGroupSms.loadLabel(mPackageManager)).thenReturn(LABEL_SMS);
when(mPackageManager.getPermissionGroupInfo(eq(PERM_CONTACTS), anyInt()))
.thenReturn(mGroupContacts);
when(mGroupContacts.loadLabel(mPackageManager)).thenReturn(LABEL_CONTACTS);
when(mPackageManager.getPermissionGroupInfo(eq(PERM_PHONE), anyInt()))
.thenReturn(mGroupPhone);
when(mGroupPhone.loadLabel(mPackageManager)).thenReturn(LABEL_PHONE);
// create permissions
mPermLocation = new PermissionInfo();
mPermLocation.name = "Permission1";
mPermLocation.group = PERM_LOCATION;
mPermMic = new PermissionInfo();
mPermMic.name = "Permission2";
mPermMic.group = PERM_MICROPHONE;
mPermCamera = new PermissionInfo();
mPermCamera.name = "Permission3";
mPermCamera.group = PERM_CAMERA;
mPermSms = new PermissionInfo();
mPermSms.name = "Permission4";
mPermSms.group = PERM_SMS;
mPermContacts = new PermissionInfo();
mPermContacts.name = "Permission4";
mPermContacts.group = PERM_CONTACTS;
mPermPhone = new PermissionInfo();
mPermPhone.name = "Permission4";
mPermPhone.group = PERM_PHONE;
final List<PermissionInfo> permissions = new ArrayList<>();
permissions.add(mPermLocation);
permissions.add(mPermMic);
permissions.add(mPermCamera);
permissions.add(mPermSms);
permissions.add(mPermContacts);
permissions.add(mPermPhone);
when(mPackageManager.queryPermissionsByGroup(anyString(), anyInt()))
.thenReturn(permissions);
mContext = RuntimeEnvironment.application;
mPreference = spy(new Preference(mContext));
mController = spy(new AppPermissionsPreferenceController(mContext, "pref_key"));
}
@@ -151,65 +60,76 @@ public class AppPermissionsPreferenceControllerTest {
}
@Test
public void updateState_noGrantedPermissions_shouldNotSetSummary() {
final List<PackageInfo> installedPackages = new ArrayList<>();
final PackageInfo info = new PackageInfo();
installedPackages.add(info);
when(mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS))
.thenReturn(installedPackages);
public void updateState_shouldResetNumPackageChecked() {
doNothing().when(mController).queryPermissionSummary();
mController.mNumPackageChecked = 3;
mController.updateState(mPreference);
assertThat(mController.mNumPackageChecked).isEqualTo(0);
}
@Test
public void updateSummary_noGrantedPermission_shouldSetNullSummary() {
doNothing().when(mController).queryPermissionSummary();
mController.updateState(mPreference);
mController.mNumPackageChecked = 2;
mController.updateSummary(new ArrayList<>());
assertThat(mPreference.getSummary()).isNull();
}
@Test
public void updateSummary_hasPermissionGroups_shouldSetPermissionAsSummary() {
doNothing().when(mController).queryPermissionSummary();
mController.updateState(mPreference);
final String permission = "location";
final ArrayList<CharSequence> labels = new ArrayList<>();
labels.add(permission);
final String summary = "Apps using " + permission;
mController.mNumPackageChecked = 2;
mController.updateSummary(labels);
assertThat(mPreference.getSummary()).isEqualTo(summary);
}
@Test
public void updateSummary_notReachCallbackCount_shouldNotSetSummary() {
doNothing().when(mController).queryPermissionSummary();
mController.updateState(mPreference);
final String permission = "location";
final ArrayList<CharSequence> labels = new ArrayList<>();
labels.add(permission);
mController.updateSummary(labels);
verify(mPreference, never()).setSummary(anyString());
}
@Test
public void updateState_hasPermissions_shouldSetSummary() {
final List<PackageInfo> installedPackages = new ArrayList<>();
final PackageInfo info = new PackageInfo();
installedPackages.add(info);
when(mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS))
.thenReturn(installedPackages);
PermissionInfo[] permissions = new PermissionInfo[4];
info.permissions = permissions;
permissions[0] = mPermLocation;
permissions[1] = mPermMic;
permissions[2] = mPermCamera;
permissions[3] = mPermSms;
public void updateSummary_hasFiveItems_shouldShowCertainNumItems() {
doNothing().when(mController).queryPermissionSummary();
mController.updateState(mPreference);
mController.mNumPackageChecked = 2;
verify(mPreference).setSummary("Apps using location, microphone, and camera");
mController.updateSummary(getPermissionGroupsSet());
permissions[0] = mPermPhone;
permissions[1] = mPermMic;
permissions[2] = mPermCamera;
permissions[3] = mPermSms;
mController.updateState(mPreference);
final CharSequence summary = mPreference.getSummary();
final int items = summary.toString().split(",").length;
assertThat(items).isEqualTo(NUM_PERMISSIONS_TO_SHOW);
}
verify(mPreference).setSummary("Apps using microphone, camera, and sms");
private List<CharSequence> getPermissionGroupsSet() {
final List<CharSequence> labels = new ArrayList<>();
labels.add("Phone");
labels.add("SMS");
labels.add("Microphone");
labels.add("Contacts");
labels.add("Camera");
labels.add("Location");
permissions[0] = mPermPhone;
permissions[1] = mPermMic;
permissions[2] = mPermContacts;
permissions[3] = mPermSms;
mController.updateState(mPreference);
verify(mPreference).setSummary("Apps using microphone, sms, and contacts");
permissions = new PermissionInfo[2];
info.permissions = permissions;
permissions[0] = mPermLocation;
permissions[1] = mPermCamera;
mController.updateState(mPreference);
verify(mPreference).setSummary("Apps using location and camera");
permissions = new PermissionInfo[1];
info.permissions = permissions;
permissions[0] = mPermCamera;
mController.updateState(mPreference);
verify(mPreference).setSummary("Apps using camera");
return labels;
}
}