diff options
11 files changed, 391 insertions, 0 deletions
diff --git a/packages/SettingsLib/Spa/gallery/res/drawable/accessibility_captioning_banner.xml b/packages/SettingsLib/Spa/gallery/res/drawable/accessibility_captioning_banner.xml new file mode 100644 index 000000000000..6597ffb57688 --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/res/drawable/accessibility_captioning_banner.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="412dp" + android:height="300dp" + android:viewportWidth="412" + android:viewportHeight="300"> + <path + android:pathData="M383.9,300H28.1C12.6,300 0,287.4 0,271.9V28.1C0,12.6 12.6,0 28.1,0h355.8C399.4,0 412,12.6 412,28.1v243.8C412,287.4 399.4,300 383.9,300z" + android:fillColor="#FFFFFF"/> + <path + android:pathData="M79.2,179.6h53.6v8.5h-53.6z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M142.5,179.6h30.4v8.5h-30.4z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M79.2,195.5h79.2v8.5h-79.2z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M168.1,195.5h34.1v8.5h-34.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M211.9,195.5h34.1v8.5h-34.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M182.7,179.6h73.1v8.5h-73.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M265.5,179.6h26.8v8.5h-26.8z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M302.1,179.6h26.8v8.5h-26.8z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M142.7,67.9h-11.5c-1.6,0 -2.9,1.3 -2.9,2.9H67.8c-7.9,0 -14.4,6.5 -14.4,14.4v132.4c0,7.9 6.5,14.4 14.4,14.4h276.4c7.9,0 14.4,-6.5 14.4,-14.4V85.2c0,-7.9 -6.5,-14.4 -14.4,-14.4H203.1c0,-1.6 -1.3,-2.9 -2.9,-2.9h-28.8c-1.6,0 -2.9,1.3 -2.9,2.9h-23C145.5,69.2 144.3,67.9 142.7,67.9zM344.2,73.7c6.4,0 11.5,5.2 11.5,11.5v132.4c0,6.3 -5.2,11.5 -11.5,11.5H67.8c-6.4,0 -11.5,-5.2 -11.5,-11.5V85.2c0,-6.3 5.2,-11.5 11.5,-11.5H344.2z" + android:fillColor="#DADCE0"/> +</vector> diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt index 43cfbb3f4f6d..6d5101fef891 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt @@ -22,6 +22,7 @@ import com.android.settingslib.spa.framework.common.SettingsPageProviderReposito import com.android.settingslib.spa.gallery.home.HomePageProvider import com.android.settingslib.spa.gallery.page.ArgumentPageProvider import com.android.settingslib.spa.gallery.page.FooterPageProvider +import com.android.settingslib.spa.gallery.page.IllustrationPageProvider import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider import com.android.settingslib.spa.gallery.page.SliderPageProvider import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider @@ -45,6 +46,7 @@ object SpaEnvironment { SpinnerPageProvider, SettingsPagerPageProvider, FooterPageProvider, + IllustrationPageProvider, ), rootPageData = listOf( SettingsPage(HomePageProvider.name), diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt index ad492a5bb161..2428bba1dd4c 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt @@ -28,6 +28,7 @@ import com.android.settingslib.spa.gallery.R import com.android.settingslib.spa.gallery.SpaEnvironment import com.android.settingslib.spa.gallery.page.ArgumentPageProvider import com.android.settingslib.spa.gallery.page.FooterPageProvider +import com.android.settingslib.spa.gallery.page.IllustrationPageProvider import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider import com.android.settingslib.spa.gallery.page.SliderPageProvider import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider @@ -53,6 +54,7 @@ private fun HomePage() { SpinnerPageProvider.EntryItem() SettingsPagerPageProvider.EntryItem() FooterPageProvider.EntryItem() + IllustrationPageProvider.EntryItem() /** * A test button to generate hierarchy. diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt new file mode 100644 index 000000000000..5db6e7ac1d36 --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/IllustrationPage.kt @@ -0,0 +1,73 @@ +/* + * Copyright (C) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.gallery.page + +import android.os.Bundle +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.android.settingslib.spa.framework.common.SettingsPageProvider +import com.android.settingslib.spa.framework.compose.navigator +import com.android.settingslib.spa.framework.theme.SettingsTheme +import com.android.settingslib.spa.gallery.R +import com.android.settingslib.spa.widget.Illustration +import com.android.settingslib.spa.widget.IllustrationModel +import com.android.settingslib.spa.widget.ResourceType +import com.android.settingslib.spa.widget.preference.Preference +import com.android.settingslib.spa.widget.preference.PreferenceModel + +object IllustrationPageProvider : SettingsPageProvider { + override val name = "Illustration" + + @Composable + override fun Page(arguments: Bundle?) { + IllustrationPage() + } + + @Composable + fun EntryItem() { + Preference(object : PreferenceModel { + override val title = "Sample Illustration" + override val onClick = navigator(name) + }) + } +} + +@Composable +private fun IllustrationPage() { + Column(Modifier.verticalScroll(rememberScrollState())) { + Preference(object : PreferenceModel { + override val title = "Image Illustration" + }) + + Illustration(object : IllustrationModel { + override val resId = R.drawable.accessibility_captioning_banner + override val resourceType = ResourceType.IMAGE + }) + } +} + +@Preview(showBackground = true) +@Composable +private fun IllustrationPagePreview() { + SettingsTheme { + IllustrationPage() + } +} diff --git a/packages/SettingsLib/Spa/spa/build.gradle b/packages/SettingsLib/Spa/spa/build.gradle index ad69da314735..104966d9b097 100644 --- a/packages/SettingsLib/Spa/spa/build.gradle +++ b/packages/SettingsLib/Spa/spa/build.gradle @@ -66,4 +66,5 @@ dependencies { api 'androidx.navigation:navigation-compose:2.5.0' api 'com.google.android.material:material:1.6.1' debugApi "androidx.compose.ui:ui-tooling:$jetpack_compose_version" + implementation 'com.airbnb.android:lottie-compose:5.2.0' } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt index c1a3c2018186..c2223e684f29 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsDimension.kt @@ -39,4 +39,10 @@ object SettingsDimension { /** The size when app icon is displayed in App info page. */ val appIconInfoSize = 48.dp + + /** The sizes info of illustration widget. */ + val illustrationMaxWidth = 412.dp + val illustrationMaxHeight = 300.dp + val illustrationPadding = 16.dp + val illustrationCornerRadius = 28.dp } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/Illustration.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/Illustration.kt new file mode 100644 index 000000000000..0d4e0c505943 --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/Illustration.kt @@ -0,0 +1,99 @@ +/* + * Copyright (C) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.widget + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.sizeIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import com.android.settingslib.spa.framework.theme.SettingsDimension +import com.android.settingslib.spa.widget.ui.ImageBox + +enum class ResourceType { IMAGE, LOTTIE } + +/** + * The widget model for [Illustration] widget. + */ +interface IllustrationModel { + /** + * The resource id of this [Illustration]. + */ + val resId: Int + + /** + * The resource type of the [Illustration]. + * + * It should be Lottie or Image. + */ + val resourceType: ResourceType +} + +/** + * Illustration widget. + * + * Data is provided through [IllustrationModel]. + */ +@Composable +fun Illustration(model: IllustrationModel) { + Illustration( + resId = model.resId, + resourceType = model.resourceType, + modifier = Modifier, + ) +} + +@Composable +fun Illustration( + resId: Int, + resourceType: ResourceType, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(SettingsDimension.illustrationPadding), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + val illustrationModifier = modifier + .sizeIn( + maxWidth = SettingsDimension.illustrationMaxWidth, + maxHeight = SettingsDimension.illustrationMaxHeight, + ) + .clip(RoundedCornerShape(SettingsDimension.illustrationCornerRadius)) + .background(color = MaterialTheme.colorScheme.surface) + + when (resourceType) { + ResourceType.LOTTIE -> { + // TODO: Add Lottie function after lottie is enabled. + } + ResourceType.IMAGE -> { + ImageBox( + resId = resId, + contentDescription = null, + modifier = illustrationModifier, + ) + } + } + } +} diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Image.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Image.kt new file mode 100644 index 000000000000..0790bf8bca6c --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Image.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.widget.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource + +@Composable +fun ImageBox( + resId: Int, + contentDescription: String?, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier, + ) { + Image( + painter = painterResource(resId), + contentDescription = contentDescription, + ) + } +} diff --git a/packages/SettingsLib/Spa/tests/build.gradle b/packages/SettingsLib/Spa/tests/build.gradle index 5f93a9f4e4b5..21d696f7e90c 100644 --- a/packages/SettingsLib/Spa/tests/build.gradle +++ b/packages/SettingsLib/Spa/tests/build.gradle @@ -31,6 +31,9 @@ android { } sourceSets { + main { + res.srcDirs = ["res"] + } androidTest { kotlin { srcDir "src" diff --git a/packages/SettingsLib/Spa/tests/res/drawable/accessibility_captioning_banner.xml b/packages/SettingsLib/Spa/tests/res/drawable/accessibility_captioning_banner.xml new file mode 100644 index 000000000000..6597ffb57688 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/res/drawable/accessibility_captioning_banner.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2021 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. +--> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="412dp" + android:height="300dp" + android:viewportWidth="412" + android:viewportHeight="300"> + <path + android:pathData="M383.9,300H28.1C12.6,300 0,287.4 0,271.9V28.1C0,12.6 12.6,0 28.1,0h355.8C399.4,0 412,12.6 412,28.1v243.8C412,287.4 399.4,300 383.9,300z" + android:fillColor="#FFFFFF"/> + <path + android:pathData="M79.2,179.6h53.6v8.5h-53.6z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M142.5,179.6h30.4v8.5h-30.4z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M79.2,195.5h79.2v8.5h-79.2z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M168.1,195.5h34.1v8.5h-34.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M211.9,195.5h34.1v8.5h-34.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M182.7,179.6h73.1v8.5h-73.1z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M265.5,179.6h26.8v8.5h-26.8z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M302.1,179.6h26.8v8.5h-26.8z" + android:fillColor="#1A73E8"/> + <path + android:pathData="M142.7,67.9h-11.5c-1.6,0 -2.9,1.3 -2.9,2.9H67.8c-7.9,0 -14.4,6.5 -14.4,14.4v132.4c0,7.9 6.5,14.4 14.4,14.4h276.4c7.9,0 14.4,-6.5 14.4,-14.4V85.2c0,-7.9 -6.5,-14.4 -14.4,-14.4H203.1c0,-1.6 -1.3,-2.9 -2.9,-2.9h-28.8c-1.6,0 -2.9,1.3 -2.9,2.9h-23C145.5,69.2 144.3,67.9 142.7,67.9zM344.2,73.7c6.4,0 11.5,5.2 11.5,11.5v132.4c0,6.3 -5.2,11.5 -11.5,11.5H67.8c-6.4,0 -11.5,-5.2 -11.5,-11.5V85.2c0,-6.3 5.2,-11.5 11.5,-11.5H344.2z" + android:fillColor="#DADCE0"/> +</vector> diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/IllustrationTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/IllustrationTest.kt new file mode 100644 index 000000000000..d2a07e9e041c --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/IllustrationTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.spa.widget + +import androidx.annotation.DrawableRes +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.SemanticsPropertyKey +import androidx.compose.ui.semantics.SemanticsPropertyReceiver +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.test.SemanticsMatcher +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.filterToOne +import androidx.compose.ui.test.hasAnyAncestor +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.tests.R +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class IllustrationTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val DrawableId = SemanticsPropertyKey<Int>("DrawableResId") + private var SemanticsPropertyReceiver.drawableId by DrawableId + + @Test + fun image_displayed() { + val resId = R.drawable.accessibility_captioning_banner + composeTestRule.setContent { + Illustration( + resId = resId, + resourceType = ResourceType.IMAGE, + modifier = Modifier.semantics { drawableId = resId } + ) + } + + fun hasDrawable(@DrawableRes id: Int): SemanticsMatcher = + SemanticsMatcher.expectValue(DrawableId, id) + + val isIllustrationNode = !hasAnyAncestor(hasDrawable(resId)) + composeTestRule.onAllNodes(hasDrawable(resId)) + .filterToOne(isIllustrationNode) + .assertIsDisplayed() + } +} |