summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PermissionController/res/xml/roles.xml10
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/AppOp.java5
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Permission.java5
-rw-r--r--PermissionController/role-controller/java/com/android/role/controller/model/Role.java4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/LocationProviderDialogScreen.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/TEST_MAPPING4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt10
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearEnhancedConfirmationScreen.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionScreen.kt12
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionScreen.kt20
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsScreen.kt14
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageDetailsScreen.kt14
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt15
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt10
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt231
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/AlertDialog.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt)8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Chip.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt)31
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Icon.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Icon.kt)21
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListFooter.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListFooter.kt)6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListHeader.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt)12
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ResponsiveDialog.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt)10
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChip.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChip.kt)2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChipToggleControl.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChipToggleControl.kt)2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Wear2Scaffold.kt264
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnDefaults.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt)16
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnState.kt (renamed from PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt)6
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButton.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButtonStyle.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionConfirmationDialog.kt8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionListFooter.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionScaffold.kt2
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControl.kt23
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControlStyle.kt4
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListScreen.kt8
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppScreen.kt10
-rw-r--r--PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleScreen.kt2
-rw-r--r--SafetyCenter/Resources/res/raw-v36/safety_center_config.xml30
-rw-r--r--SafetyCenter/Resources/res/values-v36/config.xml21
-rw-r--r--SafetyCenter/Resources/res/values-v36/strings.xml33
-rw-r--r--tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt33
-rw-r--r--tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt35
-rw-r--r--tests/cts/role/Android.bp3
-rw-r--r--tests/cts/role/AndroidManifest.xml1
-rw-r--r--tests/cts/role/AndroidTest.xml3
-rw-r--r--tests/cts/role/src/android/app/role/cts/ChooseNoteRoleAppTest.kt70
48 files changed, 625 insertions, 419 deletions
diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml
index fb12ed0d0..69ea7b1b7 100644
--- a/PermissionController/res/xml/roles.xml
+++ b/PermissionController/res/xml/roles.xml
@@ -724,10 +724,6 @@
featureFlag="android.app.appfunctions.flags.Flags.enableAppFunctionManager" />
<permission name="android.permission.EXECUTE_APP_FUNCTIONS_TRUSTED"
featureFlag="android.app.appfunctions.flags.Flags.enableAppFunctionManager" />
- <permission name="android.permission.COPY_ACCOUNTS"
- featureFlag="android.app.admin.flags.Flags.splitCreateManagedProfileEnabled" />
- <permission name="android.permission.REMOVE_ACCOUNTS"
- featureFlag="android.app.admin.flags.Flags.splitCreateManagedProfileEnabled" />
</permissions>
</role>
@@ -1495,10 +1491,8 @@
<permission name="android.permission.MANAGE_DEVICE_POLICY_SMS" minSdkVersion="35" />
<permission name="android.permission.MANAGE_DEVICE_POLICY_APP_FUNCTIONS"
featureFlag="android.app.appfunctions.flags.Flags.enableAppFunctionManager" />
- <permission name="android.permission.COPY_ACCOUNTS"
- featureFlag="android.app.admin.flags.Flags.splitCreateManagedProfileEnabled" />
- <permission name="android.permission.REMOVE_ACCOUNTS"
- featureFlag="android.app.admin.flags.Flags.splitCreateManagedProfileEnabled" />
+ <permission name="android.permission.MANAGE_DEFAULT_APPLICATIONS" minSdkVersion="36"
+ featureFlag="com.android.permission.flags.Flags.crossUserRoleEnabled" />
</permissions>
</role>
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/AppOp.java b/PermissionController/role-controller/java/com/android/role/controller/model/AppOp.java
index 56c4944a0..99145c747 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/AppOp.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/AppOp.java
@@ -26,6 +26,7 @@ import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.modules.utils.build.SdkLevel;
+import com.android.role.controller.util.RoleFlags;
import com.android.role.controller.util.PackageUtils;
import java.util.Objects;
@@ -137,8 +138,8 @@ public class AppOp {
return false;
}
return Build.VERSION.SDK_INT >= mMinSdkVersion
- // Workaround to match the value 35 for V in roles.xml before SDK finalization.
- || (mMinSdkVersion == 35 && SdkLevel.isAtLeastV());
+ // Workaround to match the value 36 for B in roles.xml before SDK finalization.
+ || (mMinSdkVersion == 36 && RoleFlags.isAtLeastB());
}
private boolean isAvailableAsUser(@NonNull String packageName,
diff --git a/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java b/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java
index 05b19ff94..889f5263d 100644
--- a/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java
+++ b/PermissionController/role-controller/java/com/android/role/controller/model/Permission.java
@@ -26,6 +26,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.modules.utils.build.SdkLevel;
+import com.android.role.controller.util.RoleFlags;
import com.android.role.controller.util.UserUtils;
import java.util.Objects;
@@ -97,8 +98,8 @@ public class Permission {
return false;
}
if (Build.VERSION.SDK_INT >= mMinSdkVersion
- // Workaround to match the value 35 for V in roles.xml before SDK finalization.
- || (mMinSdkVersion == 35 && SdkLevel.isAtLeastV())) {
+ // Workaround to match the value 36 for B in roles.xml before SDK finalization.
+ || (mMinSdkVersion == 36 && RoleFlags.isAtLeastB())) {
return true;
}
if (Build.VERSION.SDK_INT >= mOptionalMinSdkVersion) {
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 1d49b3c1a..9773b93a9 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
@@ -502,8 +502,8 @@ public class Role {
return false;
}
return (Build.VERSION.SDK_INT >= mMinSdkVersion
- // Workaround to match the value 35 for V in roles.xml before SDK finalization.
- || (mMinSdkVersion == 35 && SdkLevel.isAtLeastV()))
+ // Workaround to match the value 36 for B in roles.xml before SDK finalization.
+ || (mMinSdkVersion == 36 && RoleFlags.isAtLeastB()))
&& Build.VERSION.SDK_INT <= mMaxSdkVersion;
}
diff --git a/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt b/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt
index 5f9f58221..116b52cfb 100644
--- a/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/incident/wear/WearConfirmationScreen.kt
@@ -30,7 +30,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.wear.compose.material.CircularProgressIndicator
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionConfirmationDialog
import com.android.permissioncontroller.permission.ui.wear.theme.ResourceHelper
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/LocationProviderDialogScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/LocationProviderDialogScreen.kt
index 510d19706..691ceae25 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/LocationProviderDialogScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/LocationProviderDialogScreen.kt
@@ -26,7 +26,7 @@ import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.SwipeToDismissBox
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionScaffold
import com.android.permissioncontroller.permission.ui.wear.model.LocationProviderInterceptDialogArgs
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/TEST_MAPPING b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/TEST_MAPPING
index da2dcd839..3cc91855d 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/TEST_MAPPING
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/TEST_MAPPING
@@ -15,10 +15,6 @@
{
// Flaky
"exclude-filter": "android.permissionui.cts.EnhancedConfirmationManagerTest"
- },
- {
- // Currently failing (b/387705174)
- "exclude-filter": "android.permissionui.cts.PermissionTapjackingTest"
}
]
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt
index 13fb30d73..686dd1b62 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionGroupsScreen.kt
@@ -25,11 +25,11 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import com.android.permissioncontroller.R
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChip
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionConfirmationDialog
import com.android.permissioncontroller.permission.ui.wear.model.RevokeDialogArgs
import com.android.permissioncontroller.permission.ui.wear.theme.ResourceHelper
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt
index 0b96214a2..55db66d41 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearAppPermissionScreen.kt
@@ -30,16 +30,16 @@ import com.android.permissioncontroller.permission.ui.model.AppPermissionViewMod
import com.android.permissioncontroller.permission.ui.model.AppPermissionViewModel.ButtonState
import com.android.permissioncontroller.permission.ui.model.AppPermissionViewModel.ButtonType
import com.android.permissioncontroller.permission.ui.v33.AdvancedConfirmDialogArgs
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
-import com.android.permissioncontroller.permission.ui.wear.elements.ListFooter
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChip
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ListFooter
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.toggleChipDisabledColors
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionConfirmationDialog
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionIconBuilder
import com.android.permissioncontroller.permission.ui.wear.elements.material3.defaultAlertConfirmIcon
import com.android.permissioncontroller.permission.ui.wear.elements.material3.defaultAlertDismissIcon
-import com.android.permissioncontroller.permission.ui.wear.elements.toggleChipDisabledColors
import com.android.permissioncontroller.permission.ui.wear.model.AppPermissionConfirmDialogViewModel
import com.android.permissioncontroller.permission.ui.wear.model.ConfirmDialogArgs
import com.android.permissioncontroller.permission.ui.wear.theme.ResourceHelper
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearEnhancedConfirmationScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearEnhancedConfirmationScreen.kt
index 0f37511de..a0e41b579 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearEnhancedConfirmationScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearEnhancedConfirmationScreen.kt
@@ -43,11 +43,11 @@ import com.android.permissioncontroller.permission.ui.wear.elements.CheckYourPho
import com.android.permissioncontroller.permission.ui.wear.elements.CheckYourPhoneState
import com.android.permissioncontroller.permission.ui.wear.elements.CheckYourPhoneState.InProgress
import com.android.permissioncontroller.permission.ui.wear.elements.CheckYourPhoneState.Success
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
import com.android.permissioncontroller.permission.ui.wear.elements.dismiss
import com.android.permissioncontroller.permission.ui.wear.elements.findActivity
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionConfirmationDialog
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionIconBuilder
import com.android.permissioncontroller.permission.ui.wear.model.WearEnhancedConfirmationViewModel
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
index 4670cfb78..35c2ab046 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearGrantPermissionsScreen.kt
@@ -42,7 +42,7 @@ import com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.N
import com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.NO_UPGRADE_OT_BUTTON
import com.android.permissioncontroller.permission.ui.wear.GrantPermissionsWearViewHandler.BUTTON_RES_ID_TO_NUM
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButton
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionToggleControl
import com.android.permissioncontroller.permission.ui.wear.model.WearGrantPermissionsViewModel
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionScreen.kt
index 1563f6a57..15d4cd370 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageCustomPermissionScreen.kt
@@ -25,13 +25,13 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.ui.model.ManageCustomPermissionsViewModel
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
@Composable
fun WearManageCustomPermissionScreen(
viewModel: ManageCustomPermissionsViewModel,
- onPermGroupClick: (String) -> Unit
+ onPermGroupClick: (String) -> Unit,
) {
val permissionGroups = viewModel.uiDataLiveData.observeAsState(emptyMap())
var isLoading by remember { mutableStateOf(true) }
@@ -39,7 +39,7 @@ fun WearManageCustomPermissionScreen(
WearManageCustomPermissionContent(
isLoading,
getPermGroupChipParams(permissionGroups.value),
- onPermGroupClick
+ onPermGroupClick,
)
if (isLoading && permissionGroups.value.isNotEmpty()) {
@@ -51,11 +51,11 @@ fun WearManageCustomPermissionScreen(
internal fun WearManageCustomPermissionContent(
isLoading: Boolean,
permGroupChipParams: List<PermGroupChipParam>,
- onPermGroupClick: (String) -> Unit
+ onPermGroupClick: (String) -> Unit,
) {
ScrollableScreen(
title = stringResource(R.string.additional_permissions),
- isLoading = isLoading
+ isLoading = isLoading,
) {
for (params in permGroupChipParams) {
item {
@@ -65,7 +65,7 @@ internal fun WearManageCustomPermissionContent(
icon = params.icon,
secondaryLabel = params.secondaryLabel,
secondaryLabelMaxLines = 3,
- onClick = { onPermGroupClick(params.permGroupName) }
+ onClick = { onPermGroupClick(params.permGroupName) },
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionScreen.kt
index 9aacd65d3..20f87f6ba 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearManageStandardPermissionScreen.kt
@@ -29,8 +29,8 @@ import androidx.compose.ui.res.stringResource
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.model.livedatatypes.PermGroupPackagesUiInfo
import com.android.permissioncontroller.permission.ui.model.ManageStandardPermissionsViewModel
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
import com.android.permissioncontroller.permission.utils.KotlinUtils.getPermGroupIcon
import com.android.permissioncontroller.permission.utils.KotlinUtils.getPermGroupLabel
import com.android.permissioncontroller.permission.utils.StringUtils
@@ -42,7 +42,7 @@ fun WearManageStandardPermissionScreen(
viewModel: ManageStandardPermissionsViewModel,
onPermGroupClick: (String) -> Unit,
onCustomPermissionsClick: () -> Unit,
- onAutoRevokedClick: () -> Unit
+ onAutoRevokedClick: () -> Unit,
) {
val permissionGroups = viewModel.uiDataLiveData.observeAsState(emptyMap())
val numCustomPermGroups = viewModel.numCustomPermGroups.observeAsState(0)
@@ -56,7 +56,7 @@ fun WearManageStandardPermissionScreen(
numAutoRevoked.value,
onPermGroupClick,
onCustomPermissionsClick,
- onAutoRevokedClick
+ onAutoRevokedClick,
)
if (isLoading && permissionGroups.value.isNotEmpty()) {
@@ -92,7 +92,7 @@ internal fun getPermGroupChipParams(
label = getPermGroupLabel(context, it.key).toString(),
icon = getPermGroupIcon(context, it.key),
secondaryLabel =
- stringResource(summary, uiInfo.nonSystemGranted, uiInfo.nonSystemTotal)
+ stringResource(summary, uiInfo.nonSystemGranted, uiInfo.nonSystemTotal),
)
}
.sortedWith { lhs, rhs -> collator.compare(lhs.label, rhs.label) }
@@ -107,11 +107,11 @@ internal fun WearManageStandardPermissionContent(
numAutoRevoked: Int,
onPermGroupClick: (String) -> Unit,
onCustomPermissionsClick: () -> Unit,
- onAutoRevokedClick: () -> Unit
+ onAutoRevokedClick: () -> Unit,
) {
ScrollableScreen(
title = stringResource(R.string.app_permission_manager),
- isLoading = isLoading
+ isLoading = isLoading,
) {
for (params in permGroupChipParams) {
item {
@@ -121,7 +121,7 @@ internal fun WearManageStandardPermissionContent(
icon = params.icon,
secondaryLabel = params.secondaryLabel,
secondaryLabelMaxLines = 3,
- onClick = { onPermGroupClick(params.permGroupName) }
+ onClick = { onPermGroupClick(params.permGroupName) },
)
}
}
@@ -136,10 +136,10 @@ internal fun WearManageStandardPermissionContent(
StringUtils.getIcuPluralsString(
LocalContext.current,
R.string.additional_permissions_more,
- numCustomPermGroups
+ numCustomPermGroups,
),
secondaryLabelMaxLines = 3,
- onClick = onCustomPermissionsClick
+ onClick = onCustomPermissionsClick,
)
}
}
@@ -152,7 +152,7 @@ internal fun WearManageStandardPermissionContent(
icon = R.drawable.ic_info,
secondaryLabel = stringResource(R.string.auto_revoke_setting_subtitle),
secondaryLabelMaxLines = 3,
- onClick = onAutoRevokedClick
+ onClick = onAutoRevokedClick,
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsScreen.kt
index 8e779cb8c..00ebf2f34 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionAppsScreen.kt
@@ -32,9 +32,9 @@ import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Text
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.ui.Category
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
-import com.android.permissioncontroller.permission.ui.wear.elements.ListSubheader
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ListSubheader
/** Compose the screen associated to a [WearPermissionAppsFragment]. */
@Composable
@@ -65,7 +65,7 @@ fun WearPermissionAppsScreen(helper: WearPermissionAppsHelper) {
subtitle = subTitle,
showAlways = showAlways,
isLoading = isLoading,
- onShowSystemClick = helper.onShowSystemClick
+ onShowSystemClick = helper.onShowSystemClick,
)
}
}
@@ -84,7 +84,7 @@ internal fun WearPermissionAppsContent(
subtitle: String,
showAlways: Boolean,
isLoading: Boolean,
- onShowSystemClick: (showSystem: Boolean) -> Unit
+ onShowSystemClick: (showSystem: Boolean) -> Unit,
) {
ScrollableScreen(title = title, subtitle = subtitle, isLoading = isLoading) {
val firstItemIndex = categoryOrder.indexOfFirst { !chipsByCategory[it].isNullOrEmpty() }
@@ -100,7 +100,7 @@ internal fun WearPermissionAppsContent(
top = if (index == firstItemIndex) 0.dp else 12.dp,
bottom = 4.dp,
start = 14.dp,
- end = 14.dp
+ end = 14.dp,
)
) {
Text(text = stringResource(getCategoryString(category, showAlways)))
@@ -116,7 +116,7 @@ internal fun WearPermissionAppsContent(
icon = it.icon,
enabled = it.enabled,
onClick = { it.onClick() },
- modifier = Modifier.fillMaxWidth()
+ modifier = Modifier.fillMaxWidth(),
)
}
}
@@ -163,5 +163,5 @@ internal val categoryOrder =
Category.ALLOWED.categoryName,
Category.ALLOWED_FOREGROUND.categoryName,
Category.ASK.categoryName,
- Category.DENIED.categoryName
+ Category.DENIED.categoryName,
)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageDetailsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageDetailsScreen.kt
index 1259c1ab5..63a6cd5a5 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageDetailsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageDetailsScreen.kt
@@ -37,15 +37,15 @@ import com.android.permissioncontroller.permission.ui.model.v31.BasePermissionUs
import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageDetailsViewModel
import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageDetailsViewModel.AppPermissionAccessUiInfo
import com.android.permissioncontroller.permission.ui.model.v31.PermissionUsageDetailsViewModel.PermissionUsageDetailsUiState
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
import com.android.permissioncontroller.permission.utils.KotlinUtils
@RequiresApi(Build.VERSION_CODES.S)
@Composable
fun WearPermissionUsageDetailsScreen(
permissionGroup: String,
- viewModel: BasePermissionUsageDetailsViewModel
+ viewModel: BasePermissionUsageDetailsViewModel,
) {
val context = LocalContext.current
val uiData = viewModel.getPermissionUsagesDetailsInfoUiLiveData().observeAsState(null)
@@ -56,7 +56,7 @@ fun WearPermissionUsageDetailsScreen(
val subtitle =
stringResource(
R.string.permission_group_usage_title,
- KotlinUtils.getPermGroupLabel(context, permissionGroup)
+ KotlinUtils.getPermGroupLabel(context, permissionGroup),
)
val hasSystemApps: Boolean =
@@ -80,7 +80,7 @@ fun WearPermissionUsageDetailsScreen(
uiInfo.accessStartTime,
uiInfo.accessEndTime,
uiInfo.showingAttribution,
- uiInfo.attributionTags
+ uiInfo.attributionTags,
)
context.startActivityAsUser(intent, uiInfo.userHandle)
}
@@ -108,7 +108,7 @@ fun WearPermissionUsageDetailsScreen(
onShowSystemClick,
appPermissionAccessUiInfoList,
onChipClick,
- onManagePermissionClick
+ onManagePermissionClick,
)
if (isLoading && uiData.value != null) {
@@ -126,7 +126,7 @@ internal fun WearPermissionUsageDetailsContent(
onShowSystemClick: (Boolean) -> Unit,
appPermissionAccessUiInfoList: List<AppPermissionAccessUiInfo>,
onChipClick: (AppPermissionAccessUiInfo) -> Unit,
- onManagePermissionClick: () -> Unit
+ onManagePermissionClick: () -> Unit,
) {
ScrollableScreen(title = title, subtitle = subtitle, isLoading = isLoading) {
if (appPermissionAccessUiInfoList.isEmpty()) {
@@ -142,7 +142,7 @@ internal fun WearPermissionUsageDetailsContent(
.format(uiInfo.accessEndTime),
secondaryLabelMaxLines = Int.MAX_VALUE,
icon = uiInfo.badgedPackageIcon,
- onClick = { onChipClick(uiInfo) }
+ onClick = { onChipClick(uiInfo) },
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt
index f83d3338d..20e0dd69b 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearPermissionUsageScreen.kt
@@ -32,17 +32,14 @@ import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.ui.handheld.v31.PermissionUsageControlPreference
import com.android.permissioncontroller.permission.ui.viewmodel.v31.PermissionUsageViewModel
import com.android.permissioncontroller.permission.ui.viewmodel.v31.PermissionUsagesUiState
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
import com.android.permissioncontroller.permission.utils.Utils
import java.text.Collator
@RequiresApi(Build.VERSION_CODES.S)
@Composable
-fun WearPermissionUsageScreen(
- sessionId: Long,
- viewModel: PermissionUsageViewModel,
-) {
+fun WearPermissionUsageScreen(sessionId: Long, viewModel: PermissionUsageViewModel) {
val context = LocalContext.current
val permissionUsagesUiData = viewModel.permissionUsagesUiLiveData.observeAsState(null)
val showSystem = viewModel.showSystemAppsLiveData.observeAsState(false)
@@ -97,7 +94,7 @@ fun WearPermissionUsageScreen(
hasSystemApps,
showSystem.value,
onShowSystemClick,
- permissionGroupPreferences
+ permissionGroupPreferences,
)
if (isLoading && isDataLoaded) {
@@ -111,11 +108,11 @@ internal fun WearPermissionUsageContent(
hasSystemApps: Boolean,
showSystem: Boolean,
onShowSystemClick: (Boolean) -> Unit,
- permissionGroupPreferences: List<PermissionUsageControlPreference>
+ permissionGroupPreferences: List<PermissionUsageControlPreference>,
) {
ScrollableScreen(
title = stringResource(R.string.permission_usage_title),
- isLoading = isLoading
+ isLoading = isLoading,
) {
if (permissionGroupPreferences.isEmpty()) {
item { Chip(label = stringResource(R.string.no_permissions), onClick = {}) }
@@ -129,7 +126,7 @@ internal fun WearPermissionUsageContent(
secondaryLabelMaxLines = Int.MAX_VALUE,
icon = preference.icon,
enabled = preference.isEnabled,
- onClick = { preference.performClick() }
+ onClick = { preference.performClick() },
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt
index 423fa7759..9170b7d20 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/WearUnusedAppsScreen.kt
@@ -25,9 +25,9 @@ import com.android.permissioncontroller.R
import com.android.permissioncontroller.hibernation.isHibernationEnabled
import com.android.permissioncontroller.permission.ui.model.UnusedAppsViewModel.UnusedPeriod
import com.android.permissioncontroller.permission.ui.model.UnusedAppsViewModel.UnusedPeriod.Companion.allPeriods
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
-import com.android.permissioncontroller.permission.ui.wear.elements.Icon
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Icon
import com.android.permissioncontroller.permission.ui.wear.model.WearUnusedAppsViewModel
@Composable
@@ -43,7 +43,7 @@ fun WearUnusedAppsScreen(viewModel: WearUnusedAppsViewModel) {
showTimeText = true,
title = getScreenTitle(),
isLoading = loading.value,
- subtitle = getSubTitle(!infoMsgCategoryVisibility.value)
+ subtitle = getSubTitle(!infoMsgCategoryVisibility.value),
) {
for (period in allPeriods) {
if (!unusedAppChips.value.containsKey(period)) {
@@ -62,7 +62,7 @@ fun WearUnusedAppsScreen(viewModel: WearUnusedAppsViewModel) {
secondaryLabel = unusedAppChip.summary,
icon = unusedAppChip.icon,
iconContentDescription = unusedAppChip.contentDescription,
- onClick = unusedAppChip.onClick
+ onClick = unusedAppChip.onClick,
)
}
}
@@ -108,5 +108,5 @@ private fun posByPeriod(period: UnusedPeriod) =
private fun categoryTitleByPeriod(period: UnusedPeriod) =
MessageFormat.format(
stringResource(R.string.last_opened_category_title),
- mapOf("count" to period.months)
+ mapOf("count" to period.months),
)
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt
index b84f840cf..d01692159 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ScrollableScreen.kt
@@ -19,56 +19,20 @@ package com.android.permissioncontroller.permission.ui.wear.elements
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
-import android.graphics.drawable.Drawable
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.focusRequester
-import androidx.compose.ui.graphics.ColorFilter
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
import androidx.fragment.app.FragmentActivity
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.compose.LocalLifecycleOwner
-import androidx.lifecycle.repeatOnLifecycle
import androidx.wear.compose.foundation.SwipeToDismissValue
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
-import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
-import androidx.wear.compose.foundation.lazy.ScalingLazyListState
import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState
-import androidx.wear.compose.material.CircularProgressIndicator
-import androidx.wear.compose.material.MaterialTheme
-import androidx.wear.compose.material.PositionIndicator
-import androidx.wear.compose.material.Scaffold
import androidx.wear.compose.material.SwipeToDismissBox
-import androidx.wear.compose.material.Text
-import androidx.wear.compose.material.TimeText
-import androidx.wear.compose.material.Vignette
-import androidx.wear.compose.material.VignettePosition
-import androidx.wear.compose.material.scrollAway
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionScaffold
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion.MATERIAL2_5
-import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme
/**
* Screen that contains a list of items defined using the [content] parameter, adds the time text
@@ -135,201 +99,6 @@ fun ScrollableScreen(
}
}
-@Composable
-internal fun Wear2Scaffold(
- showTimeText: Boolean,
- title: String?,
- subtitle: CharSequence?,
- image: Any?,
- isLoading: Boolean,
- content: ScalingLazyListScope.() -> Unit,
- titleTestTag: String? = null,
- subtitleTestTag: String? = null,
-) {
- val itemsSpacedBy = 4.dp
- val screenWidth = LocalConfiguration.current.screenWidthDp
- val screenHeight = LocalConfiguration.current.screenHeightDp
- val scrollContentHorizontalPadding = (screenWidth * 0.052).dp
- val titleHorizontalPadding = (screenWidth * 0.0884).dp
- val subtitleHorizontalPadding = (screenWidth * 0.0416).dp
- val scrollContentTopPadding = (screenHeight * 0.1456).dp - itemsSpacedBy
- val scrollContentBottomPadding = (screenHeight * 0.3636).dp
- val titleBottomPadding =
- if (subtitle == null) {
- 8.dp
- } else {
- 4.dp
- }
- val subtitleBottomPadding = 8.dp
- val timeTextTopPadding =
- if (showTimeText) {
- 1.dp
- } else {
- 0.dp
- }
- val titlePaddingValues =
- PaddingValues(
- start = titleHorizontalPadding,
- top = 4.dp,
- bottom = titleBottomPadding,
- end = titleHorizontalPadding,
- )
- val subTitlePaddingValues =
- PaddingValues(
- start = subtitleHorizontalPadding,
- top = 4.dp,
- bottom = subtitleBottomPadding,
- end = subtitleHorizontalPadding,
- )
- val initialCenterIndex = 0
- val centerHeightDp = Dp(LocalConfiguration.current.screenHeightDp / 2.0f)
- // We are adding TimeText's padding to create a smooth scrolling
- val initialCenterItemScrollOffset = scrollContentTopPadding + timeTextTopPadding
- val scrollAwayOffset = centerHeightDp - initialCenterItemScrollOffset
- val focusRequester = remember { FocusRequester() }
- val listState = remember { ScalingLazyListState(initialCenterItemIndex = initialCenterIndex) }
- LaunchedEffect(title) {
- listState.animateScrollToItem(index = 0) // Scroll to the top when triggerValue changes
- }
- WearPermissionTheme {
- Scaffold(
- modifier = Modifier.focusRequester(focusRequester),
- timeText = {
- if (showTimeText && !isLoading) {
- TimeText(
- modifier =
- Modifier.scrollAway(listState, initialCenterIndex, scrollAwayOffset)
- .padding(top = timeTextTopPadding)
- )
- }
- },
- vignette = { Vignette(vignettePosition = VignettePosition.TopAndBottom) },
- positionIndicator =
- if (!isLoading) {
- { PositionIndicator(scalingLazyListState = listState) }
- } else {
- null
- },
- ) {
- Box(modifier = Modifier.fillMaxSize()) {
- if (isLoading) {
- CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
- } else {
- val iconColor = chipDefaultColors().iconColor(true).value
- ScalingLazyColumn(
- modifier = Modifier.fillMaxWidth(),
- state = listState,
- // Set autoCentering to null to avoid adding extra padding based on the
- // content.
- autoCentering = null,
- contentPadding =
- PaddingValues(
- start = scrollContentHorizontalPadding,
- end = scrollContentHorizontalPadding,
- top = scrollContentTopPadding,
- bottom = scrollContentBottomPadding,
- ),
- ) {
- staticItem()
- image?.let {
- val imageModifier = Modifier.size(24.dp)
- when (image) {
- is Int ->
- item {
- Image(
- painter = painterResource(id = image),
- contentDescription = null,
- contentScale = ContentScale.Crop,
- modifier = imageModifier,
- colorFilter = ColorFilter.tint(iconColor),
- )
- }
- is Drawable ->
- item {
- Image(
- painter = rememberDrawablePainter(image),
- contentDescription = null,
- contentScale = ContentScale.Crop,
- modifier = imageModifier,
- colorFilter = ColorFilter.tint(iconColor),
- )
- }
- else -> {}
- }
- }
- if (title != null) {
- item {
- var modifier: Modifier = Modifier
- if (titleTestTag != null) {
- modifier = modifier.testTag(titleTestTag)
- }
- ListHeader(modifier = Modifier.padding(titlePaddingValues)) {
- Text(
- text = title,
- textAlign = TextAlign.Center,
- modifier = modifier,
- )
- }
- }
- }
- if (subtitle != null) {
- item {
- var modifier: Modifier =
- Modifier.align(Alignment.Center).padding(subTitlePaddingValues)
- if (subtitleTestTag != null) {
- modifier = modifier.testTag(subtitleTestTag)
- }
- AnnotatedText(
- text = subtitle,
- style =
- MaterialTheme.typography.body2.copy(
- color = MaterialTheme.colors.onSurfaceVariant
- ),
- modifier = modifier,
- shouldCapitalize = true,
- )
- }
- }
-
- content()
- }
- RequestFocusOnResume(focusRequester = focusRequester)
- }
- }
- }
- }
-}
-
-private fun ScalingLazyListScope.staticItem() {
- /*
- This empty item helps to ensure accurate scroll offset calculation. If auto centering is enabled
- initial item's(first item for us) center matches the center of the screen. Scroll offset is 0 at
- that point.
-
- if auto centering is not enabled, initial item will start at the top of the screen with the
- scroll offset equal to ScreenHeight/2 - scrollContentTopPadding - firstItemHeight/2.
-
- We need to this offset value to properly move time text.That is the scroll-away offset of the
- Time Text is equal to the scroll offset of the list at initial position.
-
- It is easier to calculate if we know the values of ScreenHeight, ScrollContentTopPadding and
- FirstItem's height. ScreenHeight and ScrollContentPadding are constants but height of the
- FirstItem depends on the content. Instead of measuring the height, we can simplify the
- calculation with an empty item with 0dp height.
- */
- item {}
-}
-
-@Composable
-private fun RequestFocusOnResume(focusRequester: FocusRequester) {
- val lifecycleOwner = LocalLifecycleOwner.current
- LaunchedEffect(Unit) {
- lifecycleOwner.repeatOnLifecycle(state = Lifecycle.State.RESUMED) {
- focusRequester.requestFocus()
- }
- }
-}
-
internal fun dismiss(activity: Activity) {
if (activity is FragmentActivity) {
if (!activity.supportFragmentManager.popBackStackImmediate()) {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/AlertDialog.kt
index a700c02e2..2bd72624f 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/AlertDialog.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/AlertDialog.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
@@ -34,9 +34,9 @@ import androidx.wear.compose.material.LocalTextStyle
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.dialog.Dialog
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.rememberColumnState
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnDefaults
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnState
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.rememberColumnState
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionIconBuilder
data class DialogButtonContent(
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Chip.kt
index 40f097c67..15542ec20 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Chip.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Chip.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import android.graphics.drawable.Drawable
import androidx.annotation.StringRes
@@ -46,6 +46,7 @@ import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.contentColorFor
+import com.android.permissioncontroller.permission.ui.wear.elements.rememberDrawablePainter
/**
* This component is an alternative to [Chip], providing the following:
@@ -67,7 +68,7 @@ fun Chip(
textColor: Color = MaterialTheme.colors.onSurface,
iconColor: Color = Color.Unspecified,
colors: ChipColors = chipDefaultColors(),
- enabled: Boolean = true
+ enabled: Boolean = true,
) {
val iconParam: (@Composable BoxScope.() -> Unit)? =
icon?.let {
@@ -87,21 +88,21 @@ fun Chip(
imageVector = icon,
tint = iconColor,
contentDescription = iconContentDescription,
- modifier = iconModifier
+ modifier = iconModifier,
)
is Int ->
Icon(
painter = painterResource(id = icon),
tint = iconColor,
contentDescription = iconContentDescription,
- modifier = iconModifier
+ modifier = iconModifier,
)
is Drawable ->
Icon(
painter = rememberDrawablePainter(icon),
tint = iconColor,
contentDescription = iconContentDescription,
- modifier = iconModifier
+ modifier = iconModifier,
)
else -> {}
}
@@ -120,7 +121,7 @@ fun Chip(
largeIcon = largeIcon,
textColor = textColor,
colors = colors,
- enabled = enabled
+ enabled = enabled,
)
}
@@ -143,7 +144,7 @@ fun Chip(
textColor: Color = MaterialTheme.colors.onSurface,
iconColor: Color = Color.Unspecified,
colors: ChipColors = chipDefaultColors(),
- enabled: Boolean = true
+ enabled: Boolean = true,
) {
Chip(
label = stringResource(id = labelId),
@@ -157,7 +158,7 @@ fun Chip(
textColor = textColor,
iconColor = iconColor,
colors = colors,
- enabled = enabled
+ enabled = enabled,
)
}
@@ -180,7 +181,7 @@ fun Chip(
textColor: Color = MaterialTheme.colors.onSurface,
secondaryTextColor: Color = MaterialTheme.colors.primary,
colors: ChipColors = chipDefaultColors(),
- enabled: Boolean = true
+ enabled: Boolean = true,
) {
val hasSecondaryLabel = secondaryLabel != null
val hasIcon = icon != null
@@ -196,8 +197,8 @@ fun Chip(
style =
MaterialTheme.typography.button.copy(
fontWeight = FontWeight.W600,
- hyphens = Hyphens.Auto
- )
+ hyphens = Hyphens.Auto,
+ ),
)
}
@@ -209,7 +210,7 @@ fun Chip(
color = secondaryTextColor,
overflow = TextOverflow.Ellipsis,
maxLines = secondaryLabelMaxLines ?: 1,
- style = MaterialTheme.typography.caption2
+ style = MaterialTheme.typography.caption2,
)
}
}
@@ -221,7 +222,7 @@ fun Chip(
start = 10.dp,
top = verticalPadding,
end = ChipDefaults.ChipHorizontalPadding,
- bottom = verticalPadding
+ bottom = verticalPadding,
)
} else {
ChipDefaults.ContentPadding
@@ -236,7 +237,7 @@ fun Chip(
colors = colors,
enabled = enabled,
contentPadding = contentPadding,
- shape = RoundedCornerShape(26.dp)
+ shape = RoundedCornerShape(26.dp),
)
}
@@ -258,6 +259,6 @@ fun chipDisabledColors(): ChipColors {
backgroundColor = backgroundColor.copy(alpha = ContentAlpha.disabled),
contentColor = contentColor.copy(alpha = ContentAlpha.disabled),
secondaryContentColor = secondaryContentColor.copy(alpha = ContentAlpha.disabled),
- iconColor = iconColor.copy(alpha = ContentAlpha.disabled)
+ iconColor = iconColor.copy(alpha = ContentAlpha.disabled),
)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Icon.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Icon.kt
index 1a304b37e..3cfac7eef 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/Icon.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Icon.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import android.graphics.drawable.Drawable
import androidx.annotation.DrawableRes
@@ -29,6 +29,7 @@ import androidx.compose.ui.unit.LayoutDirection
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.LocalContentAlpha
import androidx.wear.compose.material.LocalContentColor
+import com.android.permissioncontroller.permission.ui.wear.elements.rememberDrawablePainter
/**
* This component is an alternative to [Icon], providing the following:
@@ -40,7 +41,7 @@ public fun Icon(
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
- rtlMode: IconRtlMode = IconRtlMode.Default
+ rtlMode: IconRtlMode = IconRtlMode.Default,
) {
val shouldMirror =
rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
@@ -48,7 +49,7 @@ public fun Icon(
modifier = modifier.scale(scaleX = if (shouldMirror) -1f else 1f, scaleY = 1f),
imageVector = imageVector,
contentDescription = contentDescription,
- tint = tint
+ tint = tint,
)
}
@@ -62,7 +63,7 @@ public fun Icon(
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
- rtlMode: IconRtlMode = IconRtlMode.Default
+ rtlMode: IconRtlMode = IconRtlMode.Default,
) {
val shouldMirror =
rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
@@ -71,7 +72,7 @@ public fun Icon(
painter = painterResource(id = id),
contentDescription = contentDescription,
modifier = modifier.scale(scaleX = if (shouldMirror) -1f else 1f, scaleY = 1f),
- tint = tint
+ tint = tint,
)
}
@@ -86,7 +87,7 @@ fun Icon(
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
- rtlMode: IconRtlMode = IconRtlMode.Default
+ rtlMode: IconRtlMode = IconRtlMode.Default,
) {
val shouldMirror =
rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
@@ -98,7 +99,7 @@ fun Icon(
imageVector = icon,
modifier = iconModifier,
contentDescription = contentDescription,
- tint = tint
+ tint = tint,
)
}
is Int -> {
@@ -106,7 +107,7 @@ fun Icon(
painter = painterResource(id = icon),
contentDescription = contentDescription,
modifier = iconModifier,
- tint = tint
+ tint = tint,
)
}
is Drawable -> {
@@ -114,7 +115,7 @@ fun Icon(
painter = rememberDrawablePainter(icon),
contentDescription = contentDescription,
modifier = iconModifier,
- tint = tint
+ tint = tint,
)
}
else -> throw IllegalArgumentException("Type not supported.")
@@ -123,5 +124,5 @@ fun Icon(
public enum class IconRtlMode {
Default,
- Mirrored
+ Mirrored,
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListFooter.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListFooter.kt
index 5ed912ec6..4f6d47faf 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListFooter.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListFooter.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
@@ -52,7 +52,7 @@ fun ListFooter(description: String, iconRes: Int? = null, onClick: (() -> Unit)?
contentDescription = null,
modifier =
Modifier.size(LeadingIconSize, LeadingIconSize)
- .align(Alignment.CenterVertically)
+ .align(Alignment.CenterVertically),
)
Spacer(modifier = Modifier.width(LeadingIconEndSpacing))
}
@@ -62,7 +62,7 @@ fun ListFooter(description: String, iconRes: Int? = null, onClick: (() -> Unit)?
textAlign = TextAlign.Start,
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colors.onSurfaceVariant,
- style = MaterialTheme.typography.caption2
+ style = MaterialTheme.typography.caption2,
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListHeader.kt
index 0a2a3937c..2d3eb0d52 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ListHeader.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ListHeader.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -60,7 +60,7 @@ fun ListHeader(
modifier: Modifier = Modifier,
backgroundColor: Color = Color.Transparent,
contentColor: Color = MaterialTheme.colors.onBackground,
- content: @Composable RowScope.() -> Unit
+ content: @Composable RowScope.() -> Unit,
) {
Row(
horizontalArrangement = Arrangement.Center,
@@ -69,14 +69,14 @@ fun ListHeader(
mergeDescendants = true
) {
heading()
- }
+ },
) {
CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalTextStyle provides
MaterialTheme.typography.title3.copy(
fontWeight = FontWeight.W600,
- hyphens = Hyphens.Auto
+ hyphens = Hyphens.Auto,
),
) {
content()
@@ -111,7 +111,7 @@ fun ListSubheader(
.fillMaxWidth()
.wrapContentSize(align = Alignment.CenterStart)
.background(backgroundColor)
- .semantics(mergeDescendants = true) { heading() }
+ .semantics(mergeDescendants = true) { heading() },
) {
CompositionLocalProvider(
LocalContentColor provides contentColor,
@@ -120,7 +120,7 @@ fun ListSubheader(
if (icon != null) {
Box(
modifier = Modifier.wrapContentSize(align = Alignment.CenterStart),
- content = icon
+ content = icon,
)
Spacer(modifier = Modifier.width(6.dp))
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ResponsiveDialog.kt
index 361a6c925..c43c45358 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ResponsiveDialog.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ResponsiveDialog.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Arrangement.spacedBy
@@ -44,10 +44,10 @@ import androidx.wear.compose.material.LocalTextStyle
import androidx.wear.compose.material.MaterialTheme
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumn
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults.responsive
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.rememberColumnState
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumn
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnDefaults.responsive
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnState
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.rememberColumnState
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionIconBuilder
import com.android.permissioncontroller.permission.ui.wear.elements.material3.defaultAlertConfirmIcon
import com.android.permissioncontroller.permission.ui.wear.elements.material3.defaultAlertDismissIcon
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChip.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChip.kt
index 2e89586c9..421d5ca4f 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChip.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChip.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.BoxScope
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChipToggleControl.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChipToggleControl.kt
index b6f6db4d3..56fbf3d61 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/ToggleChipToggleControl.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/ToggleChipToggleControl.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.permissioncontroller.permission.ui.wear.elements
+package com.android.permissioncontroller.permission.ui.wear.elements.material2
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Wear2Scaffold.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Wear2Scaffold.kt
new file mode 100644
index 000000000..3575b3cff
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/Wear2Scaffold.kt
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2025 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
+ *
+ * https://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.ui.wear.elements.material2
+
+import android.graphics.drawable.Drawable
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.compose.LocalLifecycleOwner
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
+import androidx.wear.compose.foundation.lazy.ScalingLazyListState
+import androidx.wear.compose.material.CircularProgressIndicator
+import androidx.wear.compose.material.MaterialTheme
+import androidx.wear.compose.material.PositionIndicator
+import androidx.wear.compose.material.Scaffold
+import androidx.wear.compose.material.Text
+import androidx.wear.compose.material.TimeText
+import androidx.wear.compose.material.Vignette
+import androidx.wear.compose.material.VignettePosition
+import androidx.wear.compose.material.scrollAway
+import com.android.permissioncontroller.permission.ui.wear.elements.AnnotatedText
+import com.android.permissioncontroller.permission.ui.wear.elements.rememberDrawablePainter
+import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionTheme
+
+/**
+ * This component is wrapper on material 2 scaffold component. It helps with time text, scroll
+ * indicator and standard list elements like title, icon and subtitle.
+ */
+@Composable
+fun Wear2Scaffold(
+ showTimeText: Boolean,
+ title: String?,
+ subtitle: CharSequence?,
+ image: Any?,
+ isLoading: Boolean,
+ content: ScalingLazyListScope.() -> Unit,
+ titleTestTag: String? = null,
+ subtitleTestTag: String? = null,
+) {
+ val itemsSpacedBy = 4.dp
+ val screenWidth = LocalConfiguration.current.screenWidthDp
+ val screenHeight = LocalConfiguration.current.screenHeightDp
+ val scrollContentHorizontalPadding = (screenWidth * 0.052).dp
+ val titleHorizontalPadding = (screenWidth * 0.0884).dp
+ val subtitleHorizontalPadding = (screenWidth * 0.0416).dp
+ val scrollContentTopPadding = (screenHeight * 0.1456).dp - itemsSpacedBy
+ val scrollContentBottomPadding = (screenHeight * 0.3636).dp
+ val titleBottomPadding =
+ if (subtitle == null) {
+ 8.dp
+ } else {
+ 4.dp
+ }
+ val subtitleBottomPadding = 8.dp
+ val timeTextTopPadding =
+ if (showTimeText) {
+ 1.dp
+ } else {
+ 0.dp
+ }
+ val titlePaddingValues =
+ PaddingValues(
+ start = titleHorizontalPadding,
+ top = 4.dp,
+ bottom = titleBottomPadding,
+ end = titleHorizontalPadding,
+ )
+ val subTitlePaddingValues =
+ PaddingValues(
+ start = subtitleHorizontalPadding,
+ top = 4.dp,
+ bottom = subtitleBottomPadding,
+ end = subtitleHorizontalPadding,
+ )
+ val initialCenterIndex = 0
+ val centerHeightDp = Dp(LocalConfiguration.current.screenHeightDp / 2.0f)
+ // We are adding TimeText's padding to create a smooth scrolling
+ val initialCenterItemScrollOffset = scrollContentTopPadding + timeTextTopPadding
+ val scrollAwayOffset = centerHeightDp - initialCenterItemScrollOffset
+ val focusRequester = remember { FocusRequester() }
+ val listState = remember { ScalingLazyListState(initialCenterItemIndex = initialCenterIndex) }
+ LaunchedEffect(title) {
+ listState.animateScrollToItem(index = 0) // Scroll to the top when triggerValue changes
+ }
+ WearPermissionTheme {
+ Scaffold(
+ modifier = Modifier.focusRequester(focusRequester),
+ timeText = {
+ if (showTimeText && !isLoading) {
+ TimeText(
+ modifier =
+ Modifier.scrollAway(listState, initialCenterIndex, scrollAwayOffset)
+ .padding(top = timeTextTopPadding)
+ )
+ }
+ },
+ vignette = { Vignette(vignettePosition = VignettePosition.TopAndBottom) },
+ positionIndicator =
+ if (!isLoading) {
+ { PositionIndicator(scalingLazyListState = listState) }
+ } else {
+ null
+ },
+ ) {
+ Box(modifier = Modifier.fillMaxSize()) {
+ if (isLoading) {
+ CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
+ } else {
+ val iconColor =
+ com.android.permissioncontroller.permission.ui.wear.elements.material2
+ .chipDefaultColors()
+ .iconColor(true)
+ .value
+ ScalingLazyColumn(
+ modifier = Modifier.fillMaxWidth(),
+ state = listState,
+ // Set autoCentering to null to avoid adding extra padding based on the
+ // content.
+ autoCentering = null,
+ contentPadding =
+ PaddingValues(
+ start = scrollContentHorizontalPadding,
+ end = scrollContentHorizontalPadding,
+ top = scrollContentTopPadding,
+ bottom = scrollContentBottomPadding,
+ ),
+ ) {
+ staticItem()
+ image?.let {
+ val imageModifier = Modifier.size(24.dp)
+ when (image) {
+ is Int ->
+ item {
+ Image(
+ painter = painterResource(id = image),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = imageModifier,
+ colorFilter = ColorFilter.tint(iconColor),
+ )
+ }
+ is Drawable ->
+ item {
+ Image(
+ painter = rememberDrawablePainter(image),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = imageModifier,
+ colorFilter = ColorFilter.tint(iconColor),
+ )
+ }
+ else -> {}
+ }
+ }
+ if (title != null) {
+ item {
+ var modifier: Modifier = Modifier
+ if (titleTestTag != null) {
+ modifier = modifier.testTag(titleTestTag)
+ }
+ com.android.permissioncontroller.permission.ui.wear.elements
+ .material2
+ .ListHeader(modifier = Modifier.padding(titlePaddingValues)) {
+ Text(
+ text = title,
+ textAlign = TextAlign.Center,
+ modifier = modifier,
+ )
+ }
+ }
+ }
+ if (subtitle != null) {
+ item {
+ var modifier: Modifier =
+ Modifier.align(Alignment.Center).padding(subTitlePaddingValues)
+ if (subtitleTestTag != null) {
+ modifier = modifier.testTag(subtitleTestTag)
+ }
+ AnnotatedText(
+ text = subtitle,
+ style =
+ MaterialTheme.typography.body2.copy(
+ color = MaterialTheme.colors.onSurfaceVariant
+ ),
+ modifier = modifier,
+ shouldCapitalize = true,
+ )
+ }
+ }
+
+ content()
+ }
+ RequestFocusOnResume(focusRequester = focusRequester)
+ }
+ }
+ }
+ }
+}
+
+private fun ScalingLazyListScope.staticItem() {
+ /*
+ This empty item helps to ensure accurate scroll offset calculation. If auto centering is enabled
+ initial item's(first item for us) center matches the center of the screen. Scroll offset is 0 at
+ that point.
+
+ if auto centering is not enabled, initial item will start at the top of the screen with the
+ scroll offset equal to ScreenHeight/2 - scrollContentTopPadding - firstItemHeight/2.
+
+ We need to this offset value to properly move time text.That is the scroll-away offset of the
+ Time Text is equal to the scroll offset of the list at initial position.
+
+ It is easier to calculate if we know the values of ScreenHeight, ScrollContentTopPadding and
+ FirstItem's height. ScreenHeight and ScrollContentPadding are constants but height of the
+ FirstItem depends on the content. Instead of measuring the height, we can simplify the
+ calculation with an empty item with 0dp height.
+ */
+ item {}
+}
+
+@Composable
+private fun RequestFocusOnResume(focusRequester: FocusRequester) {
+ val lifecycleOwner = LocalLifecycleOwner.current
+ LaunchedEffect(Unit) {
+ lifecycleOwner.repeatOnLifecycle(state = Lifecycle.State.RESUMED) {
+ focusRequester.requestFocus()
+ }
+ }
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnDefaults.kt
index 550f1dc24..c06fdaf14 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnDefaults.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnDefaults.kt
@@ -16,7 +16,7 @@
@file:Suppress("ObjectLiteralToLambda")
-package com.android.permissioncontroller.permission.ui.wear.elements.layout
+package com.android.permissioncontroller.permission.ui.wear.elements.material2.layout
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
@@ -33,7 +33,7 @@ import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults
import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType
import androidx.wear.compose.foundation.lazy.ScalingParams
import androidx.wear.compose.material.ChipDefaults
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState.RotaryMode
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnState.RotaryMode
import kotlin.math.sqrt
// This file's content is copied from ScalingLazyColumnDefaults.kt from Horologist (go/horologist),
@@ -63,10 +63,7 @@ object ScalingLazyColumnDefaults {
firstItemIsFullWidth: Boolean = true,
additionalPaddingAtBottom: Dp = 10.dp,
verticalArrangement: Arrangement.Vertical =
- Arrangement.spacedBy(
- space = 4.dp,
- alignment = Alignment.Top,
- ),
+ Arrangement.spacedBy(space = 4.dp, alignment = Alignment.Top),
horizontalPaddingPercent: Float = 0.052f,
rotaryMode: RotaryMode? = RotaryMode.Scroll,
hapticsEnabled: Boolean = true,
@@ -145,7 +142,7 @@ object ScalingLazyColumnDefaults {
return (radius -
sqrt(
(radius - childViewHeight + childViewWidth * 0.5f) *
- (radius - childViewWidth * 0.5f),
+ (radius - childViewWidth * 0.5f)
) -
childViewHeight * 0.5f)
.dp
@@ -225,10 +222,7 @@ object ScalingLazyColumnDefaults {
last.bottomPaddingDp * height + first.paddingCorrection
} else {
if (configuration.isScreenRound) {
- calculateVerticalOffsetForChip(
- screenWidthDp,
- horizontalPercent,
- ) + 10.dp
+ calculateVerticalOffsetForChip(screenWidthDp, horizontalPercent) + 10.dp
} else {
0.dp
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnState.kt
index b3698a60c..0e669f6ff 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/layout/ScalingLazyColumnState.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material2/layout/ScalingLazyColumnState.kt
@@ -17,7 +17,7 @@
@file:Suppress("ObjectLiteralToLambda")
@file:OptIn(ExperimentalWearFoundationApi::class)
-package com.android.permissioncontroller.permission.ui.wear.elements.layout
+package com.android.permissioncontroller.permission.ui.wear.elements.material2.layout
import androidx.compose.foundation.MutatePriority
import androidx.compose.foundation.gestures.FlingBehavior
@@ -42,8 +42,8 @@ import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType
import androidx.wear.compose.foundation.lazy.ScalingLazyListScope
import androidx.wear.compose.foundation.lazy.ScalingLazyListState
import androidx.wear.compose.foundation.lazy.ScalingParams
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnDefaults.responsiveScalingParams
-import com.android.permissioncontroller.permission.ui.wear.elements.layout.ScalingLazyColumnState.RotaryMode
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnDefaults.responsiveScalingParams
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.layout.ScalingLazyColumnState.RotaryMode
// This file is a copy of ScalingLazyColumnState.kt from Horologist (go/horologist),
// remove it once after wear compose supports large screen dialogs.
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 7aa165b0f..942a420a8 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
@@ -33,7 +33,7 @@ import androidx.wear.compose.material3.ButtonDefaults
import androidx.wear.compose.material3.LocalTextConfiguration
import androidx.wear.compose.material3.LocalTextStyle
import androidx.wear.compose.material3.Text
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
/**
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButtonStyle.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButtonStyle.kt
index 504c69bb0..36d3f9f33 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButtonStyle.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionButtonStyle.kt
@@ -21,8 +21,8 @@ import androidx.wear.compose.material.ChipColors
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material3.ButtonColors
import androidx.wear.compose.material3.ButtonDefaults
-import com.android.permissioncontroller.permission.ui.wear.elements.chipDefaultColors
-import com.android.permissioncontroller.permission.ui.wear.elements.chipDisabledColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.chipDefaultColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.chipDisabledColors
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButtonStyle.DisabledLike
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButtonStyle.Primary
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButtonStyle.Secondary
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionConfirmationDialog.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionConfirmationDialog.kt
index 4647d6eae..430831248 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionConfirmationDialog.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionConfirmationDialog.kt
@@ -25,8 +25,8 @@ import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material3.AlertDialog as Material3AlertDialog
import androidx.wear.compose.material3.AlertDialogDefaults
import androidx.wear.compose.material3.Text
-import com.android.permissioncontroller.permission.ui.wear.elements.AlertDialog
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.AlertDialog
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
@Composable
@@ -91,7 +91,7 @@ private fun WearPermissionConfirmationDialogInternal(
} ?: AlertDialogDefaults.ConfirmIcon
Material3AlertDialog(
- show = show,
+ visible = show,
onDismissRequest = edgeButtonContent.onClick,
edgeButton = {
AlertDialogDefaults.EdgeButton(onClick = edgeButtonContent.onClick, content = edgeIcon)
@@ -148,7 +148,7 @@ private fun WearPermissionConfirmationDialogInternal(
}
Material3AlertDialog(
- show = show,
+ visible = show,
onDismissRequest = negativeButtonContent?.onClick ?: {},
confirmButton = positiveButton ?: {},
dismissButton = negativeButton ?: {},
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 cd18b5b09..35efe5db1 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
@@ -21,7 +21,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material3.ButtonDefaults
-import com.android.permissioncontroller.permission.ui.wear.elements.ListFooter
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ListFooter
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
/** This component is creates a transparent styled button to use as a list footer. */
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionScaffold.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionScaffold.kt
index babd7fb6f..98b8facf7 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionScaffold.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionScaffold.kt
@@ -54,7 +54,7 @@ import androidx.wear.compose.material3.TimeText
import androidx.wear.compose.material3.lazy.scrollTransform
import com.android.permissioncontroller.permission.ui.wear.elements.AnnotatedText
import com.android.permissioncontroller.permission.ui.wear.elements.ListScopeWrapper
-import com.android.permissioncontroller.permission.ui.wear.elements.Wear2Scaffold
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Wear2Scaffold
import com.android.permissioncontroller.permission.ui.wear.elements.rememberDrawablePainter
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion.MATERIAL2_5
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControl.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControl.kt
index 9841ca521..6fea14082 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControl.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControl.kt
@@ -20,14 +20,17 @@ import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.stateDescription
import androidx.wear.compose.material3.CheckboxButton
import androidx.wear.compose.material3.LocalTextConfiguration
import androidx.wear.compose.material3.RadioButton
import androidx.wear.compose.material3.SwitchButton
import androidx.wear.compose.material3.Text
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChip
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
-import com.android.permissioncontroller.permission.ui.wear.elements.toggleControlSemantics
+import com.android.permissioncontroller.R
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
/**
@@ -118,12 +121,16 @@ private fun WearPermissionToggleControlInternal(
}
val iconParam: (@Composable BoxScope.() -> Unit)? = iconBuilder?.let { { it.build() } }
-
+ val toggleControlStateDescription =
+ stringResource(
+ if (checked) {
+ R.string.on
+ } else {
+ R.string.off
+ }
+ )
val updatedModifier =
- modifier
- .fillMaxWidth()
- // .heightIn(min = 58.dp) // TODO(b/370783358): This should be a overlaid value
- .toggleControlSemantics(toggleControl, checked)
+ modifier.fillMaxWidth().semantics { stateDescription = toggleControlStateDescription }
when (toggleControl) {
ToggleChipToggleControl.Radio ->
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControlStyle.kt b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControlStyle.kt
index b5746f019..048a06861 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControlStyle.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/ui/wear/elements/material3/WearPermissionToggleControlStyle.kt
@@ -25,8 +25,8 @@ import androidx.wear.compose.material3.RadioButtonColors
import androidx.wear.compose.material3.RadioButtonDefaults.radioButtonColors
import androidx.wear.compose.material3.SwitchButtonColors
import androidx.wear.compose.material3.SwitchButtonDefaults.switchButtonColors
-import com.android.permissioncontroller.permission.ui.wear.elements.toggleChipBackgroundColors
-import com.android.permissioncontroller.permission.ui.wear.elements.toggleChipDisabledColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.toggleChipBackgroundColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.toggleChipDisabledColors
/**
* Defines toggle control styles, It helps in setting the right colors scheme to a toggle control.
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListScreen.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListScreen.kt
index afee50389..c322b2bef 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppListScreen.kt
@@ -29,10 +29,10 @@ import androidx.compose.ui.res.stringResource
import androidx.lifecycle.LiveData
import androidx.wear.compose.material.Text
import com.android.permissioncontroller.R
-import com.android.permissioncontroller.permission.ui.wear.elements.Chip
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.chipDefaultColors
-import com.android.permissioncontroller.permission.ui.wear.elements.chipDisabledColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.Chip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.chipDefaultColors
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.chipDisabledColors
import com.android.permissioncontroller.role.ui.RoleItem
@Composable
@@ -65,7 +65,7 @@ fun WearDefaultAppListScreen(
onClick = pref.getOnClicked(),
modifier = Modifier.fillMaxWidth(),
labelMaxLines = Int.MAX_VALUE,
- secondaryLabelMaxLines = Integer.MAX_VALUE
+ secondaryLabelMaxLines = Integer.MAX_VALUE,
)
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppScreen.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppScreen.kt
index 5a90380e0..50b109248 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearDefaultAppScreen.kt
@@ -26,13 +26,13 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.wear.compose.material.ToggleChipDefaults
-import com.android.permissioncontroller.permission.ui.wear.elements.DialogButtonContent
-import com.android.permissioncontroller.permission.ui.wear.elements.ListFooter
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChip
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.DialogButtonContent
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ListFooter
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChip
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.toggleChipDisabledColors
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionConfirmationDialog
-import com.android.permissioncontroller.permission.ui.wear.elements.toggleChipDisabledColors
import com.android.permissioncontroller.permission.ui.wear.theme.ResourceHelper
import com.android.permissioncontroller.permission.ui.wear.theme.WearPermissionMaterialUIVersion
import com.android.permissioncontroller.role.ui.wear.model.ConfirmDialogArgs
diff --git a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleScreen.kt b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleScreen.kt
index 4a00efa1a..f891fc25f 100644
--- a/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleScreen.kt
+++ b/PermissionController/src/com/android/permissioncontroller/role/ui/wear/WearRequestRoleScreen.kt
@@ -32,7 +32,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.ui.wear.elements.ScrollableScreen
-import com.android.permissioncontroller.permission.ui.wear.elements.ToggleChipToggleControl
+import com.android.permissioncontroller.permission.ui.wear.elements.material2.ToggleChipToggleControl
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButton
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionButtonStyle
import com.android.permissioncontroller.permission.ui.wear.elements.material3.WearPermissionIconBuilder
diff --git a/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml b/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
index de033ac44..cb6323fff 100644
--- a/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
+++ b/SafetyCenter/Resources/res/raw-v36/safety_center_config.xml
@@ -30,6 +30,36 @@
initialDisplayState="disabled"
notificationsAllowed="true"/>
<dynamic-safety-source
+ id="AndroidFaceUnlock"
+ packageName="com.android.settings"
+ profile="all_profiles"
+ title="@com.android.safetycenter.resources:string/face_unlock_title"
+ titleForWork="@com.android.safetycenter.resources:string/face_unlock_title_for_work"
+ titleForPrivateProfile="@com.android.safetycenter.resources:string/face_unlock_title_for_private_profile"
+ searchTerms="@com.android.safetycenter.resources:string/face_unlock_search_terms"
+ refreshOnPageOpenAllowed="true"
+ initialDisplayState="hidden"/>
+ <dynamic-safety-source
+ id="AndroidFingerprintUnlock"
+ packageName="com.android.settings"
+ profile="all_profiles"
+ title="@com.android.safetycenter.resources:string/fingerprint_unlock_title"
+ titleForWork="@com.android.safetycenter.resources:string/fingerprint_unlock_title_for_work"
+ titleForPrivateProfile="@com.android.safetycenter.resources:string/fingerprint_unlock_title_for_private_profile"
+ searchTerms="@com.android.safetycenter.resources:string/fingerprint_unlock_search_terms"
+ refreshOnPageOpenAllowed="true"
+ initialDisplayState="hidden"/>
+ <dynamic-safety-source
+ id="AndroidWearUnlock"
+ packageName="com.android.settings"
+ profile="all_profiles"
+ title="@com.android.safetycenter.resources:string/wear_unlock_title"
+ titleForWork="@com.android.safetycenter.resources:string/wear_unlock_title_for_work"
+ titleForPrivateProfile="@com.android.safetycenter.resources:string/wear_unlock_title_for_private_profile"
+ searchTerms="@com.android.safetycenter.resources:string/wear_unlock_search_terms"
+ refreshOnPageOpenAllowed="true"
+ initialDisplayState="hidden"/>
+ <dynamic-safety-source
id="AndroidBiometrics"
packageName="com.android.settings"
profile="all_profiles"
diff --git a/SafetyCenter/Resources/res/values-v36/config.xml b/SafetyCenter/Resources/res/values-v36/config.xml
new file mode 100644
index 000000000..6fa28a340
--- /dev/null
+++ b/SafetyCenter/Resources/res/values-v36/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Comma separated list of safety source IDs to show in the same task as the safety center -->
+ <string name="config_same_task_safety_source_ids" translatable="false">AndroidAccessibility,AndroidBackgroundLocation,AndroidBiometrics,AndroidFaceUnlock,AndroidFingerprintUnlock,AndroidHealthConnect,AndroidLockScreen,AndroidPrivateSpace,AndroidMoreSettings,AndroidNotificationListener,AndroidPermissionAutoRevoke,AndroidPermissionManager,AndroidPermissionUsage,AndroidPrivacyAppDataSharingUpdates,AndroidPrivacyControls,AndroidWearUnlock,AndroidWorkPolicyInfo</string>
+</resources>
diff --git a/SafetyCenter/Resources/res/values-v36/strings.xml b/SafetyCenter/Resources/res/values-v36/strings.xml
new file mode 100644
index 000000000..f452e045a
--- /dev/null
+++ b/SafetyCenter/Resources/res/values-v36/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="face_unlock_title" description="The default title of the setting for managing face unlock options on the device">Face</string>
+ <string name="face_unlock_title_for_work" description="The default title of the setting for managing face unlock options for work on the device">Face for work</string>
+ <string name="face_unlock_title_for_private_profile" description="The default title of the setting for managing face unlock options for private profile on the device"><!-- Empty placeholder--></string>
+ <string name="face_unlock_search_terms" description="Search keywords of the setting for managing face unlock options on the device">Face unlock, Face</string>
+
+ <string name="fingerprint_unlock_title" description="The default title of the setting for managing fingerprint unlock options on the device">Fingerprint</string>
+ <string name="fingerprint_unlock_title_for_work" description="The default title of the setting for managing fingerprint unlock options for work on the device">Fingerprint for work</string>
+ <string name="fingerprint_unlock_title_for_private_profile" description="The default title of the setting for managing fingerprint unlock options for private profile on the device"><!-- Empty placeholder--></string>
+ <string name="fingerprint_unlock_search_terms" description="Search keywords of the setting for managing fingerprint unlock options on the device">Fingerprint, Finger, Add fingerprint</string>
+
+ <string name="wear_unlock_title" description="The default title of the setting for managing wear unlock options on the device">Watch</string>
+ <string name="wear_unlock_title_for_work" description="The default title of the setting for managing wear unlock options for work on the device">Watch for work</string>
+ <string name="wear_unlock_title_for_private_profile" description="The default title of the setting for managing wear unlock options for private profile on the device"><!-- Empty placeholder--></string>
+ <string name="wear_unlock_search_terms" description="Search keywords of the setting for managing wear unlock options on the device">Watch, Watch unlock</string>
+</resources>
diff --git a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
index 687234582..44eef2144 100644
--- a/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
+++ b/tests/cts/permissionmultidevice/src/android/permissionmultidevice/cts/DeviceAwarePermissionGrantTest.kt
@@ -93,7 +93,7 @@ class DeviceAwarePermissionGrantTest {
val displayConfigBuilder =
VirtualDeviceRule.createDefaultVirtualDisplayConfigBuilder(
DISPLAY_WIDTH,
- DISPLAY_HEIGHT
+ DISPLAY_HEIGHT,
)
.setFlags(
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC or
@@ -114,7 +114,7 @@ class DeviceAwarePermissionGrantTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun onHostDevice_requestPermissionForHostDevice_shouldGrantPermission() {
@@ -124,13 +124,13 @@ class DeviceAwarePermissionGrantTest {
false,
"",
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = false
+ expectPermissionGrantedOnRemoteDevice = false,
)
}
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun onHostDevice_requestPermissionForRemoteDevice_shouldGrantPermission() {
@@ -140,13 +140,13 @@ class DeviceAwarePermissionGrantTest {
true,
deviceDisplayName,
expectPermissionGrantedOnDefaultDevice = false,
- expectPermissionGrantedOnRemoteDevice = true
+ expectPermissionGrantedOnRemoteDevice = true,
)
}
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@RequiresFlagsDisabled(Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES)
@Test
@@ -160,8 +160,9 @@ class DeviceAwarePermissionGrantTest {
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
- Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES
+ Flags.FLAG_ALLOW_HOST_PERMISSION_DIALOGS_ON_VIRTUAL_DEVICES,
)
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.BAKLAVA, codeName = "Baklava")
@Test
fun onRemoteDevice_requestPermissionForHostDevice_shouldGrantPermission() {
// Create a virtual device with default policy, so that camera permission request will
@@ -176,16 +177,18 @@ class DeviceAwarePermissionGrantTest {
virtualDisplay.display.displayId,
virtualDevice.deviceId,
true,
- Settings.Global.getString(defaultDeviceContext.contentResolver,
- Settings.Global.DEVICE_NAME),
+ Settings.Global.getString(
+ defaultDeviceContext.contentResolver,
+ Settings.Global.DEVICE_NAME,
+ ),
expectPermissionGrantedOnDefaultDevice = true,
- expectPermissionGrantedOnRemoteDevice = false
+ expectPermissionGrantedOnRemoteDevice = false,
)
}
@RequiresFlagsEnabled(
Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED,
- Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED
+ Flags.FLAG_DEVICE_AWARE_PERMISSIONS_ENABLED,
)
@Test
fun onRemoteDevice_requestPermissionForRemoteDevice_shouldGrantPermission() {
@@ -195,7 +198,7 @@ class DeviceAwarePermissionGrantTest {
true,
deviceDisplayName,
expectPermissionGrantedOnDefaultDevice = false,
- expectPermissionGrantedOnRemoteDevice = true
+ expectPermissionGrantedOnRemoteDevice = true,
)
}
@@ -205,7 +208,7 @@ class DeviceAwarePermissionGrantTest {
showDeviceName: Boolean,
expectedDeviceNameInDialog: String,
expectPermissionGrantedOnDefaultDevice: Boolean,
- expectPermissionGrantedOnRemoteDevice: Boolean
+ expectPermissionGrantedOnRemoteDevice: Boolean,
) {
// Assert no permission granted to either default device or virtual device at the beginning
assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, false)
@@ -240,13 +243,13 @@ class DeviceAwarePermissionGrantTest {
assertAppHasPermissionForDevice(DEVICE_ID_DEFAULT, expectPermissionGrantedOnDefaultDevice)
assertAppHasPermissionForDevice(
virtualDevice.deviceId,
- expectPermissionGrantedOnRemoteDevice
+ expectPermissionGrantedOnRemoteDevice,
)
}
private fun requestPermissionOnDevice(
displayId: Int,
- targetDeviceId: Int
+ targetDeviceId: Int,
): CompletableFuture<Bundle> {
val future = CompletableFuture<Bundle>()
val callback = RemoteCallback { result: Bundle? -> future.complete(result) }
diff --git a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt
index 8e91a00ce..9ec09dab7 100644
--- a/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt
+++ b/tests/cts/permissionui/src/android/permissionui/cts/EnhancedConfirmationManagerTest.kt
@@ -78,20 +78,14 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun installedAppStartsWithModeDefault() {
installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST)
- eventually {
- runWithShellPermissionIdentity {
- assertEquals(
- getAppEcmState(context, appOpsManager, APP_PACKAGE_NAME),
- AppOpsManager.MODE_DEFAULT
- )
- }
- }
+ waitForModeDefault()
}
@RequiresFlagsEnabled(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED)
@Test
fun givenStoreAppThenIsNotRestrictedFromProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) }
}
@@ -101,6 +95,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenLocalAppThenIsRestrictedFromProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromLocalFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) }
}
@@ -110,6 +105,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenDownloadedThenAppIsRestrictedFromProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) }
}
@@ -119,6 +115,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenExplicitlyRestrictedAppThenIsRestrictedFromProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromStore(APP_APK_NAME_LATEST)
+ waitForModeDefault()
eventually {
runWithShellPermissionIdentity {
assertEquals(
@@ -138,6 +135,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenRestrictedAppThenIsNotRestrictedFromNonProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertFalse(ecm.isRestricted(APP_PACKAGE_NAME, NON_PROTECTED_SETTING)) }
}
@@ -147,6 +145,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenRestrictedAppThenClearRestrictionNotAllowedByDefault() {
installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertFalse(ecm.isClearRestrictionAllowed(APP_PACKAGE_NAME)) }
}
@@ -156,6 +155,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun givenRestrictedAppWhenClearRestrictionThenNotRestrictedFromProtectedSetting() {
installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
runWithShellPermissionIdentity {
eventually { assertTrue(ecm.isRestricted(APP_PACKAGE_NAME, PROTECTED_SETTING)) }
ecm.setClearRestrictionAllowed(APP_PACKAGE_NAME)
@@ -169,6 +169,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
@Test
fun createRestrictedSettingDialogIntentReturnsIntent() {
installPackageWithInstallSourceAndMetadataFromDownloadedFile(APP_APK_NAME_LATEST)
+ waitForModeDefault()
val intent = ecm.createRestrictedSettingDialogIntent(APP_PACKAGE_NAME, PROTECTED_SETTING)
@@ -181,6 +182,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms(
APP_APK_NAME_LATEST
)
+ waitForModeDefault()
val permissionAndExpectedGrantResults =
arrayOf(
GROUP_2_PERMISSION_1_RESTRICTED to false,
@@ -207,6 +209,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms(
APP_APK_NAME_LATEST
)
+ waitForModeDefault()
requestAppPermissionsAndAssertResult(
GROUP_3_PERMISSION_1_UNRESTRICTED to false,
@@ -236,6 +239,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms(
APP_APK_NAME_LATEST
)
+ waitForModeDefault()
requestAppPermissionsAndAssertResult(
GROUP_3_PERMISSION_1_UNRESTRICTED to true,
@@ -254,6 +258,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
installPackageWithInstallSourceFromDownloadedFileAndAllowHardRestrictedPerms(
APP_APK_NAME_LATEST
)
+ waitForModeDefault()
requestAppPermissionsAndAssertResult(
GROUP_4_PERMISSION_1_UNRESTRICTED to true,
@@ -287,6 +292,18 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
)
}
+ private fun waitForModeDefault() {
+ eventually {
+ runWithShellPermissionIdentity {
+ assertEquals(
+ "Timed out waiting for package mode to change to MODE_DEFAULT",
+ getAppEcmState(context, appOpsManager, APP_PACKAGE_NAME),
+ AppOpsManager.MODE_DEFAULT
+ )
+ }
+ }
+ }
+
companion object {
private const val GROUP_2_PERMISSION_1_RESTRICTED = Manifest.permission.SEND_SMS
private const val GROUP_2_PERMISSION_2_RESTRICTED = Manifest.permission.READ_SMS
@@ -294,7 +311,7 @@ class EnhancedConfirmationManagerTest : BaseUsePermissionTest() {
Manifest.permission.ACCESS_FINE_LOCATION
private const val GROUP_3_PERMISSION_2_UNRESTRICTED =
Manifest.permission.ACCESS_COARSE_LOCATION
- private const val GROUP_4_PERMISSION_1_UNRESTRICTED = Manifest.permission.BODY_SENSORS
+ private const val GROUP_4_PERMISSION_1_UNRESTRICTED = Manifest.permission.CAMERA
private const val NON_PROTECTED_SETTING = "example_setting_which_is_not_protected"
private const val PROTECTED_SETTING = "android:bind_accessibility_service"
diff --git a/tests/cts/role/Android.bp b/tests/cts/role/Android.bp
index 665662951..ea9af5d8e 100644
--- a/tests/cts/role/Android.bp
+++ b/tests/cts/role/Android.bp
@@ -37,7 +37,9 @@ android_test {
"bedstead-multiuser",
"flag-junit",
"platform-test-annotations",
+ "platform-test-rules",
"truth",
+ "uiautomator-helpers",
],
test_suites: [
@@ -48,6 +50,7 @@ android_test {
],
data: [
+ ":CtsDefaultNotesApp",
":CtsRoleTestApp",
":CtsRoleTestApp28",
":CtsRoleTestApp33WithoutInCallService",
diff --git a/tests/cts/role/AndroidManifest.xml b/tests/cts/role/AndroidManifest.xml
index a8c8c8e3d..7ea4287dc 100644
--- a/tests/cts/role/AndroidManifest.xml
+++ b/tests/cts/role/AndroidManifest.xml
@@ -22,6 +22,7 @@
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
+ <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application>
diff --git a/tests/cts/role/AndroidTest.xml b/tests/cts/role/AndroidTest.xml
index 73f23dd1b..9a60b09e3 100644
--- a/tests/cts/role/AndroidTest.xml
+++ b/tests/cts/role/AndroidTest.xml
@@ -32,6 +32,8 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsRoleTestCases.apk" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="CtsDefaultNotesApp.apk" />
</target_preparer>
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
@@ -40,6 +42,7 @@
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
+ <option name="push" value="CtsDefaultNotesApp.apk->/data/local/tmp/cts-role/CtsDefaultNotesApp.apk" />
<option name="push" value="CtsRoleTestApp.apk->/data/local/tmp/cts-role/CtsRoleTestApp.apk" />
<option name="push" value="CtsRoleTestApp28.apk->/data/local/tmp/cts-role/CtsRoleTestApp28.apk" />
<option name="push" value="CtsRoleTestApp33WithoutInCallService.apk->/data/local/tmp/cts-role/CtsRoleTestApp33WithoutInCallService.apk" />
diff --git a/tests/cts/role/src/android/app/role/cts/ChooseNoteRoleAppTest.kt b/tests/cts/role/src/android/app/role/cts/ChooseNoteRoleAppTest.kt
new file mode 100644
index 000000000..18003d1d9
--- /dev/null
+++ b/tests/cts/role/src/android/app/role/cts/ChooseNoteRoleAppTest.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2025 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 android.app.role.cts
+
+import android.content.Intent
+import android.platform.test.rule.NotesRoleManagerRule
+import android.platform.uiautomatorhelpers.WaitUtils.ensureThat
+import android.provider.Settings
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.By.text
+import com.android.compatibility.common.util.UiAutomatorUtils2.getUiDevice
+import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObject
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class ChooseNoteRoleAppTest {
+
+ @[Rule JvmField]
+ val rule = NotesRoleManagerRule(requiredNotesRoleHolderPackage = NOTES_APP_PACKAGE_NAME)
+
+ @Before
+ fun setUp() {
+ rule.utils.clearRoleHolder()
+ InstrumentationRegistry.getInstrumentation()
+ .context
+ .startActivity(
+ Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
+ )
+ }
+
+ @After
+ fun after() {
+ getUiDevice().pressHome()
+ }
+
+ @Test
+ fun chooseNoteRoleHolderApp() {
+ ensureThat { rule.utils.getRoleHolderPackageName().isEmpty() }
+
+ // Scroll to "Notes app" item in Default apps screen and click on it
+ waitFindObject(text("Notes app")).click()
+ // Scroll to "CtsDefaultNotesApp" item and click on it
+ waitFindObject(text("CtsDefaultNotesApp")).click()
+
+ assertEquals(rule.utils.getRoleHolderPackageName(), NOTES_APP_PACKAGE_NAME)
+ }
+
+ private companion object {
+ const val NOTES_APP_PACKAGE_NAME = "com.android.cts.notesapp"
+ }
+}