diff options
3 files changed, 71 insertions, 134 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java index ddcdf1319..61ad86a72 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java @@ -67,6 +67,7 @@ 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; @@ -487,7 +488,7 @@ public class GrantPermissionsActivity extends SettingsActivity mViewModel.sendDirectlyToSettings(top, info.getGroupName()); return; } else if (info.getPrompt() == Prompt.NO_UI_PHOTO_PICKER_REDIRECT) { - mViewModel.openPhotoPicker(top); + mViewModel.openPhotoPicker(top, GRANTED_USER_SELECTED); return; } else if (info.getPrompt() == Prompt.NO_UI_FILTER_THIS_GROUP) { // Filtered permissions should be removed from the requested permissions list entirely, @@ -738,14 +739,16 @@ public class GrantPermissionsActivity extends SettingsActivity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode != APP_PERMISSION_REQUEST_CODE - && requestCode != PHOTO_PICKER_REQUEST_CODE) { + Consumer<Intent> callback = mViewModel.getActivityResultCallback(); + if (callback == null || (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); } - mViewModel.handleCallback(data, requestCode); + callback.accept(data); + mViewModel.setActivityResultCallback(null); } @Override @@ -765,10 +768,11 @@ public class GrantPermissionsActivity extends SettingsActivity mPreMergeShownGroupName = null; } - if (Objects.equals(READ_MEDIA_VISUAL, name) && result == GRANTED_USER_SELECTED) { + if (Objects.equals(READ_MEDIA_VISUAL, name) + && result == GrantPermissionsViewHandler.GRANTED_USER_SELECTED) { // Only the top activity can receive activity results Activity top = mFollowerActivities.isEmpty() ? this : mFollowerActivities.get(0); - mViewModel.openPhotoPicker(top); + mViewModel.openPhotoPicker(top, result); 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 3786b99bd..d4947694e 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt @@ -171,17 +171,7 @@ 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() - } - } - } + var activityResultCallback: Consumer<Intent>? = null /** * An internal class which represents the state of a current AppPermissionGroup grant request. @@ -1006,9 +996,7 @@ class GrantPermissionsViewModel( Log.i( 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" ) @@ -1035,7 +1023,6 @@ class GrantPermissionsViewModel( for ((groupName, groupState) in groupStates) { outState.putInt(groupName, groupState.state) } - activityResultCallback?.let { outState.putInt(SAVED_REQUEST_CODE_KEY, it.requestCode) } } /** @@ -1061,25 +1048,12 @@ 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 = - ResultCallback( - { - groupStates[HEALTH_PERMISSION_GROUP]?.state = STATE_SKIPPED - requestInfosLiveData.update() - }, - APP_PERMISSION_REQUEST_CODE - ) + activityResultCallback = Consumer { + groupStates[HEALTH_PERMISSION_GROUP]?.state = STATE_SKIPPED + requestInfosLiveData.update() + } val healthPermissions = unfilteredAffectedPermissions .filter { permission -> isHealthPermission(activity, permission) } @@ -1102,47 +1076,51 @@ class GrantPermissionsViewModel( */ fun sendDirectlyToSettings(activity: Activity, groupName: String) { if (activityResultCallback == null) { - activityResultCallback = - ResultCallback( - Consumer { data -> - if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) { - // User didn't interact, count against rate limit - val group = groupStates[groupName]?.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 = Consumer { data -> + if (data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) == null) { + // User didn't interact, count against rate limit + val group = groupStates[groupName]?.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 + ) + } + } - groupStates[groupName]?.state = STATE_SKIPPED - // Update our liveData now that there is a new skipped group - requestInfosLiveData.update() - }, - APP_PERMISSION_REQUEST_CODE - ) + groupStates[groupName]?.state = STATE_SKIPPED + // Update our liveData now that there is a new skipped group + requestInfosLiveData.update() + } startAppPermissionFragment(activity, groupName) } } - fun openPhotoPicker(activity: Activity) { + fun openPhotoPicker(activity: Activity, result: Int) { if (activityResultCallback != null) { return } if (groupStates[READ_MEDIA_VISUAL]?.affectedPermissions == null) { return } - setPhotoPickerCallback() + 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, @@ -1151,22 +1129,6 @@ class GrantPermissionsViewModel( ) } - 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 - ) - } - /** * Send the user to the AppPermissionFragment from a link. Used for Q- apps * @@ -1175,19 +1137,15 @@ class GrantPermissionsViewModel( */ fun sendToSettingsFromLink(activity: Activity, groupName: String) { startAppPermissionFragment(activity, groupName) - activityResultCallback = - ResultCallback( - { data -> - val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) - if (returnGroupName != null) { - groupStates[returnGroupName]?.state = STATE_SKIPPED - val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1) - logSettingsInteraction(returnGroupName, result) - requestInfosLiveData.update() - } - }, - APP_PERMISSION_REQUEST_CODE - ) + activityResultCallback = Consumer { data -> + val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) + if (returnGroupName != null) { + groupStates[returnGroupName]?.state = STATE_SKIPPED + val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, -1) + logSettingsInteraction(returnGroupName, result) + requestInfosLiveData.update() + } + } } /** @@ -1207,19 +1165,15 @@ class GrantPermissionsViewModel( putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName) putExtra(Constants.EXTRA_SESSION_ID, sessionId) } - activityResultCallback = - ResultCallback( - { data -> - val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) - if (returnGroupName != null) { - groupStates[returnGroupName]?.state = STATE_SKIPPED - val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED) - logSettingsInteraction(returnGroupName, result) - requestInfosLiveData.update() - } - }, - APP_PERMISSION_REQUEST_CODE - ) + activityResultCallback = Consumer { data -> + val returnGroupName = data?.getStringExtra(EXTRA_RESULT_PERMISSION_INTERACTED) + if (returnGroupName != null) { + groupStates[returnGroupName]?.state = STATE_SKIPPED + val result = data.getIntExtra(EXTRA_RESULT_PERMISSION_RESULT, CANCELED) + logSettingsInteraction(returnGroupName, result) + requestInfosLiveData.update() + } + } activity.startActivityForResult(intent, APP_PERMISSION_REQUEST_CODE) } @@ -1371,7 +1325,6 @@ 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_GRANTED = 1 private const val STATE_DENIED = 2 diff --git a/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt index 1f1aba1e7..018a6e486 100644 --- a/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt +++ b/tests/cts/permissionui/src/android/permissionui/cts/PhotoPickerPermissionTest.kt @@ -20,8 +20,6 @@ import android.Manifest.permission.ACCESS_MEDIA_LOCATION import android.Manifest.permission.READ_MEDIA_IMAGES import android.Manifest.permission.READ_MEDIA_VIDEO import android.Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED -import android.app.UiAutomation.ROTATION_FREEZE_270 -import android.app.UiAutomation.ROTATION_UNFREEZE import android.content.pm.PackageManager import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME import android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT @@ -468,31 +466,13 @@ class PhotoPickerPermissionTest : BaseUsePermissionTest() { } @Test - fun testDismissAfterActivityRecreatedWithPickerOpen() { - installPackage(APP_APK_PATH_LATEST) - requestAppPermissionsAndAssertResult( - READ_MEDIA_IMAGES to false, - READ_MEDIA_VISUAL_USER_SELECTED to true, - waitForWindowTransition = false - ) { - doAndWaitForWindowTransition { click(By.res(SELECT_BUTTON)) } - clickImageOrVideo() - try { - doAndWaitForWindowTransition { uiAutomation.setRotation(ROTATION_FREEZE_270) } - clickImageOrVideo() - doAndWaitForWindowTransition { clickAllow() } - } finally { - uiAutomation.setRotation(ROTATION_UNFREEZE) - } - } - } - - @Test fun testCanSelectPhotosInSettings() { installPackage(APP_APK_PATH_LATEST) navigateToIndividualPermissionSetting(READ_MEDIA_IMAGES) click(By.res(SELECT_RADIO_BUTTON)) - doAndWaitForWindowTransition { click(By.res(EDIT_PHOTOS_BUTTON)) } + doAndWaitForWindowTransition { + click(By.res(EDIT_PHOTOS_BUTTON)) + } clickImageOrVideo() clickAllow() } |