Add single provider and single account screens

Bug: 301206470
Test: N/A - feature not fully implemented yet

Change-Id: I25f54e2bcb8228b46a8ca7a89f63753c639a26ef
diff --git a/packages/CredentialManager/horologist/Android.bp b/packages/CredentialManager/horologist/Android.bp
index bb324bb..bb255bd 100644
--- a/packages/CredentialManager/horologist/Android.bp
+++ b/packages/CredentialManager/horologist/Android.bp
@@ -16,6 +16,7 @@
         "androidx.compose.foundation_foundation",
         "androidx.compose.runtime_runtime",
         "androidx.compose.ui_ui",
+        "androidx.compose.ui_ui-tooling",
         "androidx.navigation_navigation-compose",
         "androidx.lifecycle_lifecycle-extensions",
         "androidx.lifecycle_lifecycle-runtime-ktx",
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt
new file mode 100644
index 0000000..e6025fc
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/layout/BelowTimeTextPreview.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 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.google.android.horologist.compose.layout
+
+import androidx.compose.runtime.Composable
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+public fun belowTimeTextPreview(): ScalingLazyColumnState {
+    return ScalingLazyColumnDefaults.belowTimeText().create()
+}
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt
new file mode 100644
index 0000000..57e0c10
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Button.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2023 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.google.android.horologist.compose.material
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.unit.Dp
+import androidx.wear.compose.material.Button
+import androidx.wear.compose.material.ButtonColors
+import androidx.wear.compose.material.ButtonDefaults
+import androidx.wear.compose.material.ButtonDefaults.DefaultButtonSize
+import androidx.wear.compose.material.ButtonDefaults.DefaultIconSize
+import androidx.wear.compose.material.ButtonDefaults.LargeButtonSize
+import androidx.wear.compose.material.ButtonDefaults.LargeIconSize
+import androidx.wear.compose.material.ButtonDefaults.SmallButtonSize
+import androidx.wear.compose.material.ButtonDefaults.SmallIconSize
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * This component is an alternative to [Button], providing the following:
+ * - a convenient way of providing an icon and choosing its size from a range of sizes recommended
+ * by the Wear guidelines;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Button(
+    imageVector: ImageVector,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        icon = imageVector,
+        contentDescription = contentDescription,
+        onClick = onClick,
+        modifier = modifier,
+        colors = colors,
+        buttonSize = buttonSize,
+        iconRtlMode = iconRtlMode,
+        enabled = enabled,
+    )
+}
+
+/**
+ * This component is an alternative to [Button], providing the following:
+ * - a convenient way of providing an icon and choosing its size from a range of sizes recommended
+ * by the Wear guidelines;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Button(
+    @DrawableRes id: Int,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        icon = id,
+        contentDescription = contentDescription,
+        onClick = onClick,
+        modifier = modifier,
+        colors = colors,
+        buttonSize = buttonSize,
+        iconRtlMode = iconRtlMode,
+        enabled = enabled,
+    )
+}
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+internal fun Button(
+    icon: Any,
+    contentDescription: String,
+    onClick: () -> Unit,
+    modifier: Modifier = Modifier,
+    colors: ButtonColors = ButtonDefaults.primaryButtonColors(),
+    buttonSize: ButtonSize = ButtonSize.Default,
+    iconRtlMode: IconRtlMode = IconRtlMode.Default,
+    enabled: Boolean = true,
+) {
+    Button(
+        onClick = onClick,
+        modifier = modifier.size(buttonSize.tapTargetSize),
+        enabled = enabled,
+        colors = colors,
+    ) {
+        val iconModifier = Modifier
+            .size(buttonSize.iconSize)
+            .align(Alignment.Center)
+
+        Icon(
+            icon = icon,
+            contentDescription = contentDescription,
+            modifier = iconModifier,
+            rtlMode = iconRtlMode,
+        )
+    }
+}
+
+@ExperimentalHorologistApi
+public sealed class ButtonSize(
+    public val iconSize: Dp,
+    public val tapTargetSize: Dp,
+) {
+    public object Default :
+        ButtonSize(iconSize = DefaultIconSize, tapTargetSize = DefaultButtonSize)
+
+    public object Large : ButtonSize(iconSize = LargeIconSize, tapTargetSize = LargeButtonSize)
+    public object Small : ButtonSize(iconSize = SmallIconSize, tapTargetSize = SmallButtonSize)
+
+    /**
+     * Custom sizes should follow the [accessibility principles and guidance for touch targets](https://developer.android.com/training/wearables/accessibility#set-minimum).
+     */
+    public data class Custom(val customIconSize: Dp, val customTapTargetSize: Dp) :
+        ButtonSize(iconSize = customIconSize, tapTargetSize = customTapTargetSize)
+}
+
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt
new file mode 100644
index 0000000..74e54c0
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/Icon.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2023 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.google.android.horologist.compose.material
+
+import androidx.annotation.DrawableRes
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.scale
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.res.painterResource
+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.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * This component is an alternative to [Icon], providing the following:
+ * - a convenient way of setting the icon to be mirrored in RTL mode;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Icon(
+    imageVector: ImageVector,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+    Icon(
+        modifier = modifier.scale(
+            scaleX = if (shouldMirror) -1f else 1f,
+            scaleY = 1f,
+        ),
+        imageVector = imageVector,
+        contentDescription = contentDescription,
+        tint = tint,
+    )
+}
+
+/**
+ * This component is an alternative to [Icon], providing the following:
+ * - a convenient way of setting the icon to be mirrored in RTL mode;
+ */
+@ExperimentalHorologistApi
+@Composable
+public fun Icon(
+    @DrawableRes id: Int,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+
+    Icon(
+        painter = painterResource(id = id),
+        contentDescription = contentDescription,
+        modifier = modifier.scale(
+            scaleX = if (shouldMirror) -1f else 1f,
+            scaleY = 1f,
+        ),
+        tint = tint,
+    )
+}
+
+@OptIn(ExperimentalHorologistApi::class)
+@Composable
+internal fun Icon(
+    icon: Any,
+    contentDescription: String?,
+    modifier: Modifier = Modifier,
+    tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
+    rtlMode: IconRtlMode = IconRtlMode.Default,
+) {
+    val shouldMirror =
+        rtlMode == IconRtlMode.Mirrored && LocalLayoutDirection.current == LayoutDirection.Rtl
+
+    val iconModifier = modifier.scale(
+        scaleX = if (shouldMirror) -1f else 1f,
+        scaleY = 1f,
+    )
+    when (icon) {
+        is ImageVector -> {
+            Icon(
+                imageVector = icon,
+                modifier = iconModifier,
+                contentDescription = contentDescription,
+                tint = tint,
+            )
+        }
+
+        is Int -> {
+            Icon(
+                painter = painterResource(id = icon),
+                contentDescription = contentDescription,
+                modifier = iconModifier,
+                tint = tint,
+            )
+        }
+
+        else -> throw IllegalArgumentException("Type not supported.")
+    }
+}
+
+@ExperimentalHorologistApi
+public enum class IconRtlMode {
+    Default,
+    Mirrored,
+}
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt
new file mode 100644
index 0000000..39de2e1
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/material/util/A11y.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 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.google.android.horologist.compose.material.util
+
+import com.google.android.horologist.annotations.ExperimentalHorologistApi
+
+/**
+ * Make explicit that a conscious decision was made to mark an element as decorative, so it does not
+ * have associated actions or state.
+ *
+ * https://developer.android.com/jetpack/compose/accessibility#describe-visual
+ */
+@ExperimentalHorologistApi
+public val DECORATIVE_ELEMENT_CONTENT_DESCRIPTION: String? = null
diff --git a/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt
new file mode 100644
index 0000000..0bfceee
--- /dev/null
+++ b/packages/CredentialManager/horologist/src/com/google/android/horologist/compose/tools/WearPreview.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 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.google.android.horologist.compose.tools
+
+import androidx.compose.ui.tooling.preview.Preview
+
+@Preview(
+    backgroundColor = 0xff000000,
+    showBackground = true,
+)
+public annotation class WearPreview