diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-02 22:45:31 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-11-02 22:45:31 +0000 |
commit | 0200d6fbca83dca25736cdef8fa67f4c55552ae0 (patch) | |
tree | d4c2bbf2e2847a3569ebe3a3119ac5d6586eec16 /PermissionController/src/com/android/permissioncontroller/permission/utils | |
parent | ec92dfe7d68b2aec544825ebe61c45df98cae6b7 (diff) | |
parent | 17440e9d4d86da90a850ad04dbc41cb59d30cdec (diff) | |
download | Permission-0200d6fbca83dca25736cdef8fa67f4c55552ae0.tar.gz |
Snap for 11041982 from 17440e9d4d86da90a850ad04dbc41cb59d30cdec to mainline-uwb-releaseaml_uwb_341310300aml_uwb_341310030android14-mainline-uwb-release
Change-Id: If31740c980b44eae1671d1a80e4f088e8f9ef7e4
Diffstat (limited to 'PermissionController/src/com/android/permissioncontroller/permission/utils')
8 files changed, 127 insertions, 117 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/AndroidUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/AndroidUtils.kt index 6a6623da7..a5f78aa53 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/AndroidUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/AndroidUtils.kt @@ -26,19 +26,19 @@ import android.content.pm.PackageManager import android.content.pm.ResolveInfo import android.os.Looper import android.os.UserHandle -import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.Executors +import kotlinx.coroutines.asCoroutineDispatcher -/** - * Gets an [Application] instance from a regular [Context] - */ -val Context.application: Application get() = when (this) { - is Application -> this - is Activity -> application - is Service -> application - is ContextWrapper -> baseContext.application - else -> applicationContext as Application -} +/** Gets an [Application] instance from a regular [Context] */ +val Context.application: Application + get() = + when (this) { + is Application -> this + is Activity -> application + is Service -> application + is ContextWrapper -> baseContext.application + else -> applicationContext as Application + } /** * The number of threads in the IPC thread pool. Set to the maximum number of binder threads allowed @@ -46,21 +46,16 @@ val Context.application: Application get() = when (this) { */ const val IPC_THREAD_POOL_COUNT = 8 -/** - * A coroutine dispatcher with a fixed thread pool size, to be used for background tasks - */ +/** A coroutine dispatcher with a fixed thread pool size, to be used for background tasks */ val IPC = Executors.newFixedThreadPool(IPC_THREAD_POOL_COUNT).asCoroutineDispatcher() -/** - * Assert that an operation is running on main thread - */ -fun ensureMainThread() = check(Looper.myLooper() == Looper.getMainLooper()) { - "Only meant to be used on the main thread" -} +/** Assert that an operation is running on main thread */ +fun ensureMainThread() = + check(Looper.myLooper() == Looper.getMainLooper()) { + "Only meant to be used on the main thread" + } -/** - * A more readable version of [PackageManager.updatePermissionFlags] - */ +/** A more readable version of [PackageManager.updatePermissionFlags] */ fun PackageManager.updatePermissionFlags( permissionName: String, packageName: String, @@ -68,18 +63,14 @@ fun PackageManager.updatePermissionFlags( vararg flags: Pair<Int, Boolean> ) { val mask = flags.fold(0, { mask, (flag, _) -> mask or flag }) - val value = flags.fold(0, - { mask2, (flag, flagValue) -> if (flagValue) mask2 or flag else mask2 }) + val value = + flags.fold(0, { mask2, (flag, flagValue) -> if (flagValue) mask2 or flag else mask2 }) updatePermissionFlags(permissionName, packageName, mask, value, user) } -/** - * Gets a [ComponentInfo] from a [ResolveInfo] - */ +/** Gets a [ComponentInfo] from a [ResolveInfo] */ val ResolveInfo.componentInfo: ComponentInfo get() { return (activityInfo as ComponentInfo?) - ?: serviceInfo - ?: providerInfo - ?: throw IllegalStateException("Missing ComponentInfo!") - }
\ No newline at end of file + ?: serviceInfo ?: providerInfo ?: throw IllegalStateException("Missing ComponentInfo!") + } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/DebugUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/DebugUtils.kt index cf8a69b40..96d634ded 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/DebugUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/DebugUtils.kt @@ -25,24 +25,21 @@ import java.util.Collections.reverse */ fun shortStackTrace() = permissionsStackTrace().toShortString() -/** - * [StackTraceElement]s of only the permission-related frames - */ -fun permissionsStackTrace() = stackTraceWithin("com.android.permissioncontroller") - .dropLastWhile { it.className.contains(".DebugUtils") } +/** [StackTraceElement]s of only the permission-related frames */ +fun permissionsStackTrace() = + stackTraceWithin("com.android.permissioncontroller").dropLastWhile { + it.className.contains(".DebugUtils") + } /** * [StackTraceElement]s of only frames who's [full class name][StackTraceElement.getClassName] * starts with [pkgPrefix] */ -fun stackTraceWithin(pkgPrefix: String) = Thread - .currentThread() - .stackTrace - .dropWhile { - !it.className.startsWith(pkgPrefix) - }.takeWhile { - it.className.startsWith(pkgPrefix) - } +fun stackTraceWithin(pkgPrefix: String) = + Thread.currentThread() + .stackTrace + .dropWhile { !it.className.startsWith(pkgPrefix) } + .takeWhile { it.className.startsWith(pkgPrefix) } /** * Renders a stack trace slice to a short-ish single-line string. diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt index 358f86f4b..f2aa0ae66 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt @@ -25,6 +25,7 @@ import android.Manifest.permission.POST_NOTIFICATIONS import android.Manifest.permission.READ_MEDIA_IMAGES import android.Manifest.permission.READ_MEDIA_VIDEO import android.Manifest.permission_group.NOTIFICATIONS +import android.app.Activity import android.app.ActivityManager import android.app.AppOpsManager import android.app.AppOpsManager.MODE_ALLOWED @@ -59,8 +60,10 @@ import android.health.connect.HealthConnectManager import android.os.Build import android.os.Bundle import android.os.UserHandle +import android.os.UserManager import android.permission.PermissionManager import android.provider.DeviceConfig +import android.provider.MediaStore import android.provider.Settings import android.safetylabel.SafetyLabelConstants.PERMISSION_RATIONALE_ENABLED import android.safetylabel.SafetyLabelConstants.SAFETY_LABEL_CHANGE_NOTIFICATIONS_ENABLED @@ -297,17 +300,14 @@ object KotlinUtils { ) } - /** - * Whether the Photo Picker Prompt is supported by the device - * - */ + /** Whether the Photo Picker Prompt is supported by the device */ @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codename = "UpsideDownCake") fun isPhotoPickerPromptSupported(): Boolean { val app = PermissionControllerApplication.get() return SdkLevel.isAtLeastU() && - !DeviceUtils.isAuto(app) && - !DeviceUtils.isTelevision(app) && - !DeviceUtils.isWear(app) + !DeviceUtils.isAuto(app) && + !DeviceUtils.isTelevision(app) && + !DeviceUtils.isWear(app) } /* @@ -650,6 +650,28 @@ object KotlinUtils { } } + fun openPhotoPickerForApp( + activity: Activity, + uid: Int, + requestedPermissions: List<String>, + requestCode: Int + ) { + // A clone profile doesn't have a MediaProvider. If the app's user is a clone profile, open + // the photo picker in the parent profile + val appUser = UserHandle.getUserHandleForUid(uid) + val userManager = + activity.createContextAsUser(appUser, 0).getSystemService(UserManager::class.java)!! + val user = if (userManager.isCloneProfile) { + userManager.getProfileParent(appUser) ?: appUser + } else { + appUser + } + val pickerIntent = Intent(MediaStore.ACTION_USER_SELECT_IMAGES_FOR_APP) + .putExtra(Intent.EXTRA_UID, uid) + .setType(getMimeTypeForPermissions(requestedPermissions)) + activity.startActivityForResultAsUser(pickerIntent, requestCode, user) + } + /** Return a specific MIME type, if a set of permissions is associated with one */ fun getMimeTypeForPermissions(permissions: List<String>): String? { if (permissions.contains(READ_MEDIA_IMAGES) && !permissions.contains(READ_MEDIA_VIDEO)) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt index 32d3a5325..840a033c3 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/PermissionMapping.kt @@ -23,10 +23,9 @@ import android.content.pm.PackageManager import android.content.pm.PermissionInfo import android.health.connect.HealthPermissions.HEALTH_PERMISSION_GROUP import android.util.Log - import com.android.modules.utils.build.SdkLevel -import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permission.safetylabel.DataCategoryConstants +import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup /** * This file contains the canonical mapping of permission to permission group, used in the @@ -36,15 +35,16 @@ object PermissionMapping { private val LOG_TAG = "PermissionMapping" - private val PERMISSION_GROUPS_TO_DATA_CATEGORIES: Map<String, List<String>> = mapOf( - Manifest.permission_group.LOCATION to listOf(DataCategoryConstants.CATEGORY_LOCATION)) + private val PERMISSION_GROUPS_TO_DATA_CATEGORIES: Map<String, List<String>> = + mapOf(Manifest.permission_group.LOCATION to listOf(DataCategoryConstants.CATEGORY_LOCATION)) @JvmField val SENSOR_DATA_PERMISSIONS: List<String> = listOf( Manifest.permission_group.LOCATION, Manifest.permission_group.CAMERA, - Manifest.permission_group.MICROPHONE) + Manifest.permission_group.MICROPHONE + ) @JvmField val STORAGE_SUPERGROUP_PERMISSIONS: List<String> = @@ -53,7 +53,8 @@ object PermissionMapping { listOf( Manifest.permission_group.STORAGE, Manifest.permission_group.READ_MEDIA_AURAL, - Manifest.permission_group.READ_MEDIA_VISUAL) + Manifest.permission_group.READ_MEDIA_VISUAL + ) val PARTIAL_MEDIA_PERMISSIONS: MutableSet<String> = mutableSetOf() @@ -68,7 +69,6 @@ object PermissionMapping { private val HEALTH_PERMISSIONS_SET: MutableSet<String> = mutableSetOf() - init { PLATFORM_PERMISSIONS[Manifest.permission.READ_CONTACTS] = Manifest.permission_group.CONTACTS PLATFORM_PERMISSIONS[Manifest.permission.WRITE_CONTACTS] = @@ -202,7 +202,6 @@ object PermissionMapping { * platform permission. * * @param permission the permission to resolve - * * @return The group the permission belongs to */ @JvmStatic @@ -214,7 +213,6 @@ object PermissionMapping { * Get name of the permission group a permission belongs to. * * @param permission the [info][PermissionInfo] of the permission to resolve - * * @return The group the permission belongs to */ @JvmStatic @@ -230,9 +228,8 @@ object PermissionMapping { * Get the names for all platform permissions belonging to a group. * * @param group the group - * * @return The permission names or an empty list if the group does not have platform runtime - * permissions + * permissions */ @JvmStatic fun getPlatformPermissionNamesOfGroup(group: String): List<String> { @@ -245,19 +242,19 @@ object PermissionMapping { * * @param pm Package manager to use to resolve permission infos * @param group the group - * * @return The infos for platform permissions belonging to the group or an empty list if the - * group does not have platform runtime permissions + * group does not have platform runtime permissions */ @JvmStatic fun getPlatformPermissionsOfGroup(pm: PackageManager, group: String): List<PermissionInfo> { val permInfos = mutableListOf<PermissionInfo>() for (permName in PLATFORM_PERMISSION_GROUPS[group] ?: emptyList()) { - val permInfo: PermissionInfo = try { + val permInfo: PermissionInfo = + try { pm.getPermissionInfo(permName, 0) - } catch (e: PackageManager.NameNotFoundException) { - throw IllegalStateException("$permName not defined by platform", e) - } + } catch (e: PackageManager.NameNotFoundException) { + throw IllegalStateException("$permName not defined by platform", e) + } permInfos.add(permInfo) } return permInfos @@ -300,6 +297,7 @@ object PermissionMapping { /** * Whether the permission group supports one-time + * * @param permissionGroup The permission group to check * @return `true` iff the group supports one-time */ @@ -308,9 +306,7 @@ object PermissionMapping { return ONE_TIME_PERMISSION_GROUPS.contains(permissionGroup) } - /** - * Adds health permissions as platform permissions. - */ + /** Adds health permissions as platform permissions. */ @JvmStatic fun addHealthPermissionsToPlatform(permissions: Set<String>) { if (permissions.isEmpty()) { @@ -338,8 +334,9 @@ object PermissionMapping { return emptySet() } - val appSupportsPickerPrompt = group - .permissions[Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED]?.isImplicit == false + val appSupportsPickerPrompt = + group.permissions[Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED]?.isImplicit == + false return if (appSupportsPickerPrompt) { PARTIAL_MEDIA_PERMISSIONS @@ -348,9 +345,7 @@ object PermissionMapping { } } - /** - * Returns true if the given permission is a health platform permission. - */ + /** Returns true if the given permission is a health platform permission. */ @JvmStatic fun isHealthPermission(permissionName: String): Boolean { return HEALTH_PERMISSIONS_SET.contains(permissionName) @@ -386,8 +381,8 @@ object PermissionMapping { /** * Get the SafetyLabel categories pertaining to a specified permission group. * - * @return The categories, or an empty list if the group does not have a supported mapping - * to safety label category + * @return The categories, or an empty list if the group does not have a supported mapping to + * safety label category */ fun getDataCategoriesForPermissionGroup(permissionGroupName: String): List<String> { return if (isSafetyLabelAwarePermissionGroup(permissionGroupName)) { diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/SystemTimeSource.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/SystemTimeSource.kt index dc05ededc..116c498be 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/SystemTimeSource.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/SystemTimeSource.kt @@ -18,9 +18,7 @@ package com.android.permissioncontroller.permission.utils import android.os.SystemClock -/** - * Time source that uses the system time. - */ +/** Time source that uses the system time. */ class SystemTimeSource : TimeSource { override fun currentTimeMillis(): Long { @@ -30,4 +28,4 @@ class SystemTimeSource : TimeSource { override fun elapsedRealtime(): Long { return SystemClock.elapsedRealtime() } -}
\ No newline at end of file +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/TimeSource.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/TimeSource.kt index 00b93f405..29883e1f3 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/TimeSource.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/TimeSource.kt @@ -16,18 +16,12 @@ package com.android.permissioncontroller.permission.utils -/** - * Interface for system time components. - */ +/** Interface for system time components. */ interface TimeSource { - /** - * Returns the current time in milliseconds. - */ + /** Returns the current time in milliseconds. */ fun currentTimeMillis(): Long - /** - * Returns milliseconds since boot, including time spent in sleep. - */ + /** Returns milliseconds since boot, including time spent in sleep. */ fun elapsedRealtime(): Long -}
\ No newline at end of file +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/UserSensitiveFlagsUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/UserSensitiveFlagsUtils.kt index 3cd9891ee..50cacf876 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/UserSensitiveFlagsUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/UserSensitiveFlagsUtils.kt @@ -25,9 +25,9 @@ import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.data.UserSensitivityLiveData import com.android.permissioncontroller.permission.model.livedatatypes.UidSensitivityState import com.android.permissioncontroller.permission.utils.Utils.FLAGS_ALWAYS_USER_SENSITIVE +import java.lang.IllegalStateException import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch -import java.lang.IllegalStateException private const val LOG_TAG = "UserSensitiveFlagsUtils" @@ -35,10 +35,9 @@ private const val LOG_TAG = "UserSensitiveFlagsUtils" * Update the [PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED] and * [PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED] for all apps of this user. * - * @see UserSensitivityLiveData.loadDataAndPostValue - * * @param user The user for whom packages will be updated * @param callback A callback which will be executed when finished + * @see UserSensitivityLiveData.loadDataAndPostValue */ fun updateUserSensitiveForUser(user: UserHandle, callback: Runnable) { GlobalScope.launch(IPC) { @@ -47,7 +46,8 @@ fun updateUserSensitiveForUser(user: UserHandle, callback: Runnable) { if (uidUserSensitivity == null) { callback.run() throw IllegalStateException( - "All uids sensitivity liveData should not be null if initialized") + "All uids sensitivity liveData should not be null if initialized" + ) } updateUserSensitiveForUidsInternal(uidUserSensitivity, user, callback) } @@ -62,28 +62,38 @@ private fun updateUserSensitiveForUidsInternal( val pm = userContext.packageManager for ((uid, uidState) in uidsUserSensitivity) { - for (pkg in uidState.packages) { - for (perm in pkg.requestedPermissions) { - var flags = uidState.permStates[perm] ?: continue + for (pkg in uidState.packages) { + for (perm in pkg.requestedPermissions) { + var flags = uidState.permStates[perm] ?: continue - try { - val oldFlags = pm.getPermissionFlags(perm, pkg.packageName, user) and + try { + val oldFlags = + pm.getPermissionFlags(perm, pkg.packageName, user) and FLAGS_ALWAYS_USER_SENSITIVE - if (flags != oldFlags) { - pm.updatePermissionFlags(perm, pkg.packageName, - FLAGS_ALWAYS_USER_SENSITIVE, flags, user) - } - } catch (e: IllegalArgumentException) { - if (e.message?.startsWith("Unknown permission: ") == false) { - Log.e(LOG_TAG, "Unexpected exception while updating flags for " + - "${pkg.packageName} (uid $uid) permission $perm", e) - } else { - // Unknown permission - ignore - } + if (flags != oldFlags) { + pm.updatePermissionFlags( + perm, + pkg.packageName, + FLAGS_ALWAYS_USER_SENSITIVE, + flags, + user + ) + } + } catch (e: IllegalArgumentException) { + if (e.message?.startsWith("Unknown permission: ") == false) { + Log.e( + LOG_TAG, + "Unexpected exception while updating flags for " + + "${pkg.packageName} (uid $uid) permission $perm", + e + ) + } else { + // Unknown permission - ignore } } } } + } callback?.run() } @@ -98,8 +108,11 @@ fun updateUserSensitiveForUid(uid: Int, callback: Runnable? = null) { GlobalScope.launch(IPC) { val uidSensitivityState = UserSensitivityLiveData[uid].getInitializedValue() if (uidSensitivityState != null) { - updateUserSensitiveForUidsInternal(uidSensitivityState, - UserHandle.getUserHandleForUid(uid), callback) + updateUserSensitiveForUidsInternal( + uidSensitivityState, + UserHandle.getUserHandleForUid(uid), + callback + ) } else { Log.e(LOG_TAG, "No packages associated with uid $uid, not updating flags") callback?.run() diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/v34/SafetyLabelUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/v34/SafetyLabelUtils.kt index 5dbe203f9..9fd8ab916 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/v34/SafetyLabelUtils.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/v34/SafetyLabelUtils.kt @@ -32,8 +32,8 @@ object SafetyLabelUtils { groupName: String ): Set<Int> { val purposeSet = mutableSetOf<Int>() - val categoriesForPermission = PermissionMapping - .getDataCategoriesForPermissionGroup(groupName) + val categoriesForPermission = + PermissionMapping.getDataCategoriesForPermissionGroup(groupName) categoriesForPermission.forEach categoryLoop@{ category -> val dataCategory: DataCategory? = safetyLabel.dataLabel.dataShared[category] if (dataCategory == null) { |