diff --git a/res/raw/notification_interruption_model.mp4 b/res/raw/notification_interruption_model.mp4 index 5782091a1a1..5183afa36a9 100644 Binary files a/res/raw/notification_interruption_model.mp4 and b/res/raw/notification_interruption_model.mp4 differ diff --git a/src/com/android/settings/applications/AppPermissionsPreferenceController.java b/src/com/android/settings/applications/AppPermissionsPreferenceController.java index 0137276c942..59341d5447f 100644 --- a/src/com/android/settings/applications/AppPermissionsPreferenceController.java +++ b/src/com/android/settings/applications/AppPermissionsPreferenceController.java @@ -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 mPermissionGroups; + + private final PermissionsSummaryHelper.PermissionsResultCallback mPermissionsCallback = + new PermissionsSummaryHelper.PermissionsResultCallback() { + @Override + public void onPermissionSummaryResult(int standardGrantedPermissionCount, + int requestedPermissionCount, int additionalGrantedPermissionCount, + List 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 permissions = getAllPermissionsInGroups(); - Set grantedPermissionGroups = getGrantedPermissionGroups(permissions); - int count = 0; - final List 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 getGrantedPermissionGroups(Set permissions) { - ArraySet grantedPermissionGroups = new ArraySet<>(); - List installedPackages = + @VisibleForTesting + void queryPermissionSummary() { + final List installedPackages = mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS); - for (PackageInfo installedPackage : installedPackages) { - if (installedPackage.permissions == null) { - continue; - } - for (PermissionInfo permissionInfo : installedPackage.permissions) { - if (permissions.contains(permissionInfo.name) - && !grantedPermissionGroups.contains(permissionInfo.group)) { - grantedPermissionGroups.add(permissionInfo.group); - } - } + // Here we only get the first three apps and check their permissions. + final List 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); } - 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 grantedGroupLabels) { + mPermissionGroups.addAll(grantedGroupLabels); + mNumPackageChecked++; - private Set getAllPermissionsInGroups() { - ArraySet result = new ArraySet<>(); - for (String group : PERMISSION_GROUPS) { - try { - final List 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); - } + if (mNumPackageChecked < NUM_PACKAGE_TO_CHECK) { + return; } - return result; + + final List 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); } -} +} \ No newline at end of file diff --git a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java index 347d4eb7934..82bec0b4e45 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/NightDisplayConditionController.java @@ -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; diff --git a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java index 8267df01b0a..aa4d53b7f59 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/BluetoothDevicesSlice.java @@ -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; diff --git a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java index ee9d089a342..ccccd39c68a 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java +++ b/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSlice.java @@ -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()); } diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java index 05513771b8c..9eb7faef909 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardController.java @@ -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; diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java index cbe5ede4ece..3f35fb5ba1d 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java @@ -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; diff --git a/src/com/android/settings/network/telephony/CellInfoUtil.java b/src/com/android/settings/network/telephony/CellInfoUtil.java index ce382eb5c10..def81a10c64 100644 --- a/src/com/android/settings/network/telephony/CellInfoUtil.java +++ b/src/com/android/settings/network/telephony/CellInfoUtil.java @@ -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 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()); + } } diff --git a/src/com/android/settings/network/telephony/NetworkScanHelper.java b/src/com/android/settings/network/telephony/NetworkScanHelper.java index 5184877e73d..1117a84c33f 100644 --- a/src/com/android/settings/network/telephony/NetworkScanHelper.java +++ b/src/com/android/settings/network/telephony/NetworkScanHelper.java @@ -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 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 cellInfos = result.getOperators() + final List 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); } } } diff --git a/src/com/android/settings/network/telephony/NetworkSelectSettings.java b/src/com/android/settings/network/telephony/NetworkSelectSettings.java index d27a0c8a3f8..98bfc0d72cd 100644 --- a/src/com/android/settings/network/telephony/NetworkSelectSettings.java +++ b/src/com/android/settings/network/telephony/NetworkSelectSettings.java @@ -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 results = aggregateCellInfoList((List) msg.obj); + Log.d(TAG, "CellInfoList after aggregation: " + + CellInfoUtil.cellInfoListToString(results)); mCellInfoList = new ArrayList<>(results); if (mCellInfoList != null && mCellInfoList.size() != 0) { updateAllPreferenceCategory(); diff --git a/tests/robotests/src/com/android/settings/applications/AppPermissionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/AppPermissionsPreferenceControllerTest.java index 4343e16143e..986c2c77fb2 100644 --- a/tests/robotests/src/com/android/settings/applications/AppPermissionsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppPermissionsPreferenceControllerTest.java @@ -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 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 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 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 labels = new ArrayList<>(); + labels.add(permission); + + mController.updateSummary(labels); + verify(mPreference, never()).setSummary(anyString()); } @Test - public void updateState_hasPermissions_shouldSetSummary() { - final List 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 getPermissionGroupsSet() { + final List 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; } }