diff options
Diffstat (limited to 'src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java')
-rw-r--r-- | src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java | 350 |
1 files changed, 171 insertions, 179 deletions
diff --git a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java index db1c94d8..9ad52539 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java +++ b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java @@ -22,8 +22,14 @@ 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.support.wearable.view.WearableListView; +import android.os.UserHandle; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.PreferenceScreen; +import android.preference.SwitchPreference; +import android.support.wearable.view.WearableDialogHelper; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -33,25 +39,20 @@ 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.ui.wear.settings.PermissionsSettingsAdapter; -import com.android.packageinstaller.permission.ui.wear.settings.SettingsAdapter; +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; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import java.util.ArrayList; import java.util.List; -public final class AppPermissionsFragmentWear extends TitledSettingsFragment { +public final class AppPermissionsFragmentWear extends PreferenceFragment { + private static final String LOG_TAG = "AppPermFragWear"; - private static final String LOG_TAG = "ManagePermsFragment"; - - private static final int WARNING_CONFIRMATION_REQUEST = 252; - private List<AppPermissionGroup> mToggledGroups; - private AppPermissions mAppPermissions; - private PermissionsSettingsAdapter mAdapter; - - private boolean mHasConfirmedRevoke; + private static final String KEY_NO_PERMISSIONS = "no_permissions"; public static AppPermissionsFragmentWear newInstance(String packageName) { return setPackageName(new AppPermissionsFragmentWear(), packageName); @@ -64,17 +65,53 @@ public final class AppPermissionsFragmentWear extends TitledSettingsFragment { return fragment; } + private PackageManager mPackageManager; + private List<AppPermissionGroup> mToggledGroups; + private AppPermissions mAppPermissions; + + private boolean mHasConfirmedRevoke; + + /** + * Provides click behavior for disabled preferences. + * We can't use {@link PreferenceFragment#onPreferenceTreeClick}, as the base + * {@link SwitchPreference} doesn't delegate to that method if the preference is disabled. + */ + private static class PermissionSwitchPreference extends SwitchPreference { + + private final Activity mActivity; + + public PermissionSwitchPreference(Activity activity) { + super(activity); + this.mActivity = activity; + } + + @Override + public void performClick(PreferenceScreen preferenceScreen) { + super.performClick(preferenceScreen); + if (!isEnabled()) { + // If setting the permission is disabled, it must have been locked + // by the device or profile owner. So get that info and pass it to + // the support details dialog. + EnforcedAdmin deviceOrProfileOwner = RestrictedLockUtils.getProfileOrDeviceOwner( + mActivity, UserHandle.myUserId()); + RestrictedLockUtils.sendShowAdminSupportDetailsIntent( + mActivity, deviceOrProfileOwner); + } + } + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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; @@ -86,172 +123,158 @@ public final class AppPermissionsFragmentWear extends TitledSettingsFragment { return; } - mAppPermissions = new AppPermissions(activity, packageInfo, null, true, new Runnable() { - @Override - public void run() { - getActivity().finish(); - } - }); - - mAdapter = new PermissionsSettingsAdapter(getContext()); + mAppPermissions = new AppPermissions( + activity, packageInfo, null, true, () -> getActivity().finish()); + addPreferencesFromResource(R.xml.watch_permissions); initializePermissionGroupList(); } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.settings, container, false); - } - - @Override public void onResume() { super.onResume(); mAppPermissions.refresh(); // Also refresh the UI - final int count = mAdapter.getItemCount(); - for (int i = 0; i < count; ++i) { - updatePermissionGroupSetting(i); + for (final AppPermissionGroup group : mAppPermissions.getPermissionGroups()) { + if (Utils.areGroupPermissionsIndividuallyControlled(getContext(), group.getName())) { + for (PermissionInfo perm : getPermissionInfosFromGroup(group)) { + setPreferenceCheckedIfPresent(perm.name, + group.areRuntimePermissionsGranted(new String[]{ perm.name })); + } + } else { + setPreferenceCheckedIfPresent(group.getName(), group.areRuntimePermissionsGranted()); + } } } @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - if (mAppPermissions != null) { - initializeLayout(mAdapter); - mHeader.setText(R.string.app_permissions); - mDetails.setText(R.string.no_permissions); - if (mAdapter.getItemCount() == 0) { - mDetails.setVisibility(View.VISIBLE); - mWheel.setVisibility(View.GONE); - } else { - mDetails.setVisibility(View.GONE); - mWheel.setVisibility(View.VISIBLE); - } - } + public void onPause() { + super.onPause(); + logAndClearToggledGroups(); } private void initializePermissionGroupList() { final String packageName = mAppPermissions.getPackageInfo().packageName; List<AppPermissionGroup> groups = mAppPermissions.getPermissionGroups(); - List<SettingsAdapter.Setting<AppPermissionGroup>> nonSystemGroups = new ArrayList<>(); + List<SwitchPreference> nonSystemPreferences = new ArrayList<>(); - final int count = groups.size(); - for (int i = 0; i < count; ++i) { - final AppPermissionGroup group = groups.get(i); + if (!groups.isEmpty()) { + getPreferenceScreen().removePreference(findPreference(KEY_NO_PERMISSIONS)); + } + + for (final AppPermissionGroup group : groups) { if (!Utils.shouldShowPermission(group, packageName)) { continue; } boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); - SettingsAdapter.Setting<AppPermissionGroup> setting = - new SettingsAdapter.Setting<AppPermissionGroup>( - group.getLabel(), - getPermissionGroupIcon(group), - i); - setting.data = group; - - // The UI shows System settings first, then non-system settings - if (isPlatform) { - mAdapter.addSetting(setting); + 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 { - nonSystemGroups.add(setting); + final SwitchPreference pref = createSwitchPreferenceForGroup(group); + showOrAddToNonSystemPreferences(pref, nonSystemPreferences, isPlatform); } } // Now add the non-system settings to the end of the list - final int nonSystemCount = nonSystemGroups.size(); - for (int i = 0; i < nonSystemCount; ++i) { - final SettingsAdapter.Setting<AppPermissionGroup> setting = nonSystemGroups.get(i); - mAdapter.addSetting(setting); + for (SwitchPreference nonSystemPreference : nonSystemPreferences) { + getPreferenceScreen().addPreference(nonSystemPreference); } } - @Override - public void onPause() { - super.onPause(); - logAndClearToggledGroups(); - } - - @Override - public void onClick(WearableListView.ViewHolder view) { - final int index = view.getPosition(); - SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index); - final AppPermissionGroup group = setting.data; - - if (group == null) { - Log.e(LOG_TAG, "Error: AppPermissionGroup is null"); - return; - } - - // The way WearableListView is designed, there is no way to avoid this click handler - // Since the policy is fixed, ignore the click as the user is not able to change the state - // of this permission group - if (group.isPolicyFixed()) { - return; - } - - addToggledGroup(group); - - if (LocationUtils.isLocationGroupAndProvider(group.getName(), group.getApp().packageName)) { - LocationUtils.showLocationDialog(getContext(), mAppPermissions.getAppLabel()); - return; + private void showOrAddToNonSystemPreferences(SwitchPreference pref, + List<SwitchPreference> nonSystemPreferences, // Mutate + boolean isPlatform) { + // The UI shows System settings first, then non-system settings + if (isPlatform) { + getPreferenceScreen().addPreference(pref); + } else { + nonSystemPreferences.add(pref); } + } - if (!group.areRuntimePermissionsGranted()) { - group.grantRuntimePermissions(false); - } else { - final boolean grantedByDefault = group.hasGrantedByDefaultPermission(); - if (grantedByDefault || (!group.hasRuntimePermission() && !mHasConfirmedRevoke)) { - Intent intent = new Intent(getActivity(), WarningConfirmationActivity.class); - intent.putExtra(WarningConfirmationActivity.EXTRA_WARNING_MESSAGE, - getString(grantedByDefault ? - R.string.system_warning : R.string.old_sdk_deny_warning)); - intent.putExtra(WarningConfirmationActivity.EXTRA_INDEX, index); - startActivityForResult(intent, WARNING_CONFIRMATION_REQUEST); + 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 { - group.revokeRuntimePermissions(false); + group.revokeRuntimePermissions(false, new String[]{ perm.name }); } - } - - updatePermissionGroupSetting(index); + return true; + }); + return pref; } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == WARNING_CONFIRMATION_REQUEST) { - if (resultCode == Activity.RESULT_OK) { - int index = data.getIntExtra(WarningConfirmationActivity.EXTRA_INDEX, -1); - if (index == -1) { - Log.e(LOG_TAG, "Warning confirmation request came back with no index."); - return; + 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; } - SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index); - final AppPermissionGroup group = setting.data; - group.revokeRuntimePermissions(false); - if (!group.hasGrantedByDefaultPermission()) { - mHasConfirmedRevoke = true; + 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); + } } - updatePermissionGroupSetting(index); - } - } else { - super.onActivityResult(requestCode, resultCode, data); + return true; + }); } + return pref; } - private void updatePermissionGroupSetting(int index) { - SettingsAdapter.Setting<AppPermissionGroup> setting = mAdapter.get(index); - AppPermissionGroup group = setting.data; - mAdapter.updateSetting( - index, - group.getLabel(), - getPermissionGroupIcon(group), - group); + private void setPermission(AppPermissionGroup group, SwitchPreference pref, boolean grant) { + if (grant) { + group.grantRuntimePermissions(false); + } else { + group.revokeRuntimePermissions(false); + } + addToggledGroup(group); + pref.setChecked(grant); } private void addToggledGroup(AppPermissionGroup group) { @@ -274,53 +297,22 @@ public final class AppPermissionsFragmentWear extends TitledSettingsFragment { } } - private int getPermissionGroupIcon(AppPermissionGroup group) { - String groupName = group.getName(); - boolean isEnabled = group.areRuntimePermissionsGranted(); - int resId; - - switch (groupName) { - case Manifest.permission_group.CALENDAR: - resId = isEnabled ? R.drawable.ic_permission_calendar - : R.drawable.ic_permission_calendardisable; - break; - case Manifest.permission_group.CAMERA: - resId = isEnabled ? R.drawable.ic_permission_camera - : R.drawable.ic_permission_cameradisable; - break; - case Manifest.permission_group.CONTACTS: - resId = isEnabled ? R.drawable.ic_permission_contact - : R.drawable.ic_permission_contactdisable; - break; - case Manifest.permission_group.LOCATION: - resId = isEnabled ? R.drawable.ic_permission_location - : R.drawable.ic_permission_locationdisable; - break; - case Manifest.permission_group.MICROPHONE: - resId = isEnabled ? R.drawable.ic_permission_mic - : R.drawable.ic_permission_micdisable; - break; - case Manifest.permission_group.PHONE: - resId = isEnabled ? R.drawable.ic_permission_call - : R.drawable.ic_permission_calldisable; - break; - case Manifest.permission_group.SENSORS: - resId = isEnabled ? R.drawable.ic_permission_sensor - : R.drawable.ic_permission_sensordisable; - break; - case Manifest.permission_group.SMS: - resId = isEnabled ? R.drawable.ic_permission_sms - : R.drawable.ic_permission_smsdisable; - break; - case Manifest.permission_group.STORAGE: - resId = isEnabled ? R.drawable.ic_permission_storage - : R.drawable.ic_permission_storagedisable; - break; - default: - resId = isEnabled ? R.drawable.ic_permission_shield - : R.drawable.ic_permission_shielddisable; + private List<PermissionInfo> getPermissionInfosFromGroup(AppPermissionGroup group) { + ArrayList<PermissionInfo> 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; + } - return resId; + private void setPreferenceCheckedIfPresent(String preferenceKey, boolean checked) { + Preference pref = findPreference(preferenceKey); + if (pref instanceof SwitchPreference) { + ((SwitchPreference) pref).setChecked(checked); + } } } |