From 1019d73896ca8ec9baac1492c08443c7a6339380 Mon Sep 17 00:00:00 2001 From: Shijian Li Date: Mon, 2 Jan 2017 15:55:55 +0000 Subject: Expand all permissions when permissions in a group are individually managed. Test: Manually tested on sawshark_sw where WRITE_CONTACTS and READ_CONTACTS are shown separately for Android Wear App. Also tested on sawshark where only one "Contacts" group shown on behalf of WRITE_CONTACTS and READ_CONTACTS. Bug: 33856934 Change-Id: I299c54e38236d039204a01d8113f427b1fc71c43 --- .../ui/wear/AppPermissionsFragmentWear.java | 159 ++++++++++++++------- .../packageinstaller/permission/utils/Utils.java | 10 ++ 2 files changed, 116 insertions(+), 53 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java index 6eac0c67..d2d1f718 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java +++ b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java @@ -22,6 +22,7 @@ import android.app.Fragment; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; import android.os.Bundle; import android.os.UserHandle; import android.preference.Preference; @@ -38,6 +39,7 @@ import android.widget.Toast; import com.android.packageinstaller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; +import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; @@ -63,6 +65,7 @@ public final class AppPermissionsFragmentWear extends PreferenceFragment { return fragment; } + private PackageManager mPackageManager; private List mToggledGroups; private AppPermissions mAppPermissions; @@ -103,11 +106,12 @@ public final class AppPermissionsFragmentWear extends PreferenceFragment { String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); Activity activity = getActivity(); - PackageManager pm = activity.getPackageManager(); + mPackageManager = activity.getPackageManager(); + PackageInfo packageInfo; try { - packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); + packageInfo = mPackageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e); packageInfo = null; @@ -149,7 +153,7 @@ public final class AppPermissionsFragmentWear extends PreferenceFragment { private void initializePermissionGroupList() { final String packageName = mAppPermissions.getPackageInfo().packageName; List groups = mAppPermissions.getPermissionGroups(); - List nonSystemGroups = new ArrayList<>(); + List nonSystemPreferences = new ArrayList<>(); if (!groups.isEmpty()) { getPreferenceScreen().removePreference(findPreference(KEY_NO_PERMISSIONS)); @@ -162,64 +166,101 @@ public final class AppPermissionsFragmentWear extends PreferenceFragment { boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); - final SwitchPreference pref = new PermissionSwitchPreference(getActivity()); - pref.setKey(group.getName()); - pref.setTitle(group.getLabel()); - pref.setChecked(group.areRuntimePermissionsGranted()); - - if (group.isPolicyFixed()) { - pref.setEnabled(false); + if (Utils.areGroupPermissionsIndividuallyControlled(getContext(), group.getName())) { + // If permission is controlled individually, we show all requested permission + // inside this group. + for (PermissionInfo perm : getPermissionInfosFromGroup(group)) { + final SwitchPreference pref = createSwitchPreferenceForPermission(group, perm); + showOrAddToNonSystemPreferences(pref, nonSystemPreferences, isPlatform); + } } else { - pref.setOnPreferenceChangeListener((p, newVal) -> { - if (LocationUtils.isLocationGroupAndProvider( - group.getName(), group.getApp().packageName)) { - LocationUtils.showLocationDialog( - getContext(), mAppPermissions.getAppLabel()); - return false; - } + final SwitchPreference pref = createSwitchPreferenceForGroup(group); + showOrAddToNonSystemPreferences(pref, nonSystemPreferences, isPlatform); + } + } - if ((Boolean) newVal) { - setPermission(group, pref, true); - } else { - final boolean grantedByDefault = group.hasGrantedByDefaultPermission(); - if (grantedByDefault - || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) { - new WearableDialogHelper.DialogBuilder(getContext()) - .setNegativeIcon(R.drawable.confirm_button) - .setPositiveIcon(R.drawable.cancel_button) - .setNegativeButton(R.string.grant_dialog_button_deny_anyway, - (dialog, which) -> { - setPermission(group, pref, false); - if (!group.hasGrantedByDefaultPermission()) { - mHasConfirmedRevoke = true; - } - }) - .setPositiveButton(R.string.cancel, (dialog, which) -> {}) - .setMessage(grantedByDefault ? - R.string.system_warning : R.string.old_sdk_deny_warning) - .show(); - return false; - } else { - setPermission(group, pref, false); - } - } + // Now add the non-system settings to the end of the list + for (SwitchPreference nonSystemPreference : nonSystemPreferences) { + getPreferenceScreen().addPreference(nonSystemPreference); + } + } - return true; - }); - } + private void showOrAddToNonSystemPreferences(SwitchPreference pref, + List nonSystemPreferences, // Mutate + boolean isPlatform) { + // The UI shows System settings first, then non-system settings + if (isPlatform) { + getPreferenceScreen().addPreference(pref); + } else { + nonSystemPreferences.add(pref); + } + } - // The UI shows System settings first, then non-system settings - if (isPlatform) { - getPreferenceScreen().addPreference(pref); + private SwitchPreference createSwitchPreferenceForPermission(AppPermissionGroup group, + PermissionInfo perm) { + final SwitchPreference pref = new PermissionSwitchPreference(getActivity()); + pref.setKey(perm.name); + pref.setTitle(perm.loadLabel(mPackageManager)); + pref.setChecked(group.areRuntimePermissionsGranted(new String[]{ perm.name })); + pref.setOnPreferenceChangeListener((p, newVal) -> { + if((Boolean) newVal) { + group.grantRuntimePermissions(false, new String[]{ perm.name }); } else { - nonSystemGroups.add(pref); + group.revokeRuntimePermissions(true, new String[]{ perm.name }); } - } + return true; + }); + return pref; + } - // Now add the non-system settings to the end of the list - for (SwitchPreference nonSystemGroup : nonSystemGroups) { - getPreferenceScreen().addPreference(nonSystemGroup); + private SwitchPreference createSwitchPreferenceForGroup(AppPermissionGroup group) { + final SwitchPreference pref = new PermissionSwitchPreference(getActivity()); + + pref.setKey(group.getName()); + pref.setTitle(group.getLabel()); + pref.setChecked(group.areRuntimePermissionsGranted()); + + if (group.isPolicyFixed()) { + pref.setEnabled(false); + } else { + pref.setOnPreferenceChangeListener((p, newVal) -> { + if (LocationUtils.isLocationGroupAndProvider( + group.getName(), group.getApp().packageName)) { + LocationUtils.showLocationDialog( + getContext(), mAppPermissions.getAppLabel()); + return false; + } + + if ((Boolean) newVal) { + setPermission(group, pref, true); + } else { + final boolean grantedByDefault = group.hasGrantedByDefaultPermission(); + if (grantedByDefault + || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) { + new WearableDialogHelper.DialogBuilder(getContext()) + .setNegativeIcon(R.drawable.confirm_button) + .setPositiveIcon(R.drawable.cancel_button) + .setNegativeButton(R.string.grant_dialog_button_deny_anyway, + (dialog, which) -> { + setPermission(group, pref, false); + if (!group.hasGrantedByDefaultPermission()) { + mHasConfirmedRevoke = true; + } + }) + .setPositiveButton(R.string.cancel, (dialog, which) -> {}) + .setMessage(grantedByDefault ? + R.string.system_warning : R.string.old_sdk_deny_warning) + .show(); + return false; + } else { + setPermission(group, pref, false); + } + } + + return true; + }); } + return pref; } private void setPermission(AppPermissionGroup group, SwitchPreference pref, boolean grant) { @@ -251,4 +292,16 @@ public final class AppPermissionsFragmentWear extends PreferenceFragment { mToggledGroups = null; } } + + private List getPermissionInfosFromGroup(AppPermissionGroup group) { + ArrayList permInfos = new ArrayList<>(group.getPermissions().size()); + for(Permission perm : group.getPermissions()) { + try { + permInfos.add(mPackageManager.getPermissionInfo(perm.getName(), 0)); + } catch (PackageManager.NameNotFoundException e) { + Log.w(LOG_TAG, "No permission:" + perm.getName()); + } + } + return permInfos; + } } diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 22663e13..c2da5824 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -145,4 +145,14 @@ public final class Utils { return info.isSystemApp() && (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0 && !launcherPkgs.contains(info.packageName); } + + public static boolean areGroupPermissionsIndividuallyControlled(Context context, String group) { + if (!context.getResources().getBoolean( + com.android.internal.R.bool.config_permissionReviewRequired)) { + return false; + } + return Manifest.permission_group.SMS.equals(group) + || Manifest.permission_group.PHONE.equals(group) + || Manifest.permission_group.CONTACTS.equals(group); + } } -- cgit v1.2.3