summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author mrulhania <mrulhania@google.com> 2025-06-09 18:05:20 -0700
committer Kampalus <kampalus@protonmail.ch> 2025-09-18 12:32:32 +0200
commitdee96e95951c951951e552345f6e9e0cc8d57ab7 (patch)
tree91a3db845d053a26794a759121ee8a010ae1b94c
parentfd6db90f998351ae7896543bc08d730ecbbc4f12 (diff)
[SP 2025-09-01] Stop one-time sessions iff when no one-time permission is grantedbanksia-dev
Stoping the session on one of one-time permission revoke termintes the only session running for all one time permission grants. We need to stop the session when no permission is granted as one time. Bug: 419105158 Test: manual Flag: EXEMPT bug fix LOW_COVERAGE_REASON=NON_CODE_ONLY Relnote: security bug fix (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2b7a2c80f69a80163d35f45b5300d400884945a0) Merged-In: I59d6f13e23e326b055e0221da52bb22bd54de5d7 Change-Id: I59d6f13e23e326b055e0221da52bb22bd54de5d7
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/AppPermissionGroup.java29
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt25
2 files changed, 38 insertions, 16 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/AppPermissionGroup.java b/PermissionController/src/com/android/permissioncontroller/permission/model/AppPermissionGroup.java
index 3b2cc7ee0..f6c98da9e 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/model/AppPermissionGroup.java
+++ b/PermissionController/src/com/android/permissioncontroller/permission/model/AppPermissionGroup.java
@@ -23,12 +23,15 @@ import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.MODE_IGNORED;
import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP;
import static com.android.permissioncontroller.permission.utils.Utils.isHealthPermissionUiEnabled;
import android.Manifest;
+import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.Application;
@@ -1662,12 +1665,36 @@ public final class AppPermissionGroup implements Comparable<AppPermissionGroup>
} finally {
Binder.restoreCallingIdentity(token);
}
- } else {
+ } else if (!anyPermsOfPackageOneTimeGranted(getApp())) {
+ // Stop the session only when no permission in the package is granted as one time.
mContext.getSystemService(PermissionManager.class)
.stopOneTimePermissionSession(packageName);
}
}
+ @SuppressLint("MissingPermission")
+ private boolean anyPermsOfPackageOneTimeGranted(PackageInfo packageInfo) {
+ if (packageInfo.requestedPermissions == null
+ || packageInfo.requestedPermissionsFlags == null) {
+ return false;
+ }
+
+ for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
+ if ((packageInfo.requestedPermissionsFlags[i] &
+ PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
+ continue;
+ }
+ int flags = mPackageManager.getPermissionFlags(
+ packageInfo.requestedPermissions[i], packageInfo.packageName, getUser());
+ boolean isGrantedOneTime = (flags & FLAG_PERMISSION_REVOKED_COMPAT) == 0 &&
+ (flags & FLAG_PERMISSION_ONE_TIME) != 0;
+ if (isGrantedOneTime) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Check if permission group contains a runtime permission that split from an installed
* permission and the split happened in an Android version higher than app's targetSdk.
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
index 51f098371..072ef433b 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
@@ -40,6 +40,7 @@ import android.content.Intent
import android.content.Intent.ACTION_MAIN
import android.content.Intent.CATEGORY_INFO
import android.content.Intent.CATEGORY_LAUNCHER
+import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED
import android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME
@@ -1144,7 +1145,7 @@ object KotlinUtils {
group.specialFixedStorageGrant,
)
- if (wasOneTime && !anyPermsOfPackageOneTimeGranted(app, newGroup.packageInfo, newGroup)) {
+ if (wasOneTime && !anyPermsOfPackageOneTimeGranted(app, newGroup.packageInfo)) {
// Create a new context with the given deviceId so that permission updates will be bound
// to the device
val context = ContextCompat.createDeviceContext(app.applicationContext, deviceId)
@@ -1189,30 +1190,24 @@ object KotlinUtils {
*
* @param app The current application
* @param packageInfo The packageInfo we wish to examine
- * @param group Optional, the current app permission group we are examining
* @return true if any permission in the package is granted for one time, false otherwise
*/
@Suppress("MissingPermission")
private fun anyPermsOfPackageOneTimeGranted(
app: Application,
packageInfo: LightPackageInfo,
- group: LightAppPermGroup? = null,
): Boolean {
- val user = group?.userHandle ?: UserHandle.getUserHandleForUid(packageInfo.uid)
- if (group?.isOneTime == true) {
- return true
- }
- for ((idx, permName) in packageInfo.requestedPermissions.withIndex()) {
- if (permName in group?.permissions ?: emptyMap()) {
+ val user = UserHandle.getUserHandleForUid(packageInfo.uid)
+ for ((index, permName) in packageInfo.requestedPermissions.withIndex()) {
+ if ((packageInfo.requestedPermissionsFlags[index] and
+ PackageInfo.REQUESTED_PERMISSION_GRANTED) == 0) {
continue
}
val flags =
- app.packageManager.getPermissionFlags(permName, packageInfo.packageName, user) and
- FLAG_PERMISSION_ONE_TIME
- val granted =
- packageInfo.requestedPermissionsFlags[idx] == PackageManager.PERMISSION_GRANTED &&
- (flags and FLAG_PERMISSION_REVOKED_COMPAT) == 0
- if (granted && (flags and FLAG_PERMISSION_ONE_TIME) != 0) {
+ app.packageManager.getPermissionFlags(permName, packageInfo.packageName, user)
+ val isGrantedOneTime = (flags and FLAG_PERMISSION_REVOKED_COMPAT) == 0 &&
+ (flags and FLAG_PERMISSION_ONE_TIME) != 0
+ if (isGrantedOneTime) {
return true
}
}