diff options
25 files changed, 358 insertions, 163 deletions
diff --git a/Android.bp b/Android.bp index 9b1857741..f2aab3568 100644 --- a/Android.bp +++ b/Android.bp @@ -110,6 +110,7 @@ bootclasspath_fragment { package_prefixes: [ "android.app.role", "android.app.ecm", + "android.permission.internal", "android.permission.jarjar", "android.safetycenter", "android.safetylabel", diff --git a/PermissionController/res/values-watch/donottranslate.xml b/PermissionController/res/values-watch/donottranslate.xml index 309c51388..43830a93c 100644 --- a/PermissionController/res/values-watch/donottranslate.xml +++ b/PermissionController/res/values-watch/donottranslate.xml @@ -51,32 +51,32 @@ <string name="wear_compose_material3_title_medium_font_family">font-family-flex-device-default</string> <string name="wear_compose_material3_title_large_font_family">font-family-flex-device-default</string> - <dimen name="wear_compose_material3_arc_small_font_size">14</dimen> - <dimen name="wear_compose_material3_arc_medium_font_size">15</dimen> - <dimen name="wear_compose_material3_arc_large_font_size">20</dimen> - <dimen name="wear_compose_material3_body_extra_small_font_size">10</dimen> - <dimen name="wear_compose_material3_body_small_font_size">12</dimen> - <dimen name="wear_compose_material3_body_medium_font_size">14</dimen> - <dimen name="wear_compose_material3_body_large_font_size">16</dimen> - <dimen name="wear_compose_material3_display_small_font_size">24</dimen> - <dimen name="wear_compose_material3_display_medium_font_size">30</dimen> - <dimen name="wear_compose_material3_display_large_font_size">40</dimen> - <dimen name="wear_compose_material3_label_small_font_size">13</dimen> - <dimen name="wear_compose_material3_label_medium_font_size">15</dimen> - <dimen name="wear_compose_material3_label_large_font_size">20</dimen> - <dimen name="wear_compose_material3_numeral_extra_small_font_size">24</dimen> - <dimen name="wear_compose_material3_numeral_small_font_size">30</dimen> - <dimen name="wear_compose_material3_numeral_medium_font_size">40</dimen> - <dimen name="wear_compose_material3_numeral_large_font_size">50</dimen> - <dimen name="wear_compose_material3_numeral_extra_large_font_size">60</dimen> - <dimen name="wear_compose_material3_title_small_font_size">14</dimen> - <dimen name="wear_compose_material3_title_medium_font_size">16</dimen> - <dimen name="wear_compose_material3_title_large_font_size">20</dimen> + <dimen name="wear_compose_material3_arc_small_font_size">14sp</dimen> + <dimen name="wear_compose_material3_arc_medium_font_size">15sp</dimen> + <dimen name="wear_compose_material3_arc_large_font_size">20sp</dimen> + <dimen name="wear_compose_material3_body_extra_small_font_size">10sp</dimen> + <dimen name="wear_compose_material3_body_small_font_size">12sp</dimen> + <dimen name="wear_compose_material3_body_medium_font_size">14sp</dimen> + <dimen name="wear_compose_material3_body_large_font_size">16sp</dimen> + <dimen name="wear_compose_material3_display_small_font_size">24sp</dimen> + <dimen name="wear_compose_material3_display_medium_font_size">30sp</dimen> + <dimen name="wear_compose_material3_display_large_font_size">40sp</dimen> + <dimen name="wear_compose_material3_label_small_font_size">13sp</dimen> + <dimen name="wear_compose_material3_label_medium_font_size">15sp</dimen> + <dimen name="wear_compose_material3_label_large_font_size">20sp</dimen> + <dimen name="wear_compose_material3_numeral_extra_small_font_size">24sp</dimen> + <dimen name="wear_compose_material3_numeral_small_font_size">30sp</dimen> + <dimen name="wear_compose_material3_numeral_medium_font_size">40sp</dimen> + <dimen name="wear_compose_material3_numeral_large_font_size">50sp</dimen> + <dimen name="wear_compose_material3_numeral_extra_large_font_size">60sp</dimen> + <dimen name="wear_compose_material3_title_small_font_size">14sp</dimen> + <dimen name="wear_compose_material3_title_medium_font_size">16sp</dimen> + <dimen name="wear_compose_material3_title_large_font_size">20sp</dimen> - <dimen name="wear_compose_material3_shape_corner_extra_small_size">4</dimen> - <dimen name="wear_compose_material3_shape_corner_small_size">8</dimen> - <dimen name="wear_compose_material3_shape_corner_medium_size">18</dimen> - <dimen name="wear_compose_material3_shape_corner_large_size">26</dimen> - <dimen name="wear_compose_material3_shape_corner_extra_large_size">36</dimen> + <dimen name="wear_compose_material3_shape_corner_extra_small_size">4dp</dimen> + <dimen name="wear_compose_material3_shape_corner_small_size">8dp</dimen> + <dimen name="wear_compose_material3_shape_corner_medium_size">18dp</dimen> + <dimen name="wear_compose_material3_shape_corner_large_size">26dp</dimen> + <dimen name="wear_compose_material3_shape_corner_extra_large_size">36dp</dimen> </resources> diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml index 6864506f0..106f4020f 100644 --- a/PermissionController/res/xml/roles.xml +++ b/PermissionController/res/xml/roles.xml @@ -1308,6 +1308,8 @@ <permissions> <permission-set name="nearby_devices" /> <permission-set name="virtual_device" /> + <permission-set name="notifications" + featureFlag="android.companion.virtualdevice.flags.Flags.notificationsForDeviceStreaming" /> </permissions> </role> @@ -1838,4 +1840,27 @@ shortLabel="@string/role_wallet_short_label" uiBehavior="v35.WalletRoleUiBehavior"/> + <role + name="android.app.role.SYSTEM_DEPENDENCY_INSTALLER" + allowBypassingQualification="true" + defaultHolders="config_systemDependencyInstaller" + exclusive="true" + exclusivity="user" + featureFlag="android.content.pm.Flags.sdkDependencyInstaller" + static="true" + systemOnly="true" + visible="false"> + <required-components> + <service permission="android.permission.BIND_DEPENDENCY_INSTALLER"> + <intent-filter> + <action name="android.content.pm.action.INSTALL_DEPENDENCY" /> + </intent-filter> + </service> + </required-components> + <permissions> + <permission name="android.permission.ACCESS_SHARED_LIBRARIES" /> + <permission name="android.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES" /> + </permissions> + </role> + </roles> diff --git a/PermissionController/role-controller/Android.bp b/PermissionController/role-controller/Android.bp index 612c979b5..9a046a397 100644 --- a/PermissionController/role-controller/Android.bp +++ b/PermissionController/role-controller/Android.bp @@ -33,6 +33,7 @@ java_library { "modules-utils-build_system", "android.app.appfunctions.exported-flags-aconfig-java", "android.companion.virtualdevice.flags-aconfig-java-export", + "android.content.pm.flags-aconfig-java-export", "android.permission.flags-aconfig-java-export", "android.os.flags-aconfig-java-export", ], diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java index 67a37bdef..e3269a146 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/Role.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/Role.java @@ -37,6 +37,7 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import android.util.SparseBooleanArray; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -107,6 +108,14 @@ public class Role { */ public static final int EXCLUSIVITY_PROFILE_GROUP = 2; + /** Set of valid exclusivity values. */ + private static final SparseBooleanArray sExclusivityValues = new SparseBooleanArray(); + static { + sExclusivityValues.put(EXCLUSIVITY_NONE, true); + sExclusivityValues.put(EXCLUSIVITY_USER, true); + sExclusivityValues.put(EXCLUSIVITY_PROFILE_GROUP, true); + } + /** * The name of this role. Must be unique. */ @@ -323,12 +332,24 @@ public class Role { } public boolean isExclusive() { - // TODO(b/373390494): Allow RoleBehavior to override this getExclusivity - return mExclusivity != EXCLUSIVITY_NONE; + return getExclusivity() != EXCLUSIVITY_NONE; } + @Exclusivity public int getExclusivity() { - // TODO(b/373390494): Allow RoleBehavior to override this + if (com.android.permission.flags.Flags.crossUserRoleEnabled() && mBehavior != null) { + Integer exclusivity = mBehavior.getExclusivity(); + if (exclusivity != null) { + if (!sExclusivityValues.get(exclusivity)) { + throw new IllegalArgumentException("Invalid exclusivity: " + exclusivity); + } + if (mShowNone && exclusivity == EXCLUSIVITY_NONE) { + throw new IllegalArgumentException( + "Role cannot be non-exclusive when showNone is true: " + exclusivity); + } + return exclusivity; + } + } return mExclusivity; } @@ -384,8 +405,6 @@ public class Role { * @see #mShowNone */ public boolean shouldShowNone() { - // TODO(b/373390494): Ensure RoleBehavior override doesn't conflict with this. - // mShowNone can only be true if isExclusive=true return mShowNone; } diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java b/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java index 3849a50e3..86ca8e2ce 100644 --- a/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java +++ b/PermissionController/role-controller/java/com/android/role/controller/model/RoleBehavior.java @@ -32,6 +32,14 @@ import java.util.List; public interface RoleBehavior { /** + * @see Role#getExclusivity() + */ + @Nullable + default Integer getExclusivity() { + return null; + } + + /** * @see Role#onRoleAddedAsUser(UserHandle, Context) */ default void onRoleAddedAsUser(@NonNull Role role, @NonNull UserHandle user, diff --git a/PermissionController/src/com/android/permissioncontroller/permission/compat/AppOpsManagerCompat.java b/PermissionController/src/com/android/permissioncontroller/permission/compat/AppOpsManagerCompat.java new file mode 100644 index 000000000..912c894f2 --- /dev/null +++ b/PermissionController/src/com/android/permissioncontroller/permission/compat/AppOpsManagerCompat.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.permissioncontroller.permission.compat; + +import android.app.AppOpsManager; +import android.permission.flags.Flags; + +import androidx.annotation.NonNull; + +/** + * Helper AppOpsManager compat class + */ +public class AppOpsManagerCompat { + + private AppOpsManagerCompat() {} + + /** + * For platform version <= V, call the deprecated unsafeCheckOpRawNoThrow. For newer platforms, + * call the new API checkOpRawNoThrow. + * + * @return the raw mode of the op + */ + @SuppressWarnings("deprecation") + public static int checkOpRawNoThrow(@NonNull AppOpsManager appOpsManager, @NonNull String op, + int uid, @NonNull String packageName) { + if (Flags.checkOpOverloadApiEnabled()) { + return appOpsManager.checkOpRawNoThrow(op, uid, packageName, null); + } else { + return appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName); + } + } +} diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AppOpLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AppOpLiveData.kt index 1e44f16bd..3202f5b69 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/AppOpLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AppOpLiveData.kt @@ -19,6 +19,7 @@ package com.android.permissioncontroller.permission.data import android.app.AppOpsManager import android.app.Application import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.permission.compat.AppOpsManagerCompat /** * A LiveData which represents the appop state @@ -36,13 +37,13 @@ private constructor( private val app: Application, private val packageName: String, private val op: String, - private val uid: Int + private val uid: Int, ) : SmartUpdateMediatorLiveData<Int>() { private val appOpsManager = app.getSystemService(AppOpsManager::class.java)!! override fun onUpdate() { - value = appOpsManager.unsafeCheckOpNoThrow(op, uid, packageName) + value = AppOpsManagerCompat.checkOpRawNoThrow(appOpsManager, op, uid, packageName) } override fun onActive() { @@ -62,7 +63,7 @@ private constructor( PermissionControllerApplication.get(), key.first, key.second, - key.third + key.third, ) } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/FullStoragePermissionAppsLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/FullStoragePermissionAppsLiveData.kt index 4a2d3b68a..2b6d9728e 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/FullStoragePermissionAppsLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/FullStoragePermissionAppsLiveData.kt @@ -28,6 +28,7 @@ import android.app.Application import android.os.Build import android.os.UserHandle import com.android.permissioncontroller.PermissionControllerApplication +import com.android.permissioncontroller.permission.compat.AppOpsManagerCompat import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import kotlinx.coroutines.Job @@ -46,7 +47,7 @@ object FullStoragePermissionAppsLiveData : val packageName: String, val user: UserHandle, val isLegacy: Boolean, - val isGranted: Boolean + val isGranted: Boolean, ) init { @@ -88,7 +89,7 @@ object FullStoragePermissionAppsLiveData : fun getFullStorageStateForPackage( appOpsManager: AppOpsManager, packageInfo: LightPackageInfo, - userHandle: UserHandle? = null + userHandle: UserHandle? = null, ): FullStoragePackageState? { val sdk = packageInfo.targetSdkVersion val user = userHandle ?: UserHandle.getUserHandleForUid(packageInfo.uid) @@ -97,29 +98,31 @@ object FullStoragePermissionAppsLiveData : packageInfo.packageName, user, isLegacy = true, - isGranted = true + isGranted = true, ) } else if ( sdk <= Build.VERSION_CODES.Q && - appOpsManager.unsafeCheckOpNoThrow( + AppOpsManagerCompat.checkOpRawNoThrow( + appOpsManager, OPSTR_LEGACY_STORAGE, packageInfo.uid, - packageInfo.packageName + packageInfo.packageName, ) == MODE_ALLOWED ) { return FullStoragePackageState( packageInfo.packageName, user, isLegacy = true, - isGranted = true + isGranted = true, ) } if (MANAGE_EXTERNAL_STORAGE in packageInfo.requestedPermissions) { val mode = - appOpsManager.unsafeCheckOpNoThrow( + AppOpsManagerCompat.checkOpRawNoThrow( + appOpsManager, OPSTR_MANAGE_EXTERNAL_STORAGE, packageInfo.uid, - packageInfo.packageName + packageInfo.packageName, ) val granted = mode == MODE_ALLOWED || @@ -130,7 +133,7 @@ object FullStoragePermissionAppsLiveData : packageInfo.packageName, user, isLegacy = false, - isGranted = granted + isGranted = granted, ) } return null diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt index f94999626..6dabe8ab7 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/model/ManageStandardPermissionsViewModel.kt @@ -119,7 +119,7 @@ class NumCustomPermGroupsWithPackagesLiveData() : SmartUpdateMediatorLiveData<In /** * A LiveData that tracks the names of the platform-defined permission groups, such that at least * one of the permissions in the group has been requested at runtime by at least one non-system - * application or has been pregranted to a non-system application. + * application. * * @param app The current application of the fragment */ @@ -130,10 +130,7 @@ class UsedStandardPermGroupNamesLiveData(private val app: Application) : permGroups -> if (permGroups.values.any { it != null }) { value = - permGroups - .filterValues { it != null && it.nonSystemUserSetOrPreGranted > 0 } - .keys - .toList() + permGroups.filterValues { it != null && it.nonSystemTotal > 0 }.keys.toList() } } } @@ -145,8 +142,7 @@ class UsedStandardPermGroupNamesLiveData(private val app: Application) : /** * A LiveData that tracks the names of the platform-defined permission groups, such that none of the - * the permissions in the group has been requested at runtime by any non-system application nor has - * been pregranted to any non-system application. + * the permissions in the group has been requested at runtime by any non-system application. * * @param app The current application of the fragment */ @@ -155,11 +151,7 @@ class UnusedStandardPermGroupNamesLiveData(private val app: Application) : init { addSource(PermGroupsPackagesUiInfoLiveData(app, StandardPermGroupNamesLiveData)) { permGroups -> - value = - permGroups - .filterValues { it != null && it.nonSystemUserSetOrPreGranted == 0 } - .keys - .toList() + value = permGroups.filterValues { it != null && it.nonSystemTotal == 0 }.keys.toList() } } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButton.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButton.kt index e0adf1265..1d660ca35 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButton.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButton.kt @@ -16,12 +16,16 @@ package com.android.permissioncontroller.permission.ui.wear.elements.material3 import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.requiredSizeIn import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.Hyphens +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp import androidx.wear.compose.material3.Button import androidx.wear.compose.material3.ButtonColors import androidx.wear.compose.material3.ButtonDefaults @@ -79,9 +83,9 @@ fun WearPermissionButton( } @Composable -private fun WearPermissionButtonInternal( - label: String, +internal fun WearPermissionButtonInternal( modifier: Modifier = Modifier, + label: String? = null, iconBuilder: WearPermissionIconBuilder? = null, labelMaxLines: Int? = null, secondaryLabel: String? = null, @@ -89,18 +93,31 @@ private fun WearPermissionButtonInternal( onClick: () -> Unit, enabled: Boolean = true, colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(), + contentPadding: PaddingValues = ButtonDefaults.ContentPadding, + requiresMinimumHeight: Boolean = true, ) { + val minHeight: Dp = + if (requiresMinimumHeight) { + 0.dp + } else { + 1.dp + } val iconParam: (@Composable BoxScope.() -> Unit)? = iconBuilder?.let { { it.build() } } - - val labelParam: (@Composable RowScope.() -> Unit) = { - Text( - text = label, - modifier = Modifier.fillMaxWidth(), - maxLines = labelMaxLines ?: LocalTextConfiguration.current.maxLines, - style = - LocalTextStyle.current.copy(fontWeight = FontWeight.W600, hyphens = Hyphens.Auto), - ) - } + val labelParam: (@Composable RowScope.() -> Unit)? = + label?.let { + { + Text( + text = label, + modifier = Modifier.fillMaxWidth(), + maxLines = labelMaxLines ?: LocalTextConfiguration.current.maxLines, + style = + LocalTextStyle.current.copy( + fontWeight = FontWeight.W600, + hyphens = Hyphens.Auto, + ), + ) + } + } val secondaryLabelParam: (@Composable RowScope.() -> Unit)? = secondaryLabel?.let { @@ -115,11 +132,12 @@ private fun WearPermissionButtonInternal( Button( icon = iconParam, - label = labelParam, + label = labelParam ?: {}, secondaryLabel = secondaryLabelParam, enabled = enabled, onClick = onClick, - modifier = modifier.fillMaxWidth(), + modifier = modifier.requiredSizeIn(minHeight = minHeight).fillMaxWidth(), + contentPadding = contentPadding, colors = colors, ) } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionIconBuilder.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionIconBuilder.kt index 65a85db7e..b7521d073 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionIconBuilder.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionIconBuilder.kt @@ -23,8 +23,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource -import androidx.wear.compose.material3.ButtonDefaults import androidx.wear.compose.material3.Icon +import androidx.wear.compose.material3.IconButtonDefaults import com.android.permissioncontroller.permission.ui.wear.elements.rememberDrawablePainter /** @@ -54,7 +54,7 @@ class WearPermissionIconBuilder private constructor() { var contentDescription: String? = null private set - var modifier: Modifier = Modifier.size(ButtonDefaults.IconSize) + var modifier: Modifier = Modifier.size(IconButtonDefaults.LargeIconSize) private set var tint: Color = Color.Unspecified diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionListFooter.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionListFooter.kt index 807c93370..10125c873 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionListFooter.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionListFooter.kt @@ -16,18 +16,14 @@ package com.android.permissioncontroller.permission.ui.wear.elements.material3 -import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.requiredHeightIn +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.wear.compose.material3.Button import androidx.wear.compose.material3.ButtonDefaults -import androidx.wear.compose.material3.Text import com.android.permissioncontroller.permission.ui.wear.elements.ListFooter import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion +/** This component is creates a transparent styled button to use as a list footer. */ @Composable fun WearPermissionListFooter( materialUIVersion: WearPermissionMaterialUIVersion, @@ -42,26 +38,14 @@ fun WearPermissionListFooter( onClick = onClick, ) } else { - WearPermissionListFooterInternal(label, iconBuilder, onClick) - } -} - -@Composable -private fun WearPermissionListFooterInternal( - label: String, - iconBuilder: WearPermissionIconBuilder?, - onClick: () -> Unit, -) { - val footerTextComposable: (@Composable RowScope.() -> Unit) = { - Text(modifier = Modifier.fillMaxWidth(), text = label, maxLines = Int.MAX_VALUE) + WearPermissionButtonInternal( + iconBuilder = iconBuilder, + secondaryLabel = label, + secondaryLabelMaxLines = Int.MAX_VALUE, + onClick = onClick, + contentPadding = PaddingValues(0.dp), + colors = ButtonDefaults.childButtonColors(), + requiresMinimumHeight = false, + ) } - Button( - icon = { iconBuilder?.build() }, - label = {}, - secondaryLabel = footerTextComposable, - enabled = true, - onClick = onClick, - modifier = Modifier.requiredHeightIn(min = 1.dp).fillMaxWidth(), - colors = ButtonDefaults.childButtonColors(), - ) } diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/ResourceHelper.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/ResourceHelper.kt index 3c2c38578..37b526105 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/ResourceHelper.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/theme/ResourceHelper.kt @@ -45,7 +45,7 @@ internal object ResourceHelper { @DoNotInline fun getDimen(context: Context, @DimenRes id: Int): Float? { return try { - context.resources.getDimension(id) + context.resources.getDimension(id) / context.resources.displayMetrics.density } catch (e: Exception) { null } diff --git a/service/java/com/android/permission/compat/UserHandleCompat.java b/framework-s/java/android/permission/internal/compat/UserHandleCompat.java index 1b3ebb8d6..8a3ec444d 100644 --- a/service/java/com/android/permission/compat/UserHandleCompat.java +++ b/framework-s/java/android/permission/internal/compat/UserHandleCompat.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.permission.compat; +package android.permission.internal.compat; import android.annotation.UserIdInt; import android.os.UserHandle; diff --git a/service/java/com/android/permission/compat/package-info.java b/framework-s/java/android/permission/internal/compat/package-info.java index c89cc8eab..b78aac878 100644 --- a/service/java/com/android/permission/compat/package-info.java +++ b/framework-s/java/android/permission/internal/compat/package-info.java @@ -19,4 +19,4 @@ * TODO(b/146466118) remove this javadoc tag */ @android.annotation.Hide -package com.android.permission.compat; +package android.permission.internal.compat; diff --git a/service/jarjar-rules.txt b/service/jarjar-rules.txt index 4d4d6e050..ef6971b11 100644 --- a/service/jarjar-rules.txt +++ b/service/jarjar-rules.txt @@ -10,6 +10,10 @@ rule android.companion.virtualdevice.flags.*FeatureFlags* com.android.permission rule android.companion.virtualdevice.flags.FeatureFlags* com.android.permission.jarjar.@0 rule android.companion.virtualdevice.flags.FeatureFlags com.android.permission.jarjar.@0 rule android.companion.virtualdevice.flags.Flags com.android.permission.jarjar.@0 +rule android.content.pm.*FeatureFlags* com.android.permission.jarjar.@0 +rule android.content.pm.FeatureFlags* com.android.permission.jarjar.@0 +rule android.content.pm.FeatureFlags com.android.permission.jarjar.@0 +rule android.content.pm.Flags com.android.permission.jarjar.@0 rule android.os.*FeatureFlags* com.android.permission.jarjar.@0 rule android.os.FeatureFlags* com.android.permission.jarjar.@0 rule android.os.FeatureFlags com.android.permission.jarjar.@0 diff --git a/service/java/com/android/permission/util/UserUtils.java b/service/java/com/android/permission/util/UserUtils.java index 639c7aacb..986b5af5b 100644 --- a/service/java/com/android/permission/util/UserUtils.java +++ b/service/java/com/android/permission/util/UserUtils.java @@ -24,10 +24,10 @@ import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; +import android.permission.internal.compat.UserHandleCompat; import com.android.internal.util.Preconditions; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.compat.UserHandleCompat; import com.android.permission.flags.Flags; import java.util.List; diff --git a/service/java/com/android/role/RoleService.java b/service/java/com/android/role/RoleService.java index b8e3ad8b1..c4316ff71 100644 --- a/service/java/com/android/role/RoleService.java +++ b/service/java/com/android/role/RoleService.java @@ -45,6 +45,7 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; +import android.permission.internal.compat.UserHandleCompat; import android.permission.flags.Flags; import android.provider.Settings; import android.text.TextUtils; @@ -62,7 +63,6 @@ import com.android.internal.infra.AndroidFuture; import com.android.internal.util.Preconditions; import com.android.internal.util.dump.DualDumpOutputStream; import com.android.modules.utils.build.SdkLevel; -import com.android.permission.compat.UserHandleCompat; import com.android.permission.util.ArrayUtils; import com.android.permission.util.CollectionUtils; import com.android.permission.util.ForegroundThread; diff --git a/service/java/com/android/role/RoleShellCommand.java b/service/java/com/android/role/RoleShellCommand.java index 808a64cb4..41f0702a2 100644 --- a/service/java/com/android/role/RoleShellCommand.java +++ b/service/java/com/android/role/RoleShellCommand.java @@ -22,11 +22,11 @@ import android.app.role.IRoleManager; import android.os.Build; import android.os.RemoteCallback; import android.os.RemoteException; +import android.permission.internal.compat.UserHandleCompat; import androidx.annotation.RequiresApi; import com.android.modules.utils.BasicShellCommandHandler; -import com.android.permission.compat.UserHandleCompat; import java.io.PrintWriter; import java.util.List; diff --git a/service/java/com/android/safetycenter/UserProfileGroup.java b/service/java/com/android/safetycenter/UserProfileGroup.java index a78113b04..d4b051d0f 100644 --- a/service/java/com/android/safetycenter/UserProfileGroup.java +++ b/service/java/com/android/safetycenter/UserProfileGroup.java @@ -26,11 +26,11 @@ import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; +import android.permission.internal.compat.UserHandleCompat; import android.util.Log; import androidx.annotation.Nullable; -import com.android.permission.compat.UserHandleCompat; import com.android.permission.util.UserUtils; import java.lang.annotation.Retention; diff --git a/service/lint-baseline.xml b/service/lint-baseline.xml index b10928320..6aaf3da8c 100644 --- a/service/lint-baseline.xml +++ b/service/lint-baseline.xml @@ -35,17 +35,6 @@ </issue> <issue - id="NewApi" - message="Call requires API level 31 (current min is 30): `android.os.UserHandle#getUid`" - errorLine1=" return UserHandle.of(userId).getUid(appId);" - errorLine2=" ~~~~~~"> - <location - file="packages/modules/Permission/service/java/com/android/permission/compat/UserHandleCompat.java" - line="57" - column="38"/> - </issue> - - <issue id="FlaggedApi" message="Method `RolesState()` is a flagged API and should be inside an `if (Flags.systemServerRoleControllerEnabled())` check (or annotate the surrounding method `writeFile` with `@FlaggedApi(Flags.FLAG_SYSTEM_SERVER_ROLE_CONTROLLER_ENABLED) to transfer requirement to caller`)" errorLine1=" roles = new RolesState(mVersion, packagesHash," diff --git a/tests/cts/permission/src/android/permission/cts/NfcPermissionTest.java b/tests/cts/permission/src/android/permission/cts/NfcPermissionTest.java index 1b3f65ee6..fc5ea3a44 100644 --- a/tests/cts/permission/src/android/permission/cts/NfcPermissionTest.java +++ b/tests/cts/permission/src/android/permission/cts/NfcPermissionTest.java @@ -155,23 +155,6 @@ public final class NfcPermissionTest { } /** - * Verifies that isTagIntentAppPreferenceSupported() requires Permission. - * <p> - * Requires Permission: {@link android.Manifest.permission.WRITE_SECURE_SETTINGS}. - */ - @Test - @AppModeFull - public void testIsTagIntentAppPreferenceSupported() { - try { - mNfcAdapter.isTagIntentAppPreferenceSupported(); - fail("mNfcAdapter.isTagIntentAppPreferenceSupported() did not throw SecurityException" - + " as expected"); - } catch (SecurityException se) { - // Expected Exception - } - } - - /** * Verifies that getTagIntentAppPreferenceForUser() requires Permission. * <p> * Requires Permission: {@link android.Manifest.permission.WRITE_SECURE_SETTINGS}. diff --git a/tests/cts/permissionpolicy/res/raw/OWNERS b/tests/cts/permissionpolicy/res/raw/OWNERS index 6e1a91b88..4f0306f55 100644 --- a/tests/cts/permissionpolicy/res/raw/OWNERS +++ b/tests/cts/permissionpolicy/res/raw/OWNERS @@ -1,6 +1,5 @@ hackbod@google.com patb@google.com -yamasani@google.com michaelwr@google.com narayan@google.com roosa@google.com diff --git a/tests/cts/permissionpolicy/res/raw/android_manifest.xml b/tests/cts/permissionpolicy/res/raw/android_manifest.xml index 067364ac4..b8dad240d 100644 --- a/tests/cts/permissionpolicy/res/raw/android_manifest.xml +++ b/tests/cts/permissionpolicy/res/raw/android_manifest.xml @@ -898,13 +898,26 @@ android:featureFlag="android.provider.user_keys" /> <!-- Allows an application to set default account for new contacts. - <p> This permission is only granted to system applications fulfilling the Contacts app role. + <p>This permission is only granted to system applications fulfilling the Contacts app role. <p>Protection level: internal|role @SystemApi @hide --> <permission android:name="android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS" - android:protectionLevel="internal|role" /> + android:protectionLevel="internal|role" + android:featureFlag="!android.provider.new_default_account_api_enabled"/> + + <!-- Allows an application to set default account for new contacts. + <p>This permission is only granted to system applications fulfilling the Contacts app role + and the application with known signers. + <p>Protection level: internal|role|knownSigner + @SystemApi + @hide + --> + <permission android:name="android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS" + android:protectionLevel="internal|role|knownSigner" + android:knownCerts="@array/config_setContactsDefaultAccountKnownSigners" + android:featureFlag="android.provider.new_default_account_api_enabled"/> <!-- ====================================================================== --> <!-- Permissions for accessing user's calendar --> @@ -3965,6 +3978,37 @@ android:protectionLevel="normal" android:featureFlag="android.security.aapm_api"/> + <!-- Allows an application to read the state of the ForensicService + @FlaggedApi(android.security.Flags.FLAG_AFL_API) + @SystemApi + @hide --> + <permission android:name="android.permission.READ_FORENSIC_STATE" + android:featureFlag="android.security.afl_api" + android:protectionLevel="signature|privileged" /> + <uses-permission android:name="android.permission.READ_FORENSIC_STATE" + android:featureFlag="android.security.afl_api"/> + + <!-- Allows an application to change the state of the ForensicService + @FlaggedApi(android.security.Flags.FLAG_AFL_API) + @SystemApi + @hide --> + <permission android:name="android.permission.MANAGE_FORENSIC_STATE" + android:featureFlag="android.security.afl_api" + android:protectionLevel="signature|privileged" /> + <uses-permission android:name="android.permission.MANAGE_FORENSIC_STATE" + android:featureFlag="android.security.afl_api"/> + + <!-- Must be required by any ForensicEventTransportService to ensure that + only the system can bind to it. + @FlaggedApi(android.security.Flags.FLAG_AFL_API) + @SystemApi + @hide --> + <permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE" + android:featureFlag="android.security.afl_api" + android:protectionLevel="signature" /> + <uses-permission android:name="android.permission.BIND_FORENSIC_EVENT_TRANSPORT_SERVICE" + android:featureFlag="android.security.afl_api"/> + <!-- @SystemApi @hide Allows an application to set a device owner on retail demo devices.--> <permission android:name="android.permission.PROVISION_DEMO_DEVICE" android:protectionLevel="signature|setup|knownSigner" @@ -4108,6 +4152,52 @@ android:protectionLevel="signature" /> <!-- ================================== --> + <!-- Permissions associated with picture profiles and processing --> + <!-- ================================== --> + <eat-comment /> + + <!-- @FlaggedApi(android.media.tv.flags.Flags.apply_picture_profiles) + Allows an app to apply a {@link MediaQualityManager.PictureProfile} to a layer via + {@link MediaCodec.PARAMETER_KEY_PICTURE_PROFILE} and, additionally, system apps via + {@link SurfaceControl.Transaction#setPictureProfileHandle}. + --> + <permission android:name="android.permission.APPLY_PICTURE_PROFILE" + android:protectionLevel="normal" + android:featureFlag="android.media.tv.flags.apply_picture_profiles"/> + + <!-- @hide + Allows MediaQualityManager to observe any {@link MediaQualityManager.PictureProfile} + applied to any layer in the system by apps via + {@link MediaCodec.PARAMETER_KEY_PICTURE_PROFILE} and by system apps via + {@link SurfaceControl.Transaction#setPictureProfileHandle}. + --> + <permission android:name="android.permission.OBSERVE_PICTURE_PROFILES" + android:protectionLevel="signature|privileged" + android:featureFlag="android.media.tv.flags.apply_picture_profiles"/> + + <!-- + @SystemApi + @FlaggedApi("android.media.tv.flags.media_quality_fw") + Allows an application to access its picture profile from the media quality database. + <p> Protection level: signature|privileged|vendor privileged + @hide + --> + <permission android:name="android.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE" + android:protectionLevel="signature|privileged|vendorPrivileged" + android:featureFlag="android.media.tv.flags.media_quality_fw"/> + + <!-- + @SystemApi + @FlaggedApi("android.media.tv.flags.media_quality_fw") + Allows an application to access its sound profile from the media quality database. + <p> Protection level: signature|privileged|vendor privileged + @hide + --> + <permission android:name="android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE" + android:protectionLevel="signature|privileged|vendorPrivileged" + android:featureFlag="android.media.tv.flags.media_quality_fw"/> + + <!-- ================================== --> <!-- Permissions affecting the display of other applications --> <!-- ================================== --> <eat-comment /> @@ -4812,16 +4902,16 @@ android:protectionLevel="signature|privileged|role" android:featureFlag="com.android.settingslib.flags.settings_catalyst" /> - <!-- @FlaggedApi(com.android.settingslib.flags.Flags.FLAG_SETTINGS_CATALYST) + <!-- @FlaggedApi(com.android.settingslib.flags.Flags.FLAG_WRITE_SYSTEM_PREFERENCE_PERMISSION_ENABLED) Allows an application to access the Settings Preference services to write settings values exposed by the system Settings app and system apps that contribute settings surfaced in the Settings app. <p>This allows the calling application to write settings values through the host application, agnostic of underlying storage. - <p>Protection Level: signature|privileged|appop - appop to be added in followup --> + <p>Protection Level: signature|privileged|appop --> <permission android:name="android.permission.WRITE_SYSTEM_PREFERENCES" - android:protectionLevel="signature|privileged" - android:featureFlag="com.android.settingslib.flags.settings_catalyst" /> + android:protectionLevel="signature|privileged|appop" + android:featureFlag="com.android.settingslib.flags.write_system_preference_permission_enabled" /> <!-- ========================================= --> <!-- Permissions for special development tools --> @@ -5611,6 +5701,17 @@ <permission android:name="android.permission.LOCK_DEVICE" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi + @FlaggedApi(android.security.Flags.FLAG_SECURE_LOCKDOWN) + Allows an application to lock down the device into an enhanced security state. + <p>Not for use by third-party applications. + <p>Protection level: signature|privileged + @hide + --> + <permission android:name="android.permission.MANAGE_SECURE_LOCK_DEVICE" + android:protectionLevel="signature|privileged" + android:featureFlag="android.security.secure_lockdown" /> + <!-- @SystemApi Allows low-level access to setting the orientation (actually rotation) of the screen. <p>Not for use by third-party applications. @@ -6221,6 +6322,15 @@ <permission android:name="android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT" android:protectionLevel="signature|privileged|role" /> + <!-- @SystemApi Allows an application to bypass concurrency restrictions while + recording audio. For example, apps with this permission can continue to record + while a voice call is active.</p> + @FlaggedApi(android.media.audio.Flags.FLAG_CONCURRENT_AUDIO_RECORD_BYPASS_PERMISSION) + @hide --> + <permission android:name="android.permission.BYPASS_CONCURRENT_RECORD_AUDIO_RESTRICTION" + android:featureFlag="android.media.audio.concurrent_audio_record_bypass_permission" + android:protectionLevel="signature|privileged|role" /> + <!-- @SystemApi Allows an application to capture audio for hotword detection. <p>Not for use by third-party applications.</p> @hide --> @@ -7664,7 +7774,31 @@ <!-- @SystemApi Allows an application to access shared libraries. @hide --> <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES" - android:protectionLevel="signature|installer" /> + android:protectionLevel="signature|installer" + android:featureFlag="!android.content.pm.sdk_dependency_installer" /> + + <!-- @SystemApi Allows an application to access shared libraries. + @hide --> + <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES" + android:protectionLevel="signature|installer|role" + android:featureFlag="android.content.pm.sdk_dependency_installer" /> + + <!-- @SystemApi Permission held by the system to allow binding to the dependency installer role + holder. + @FlaggedApi(android.content.pm.Flags.FLAG_SDK_DEPENDENCY_INSTALLER) + @hide --> + <permission android:name="android.permission.BIND_DEPENDENCY_INSTALLER" + android:protectionLevel="signature" + android:featureFlag="android.content.pm.sdk_dependency_installer" /> + + <!-- @SystemApi Allows an application to install shared libraries of types + {@link android.content.pm.SharedLibraryInfo#TYPE_STATIC} or + {@link android.content.pm.SharedLibraryInfo#TYPE_SDK_PACKAGE}. + @FlaggedApi(android.content.pm.Flags.FLAG_SDK_DEPENDENCY_INSTALLER) + @hide --> + <permission android:name="android.permission.INSTALL_DEPENDENCY_SHARED_LIBRARIES" + android:protectionLevel="signature|role" + android:featureFlag="android.content.pm.sdk_dependency_installer" /> <!-- Allows an app to log compat change usage. @hide <p>Not for use by third-party applications.</p> --> @@ -8390,28 +8524,6 @@ android:protectionLevel="internal" android:featureFlag="android.content.pm.verification_service" /> - <!-- - @SystemApi - @FlaggedApi("android.media.tv.flags.media_quality_fw") - Allows an application to access its picture profile from the media quality database. - <p> Protection level: signature|privileged|vendor privileged - @hide - --> - <permission android:name="android.permission.MANAGE_GLOBAL_PICTURE_QUALITY_SERVICE" - android:protectionLevel="signature|privileged|vendorPrivileged" - android:featureFlag="android.media.tv.flags.media_quality_fw"/> - - <!-- - @SystemApi - @FlaggedApi("android.media.tv.flags.media_quality_fw") - Allows an application to access its sound profile from the media quality database. - <p> Protection level: signature|privileged|vendor privileged - @hide - --> - <permission android:name="android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE" - android:protectionLevel="signature|privileged|vendorPrivileged" - android:featureFlag="android.media.tv.flags.media_quality_fw"/> - <!-- Allows app to enter trade-in-mode. <p>Protection level: signature|privileged @hide @@ -8421,6 +8533,16 @@ android:featureFlag="com.android.tradeinmode.flags.enable_trade_in_mode" /> <!-- @SystemApi + @FlaggedApi(com.android.art.flags.Flags.FLAG_EXECUTABLE_METHOD_FILE_OFFSETS) + Ability to read program metadata and attach dynamic instrumentation. + <p>Protection level: signature + @hide + --> + <permission android:name="android.permission.DYNAMIC_INSTRUMENTATION" + android:protectionLevel="signature" + android:featureFlag="com.android.art.flags.executable_method_file_offsets" /> + + <!-- @SystemApi @FlaggedApi("android.media.tv.flags.kids_mode_tvdb_sharing") This permission is required when accessing information related to singleUser-ed TIS session. |