summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nate Myren <ntmyren@google.com> 2024-01-04 13:14:02 -0800
committer Nate Myren <ntmyren@google.com> 2024-01-09 20:31:23 +0000
commit0c01d53e01fdee29ab71b8340778ba9abfe915e4 (patch)
treed8b2502aed7c038ba12e573514f3c2d7ae86a35d
parent8ec80176993a15e3c5c41389d1ea1285665b567b (diff)
Save photo picker callback state on activity destroy
When the activity is destroyed, we should remember that we were showing the photo picker. Otherwise, the dialog won't close when the photo picker is closed. Test: manual Relnote: fix UI issue with permission grant dialog Fixes: 308830728 Change-Id: Ibbf5466747e999f19e790c3b981976ff6369bb9a Merged-In: Ibbf5466747e999f19e790c3b981976ff6369bb9a
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java16
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt178
2 files changed, 121 insertions, 73 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
index a6e521138..53f8fe712 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
@@ -66,7 +66,6 @@ import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
-import androidx.core.util.Consumer;
import androidx.core.util.Preconditions;
import com.android.modules.utils.build.SdkLevel;
@@ -417,7 +416,7 @@ public class GrantPermissionsActivity extends SettingsActivity
mViewModel.sendDirectlyToSettings(top, info.getGroupName());
return;
} else if (info.getOpenPhotoPicker()) {
- mViewModel.openPhotoPicker(top, GRANTED_USER_SELECTED);
+ mViewModel.openPhotoPicker(top);
return;
}
@@ -604,16 +603,14 @@ public class GrantPermissionsActivity extends SettingsActivity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- Consumer<Intent> callback = mViewModel.getActivityResultCallback();
- if (callback == null || (requestCode != APP_PERMISSION_REQUEST_CODE
- && requestCode != PHOTO_PICKER_REQUEST_CODE)) {
+ if (requestCode != APP_PERMISSION_REQUEST_CODE
+ && requestCode != PHOTO_PICKER_REQUEST_CODE) {
return;
}
if (requestCode == PHOTO_PICKER_REQUEST_CODE) {
data = new Intent("").putExtra(INTENT_PHOTOS_SELECTED, resultCode == RESULT_OK);
}
- callback.accept(data);
- mViewModel.setActivityResultCallback(null);
+ mViewModel.handleCallback(data, requestCode);
}
@Override
@@ -633,11 +630,10 @@ public class GrantPermissionsActivity extends SettingsActivity
mPreMergeShownGroupName = null;
}
- if (Objects.equals(READ_MEDIA_VISUAL, name)
- && result == GrantPermissionsViewHandler.GRANTED_USER_SELECTED) {
+ if (Objects.equals(READ_MEDIA_VISUAL, name) && result == GRANTED_USER_SELECTED) {
// Only the top activity can receive activity results
Activity top = mFollowerActivities.isEmpty() ? this : mFollowerActivities.get(0);
- mViewModel.openPhotoPicker(top, result);
+ mViewModel.openPhotoPicker(top);
logGrantPermissionActivityButtons(name, affectedForegroundPermissions, result);
return;
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
index 3f19db475..d9fd7f2ea 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
@@ -186,6 +186,18 @@ class GrantPermissionsViewModel(
private var appPermGroupLiveDatas = mutableMapOf<String, LightAppPermGroupLiveData>()
+ internal data class ResultCallback(val consumer: Consumer<Intent>, val requestCode: Int)
+
+ private var activityResultCallback: ResultCallback? = null
+
+ init {
+ if (storedState?.containsKey(SAVED_REQUEST_CODE_KEY) == true) {
+ if (storedState.getInt(SAVED_REQUEST_CODE_KEY) == PHOTO_PICKER_REQUEST_CODE) {
+ setPhotoPickerCallback()
+ }
+ }
+ }
+
/**
* A class which represents a correctly requested permission group, and the buttons and messages
* which should be shown with it.
@@ -202,8 +214,6 @@ class GrantPermissionsViewModel(
val groupName = groupInfo.name
}
- var activityResultCallback: Consumer<Intent>? = null
-
/** A LiveData which holds a list of the currently pending RequestInfos */
val requestInfosLiveData =
object : SmartUpdateMediatorLiveData<List<RequestInfo>>() {
@@ -1494,7 +1504,9 @@ class GrantPermissionsViewModel(
Log.v(
LOG_TAG,
"Permission grant result requestId=$sessionId " +
- "callingUid=${packageInfo.uid} callingPackage=$packageName permission=$permission " +
+ "callingUid=${packageInfo.uid} " +
+ "callingPackage=$packageName " +
+ "permission=$permission " +
"isImplicit=$isImplicit result=$result " +
"isPermissionRationaleShown=$isPermissionRationaleShown"
)
@@ -1522,6 +1534,7 @@ class GrantPermissionsViewModel(
val (groupName, isBackground) = groupKey
outState.putInt(getInstanceStateKey(groupName, isBackground), groupState.state)
}
+ activityResultCallback?.let { outState.putInt(SAVED_REQUEST_CODE_KEY, it.requestCode) }
}
/**
@@ -1547,12 +1560,25 @@ class GrantPermissionsViewModel(
}
}
+ fun handleCallback(data: Intent?, requestCode: Int) {
+ val currCallback = activityResultCallback
+ if (currCallback == null || requestCode != currCallback.requestCode) {
+ return
+ }
+ currCallback.consumer.accept(data)
+ activityResultCallback = null
+ }
+
fun handleHealthConnectPermissions(activity: Activity) {
if (activityResultCallback == null) {
- activityResultCallback = Consumer {
- permGroupsToSkip.add(HEALTH_PERMISSION_GROUP)
- requestInfosLiveData.update()
- }
+ activityResultCallback =
+ ResultCallback(
+ {
+ permGroupsToSkip.add(HEALTH_PERMISSION_GROUP)
+ requestInfosLiveData.update()
+ },
+ APP_PERMISSION_REQUEST_CODE
+ )
val healthPermissions =
unfilteredAffectedPermissions
.filter { permission -> isHealthPermission(activity, permission) }
@@ -1575,55 +1601,72 @@ class GrantPermissionsViewModel(
*/
fun sendDirectlyToSettings(activity: Activity, groupName: String) {
if (activityResultCallback == null) {
- activityResultCallback = Consumer { data ->
- if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) {
- // User didn't interact, count against rate limit
- val group =
- groupStates[groupName to false]?.group
- ?: groupStates[groupName to true]?.group ?: return@Consumer
- if (group.background.isUserSet) {
- KotlinUtils.setGroupFlags(
- app,
- group,
- FLAG_PERMISSION_USER_FIXED to true,
- filterPermissions = group.backgroundPermNames
- )
- } else {
- KotlinUtils.setGroupFlags(
- app,
- group,
- FLAG_PERMISSION_USER_SET to true,
- filterPermissions = group.backgroundPermNames
- )
- }
- }
+ activityResultCallback =
+ ResultCallback(
+ Consumer { data ->
+ if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) {
+ // User didn't interact, count against rate limit
+ val group =
+ groupStates[groupName to false]?.group
+ ?: groupStates[groupName to true]?.group
+ ?: return@Consumer
+ if (group.background.isUserSet) {
+ KotlinUtils.setGroupFlags(
+ app,
+ group,
+ FLAG_PERMISSION_USER_FIXED to true,
+ filterPermissions = group.backgroundPermNames
+ )
+ } else {
+ KotlinUtils.setGroupFlags(
+ app,
+ group,
+ FLAG_PERMISSION_USER_SET to true,
+ filterPermissions = group.backgroundPermNames
+ )
+ }
+ }
- permGroupsToSkip.add(groupName)
- // Update our liveData now that there is a new skipped group
- requestInfosLiveData.update()
- }
+ permGroupsToSkip.add(groupName)
+ // Update our liveData now that there is a new skipped group
+ requestInfosLiveData.update()
+ },
+ APP_PERMISSION_REQUEST_CODE
+ )
startAppPermissionFragment(activity, groupName)
}
}
- fun openPhotoPicker(activity: Activity, result: Int) {
+ fun openPhotoPicker(activity: Activity) {
if (activityResultCallback != null) {
return
}
if (groupStates[READ_MEDIA_VISUAL to false]?.affectedPermissions == null) {
return
}
- activityResultCallback = Consumer { data ->
- val anySelected = data?.getBooleanExtra(INTENT_PHOTOS_SELECTED, true) == true
- if (anySelected) {
- onPermissionGrantResult(READ_MEDIA_VISUAL, null, result)
- } else {
- onPermissionGrantResult(READ_MEDIA_VISUAL, null, CANCELED)
- }
- requestInfosLiveData.update()
- }
- openPhotoPickerForApp(activity, packageInfo.uid, unfilteredAffectedPermissions,
- PHOTO_PICKER_REQUEST_CODE)
+ setPhotoPickerCallback()
+ openPhotoPickerForApp(
+ activity,
+ packageInfo.uid,
+ unfilteredAffectedPermissions,
+ PHOTO_PICKER_REQUEST_CODE
+ )
+ }
+
+ private fun setPhotoPickerCallback() {
+ activityResultCallback =
+ ResultCallback(
+ { data ->
+ val anySelected = data?.getBooleanExtra(INTENT_PHOTOS_SELECTED, true) == true
+ if (anySelected) {
+ onPermissionGrantResult(READ_MEDIA_VISUAL, null, GRANTED_USER_SELECTED)
+ } else {
+ onPermissionGrantResult(READ_MEDIA_VISUAL, null, CANCELED)
+ }
+ requestInfosLiveData.update()
+ },
+ PHOTO_PICKER_REQUEST_CODE
+ )
}
/**
@@ -1634,15 +1677,19 @@ class GrantPermissionsViewModel(
*/
fun sendToSettingsFromLink(activity: Activity, groupName: String) {
startAppPermissionFragment(activity, groupName)
- activityResultCallback = Consumer { data ->
- val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED)
- if (returnGroupName != null) {
- permGroupsToSkip.add(returnGroupName)
- val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1)
- logSettingsInteraction(returnGroupName, result)
- requestInfosLiveData.update()
- }
- }
+ activityResultCallback =
+ ResultCallback(
+ { data ->
+ val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED)
+ if (returnGroupName != null) {
+ permGroupsToSkip.add(returnGroupName)
+ val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1)
+ logSettingsInteraction(returnGroupName, result)
+ requestInfosLiveData.update()
+ }
+ },
+ APP_PERMISSION_REQUEST_CODE
+ )
}
/**
@@ -1662,15 +1709,19 @@ class GrantPermissionsViewModel(
putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName)
putExtra(Constants.EXTRA_SESSION_ID, sessionId)
}
- activityResultCallback = Consumer { data ->
- val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED)
- if (returnGroupName != null) {
- permGroupsToSkip.add(returnGroupName)
- val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED)
- logSettingsInteraction(returnGroupName, result)
- requestInfosLiveData.update()
- }
- }
+ activityResultCallback =
+ ResultCallback(
+ { data ->
+ val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED)
+ if (returnGroupName != null) {
+ permGroupsToSkip.add(returnGroupName)
+ val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED)
+ logSettingsInteraction(returnGroupName, result)
+ requestInfosLiveData.update()
+ }
+ },
+ APP_PERMISSION_REQUEST_CODE
+ )
activity.startActivityForResult(intent, APP_PERMISSION_REQUEST_CODE)
}
@@ -1836,6 +1887,7 @@ class GrantPermissionsViewModel(
companion object {
const val APP_PERMISSION_REQUEST_CODE = 1
const val PHOTO_PICKER_REQUEST_CODE = 2
+ const val SAVED_REQUEST_CODE_KEY = "saved_request_code"
private const val STATE_UNKNOWN = 0
private const val STATE_ALLOWED = 1
private const val STATE_DENIED = 2