diff options
author | 2019-11-21 17:06:04 +0000 | |
---|---|---|
committer | 2019-11-21 17:06:04 +0000 | |
commit | 9a660c0256530947c1948f956da48613db51cd39 (patch) | |
tree | 883982c3264f0d807c72fc090416113a7fa067df | |
parent | 69cd04e37b49c39d3999b41b935af40bf4d5b4c5 (diff) | |
parent | ef775a11b28a499ef1d474e697caa319f06f0591 (diff) |
Merge "Add "Ask" radio button in AppPermission page"
6 files changed, 86 insertions, 30 deletions
diff --git a/PermissionController/res/layout/app_permission.xml b/PermissionController/res/layout/app_permission.xml index 2795a3420..a8306cb2d 100644 --- a/PermissionController/res/layout/app_permission.xml +++ b/PermissionController/res/layout/app_permission.xml @@ -62,6 +62,11 @@ style="@style/AppPermissionRadioButton" /> <RadioButton + android:id="@+id/ask_radio_button" + android:text="@string/app_permission_button_ask" + style="@style/AppPermissionRadioButton" /> + + <RadioButton android:id="@+id/deny_radio_button" android:text="@string/app_permission_button_deny" style="@style/AppPermissionRadioButton" /> diff --git a/PermissionController/res/values/strings.xml b/PermissionController/res/values/strings.xml index d0fcc7bb6..e28972ac4 100644 --- a/PermissionController/res/values/strings.xml +++ b/PermissionController/res/values/strings.xml @@ -403,7 +403,10 @@ <!-- Title for the dialog button to allow a permission grant only when the app is in the foreground. [CHAR LIMIT=60] --> <string name="app_permission_button_allow_foreground">Allow only while using the app</string> - <!-- Title for the dialog button to deny a permission grant. [CHAR LIMIT=60] --> + <!-- Title for the dialog button to require an app to ask for a permission next time they need it. [CHAR LIMIT=60] --> + <string name="app_permission_button_ask">Ask every time</string> + + <!-- Title for the dialog button to deny with prejudice a permission grant. [CHAR LIMIT=60] --> <string name="app_permission_button_deny">Deny</string> <!-- Title for app permission [CHAR LIMIT=30] --> diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt index 9c3bb8a23..057f59991 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt @@ -92,4 +92,9 @@ data class LightAppPermGroup( val isBackgroundGranted = permissions.any { backgroundPermNames.contains(it.key) && it.value.grantedIncludingAppOp } + + /** + * Whether this App Permission Group's permissions are fixed by the user + */ + val isUserFixed = permissions.any { it.value.isUserFixed } }
\ No newline at end of file diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt index d8224af67..cce232c83 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt @@ -43,4 +43,6 @@ data class LightPermission( val isPolicyFixed = flags and PackageManager.FLAG_PERMISSION_POLICY_FIXED != 0 /** Whether this permission is fixed by the system */ val isSystemFixed = flags and PackageManager.FLAG_PERMISSION_SYSTEM_FIXED != 0 + /** Whether this permission is fixed by the system */ + val isUserFixed = flags and PackageManager.FLAG_PERMISSION_USER_FIXED != 0 }
\ No newline at end of file diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java index 3eaad5b76..f751f89e1 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java @@ -69,6 +69,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { private @NonNull RadioButton mAlwaysButton; private @NonNull RadioButton mForegroundOnlyButton; + private @NonNull RadioButton mAskButton; private @NonNull RadioButton mDenyButton; private @NonNull View mDivider; private @NonNull ViewGroup mWidgetFrame; @@ -177,6 +178,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { mAlwaysButton = root.requireViewById(R.id.allow_radio_button); mForegroundOnlyButton = root.requireViewById(R.id.foreground_only_radio_button); + mAskButton = root.requireViewById(R.id.ask_radio_button); mDenyButton = root.requireViewById(R.id.deny_radio_button); mDivider = root.requireViewById(R.id.two_target_divider); mWidgetFrame = root.requireViewById(R.id.widget_frame); @@ -217,25 +219,27 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { } mAlwaysButton.setOnClickListener((v) -> { - mViewModel.requestChange(true, this, ChangeTarget.CHANGE_BOTH); - getActivity().setResult(Activity.RESULT_OK, new Intent().putExtra( - AppPermissionActivity.EXTRA_RESULT_PERMISSION_INTERACTED, mPermGroupName)); + mViewModel.requestChange(true, false, this, ChangeTarget.CHANGE_BOTH); + setResult(); }); mForegroundOnlyButton.setOnClickListener((v) -> { - mViewModel.requestChange(true, this, ChangeTarget.CHANGE_FOREGROUND); - mViewModel.requestChange(false, this, ChangeTarget.CHANGE_BACKGROUND); - getActivity().setResult(Activity.RESULT_OK, new Intent().putExtra( - AppPermissionActivity.EXTRA_RESULT_PERMISSION_INTERACTED, mPermGroupName)); + mViewModel.requestChange(true, false, this, ChangeTarget.CHANGE_FOREGROUND); + mViewModel.requestChange(false, false, this, ChangeTarget.CHANGE_BACKGROUND); + setResult(); + }); + mAskButton.setOnClickListener((v) -> { + mViewModel.requestChange(false, false, this, ChangeTarget.CHANGE_BOTH); + setResult(); }); mDenyButton.setOnClickListener((v) -> { - mViewModel.requestChange(false, this, ChangeTarget.CHANGE_BOTH); - getActivity().setResult(Activity.RESULT_OK, new Intent().putExtra( - AppPermissionActivity.EXTRA_RESULT_PERMISSION_INTERACTED, mPermGroupName)); + mViewModel.requestChange(false, true, this, ChangeTarget.CHANGE_BOTH); + setResult(); }); setButtonState(mAlwaysButton, states.get(0), true); setButtonState(mForegroundOnlyButton, states.get(1), false); - setButtonState(mDenyButton, states.get(2), false); + setButtonState(mAskButton, states.get(2), false); + setButtonState(mDenyButton, states.get(3), false); if (mForegroundOnlyButton.getVisibility() == View.GONE) { mAlwaysButton.setText(getContext().getString(R.string.app_permission_button_allow)); @@ -246,6 +250,11 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { } + private void setResult() { + getActivity().setResult(Activity.RESULT_OK, new Intent().putExtra( + AppPermissionActivity.EXTRA_RESULT_PERMISSION_INTERACTED, mPermGroupName)); + } + private void setButtonState(RadioButton button, AppPermissionViewModel.ButtonState state, boolean requestGrant) { button.setChecked(state.isChecked()); @@ -253,8 +262,11 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { int visible = state.isShown() ? View.VISIBLE : View.GONE; button.setVisibility(visible); if (state.getCustomTarget() != null) { - button.setOnClickListener((v) -> mViewModel.requestChange(requestGrant, this, - state.getCustomTarget())); + button.setOnClickListener((v) -> { + mViewModel.requestChange(requestGrant, button == mDenyButton, this, + state.getCustomTarget()); + setResult(); + }); } } @@ -332,12 +344,15 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { * * @param changeTarget Whether background or foreground should be changed * @param messageId The Id of the string message to show + * @param userFixed Whether the permission state should be user fixed */ - void showDefaultDenyDialog(ChangeTarget changeTarget, @StringRes int messageId) { + void showDefaultDenyDialog(ChangeTarget changeTarget, @StringRes int messageId, + boolean userFixed) { Bundle args = new Bundle(); args.putInt(DefaultDenyDialog.MSG, messageId); args.putSerializable(DefaultDenyDialog.CHANGE_TARGET, changeTarget); + args.putBoolean(DefaultDenyDialog.USER_FIXED, userFixed); DefaultDenyDialog defaultDenyDialog = new DefaultDenyDialog(); defaultDenyDialog.setCancelable(true); @@ -350,13 +365,17 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { * A dialog warning the user that she/he is about to deny a permission that was granted by * default. * - * @see #showDefaultDenyDialog(ChangeTarget, int) + * @see #showDefaultDenyDialog(ChangeTarget, int, boolean) */ public static class DefaultDenyDialog extends DialogFragment { static final String MSG = DefaultDenyDialog.class.getName() + ".arg.msg"; static final String CHANGE_TARGET = DefaultDenyDialog.class.getName() + ".arg.changeTarget"; private static final String KEY = DefaultDenyDialog.class.getName() + ".arg.key"; + static final String USER_FIXED = DefaultDenyDialog.class.getName() + + ".arg.userFixed"; + + private boolean mFixed; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { @@ -368,7 +387,8 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { .setPositiveButton(R.string.grant_dialog_button_deny_anyway, (DialogInterface dialog, int which) -> fragment.mViewModel.onDenyAnyWay((ChangeTarget) - getArguments().getSerializable(CHANGE_TARGET))); + getArguments().getSerializable(CHANGE_TARGET), + getArguments().getBoolean(USER_FIXED, false))); Dialog d = b.create(); d.setCanceledOnTouchOutside(true); return d; diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt index eee6e45af..92a191a6c 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt @@ -138,6 +138,7 @@ class AppPermissionViewModel( val allowedState = ButtonState() val foregroundState = ButtonState() + val askState = ButtonState() val deniedState = ButtonState() if (group.isForegroundGranted) { @@ -147,11 +148,16 @@ class AppPermissionViewModel( foregroundState.isChecked = true } } else { - deniedState.isChecked = true + if (group.isUserFixed || group.isPolicyFullyFixed || group.isSystemFixed) { + deniedState.isChecked = true + } else { + askState.isChecked = true + } } if (group.hasPermWithBackground && !group.hasBackgroundPerms) { allowedState.isShown = false + askState.customTarget = ChangeTarget.CHANGE_FOREGROUND deniedState.customTarget = ChangeTarget.CHANGE_FOREGROUND } else if (!group.hasPermWithBackground) { foregroundState.isShown = false @@ -161,6 +167,7 @@ class AppPermissionViewModel( !group.isForegroundGranted)) { allowedState.isEnabled = false foregroundState.isEnabled = false + askState.isEnabled = false deniedState.isEnabled = false val detailId = getDetailResIdForFixedByPolicyPermissionGroup(group, @@ -169,13 +176,13 @@ class AppPermissionViewModel( detailResIdLiveData.value = detailId to null } - value = listOf(allowedState, foregroundState, deniedState) + value = listOf(allowedState, foregroundState, askState, deniedState) showAdminSupportLiveData.value = admin return } else if (Utils.areGroupPermissionsIndividuallyControlled(app, permGroupName)) { val detailId = getIndividualPermissionDetailResId(group) detailResIdLiveData.value = detailId.first to detailId.second - value = listOf(allowedState, foregroundState, deniedState) + value = listOf(allowedState, foregroundState, askState, deniedState) return } @@ -211,7 +218,7 @@ class AppPermissionViewModel( } } detailResIdLiveData.value = null - value = listOf(allowedState, foregroundState, deniedState) + value = listOf(allowedState, foregroundState, askState, deniedState) } override fun onActive() { @@ -297,6 +304,7 @@ class AppPermissionViewModel( */ fun requestChange( requestGrant: Boolean, + userFixed: Boolean, fragment: AppPermissionFragment, changeTarget: ChangeTarget ) { @@ -316,7 +324,7 @@ class AppPermissionViewModel( val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() - group.grantRuntimePermissions(false) + group.grantRuntimePermissions(userFixed) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) @@ -325,7 +333,7 @@ class AppPermissionViewModel( if (shouldChangeBackground && group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() - group.backgroundPermissions.grantRuntimePermissions(false) + group.backgroundPermissions.grantRuntimePermissions(userFixed) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) @@ -357,26 +365,39 @@ class AppPermissionViewModel( } if (showDefaultDenyDialog && !hasConfirmedRevoke && showGrantedByDefaultWarning) { - fragment.showDefaultDenyDialog(changeTarget, R.string.system_warning) + fragment.showDefaultDenyDialog(changeTarget, R.string.system_warning, userFixed) return } else if (showDefaultDenyDialog && !hasConfirmedRevoke) { - fragment.showDefaultDenyDialog(changeTarget, R.string.old_sdk_deny_warning) + fragment.showDefaultDenyDialog(changeTarget, R.string.old_sdk_deny_warning, + userFixed) return } else { val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground && group.areRuntimePermissionsGranted()) { - group.revokeRuntimePermissions(false) + group.revokeRuntimePermissions(userFixed) SafetyNetLogger.logPermissionToggled(group) } if (shouldChangeBackground && group.backgroundPermissions != null && group.backgroundPermissions.areRuntimePermissionsGranted()) { - group.backgroundPermissions.revokeRuntimePermissions(false) + group.backgroundPermissions.revokeRuntimePermissions(userFixed) SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) } + if (userFixed && !group.isUserFixed) { + group.revokeRuntimePermissions(true) + if (group.backgroundPermissions != null) { + group.backgroundPermissions.revokeRuntimePermissions(true) + } + } + if (!userFixed && group.isUserFixed) { + group.revokeRuntimePermissions(false) + if (group.backgroundPermissions != null) { + group.backgroundPermissions.revokeRuntimePermissions(false) + } + } logPermissionChanges(stateBefore) } } @@ -389,13 +410,13 @@ class AppPermissionViewModel( * @param changeTarget whether to change foreground, background, or both. * */ - fun onDenyAnyWay(changeTarget: ChangeTarget) { + fun onDenyAnyWay(changeTarget: ChangeTarget, userFixed: Boolean) { val group = appPermissionGroup ?: return var hasDefaultPermissions = false val stateBefore = createPermissionSnapshot() if (changeTarget andValue ChangeTarget.CHANGE_FOREGROUND != 0) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() - group.revokeRuntimePermissions(false) + group.revokeRuntimePermissions(userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) @@ -406,7 +427,7 @@ class AppPermissionViewModel( group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() - group.backgroundPermissions.revokeRuntimePermissions(false) + group.backgroundPermissions.revokeRuntimePermissions(userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) |