From 46db55c94f2d851d78976f189d0dcd92a396ff51 Mon Sep 17 00:00:00 2001 From: Scarlett Song Date: Fri, 14 Mar 2025 21:22:52 +0000 Subject: Support health split permission check for targetSdk<23 apps Test: atest HealthConnectAppPermissionFragmentTest Bug: 403337565 Flag: android.permission.flags.replace_body_sensor_permission_enabled Relnote: Health permission split BODY_SENSORS to READ_HEART_RATE LOW_COVERAGE_REASON=b/405152547 Change-Id: I770fdf9a551bb53a6e0d7adccd39ea6bf285c57b --- .../permission/utils/Utils.java | 46 ++++++++-------------- 1 file changed, 16 insertions(+), 30 deletions(-) (limited to 'PermissionController/src') diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java index 327142896..675a1049f 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java @@ -39,6 +39,7 @@ import static android.content.Intent.EXTRA_REASON; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; +import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED; @@ -82,6 +83,7 @@ import android.health.connect.HealthConnectManager; import android.health.connect.HealthPermissions; import android.os.Binder; import android.os.Build; +import android.os.Build.VERSION_CODES; import android.os.Parcelable; import android.os.UserHandle; import android.os.UserManager; @@ -1171,45 +1173,29 @@ public final class Utils { } } - // Split permission only applies to READ_HEART_RATE. - if (!requestedHealthPermissions.contains(HealthPermissions.READ_HEART_RATE)) { + if (!isValidSplitHealthPermissions(requestedHealthPermissions)) { return false; } - // If there are other health permissions (other than READ_HEALTH_DATA_IN_BACKGROUND) - // don't consider this a pure split-permission request. - if (requestedHealthPermissions.size() > 2) { - return false; - } - - boolean isBackgroundPermissionRequested = - requestedHealthPermissions.contains( - HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND); - // If there are two health permissions declared, make sure the other is - // READ_HEALTH_DATA_IN_BACKGROUND. - if (requestedHealthPermissions.size() == 2 && !isBackgroundPermissionRequested) { - return false; - } - - // If READ_HEALTH_DATA_IN_BACKGROUND is requested, check permission flag to see if is from - // split permission. - if (isBackgroundPermissionRequested) { - int readHealthDataInBackgroundFlag = - pm.getPermissionFlags( - HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND, packageName, user); - if (!isFromSplitPermission(readHealthDataInBackgroundFlag)) { + int targetSdk = packageInfo.getTargetSdkVersion(); + for (String perm : requestedHealthPermissions) { + if (!isFromSplitPermission(pm.getPermissionFlags(perm, packageName, user), targetSdk)) { return false; } } + return true; + } - // Check READ_HEART_RATE permission flag to see if is from split permission. - int readHeartRateFlag = - pm.getPermissionFlags(HealthPermissions.READ_HEART_RATE, packageName, user); - return isFromSplitPermission(readHeartRateFlag); + private static boolean isValidSplitHealthPermissions(List permissions) { + return (permissions.size() == 1 && permissions.contains(HealthPermissions.READ_HEART_RATE)) + || (permissions.size() == 2 && permissions.contains(HealthPermissions.READ_HEART_RATE) + && permissions.contains(HealthPermissions.READ_HEALTH_DATA_IN_BACKGROUND)); } - private static boolean isFromSplitPermission(int permissionFlag) { - return (permissionFlag & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0; + private static boolean isFromSplitPermission(int permissionFlag, int targetSdk) { + return (targetSdk >= Build.VERSION_CODES.M) + ? (permissionFlag & PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0 + : (permissionFlag & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0; } /** -- cgit v1.2.3-59-g8ed1b From dfa41abe65a81b36d9aeef2d50ee87bdb518c85e Mon Sep 17 00:00:00 2001 From: Justin Lannin Date: Thu, 20 Mar 2025 13:14:14 -0700 Subject: WearAppPermissionGroupsHelper: Prioritize platform permissions on AppInfo page. The HEALTH permission group is created by the healthfitness mainline module and not the OS_PKG. This meant that even though it is a platform permission group that it was getting sorted to the bottom of the list. Now we partition permissions based on whether they are platform permissions to ensure it takes it's rightful spot near the top. Bug: 404941005 Test: Locally built, verified ordering was fixed. Flag: EXEMPT bugfix Relnote: Fixing permission order on Wear App info page. LOW_COVERAGE_REASON=OTHER_FORM_FACTOR Change-Id: I33d901d330cd963494f83a0e4b778db3aebfb529 --- .../ui/wear/WearAppPermissionGroupsHelper.kt | 41 ++++++++++++---------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'PermissionController/src') diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt index 2933d6fda..38a3b44e9 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsHelper.kt @@ -44,6 +44,7 @@ import com.android.permissioncontroller.permission.ui.wear.model.WearAppPermissi import com.android.permissioncontroller.permission.ui.wear.model.WearLocationProviderInterceptDialogViewModel import com.android.permissioncontroller.permission.utils.ArrayUtils import com.android.permissioncontroller.permission.utils.LocationUtils +import com.android.permissioncontroller.permission.utils.PermissionMapping import com.android.permissioncontroller.permission.utils.Utils import com.android.permissioncontroller.permission.utils.legacy.LegacySafetyNetLogger import com.android.permissioncontroller.permission.utils.navigateSafe @@ -59,7 +60,7 @@ class WearAppPermissionGroupsHelper( val wearViewModel: WearAppPermissionUsagesViewModel, val revokeDialogViewModel: AppPermissionGroupsRevokeDialogViewModel, val locationProviderInterceptDialogViewModel: WearLocationProviderInterceptDialogViewModel, - private val toggledGroups: ArraySet = ArraySet() + private val toggledGroups: ArraySet = ArraySet(), ) { fun getPermissionGroupChipParams( appPermissionUsages: List @@ -71,7 +72,7 @@ class WearAppPermissionGroupsHelper( viewModel.extractGroupUsageLastAccessTime( groupUsageLastAccessTime, appPermissionUsages, - packageName + packageName, ) val groupUiInfos = viewModel.packagePermGroupsLiveData.value val groups: List = appPermissions.permissionGroups @@ -92,7 +93,7 @@ class WearAppPermissionGroupsHelper( groups .filter { Utils.shouldShowPermission(context, it) } - .partition { it.declaringPackage == Utils.OS_PKG } + .partition { PermissionMapping.isPlatformPermissionGroup(it.name) } .let { it.first.plus(it.second) } .forEach { group -> if (Utils.areGroupPermissionsIndividuallyControlled(context, group.name)) { @@ -107,7 +108,7 @@ class WearAppPermissionGroupsHelper( checked = group.areRuntimePermissionsGranted(arrayOf(perm.name)), onCheckedChanged = { checked -> run { onPermissionGrantedStateChanged(group, perm, checked) } - } + }, ) ) } @@ -123,10 +124,10 @@ class WearAppPermissionGroupsHelper( getSummary( category, it, - groupUsageLastAccessTime[it.groupName] + groupUsageLastAccessTime[it.groupName], ) }, - onClick = { onPermissionGroupClicked(group, category.categoryName) } + onClick = { onPermissionGroupClicked(group, category.categoryName) }, ) ) } @@ -138,7 +139,7 @@ class WearAppPermissionGroupsHelper( private fun getSummary( category: Category?, groupUiInfo: GroupUiInfo, - lastAccessTime: Long? + lastAccessTime: Long?, ): String { val grantSummary = getGrantSummary(category, groupUiInfo)?.let { context.getString(it) } ?: "" @@ -196,7 +197,7 @@ class WearAppPermissionGroupsHelper( private fun onPermissionGrantedStateChanged( group: AppPermissionGroup, perm: PermissionInfo, - checked: Boolean + checked: Boolean, ) { if (checked) { group.grantRuntimePermissions(true, false, arrayOf(perm.name)) @@ -247,7 +248,7 @@ class WearAppPermissionGroupsHelper( revokeDialogViewModel.hasConfirmedRevoke = true } revokeDialogViewModel.dismissDialog() - } + }, ) } else { revokePermissionInGroup(group, perm.name) @@ -261,7 +262,7 @@ class WearAppPermissionGroupsHelper( if ("user" == Build.TYPE) { Log.e( TAG, - "The impossible happens, permission $permName is not in group $group.name." + "The impossible happens, permission $permName is not in group $group.name.", ) null } else { @@ -291,13 +292,13 @@ class WearAppPermissionGroupsHelper( private fun showRevocationWarningDialog( messageId: Int, onOkButtonClick: () -> Unit, - onCancelButtonClick: () -> Unit = { revokeDialogViewModel.dismissDialog() } + onCancelButtonClick: () -> Unit = { revokeDialogViewModel.dismissDialog() }, ) { revokeDialogViewModel.revokeDialogArgs = RevokeDialogArgs( messageId = messageId, onOkButtonClick = onOkButtonClick, - onCancelButtonClick = onCancelButtonClick + onCancelButtonClick = onCancelButtonClick, ) revokeDialogViewModel.showDialogLiveData.value = true } @@ -315,13 +316,15 @@ class WearAppPermissionGroupsHelper( LocationUtils.isLocationGroupAndControllerExtraPackage( context, permGroupName, - packageName + packageName, ) ) { // Redirect to location controller extra package settings. LocationUtils.startLocationControllerExtraPackageSettings(context, user) - } else if (permGroupName.equals(HEALTH_PERMISSION_GROUP) - && android.permission.flags.Flags.replaceBodySensorPermissionEnabled()) { + } else if ( + permGroupName.equals(HEALTH_PERMISSION_GROUP) && + android.permission.flags.Flags.replaceBodySensorPermissionEnabled() + ) { // Redirect to Health&Fitness UI Utils.navigateToAppHealthConnectSettings(fragment.requireContext(), packageName, user) } else { @@ -333,7 +336,7 @@ class WearAppPermissionGroupsHelper( user, caller, sessionId, - grantCategory + grantCategory, ) fragment.findNavController().navigateSafe(R.id.perm_groups_to_app, args) } @@ -364,7 +367,7 @@ class WearAppPermissionGroupsHelper( viewModel.setAutoRevoke(checked) Log.w(TAG, "setAutoRevoke $checked") } - } + }, ) } @@ -382,12 +385,12 @@ data class PermissionGroupChipParam( val enabled: Boolean = true, val checked: Boolean? = null, val onClick: () -> Unit = {}, - val onCheckedChanged: (Boolean) -> Unit = {} + val onCheckedChanged: (Boolean) -> Unit = {}, ) data class AutoRevokeChipParam( val labelRes: Int, val visible: Boolean, val checked: Boolean = false, - val onCheckedChanged: (Boolean) -> Unit + val onCheckedChanged: (Boolean) -> Unit, ) -- cgit v1.2.3-59-g8ed1b From ea841eb0c1a11c02c8e85538e030025e9dc7cfa2 Mon Sep 17 00:00:00 2001 From: Yi-an Chen Date: Fri, 21 Mar 2025 21:43:18 +0000 Subject: [BC25] Add isExpressiveDesignEnabled to Utils Add isExpressiveDesignEnabled to determine whether the expressive design is enabled to permission controller. Bug: 349675008 Flag: com.android.settingslib.widget.theme.flags.is_expressive_design_enabled Test: Build Relnote: N/A Change-Id: I139d954be115eb6031d2ce900b8aecc4795604b4 --- .../android/permissioncontroller/permission/utils/Utils.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'PermissionController/src') diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java index 425375d7a..149bc4efc 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java +++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/Utils.java @@ -39,8 +39,6 @@ import static android.content.Intent.EXTRA_REASON; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT; -import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; @@ -83,7 +81,6 @@ import android.health.connect.HealthConnectManager; import android.health.connect.HealthPermissions; import android.os.Binder; import android.os.Build; -import android.os.Build.VERSION_CODES; import android.os.Parcelable; import android.os.UserHandle; import android.os.UserManager; @@ -118,6 +115,7 @@ import com.android.permissioncontroller.R; import com.android.permissioncontroller.permission.model.AppPermissionGroup; import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup; import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo; +import com.android.settingslib.widget.SettingsThemeHelper; import kotlin.Triple; @@ -1071,6 +1069,14 @@ public final class Utils { } } + /** + * Whether Expressive Design is enabled on this device. + */ + public static boolean isExpressiveDesignEnabled(@NonNull Context context) { + return SdkLevel.isAtLeastB() && DeviceUtils.isHandheld() + && SettingsThemeHelper.isExpressiveTheme(context); + } + /** * Returns true if the group name passed is that of the Platform health group. * @param permGroupName name of the group that needs to be checked. -- cgit v1.2.3-59-g8ed1b