summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Severson <evanseverson@google.com> 2019-11-21 17:06:04 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-11-21 17:06:04 +0000
commit9a660c0256530947c1948f956da48613db51cd39 (patch)
tree883982c3264f0d807c72fc090416113a7fa067df
parent69cd04e37b49c39d3999b41b935af40bf4d5b4c5 (diff)
parentef775a11b28a499ef1d474e697caa319f06f0591 (diff)
Merge "Add "Ask" radio button in AppPermission page"
-rw-r--r--PermissionController/res/layout/app_permission.xml5
-rw-r--r--PermissionController/res/values/strings.xml5
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt5
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java52
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt47
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)