fix: 首次提交
15
SettingsLib/Spa/.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
135
SettingsLib/Spa/.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,135 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_KEEP_LINE_BREAKS" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
SettingsLib/Spa/.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
10
SettingsLib/Spa/.idea/copyright/Apache_2.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice"
|
||||
value="Copyright (C) &#36;today.year 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."/>
|
||||
<option name="keyword" value="Copyright"/>
|
||||
<option name="allowReplaceKeyword" value=""/>
|
||||
<option name="myName" value="Apache 2"/>
|
||||
<option name="myLocal" value="true"/>
|
||||
</copyright>
|
||||
</component>
|
||||
8
SettingsLib/Spa/.idea/copyright/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="Apache 2">
|
||||
<LanguageOptions name="XML">
|
||||
<option name="fileTypeOverride" value="3" />
|
||||
<option name="prefixLines" value="false" />
|
||||
</LanguageOptions>
|
||||
</settings>
|
||||
</component>
|
||||
15
SettingsLib/Spa/.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CommitMessageInspectionProfile">
|
||||
<profile version="1.0">
|
||||
<inspection_tool class="BodyLimit" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="SubjectLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="RIGHT_MARGIN" value="50" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
9
SettingsLib/Spa/OWNERS
Normal file
@@ -0,0 +1,9 @@
|
||||
include platform/frameworks/base:/packages/SettingsLib/OWNERS
|
||||
|
||||
chaohuiw@google.com
|
||||
hanxu@google.com
|
||||
kellyz@google.com
|
||||
pierreqian@google.com
|
||||
lijun@google.com
|
||||
songchenxi@google.com
|
||||
cyl@google.com
|
||||
18
SettingsLib/Spa/TEST_MAPPING
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "SpaLibTests"
|
||||
},
|
||||
{
|
||||
"name": "SpaPrivilegedLibTests"
|
||||
},
|
||||
{
|
||||
"name": "SettingsSpaUnitTests"
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"name": "SpaScreenshotTests"
|
||||
}
|
||||
]
|
||||
}
|
||||
73
SettingsLib/Spa/build.gradle.kts
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import com.android.build.api.dsl.CommonExtension
|
||||
import com.android.build.gradle.BaseExtension
|
||||
import com.android.build.gradle.api.AndroidBasePlugin
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.android.library) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
}
|
||||
|
||||
val androidTop: String = File(rootDir, "../../../../..").canonicalPath
|
||||
|
||||
allprojects {
|
||||
extra["androidTop"] = androidTop
|
||||
extra["jetpackComposeVersion"] = "1.7.0-alpha03"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
layout.buildDirectory.set(file("$androidTop/out/gradle-spa/$name"))
|
||||
|
||||
plugins.withType<AndroidBasePlugin> {
|
||||
configure<BaseExtension> {
|
||||
compileSdkVersion(34)
|
||||
|
||||
defaultConfig {
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(libs.versions.jvm.get()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
plugins.withType<AndroidBasePlugin> {
|
||||
the(CommonExtension::class).apply {
|
||||
if (buildFeatures.compose == true) {
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = libs.versions.jvm.get()
|
||||
freeCompilerArgs = listOf("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
}
|
||||
33
SettingsLib/Spa/gallery/Android.bp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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 {
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
android_app {
|
||||
name: "SpaLibGallery",
|
||||
|
||||
srcs: ["src/**/*.kt"],
|
||||
use_resource_processor: true,
|
||||
static_libs: [
|
||||
"SpaLib",
|
||||
"androidx.compose.runtime_runtime",
|
||||
],
|
||||
kotlincflags: ["-Xjvm-default=all"],
|
||||
sdk_version: "current",
|
||||
min_sdk_version: "31",
|
||||
}
|
||||
82
SettingsLib/Spa/gallery/AndroidManifest.xml
Normal file
@@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settingslib.spa.gallery">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" />
|
||||
|
||||
<application
|
||||
android:name=".GalleryApplication"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_label"
|
||||
android:supportsRtl="true">
|
||||
<activity
|
||||
android:name=".GalleryMainActivity"
|
||||
android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="com.android.settingslib.spa.search.SpaSearchProvider"
|
||||
android:authorities="com.android.spa.gallery.search.provider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true"
|
||||
android:permission="android.permission.READ_SEARCH_INDEXABLES">
|
||||
<intent-filter>
|
||||
<action android:name="android.content.action.SPA_SEARCH_PROVIDER" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
|
||||
<provider android:name="com.android.settingslib.spa.slice.SpaSliceProvider"
|
||||
android:authorities="com.android.spa.gallery.slice.provider"
|
||||
android:exported="true" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.app.slice.category.SLICE" />
|
||||
</intent-filter>
|
||||
</provider>
|
||||
|
||||
<receiver
|
||||
android:name="com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver"
|
||||
android:exported="false">
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name="com.android.settingslib.spa.debug.BlankActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.android.settingslib.spa.debug.DebugActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<provider
|
||||
android:name="com.android.settingslib.spa.debug.DebugProvider"
|
||||
android:authorities="com.android.spa.gallery.debug.provider"
|
||||
android:exported="false">
|
||||
</provider>
|
||||
<activity
|
||||
android:name="com.android.settingslib.spa.gallery.GalleryDialogActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.SpaLib.Dialog">
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
||||
45
SettingsLib/Spa/gallery/build.gradle.kts
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.android.settingslib.spa.gallery"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.android.settingslib.spa.gallery"
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
sourceSets.getByName("main") {
|
||||
kotlin.setSrcDirs(listOf("src"))
|
||||
res.setSrcDirs(listOf("res"))
|
||||
manifest.srcFile("AndroidManifest.xml")
|
||||
}
|
||||
}
|
||||
buildFeatures {
|
||||
compose = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spa"))
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
SettingsLib/Spa/gallery/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 19 KiB |
34
SettingsLib/Spa/gallery/res/values/strings.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Gallery App label. [DO NOT TRANSLATE] -->
|
||||
<string name="app_label" translatable="false">Gallery</string>
|
||||
<!-- Gallery App name. [DO NOT TRANSLATE] -->
|
||||
<string name="app_name" translatable="false">SpaLib Gallery</string>
|
||||
|
||||
<!-- Title for single line summary preference. [DO NOT TRANSLATE] -->
|
||||
<string name="single_line_summary_preference_title" translatable="false">Preference (singleLineSummary = true)</string>
|
||||
<!-- Summary for single line summary preference. [DO NOT TRANSLATE] -->
|
||||
<string name="single_line_summary_preference_summary" translatable="false">A very long summary to show case a preference which only shows a single line summary.</string>
|
||||
<!-- Footer text with two links. [DO NOT TRANSLATE] -->
|
||||
<string name="footer_with_two_links" translatable="false">Annotated string with <a href="https://www.android.com/">link 1</a> and <a href="https://source.android.com/">link 2</a>.</string>
|
||||
|
||||
<!-- Sample title -->
|
||||
<string name="sample_title" translatable="false">Lorem ipsum</string>
|
||||
<!-- Sample text -->
|
||||
<string name="sample_text" translatable="false">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent a rhoncus tellus. Nulla facilisi. Pellentesque erat ex, maximus viae turpis</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import android.app.Application
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
|
||||
class GalleryApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
SpaEnvironmentFactory.reset(GallerySpaEnvironment(this))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.gallery
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.android.settingslib.spa.SpaBaseDialogActivity
|
||||
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
|
||||
import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogWithIcon
|
||||
|
||||
class GalleryDialogActivity : SpaBaseDialogActivity() {
|
||||
@Composable
|
||||
override fun Content() {
|
||||
SettingsAlertDialogWithIcon(
|
||||
onDismissRequest = { finish() },
|
||||
confirmButton = AlertDialogButton("confirm") { finish() },
|
||||
dismissButton = AlertDialogButton("dismiss") { finish() },
|
||||
title = "title",
|
||||
text = {
|
||||
Text(
|
||||
"text",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.android.settingslib.spa.framework.BrowseActivity
|
||||
|
||||
class GalleryMainActivity : BrowseActivity()
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import android.content.Context
|
||||
import com.android.settingslib.spa.debug.DebugLogger
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProviderRepository
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironment
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
|
||||
import com.android.settingslib.spa.gallery.card.CardPageProvider
|
||||
import com.android.settingslib.spa.gallery.chart.ChartPageProvider
|
||||
import com.android.settingslib.spa.gallery.dialog.DialogMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.dialog.NavDialogProvider
|
||||
import com.android.settingslib.spa.gallery.editor.EditorMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.editor.SettingsDropdownBoxPageProvider
|
||||
import com.android.settingslib.spa.gallery.editor.SettingsDropdownCheckBoxProvider
|
||||
import com.android.settingslib.spa.gallery.home.HomePageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.ItemListPageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.ItemOperatePageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
|
||||
import com.android.settingslib.spa.gallery.editor.SettingsOutlinedTextFieldPageProvider
|
||||
import com.android.settingslib.spa.gallery.editor.SettingsTextFieldPasswordPageProvider
|
||||
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.LoadingBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SliderPageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.ListPreferencePageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.MainSwitchPreferencePageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.TwoTargetSwitchPreferencePageProvider
|
||||
import com.android.settingslib.spa.gallery.scaffold.SearchScaffoldPageProvider
|
||||
import com.android.settingslib.spa.gallery.scaffold.SuwScaffoldPageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.CopyablePageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
|
||||
import com.android.settingslib.spa.slice.SpaSliceBroadcastReceiver
|
||||
|
||||
/**
|
||||
* Enum to define all SPP name here.
|
||||
* Since the SPP name would be used in log, DO NOT change it once it is set. One can still change
|
||||
* the display name for better readability if necessary.
|
||||
*/
|
||||
enum class SettingsPageProviderEnum(val displayName: String) {
|
||||
HOME("home"),
|
||||
PREFERENCE("preference"),
|
||||
ARGUMENT("argument"),
|
||||
ITEM_LIST("itemList"),
|
||||
ITEM_OP_PAGE("itemOp"),
|
||||
|
||||
// Add your SPPs
|
||||
}
|
||||
|
||||
class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) {
|
||||
override val pageProviderRepository = lazy {
|
||||
SettingsPageProviderRepository(
|
||||
allPageProviders = listOf(
|
||||
HomePageProvider,
|
||||
PreferenceMainPageProvider,
|
||||
PreferencePageProvider,
|
||||
SwitchPreferencePageProvider,
|
||||
MainSwitchPreferencePageProvider,
|
||||
ListPreferencePageProvider,
|
||||
TwoTargetSwitchPreferencePageProvider,
|
||||
ArgumentPageProvider,
|
||||
SliderPageProvider,
|
||||
SpinnerPageProvider,
|
||||
SettingsPagerPageProvider,
|
||||
FooterPageProvider,
|
||||
IllustrationPageProvider,
|
||||
CategoryPageProvider,
|
||||
ActionButtonPageProvider,
|
||||
ProgressBarPageProvider,
|
||||
LoadingBarPageProvider,
|
||||
ChartPageProvider,
|
||||
DialogMainPageProvider,
|
||||
NavDialogProvider,
|
||||
ItemListPageProvider,
|
||||
ItemOperatePageProvider,
|
||||
OperateListPageProvider,
|
||||
EditorMainPageProvider,
|
||||
SettingsOutlinedTextFieldPageProvider,
|
||||
SettingsDropdownBoxPageProvider,
|
||||
SettingsDropdownCheckBoxProvider,
|
||||
SettingsTextFieldPasswordPageProvider,
|
||||
SearchScaffoldPageProvider,
|
||||
SuwScaffoldPageProvider,
|
||||
CardPageProvider,
|
||||
CopyablePageProvider,
|
||||
),
|
||||
rootPages = listOf(
|
||||
HomePageProvider.createSettingsPage(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override val logger = DebugLogger()
|
||||
|
||||
override val browseActivityClass = GalleryMainActivity::class.java
|
||||
override val sliceBroadcastReceiverClass = SpaSliceBroadcastReceiver::class.java
|
||||
|
||||
// For debugging
|
||||
override val searchProviderAuthorities = "com.android.spa.gallery.search.provider"
|
||||
override val sliceProviderAuthorities = "com.android.spa.gallery.slice.provider"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.button
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.Launch
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.WarningAmber
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.button.ActionButton
|
||||
import com.android.settingslib.spa.widget.button.ActionButtons
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample ActionButton"
|
||||
|
||||
object ActionButtonPageProvider : SettingsPageProvider {
|
||||
override val name = "ActionButton"
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
val actionButtons = listOf(
|
||||
ActionButton(text = "Open", imageVector = Icons.AutoMirrored.Outlined.Launch) {},
|
||||
ActionButton(text = "Uninstall", imageVector = Icons.Outlined.Delete) {},
|
||||
ActionButton(text = "Force stop", imageVector = Icons.Outlined.WarningAmber) {},
|
||||
)
|
||||
ActionButtons(actionButtons)
|
||||
}
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun ActionButtonPagePreview() {
|
||||
SettingsTheme {
|
||||
ActionButtonPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.card
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Error
|
||||
import androidx.compose.material.icons.outlined.PowerOff
|
||||
import androidx.compose.material.icons.outlined.Shield
|
||||
import androidx.compose.material.icons.outlined.WarningAmber
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.widget.card.CardButton
|
||||
import com.android.settingslib.spa.widget.card.CardModel
|
||||
import com.android.settingslib.spa.widget.card.SettingsCard
|
||||
import com.android.settingslib.spa.widget.card.SettingsCardContent
|
||||
import com.android.settingslib.spa.widget.card.SettingsCollapsibleCard
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
object CardPageProvider : SettingsPageProvider {
|
||||
override val name = "Card"
|
||||
|
||||
override fun getTitle(arguments: Bundle?) = TITLE
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
SettingsCardWithIcon()
|
||||
SettingsCardWithoutIcon()
|
||||
SampleSettingsCollapsibleCard()
|
||||
SampleSettingsCardContent()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsCardWithIcon() {
|
||||
SettingsCard(
|
||||
CardModel(
|
||||
title = stringResource(R.string.sample_title),
|
||||
text = stringResource(R.string.sample_text),
|
||||
imageVector = Icons.Outlined.WarningAmber,
|
||||
buttons = listOf(
|
||||
CardButton(text = "Action") {},
|
||||
),
|
||||
tintColor = MaterialTheme.colorScheme.error,
|
||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsCardWithoutIcon() {
|
||||
val sampleTitle = stringResource(R.string.sample_title)
|
||||
var title by remember { mutableStateOf(sampleTitle) }
|
||||
SettingsCard(
|
||||
CardModel(
|
||||
title = title,
|
||||
text = stringResource(R.string.sample_text),
|
||||
) { title = "Clicked" }
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SampleSettingsCollapsibleCard() {
|
||||
val context = LocalContext.current
|
||||
var isVisible0 by rememberSaveable { mutableStateOf(true) }
|
||||
var isVisible1 by rememberSaveable { mutableStateOf(true) }
|
||||
val cards = remember {
|
||||
mutableStateListOf(
|
||||
CardModel(
|
||||
title = context.getString(R.string.sample_title),
|
||||
text = context.getString(R.string.sample_text),
|
||||
imageVector = Icons.Outlined.PowerOff,
|
||||
isVisible = { isVisible0 },
|
||||
onDismiss = { isVisible0 = false },
|
||||
buttons = listOf(
|
||||
CardButton(text = "Action") {},
|
||||
),
|
||||
),
|
||||
CardModel(
|
||||
title = context.getString(R.string.sample_title),
|
||||
text = context.getString(R.string.sample_text),
|
||||
imageVector = Icons.Outlined.Shield,
|
||||
isVisible = { isVisible1 },
|
||||
onDismiss = { isVisible1 = false },
|
||||
buttons = listOf(
|
||||
CardButton(text = "Action") {},
|
||||
),
|
||||
)
|
||||
)
|
||||
}
|
||||
SettingsCollapsibleCard(
|
||||
title = "More alerts",
|
||||
imageVector = Icons.Outlined.Error,
|
||||
models = cards.toList()
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SampleSettingsCardContent() {
|
||||
SettingsCard {
|
||||
SettingsCardContent {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { }
|
||||
.padding(SettingsDimension.dialogItemPadding),
|
||||
) {
|
||||
Text(text = "Abc")
|
||||
}
|
||||
}
|
||||
SettingsCardContent {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { }
|
||||
.padding(SettingsDimension.dialogItemPadding),
|
||||
) {
|
||||
Text(text = "123")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private const val TITLE = "Sample Card"
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun CardPagePreview() {
|
||||
SettingsTheme {
|
||||
CardPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.chart
|
||||
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.widget.chart.BarChart
|
||||
import com.android.settingslib.spa.widget.chart.BarChartData
|
||||
import com.android.settingslib.spa.widget.chart.BarChartModel
|
||||
import com.android.settingslib.spa.widget.chart.ColorPalette
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter
|
||||
|
||||
fun createBarChartEntry(owner: SettingsPage) = SettingsEntryBuilder.create("Bar Chart", owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Bar Chart"
|
||||
})
|
||||
BarChart(
|
||||
barChartModel = object : BarChartModel {
|
||||
override val chartDataList = listOf(
|
||||
BarChartData(x = 0f, y = listOf(12f, 2f)),
|
||||
BarChartData(x = 1f, y = listOf(5f, 1f)),
|
||||
BarChartData(x = 2f, y = listOf(21f, 2f)),
|
||||
BarChartData(x = 3f, y = listOf(5f, 1f)),
|
||||
BarChartData(x = 4f, y = listOf(10f, 0f)),
|
||||
BarChartData(x = 5f, y = listOf(9f, 1f)),
|
||||
BarChartData(x = 6f, y = listOf(1f, 1f)),
|
||||
)
|
||||
override val colors = listOf(ColorPalette.green, ColorPalette.yellow)
|
||||
override val xValueFormatter = IAxisValueFormatter { value, _ ->
|
||||
"4/${value.toInt() + 1}"
|
||||
}
|
||||
override val yValueFormatter = IAxisValueFormatter { value, _ ->
|
||||
"${value.toInt()}m"
|
||||
}
|
||||
override val yAxisMaxValue = 30f
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.chart
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.chart.LineChart
|
||||
import com.android.settingslib.spa.widget.chart.LineChartData
|
||||
import com.android.settingslib.spa.widget.chart.LineChartModel
|
||||
import com.android.settingslib.spa.widget.chart.PieChart
|
||||
import com.android.settingslib.spa.widget.chart.PieChartData
|
||||
import com.android.settingslib.spa.widget.chart.PieChartModel
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.github.mikephil.charting.formatter.IAxisValueFormatter
|
||||
import java.text.NumberFormat
|
||||
|
||||
private enum class WeekDay(val num: Int) {
|
||||
Sun(0), Mon(1), Tue(2), Wed(3), Thu(4), Fri(5), Sat(6),
|
||||
}
|
||||
private const val TITLE = "Sample Chart"
|
||||
|
||||
object ChartPageProvider : SettingsPageProvider {
|
||||
override val name = "Chart"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Line Chart", owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Line Chart"
|
||||
})
|
||||
LineChart(
|
||||
lineChartModel = object : LineChartModel {
|
||||
override val chartDataList = listOf(
|
||||
LineChartData(x = 0f, y = 0f),
|
||||
LineChartData(x = 1f, y = 0.1f),
|
||||
LineChartData(x = 2f, y = 0.2f),
|
||||
LineChartData(x = 3f, y = 0.6f),
|
||||
LineChartData(x = 4f, y = 0.9f),
|
||||
LineChartData(x = 5f, y = 1.0f),
|
||||
LineChartData(x = 6f, y = 0.8f),
|
||||
)
|
||||
override val xValueFormatter =
|
||||
IAxisValueFormatter { value, _ ->
|
||||
"${WeekDay.values()[value.toInt()]}"
|
||||
}
|
||||
override val yValueFormatter =
|
||||
IAxisValueFormatter { value, _ ->
|
||||
NumberFormat.getPercentInstance().format(value)
|
||||
}
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
entryList.add(createBarChartEntry(owner))
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Pie Chart", owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Pie Chart"
|
||||
})
|
||||
PieChart(
|
||||
pieChartModel = object : PieChartModel {
|
||||
override val chartDataList = listOf(
|
||||
PieChartData(label = "Settings", value = 20f),
|
||||
PieChartData(label = "Chrome", value = 5f),
|
||||
PieChartData(label = "Gmail", value = 3f),
|
||||
)
|
||||
override val centerText = "Today"
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun ChartPagePreview() {
|
||||
SettingsTheme {
|
||||
ChartPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.dialog
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.material3.Text
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.dialog.AlertDialogButton
|
||||
import com.android.settingslib.spa.widget.dialog.rememberAlertDialogPresenter
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Category: Dialog"
|
||||
|
||||
object DialogMainPageProvider : SettingsPageProvider {
|
||||
override val name = "DialogMain"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> = listOf(
|
||||
SettingsEntryBuilder.create("AlertDialog", owner).setUiLayoutFn {
|
||||
val alertDialogPresenter = rememberAlertDialogPresenter(
|
||||
confirmButton = AlertDialogButton("Ok"),
|
||||
dismissButton = AlertDialogButton("Cancel"),
|
||||
title = "Title",
|
||||
text = { Text("Text") },
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Show AlertDialog"
|
||||
override val onClick = alertDialogPresenter::open
|
||||
})
|
||||
}.build(),
|
||||
SettingsEntryBuilder.create("NavDialog", owner).setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Navigate to Dialog"
|
||||
override val onClick = navigator(route = NavDialogProvider.name)
|
||||
})
|
||||
}.build(),
|
||||
)
|
||||
|
||||
fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?) = TITLE
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.gallery.dialog
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.widget.dialog.SettingsDialogCard
|
||||
|
||||
object NavDialogProvider : SettingsPageProvider {
|
||||
override val name = "NavDialog"
|
||||
override val navType = SettingsPageProvider.NavType.Dialog
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SettingsDialogCard("Example Nav Dialog") {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.editor
|
||||
|
||||
import android.os.Bundle
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Category: Editor"
|
||||
|
||||
object EditorMainPageProvider : SettingsPageProvider {
|
||||
override val name = "EditorMain"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
SettingsOutlinedTextFieldPageProvider.buildInjectEntry().setLink(fromPage = owner)
|
||||
.build(),
|
||||
SettingsDropdownBoxPageProvider.buildInjectEntry().setLink(fromPage = owner)
|
||||
.build(),
|
||||
SettingsDropdownCheckBoxProvider.buildInjectEntry().setLink(fromPage = owner)
|
||||
.build(),
|
||||
SettingsTextFieldPasswordPageProvider.buildInjectEntry().setLink(fromPage = owner)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.editor
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.editor.SettingsDropdownBox
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample SettingsDropdownBox"
|
||||
|
||||
object SettingsDropdownBoxPageProvider : SettingsPageProvider {
|
||||
override val name = "SettingsDropdownBox"
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
Regular()
|
||||
NotEnabled()
|
||||
Empty()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Regular() {
|
||||
var selectedItem by remember { mutableIntStateOf(-1) }
|
||||
SettingsDropdownBox(
|
||||
label = "SettingsDropdownBox",
|
||||
options = listOf("item1", "item2", "item3"),
|
||||
selectedOptionIndex = selectedItem,
|
||||
) { selectedItem = it }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NotEnabled() {
|
||||
var selectedItem by remember { mutableIntStateOf(0) }
|
||||
SettingsDropdownBox(
|
||||
label = "Not enabled",
|
||||
options = listOf("item1", "item2", "item3"),
|
||||
enabled = false,
|
||||
selectedOptionIndex = selectedItem,
|
||||
) { selectedItem = it }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Empty() {
|
||||
var selectedItem by remember { mutableIntStateOf(-1) }
|
||||
SettingsDropdownBox(
|
||||
label = "Empty",
|
||||
options = emptyList(),
|
||||
selectedOptionIndex = selectedItem,
|
||||
) { selectedItem = it }
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SettingsDropdownBoxPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsDropdownBoxPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.gallery.editor
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.editor.SettingsDropdownCheckBox
|
||||
import com.android.settingslib.spa.widget.editor.SettingsDropdownCheckOption
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample SettingsDropdownCheckBox"
|
||||
|
||||
object SettingsDropdownCheckBoxProvider : SettingsPageProvider {
|
||||
override val name = "SettingsDropdownCheckBox"
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
SettingsDropdownCheckBox(
|
||||
label = "SettingsDropdownCheckBox",
|
||||
options = remember {
|
||||
listOf(
|
||||
SettingsDropdownCheckOption("Item 1"),
|
||||
SettingsDropdownCheckOption("Item 2"),
|
||||
SettingsDropdownCheckOption("Item 3"),
|
||||
)
|
||||
},
|
||||
)
|
||||
SettingsDropdownCheckBox(
|
||||
label = "Empty list",
|
||||
options = emptyList(),
|
||||
)
|
||||
SettingsDropdownCheckBox(
|
||||
label = "Disabled",
|
||||
options = remember {
|
||||
listOf(
|
||||
SettingsDropdownCheckOption("Item 1", selected = mutableStateOf(true)),
|
||||
SettingsDropdownCheckOption("Item 2"),
|
||||
SettingsDropdownCheckOption("Item 3"),
|
||||
)
|
||||
},
|
||||
enabled = false,
|
||||
)
|
||||
SettingsDropdownCheckBox(
|
||||
label = "With disabled item",
|
||||
options = remember {
|
||||
listOf(
|
||||
SettingsDropdownCheckOption("Item 1"),
|
||||
SettingsDropdownCheckOption("Item 2"),
|
||||
SettingsDropdownCheckOption(
|
||||
text = "Disabled item 1",
|
||||
changeable = false,
|
||||
selected = mutableStateOf(true),
|
||||
),
|
||||
SettingsDropdownCheckOption("Disabled item 2", changeable = false),
|
||||
)
|
||||
},
|
||||
)
|
||||
SettingsDropdownCheckBox(
|
||||
label = "With select all",
|
||||
options = remember {
|
||||
listOf(
|
||||
SettingsDropdownCheckOption("All", isSelectAll = true),
|
||||
SettingsDropdownCheckOption("Item 1"),
|
||||
SettingsDropdownCheckOption("Item 2"),
|
||||
SettingsDropdownCheckOption("Item 3"),
|
||||
)
|
||||
},
|
||||
)
|
||||
SettingsDropdownCheckBox(
|
||||
label = "With disabled item and select all",
|
||||
options =
|
||||
remember {
|
||||
listOf(
|
||||
SettingsDropdownCheckOption("All", isSelectAll = true, changeable = false),
|
||||
SettingsDropdownCheckOption("Item 1"),
|
||||
SettingsDropdownCheckOption("Item 2"),
|
||||
SettingsDropdownCheckOption(
|
||||
text = "Disabled item 1",
|
||||
changeable = false,
|
||||
selected = mutableStateOf(true),
|
||||
),
|
||||
SettingsDropdownCheckOption("Disabled item 2", changeable = false),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage()).setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SettingsDropdownCheckBoxPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsDropdownCheckBoxProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.editor
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.editor.SettingsOutlinedTextField
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample SettingsOutlinedTextField"
|
||||
|
||||
object SettingsOutlinedTextFieldPageProvider : SettingsPageProvider {
|
||||
override val name = "SettingsOutlinedTextField"
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
var value by remember { mutableStateOf("Enabled Value") }
|
||||
RegularScaffold(title = TITLE) {
|
||||
SettingsOutlinedTextField(
|
||||
value = value,
|
||||
label = "OutlinedTextField Enabled",
|
||||
enabled = true,
|
||||
onTextChange = {value = it})
|
||||
}
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SettingsOutlinedTextFieldPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsOutlinedTextFieldPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.editor
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.editor.SettingsTextFieldPassword
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val TITLE = "Sample SettingsTextFieldPassword"
|
||||
|
||||
object SettingsTextFieldPasswordPageProvider : SettingsPageProvider {
|
||||
override val name = "SettingsTextFieldPassword"
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
var value by remember { mutableStateOf("value") }
|
||||
RegularScaffold(title = TITLE) {
|
||||
SettingsTextFieldPassword(
|
||||
value = value,
|
||||
label = "label",
|
||||
onTextChange = { value = it })
|
||||
}
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SettingsTextFieldPasswordPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsTextFieldPasswordPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.home
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
|
||||
import com.android.settingslib.spa.gallery.card.CardPageProvider
|
||||
import com.android.settingslib.spa.gallery.chart.ChartPageProvider
|
||||
import com.android.settingslib.spa.gallery.dialog.DialogMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.editor.EditorMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageModel
|
||||
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.LoadingBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SliderPageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider
|
||||
import com.android.settingslib.spa.gallery.scaffold.SearchScaffoldPageProvider
|
||||
import com.android.settingslib.spa.gallery.scaffold.SuwScaffoldPageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.CategoryPageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.CopyablePageProvider
|
||||
import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
|
||||
import com.android.settingslib.spa.widget.scaffold.HomeScaffold
|
||||
|
||||
object HomePageProvider : SettingsPageProvider {
|
||||
override val name = SettingsPageProviderEnum.HOME.name
|
||||
override val displayName = SettingsPageProviderEnum.HOME.displayName
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
OperateListPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
|
||||
SearchScaffoldPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SuwScaffoldPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SettingsPagerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
FooterPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
IllustrationPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
CategoryPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ActionButtonPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ProgressBarPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
LoadingBarPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ChartPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
DialogMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
EditorMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
CardPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
CopyablePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return SpaEnvironmentFactory.instance.appContext.getString(R.string.app_name)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
HomeScaffold(title) {
|
||||
for (entry in entries) {
|
||||
if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
|
||||
entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
|
||||
} else {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun HomeScreenPreview() {
|
||||
SpaEnvironmentFactory.resetForPreview()
|
||||
SettingsTheme {
|
||||
HomePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val OPERATOR_PARAM_NAME = "opParam"
|
||||
|
||||
object ItemListPageProvider : SettingsPageProvider {
|
||||
override val name = SettingsPageProviderEnum.ITEM_LIST.name
|
||||
override val displayName = SettingsPageProviderEnum.ITEM_LIST.displayName
|
||||
override val parameter = listOf(
|
||||
navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
|
||||
)
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "NULL"
|
||||
return "Operation: $operation"
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!ItemOperatePageProvider.isValidArgs(arguments)) return emptyList()
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
|
||||
val owner = createSettingsPage(arguments)
|
||||
return listOf(
|
||||
ItemOperatePageProvider.buildInjectEntry(operation)!!.setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
|
||||
val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
|
||||
if (!ItemOperatePageProvider.isValidArgs(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
owner = createSettingsPage(arguments),
|
||||
label = "ItemList_$opParam",
|
||||
).setUiLayoutFn {
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = opParam
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ITEM_LIST.name + parameter.navLink(it)
|
||||
)
|
||||
}
|
||||
)
|
||||
}.setSearchDataFn {
|
||||
EntrySearchData(title = "Operation: $opParam")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
val itemList = remember {
|
||||
// Add logic to get item List during runtime.
|
||||
listOf("itemFoo", "itemBar", "itemToy")
|
||||
}
|
||||
RegularScaffold(title) {
|
||||
for (item in itemList) {
|
||||
val rtArgs = ItemOperatePageProvider.genRuntimeArguments(item)
|
||||
for (entry in entries) {
|
||||
entry.UiLayout(rtArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
|
||||
private const val OPERATOR_PARAM_NAME = "opParam"
|
||||
private const val ITEM_NAME_PARAM_NAME = "rt_nameParam"
|
||||
private val ALLOWED_OPERATOR_LIST = listOf("opDnD", "opPiP", "opInstall", "opConnect")
|
||||
|
||||
object ItemOperatePageProvider : SettingsPageProvider {
|
||||
override val name = SettingsPageProviderEnum.ITEM_OP_PAGE.name
|
||||
override val displayName = SettingsPageProviderEnum.ITEM_OP_PAGE.displayName
|
||||
override val parameter = listOf(
|
||||
navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
|
||||
navArgument(ITEM_NAME_PARAM_NAME) { type = NavType.StringType },
|
||||
)
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
// Operation name is not a runtime parameter, which should always available
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "opInValid"
|
||||
// Item name is a runtime parameter, which could be missing
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, arguments) ?: "[unset]"
|
||||
return "$operation on $itemName"
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!isValidArgs(arguments)) return emptyList()
|
||||
|
||||
val owner = createSettingsPage(arguments)
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("ItemName", owner)
|
||||
.setUiLayoutFn {
|
||||
// Item name is a runtime parameter, which needs to be read inside UiLayoutFn
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = "Item $itemName"
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
|
||||
// Operation name is not a runtime parameter, which can be read outside.
|
||||
val opName = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("ItemOp", owner)
|
||||
.setUiLayoutFn {
|
||||
var checked by rememberSaveable { mutableStateOf(false) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "Item operation: $opName"
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange =
|
||||
{ newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}.build(),
|
||||
)
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
|
||||
val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
|
||||
if (!isValidArgs(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
owner = createSettingsPage(arguments),
|
||||
label = "ItemOp_$opParam",
|
||||
).setUiLayoutFn {
|
||||
// Item name is a runtime parameter, which needs to be read inside UiLayoutFn
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = "item: $itemName"
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ITEM_OP_PAGE.name + parameter.navLink(it)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun isValidArgs(arguments: Bundle?): Boolean {
|
||||
val opParam = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)
|
||||
return (opParam != null && ALLOWED_OPERATOR_LIST.contains(opParam))
|
||||
}
|
||||
|
||||
fun genRuntimeArguments(itemName: String): Bundle {
|
||||
return bundleOf(ITEM_NAME_PARAM_NAME to itemName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Operate List Main"
|
||||
|
||||
object OperateListPageProvider : SettingsPageProvider {
|
||||
override val name = "OpList"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
ItemListPageProvider.buildInjectEntry("opPiP")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opInstall")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opDnD")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opConnect")!!.setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
object ArgumentPageProvider : SettingsPageProvider {
|
||||
// Defines all entry name in this page.
|
||||
// Note that entry name would be used in log. DO NOT change it once it is set.
|
||||
// One can still change the display name for better readability if necessary.
|
||||
private enum class EntryEnum(val displayName: String) {
|
||||
STRING_PARAM("string_param"),
|
||||
INT_PARAM("int_param"),
|
||||
}
|
||||
|
||||
private fun createEntry(owner: SettingsPage, entry: EntryEnum): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.create(owner, entry.name, entry.displayName)
|
||||
}
|
||||
|
||||
override val name = SettingsPageProviderEnum.ARGUMENT.name
|
||||
override val displayName = SettingsPageProviderEnum.ARGUMENT.displayName
|
||||
override val parameter = ArgumentPageModel.parameter
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return emptyList()
|
||||
|
||||
val owner = createSettingsPage(arguments)
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
createEntry(owner, EntryEnum.STRING_PARAM)
|
||||
// Set attributes
|
||||
.setIsSearchDataDynamic(true)
|
||||
.setSearchDataFn { ArgumentPageModel.genStringParamSearchData() }
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(it).genStringParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
entryList.add(
|
||||
createEntry(owner, EntryEnum.INT_PARAM)
|
||||
// Set attributes
|
||||
.setIsSearchDataDynamic(true)
|
||||
.setSearchDataFn { ArgumentPageModel.genIntParamSearchData() }
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(it).genIntParamPreferenceModel())
|
||||
}.build()
|
||||
)
|
||||
|
||||
entryList.add(buildInjectEntry("foo")!!.setLink(fromPage = owner).build())
|
||||
entryList.add(buildInjectEntry("bar")!!.setLink(fromPage = owner).build())
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(stringParam: String): SettingsEntryBuilder? {
|
||||
val arguments = ArgumentPageModel.buildArgument(stringParam)
|
||||
if (!ArgumentPageModel.isValidArgument(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
owner = createSettingsPage(arguments),
|
||||
label = "${name}_$stringParam",
|
||||
)
|
||||
.setSearchDataFn { ArgumentPageModel.genInjectSearchData() }
|
||||
.setUiLayoutFn {
|
||||
// Set ui rendering
|
||||
Preference(ArgumentPageModel.create(it).genInjectPreferenceModel())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return ArgumentPageModel.genPageTitle()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
val rtArgNext = remember { ArgumentPageModel.buildNextArgument(arguments) }
|
||||
RegularScaffold(title) {
|
||||
for (entry in entries) {
|
||||
if (entry.toPage != null) {
|
||||
entry.UiLayout(rtArgNext)
|
||||
} else {
|
||||
entry.UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun ArgumentPagePreview() {
|
||||
SpaEnvironmentFactory.resetForPreview()
|
||||
SettingsTheme {
|
||||
ArgumentPageProvider.Page(
|
||||
ArgumentPageModel.buildArgument(stringParam = "foo", intParam = 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.runtime.Composable
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.PageModel
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.util.getIntArg
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TAG = "ArgumentPageModel"
|
||||
|
||||
// Defines all the resources for this page.
|
||||
// In real Settings App, resources data is defined in xml, rather than SPP.
|
||||
private const val PAGE_TITLE = "Sample page with arguments"
|
||||
private const val STRING_PARAM_TITLE = "String param value"
|
||||
private const val INT_PARAM_TITLE = "Int param value"
|
||||
private const val STRING_PARAM_NAME = "stringParam"
|
||||
private const val INT_PARAM_NAME = "rt_intParam"
|
||||
private val ARGUMENT_PAGE_KEYWORDS = listOf("argument keyword1", "argument keyword2")
|
||||
|
||||
class ArgumentPageModel : PageModel() {
|
||||
|
||||
companion object {
|
||||
val parameter = listOf(
|
||||
navArgument(STRING_PARAM_NAME) { type = NavType.StringType },
|
||||
navArgument(INT_PARAM_NAME) { type = NavType.IntType },
|
||||
)
|
||||
|
||||
fun buildArgument(stringParam: String? = null, intParam: Int? = null): Bundle {
|
||||
val args = Bundle()
|
||||
if (stringParam != null) args.putString(STRING_PARAM_NAME, stringParam)
|
||||
if (intParam != null) args.putInt(INT_PARAM_NAME, intParam)
|
||||
return args
|
||||
}
|
||||
|
||||
fun buildNextArgument(arguments: Bundle? = null): Bundle {
|
||||
val intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
val nextIntParam = if (intParam != null) intParam + 1 else null
|
||||
return buildArgument(intParam = nextIntParam)
|
||||
}
|
||||
|
||||
fun isValidArgument(arguments: Bundle?): Boolean {
|
||||
val stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
|
||||
return (stringParam != null && listOf("foo", "bar").contains(stringParam))
|
||||
}
|
||||
|
||||
fun genStringParamSearchData(): EntrySearchData {
|
||||
return EntrySearchData(title = STRING_PARAM_TITLE)
|
||||
}
|
||||
|
||||
fun genIntParamSearchData(): EntrySearchData {
|
||||
return EntrySearchData(title = INT_PARAM_TITLE)
|
||||
}
|
||||
|
||||
fun genInjectSearchData(): EntrySearchData {
|
||||
return EntrySearchData(title = PAGE_TITLE, keyword = ARGUMENT_PAGE_KEYWORDS)
|
||||
}
|
||||
|
||||
fun genPageTitle(): String {
|
||||
return PAGE_TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun create(arguments: Bundle?): ArgumentPageModel {
|
||||
val pageModel: ArgumentPageModel = viewModel(key = arguments.toString())
|
||||
pageModel.initOnce(arguments)
|
||||
return pageModel
|
||||
}
|
||||
}
|
||||
|
||||
private var arguments: Bundle? = null
|
||||
private var stringParam: String? = null
|
||||
private var intParam: Int? = null
|
||||
|
||||
override fun initialize(arguments: Bundle?) {
|
||||
SpaEnvironmentFactory.instance.logger.message(
|
||||
TAG, "Initialize with args " + arguments.toString()
|
||||
)
|
||||
this.arguments = arguments
|
||||
stringParam = parameter.getStringArg(STRING_PARAM_NAME, arguments)
|
||||
intParam = parameter.getIntArg(INT_PARAM_NAME, arguments)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genStringParamPreferenceModel(): PreferenceModel {
|
||||
return object : PreferenceModel {
|
||||
override val title = STRING_PARAM_TITLE
|
||||
override val summary = { stringParam!! }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genIntParamPreferenceModel(): PreferenceModel {
|
||||
return object : PreferenceModel {
|
||||
override val title = INT_PARAM_TITLE
|
||||
override val summary = { intParam!!.toString() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun genInjectPreferenceModel(): PreferenceModel {
|
||||
val summaryArray = listOf(
|
||||
"$STRING_PARAM_NAME=" + stringParam!!,
|
||||
"$INT_PARAM_NAME=" + intParam!!
|
||||
)
|
||||
return object : PreferenceModel {
|
||||
override val title = PAGE_TITLE
|
||||
override val summary = { summaryArray.joinToString(", ") }
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ARGUMENT.name + parameter.navLink(arguments)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
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.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.AnnotatedText
|
||||
import com.android.settingslib.spa.widget.ui.Footer
|
||||
|
||||
private const val TITLE = "Sample Footer"
|
||||
|
||||
object FooterPageProvider : SettingsPageProvider {
|
||||
override val name = "Footer"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "Some Preference", owner)
|
||||
.setSearchDataFn { EntrySearchData(title = "Some Preference") }
|
||||
.setUiLayoutFn {
|
||||
Preference(remember {
|
||||
object : PreferenceModel {
|
||||
override val title = "Some Preference"
|
||||
override val summary = { "Some summary" }
|
||||
}
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
entry.UiLayout()
|
||||
}
|
||||
Footer(footerText = "Footer text always at the end of page.")
|
||||
Footer {
|
||||
AnnotatedText(R.string.footer_with_two_links)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun FooterPagePreview() {
|
||||
SettingsTheme {
|
||||
FooterPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
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.Illustration
|
||||
import com.android.settingslib.spa.widget.illustration.IllustrationModel
|
||||
import com.android.settingslib.spa.widget.illustration.ResourceType
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Sample Illustration"
|
||||
|
||||
object IllustrationPageProvider : SettingsPageProvider {
|
||||
override val name = "Illustration"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "Lottie Illustration", owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Lottie Illustration"
|
||||
})
|
||||
|
||||
Illustration(object : IllustrationModel {
|
||||
override val resId = R.raw.accessibility_shortcut_type_triple_tap
|
||||
override val resourceType = ResourceType.LOTTIE
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "Image Illustration", owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Image Illustration"
|
||||
})
|
||||
|
||||
Illustration(object : IllustrationModel {
|
||||
override val resId = R.drawable.accessibility_captioning_banner
|
||||
override val resourceType = ResourceType.IMAGE
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun IllustrationPagePreview() {
|
||||
SettingsTheme {
|
||||
IllustrationPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.CircularLoadingBar
|
||||
import com.android.settingslib.spa.widget.ui.LinearLoadingBar
|
||||
|
||||
private const val TITLE = "Sample LoadingBar"
|
||||
|
||||
object LoadingBarPageProvider : SettingsPageProvider {
|
||||
override val name = "LoadingBar"
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
var loading by remember { mutableStateOf(true) }
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
Button(
|
||||
onClick = { loading = !loading },
|
||||
modifier = Modifier.padding(start = 20.dp)
|
||||
) {
|
||||
if (loading) {
|
||||
Text(text = "Stop")
|
||||
} else {
|
||||
Text(text = "Resume")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinearLoadingBar(isLoading = loading, yOffset = 104.dp)
|
||||
CircularLoadingBar(isLoading = loading)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun LoadingBarPagePreview() {
|
||||
SettingsTheme {
|
||||
LoadingBarPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.SystemUpdate
|
||||
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.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarPreference
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarWithDataPreference
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.CircularProgressBar
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val TITLE = "Sample ProgressBar"
|
||||
|
||||
object ProgressBarPageProvider : SettingsPageProvider {
|
||||
override val name = "ProgressBar"
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
// Auto update the progress and finally jump tp 0.4f.
|
||||
var progress by remember { mutableStateOf(0f) }
|
||||
LaunchedEffect(Unit) {
|
||||
while (progress < 1f) {
|
||||
delay(100)
|
||||
progress += 0.01f
|
||||
}
|
||||
delay(500)
|
||||
progress = 0.4f
|
||||
}
|
||||
|
||||
LargeProgressBar(progress)
|
||||
SimpleProgressBar()
|
||||
ProgressBarWithData()
|
||||
CircularProgressBar(progress = progress, radius = 160f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LargeProgressBar(progress: Float) {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Large Progress Bar"
|
||||
override val progress = progress
|
||||
override val height = 20f
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleProgressBar() {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Simple Progress Bar"
|
||||
override val progress = 0.2f
|
||||
override val icon = Icons.Outlined.SystemUpdate
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProgressBarWithData() {
|
||||
ProgressBarWithDataPreference(model = object : ProgressBarPreferenceModel {
|
||||
override val title = "Progress Bar with Data"
|
||||
override val progress = 0.2f
|
||||
override val icon = Icons.Outlined.Delete
|
||||
}, data = "25G")
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun ProgressBarPagePreview() {
|
||||
SettingsTheme {
|
||||
ProgressBarPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -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.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.SettingsPager
|
||||
import com.android.settingslib.spa.widget.scaffold.SettingsScaffold
|
||||
import com.android.settingslib.spa.widget.ui.PlaceholderTitle
|
||||
|
||||
private const val TITLE = "Sample SettingsPager"
|
||||
|
||||
object SettingsPagerPageProvider : SettingsPageProvider {
|
||||
override val name = "SettingsPager"
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
SettingsScaffold(title = getTitle(arguments)) { paddingValues ->
|
||||
Box(Modifier.padding(paddingValues)) {
|
||||
SettingsPager(listOf("Personal", "Work")) {
|
||||
PlaceholderTitle("Page $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SettingsPagerPagePreview() {
|
||||
SettingsTheme {
|
||||
SettingsPagerPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.AccessAlarm
|
||||
import androidx.compose.material.icons.outlined.MusicNote
|
||||
import androidx.compose.material.icons.outlined.MusicOff
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.SliderPreference
|
||||
import com.android.settingslib.spa.widget.preference.SliderPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Sample Slider"
|
||||
|
||||
object SliderPageProvider : SettingsPageProvider {
|
||||
override val name = "Slider"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Simple Slider", owner)
|
||||
.setUiLayoutFn {
|
||||
SliderPreference(object : SliderPreferenceModel {
|
||||
override val title = "Simple Slider"
|
||||
override val initValue = 40
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Slider with icon", owner)
|
||||
.setUiLayoutFn {
|
||||
SliderPreference(object : SliderPreferenceModel {
|
||||
override val title = "Slider with icon"
|
||||
override val initValue = 30
|
||||
override val onValueChangeFinished = {
|
||||
println("onValueChangeFinished")
|
||||
}
|
||||
override val icon = Icons.Outlined.AccessAlarm
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Slider with changeable icon", owner)
|
||||
.setUiLayoutFn {
|
||||
val initValue = 0
|
||||
var icon by remember { mutableStateOf(Icons.Outlined.MusicOff) }
|
||||
var sliderPosition by remember { mutableStateOf(initValue) }
|
||||
SliderPreference(object : SliderPreferenceModel {
|
||||
override val title = "Slider with changeable icon"
|
||||
override val initValue = initValue
|
||||
override val onValueChange = { it: Int ->
|
||||
sliderPosition = it
|
||||
icon = if (it > 0) Icons.Outlined.MusicNote else Icons.Outlined.MusicOff
|
||||
}
|
||||
override val onValueChangeFinished = {
|
||||
println("onValueChangeFinished: the value is $sliderPosition")
|
||||
}
|
||||
override val icon = icon
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Slider with steps", owner)
|
||||
.setUiLayoutFn {
|
||||
SliderPreference(object : SliderPreferenceModel {
|
||||
override val title = "Slider with steps"
|
||||
override val initValue = 2
|
||||
override val valueRange = 1..5
|
||||
override val showSteps = true
|
||||
})
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SliderPagePreview() {
|
||||
SettingsTheme {
|
||||
SliderPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.ListPreference
|
||||
import com.android.settingslib.spa.widget.preference.ListPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ListPreferenceOption
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
private const val TITLE = "Sample ListPreference"
|
||||
|
||||
object ListPreferencePageProvider : SettingsPageProvider {
|
||||
override val name = "ListPreference"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?) = listOf(
|
||||
SettingsEntryBuilder.create("ListPreference", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleListPreference()
|
||||
}.build(),
|
||||
SettingsEntryBuilder.create("ListPreference not changeable", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleNotChangeableListPreference()
|
||||
}.build(),
|
||||
)
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?) = TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleListPreference() {
|
||||
val selectedId = rememberSaveable { mutableIntStateOf(1) }
|
||||
ListPreference(remember {
|
||||
object : ListPreferenceModel {
|
||||
override val title = "Preferred network type"
|
||||
override val options = listOf(
|
||||
ListPreferenceOption(id = 1, text = "5G (recommended)"),
|
||||
ListPreferenceOption(id = 2, text = "LTE"),
|
||||
ListPreferenceOption(id = 3, text = "3G"),
|
||||
)
|
||||
override val selectedId = selectedId
|
||||
override val onIdSelected: (id: Int) -> Unit = { selectedId.intValue = it }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleNotChangeableListPreference() {
|
||||
val selectedId = rememberSaveable { mutableIntStateOf(1) }
|
||||
val enableFlow = flow {
|
||||
var enabled = true
|
||||
while (true) {
|
||||
delay(3.seconds)
|
||||
enabled = !enabled
|
||||
emit(enabled)
|
||||
}
|
||||
}
|
||||
val enabled = enableFlow.collectAsStateWithLifecycle(initialValue = true)
|
||||
ListPreference(remember {
|
||||
object : ListPreferenceModel {
|
||||
override val title = "Preferred network type"
|
||||
override val enabled = { enabled.value }
|
||||
override val options = listOf(
|
||||
ListPreferenceOption(id = 1, text = "5G (recommended)"),
|
||||
ListPreferenceOption(id = 2, text = "LTE"),
|
||||
ListPreferenceOption(id = 3, text = "3G"),
|
||||
)
|
||||
override val selectedId = selectedId
|
||||
override val onIdSelected: (id: Int) -> Unit = { selectedId.intValue = it }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun ListPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
ListPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.MainSwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
|
||||
private const val TITLE = "Sample MainSwitchPreference"
|
||||
|
||||
object MainSwitchPreferencePageProvider : SettingsPageProvider {
|
||||
override val name = "MainSwitchPreference"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("MainSwitchPreference", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleMainSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("MainSwitchPreference not changeable", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleNotChangeableMainSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleMainSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(false) }
|
||||
MainSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "MainSwitchPreference"
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleNotChangeableMainSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
MainSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "Not changeable"
|
||||
override val changeable = { false }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun MainSwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
MainSwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Category: Preference"
|
||||
|
||||
object PreferenceMainPageProvider : SettingsPageProvider {
|
||||
override val name = "PreferenceMain"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
PreferencePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SwitchPreferencePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
MainSwitchPreferencePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ListPreferencePageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
TwoTargetSwitchPreferencePageProvider.buildInjectEntry()
|
||||
.setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.android.settingslib.spa.framework.common.PageModel
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val TAG = "PreferencePageModel"
|
||||
|
||||
class PreferencePageModel : PageModel() {
|
||||
companion object {
|
||||
// Defines all the resources for this page.
|
||||
// In real Settings App, resources data is defined in xml, rather than SPP.
|
||||
const val PAGE_TITLE = "Sample Preference"
|
||||
const val SIMPLE_PREFERENCE_TITLE = "Preference"
|
||||
const val SIMPLE_PREFERENCE_SUMMARY = "Simple summary"
|
||||
const val DISABLE_PREFERENCE_TITLE = "Disabled"
|
||||
const val DISABLE_PREFERENCE_SUMMARY = "Disabled summary"
|
||||
const val ASYNC_PREFERENCE_TITLE = "Async Preference"
|
||||
const val ASYNC_PREFERENCE_SUMMARY = "Async summary"
|
||||
const val MANUAL_UPDATE_PREFERENCE_TITLE = "Manual Updater"
|
||||
const val AUTO_UPDATE_PREFERENCE_TITLE = "Auto Updater"
|
||||
val SIMPLE_PREFERENCE_KEYWORDS = listOf("simple keyword1", "simple keyword2")
|
||||
|
||||
@Composable
|
||||
fun create(): PreferencePageModel {
|
||||
val pageModel: PreferencePageModel = viewModel()
|
||||
pageModel.initOnce()
|
||||
return pageModel
|
||||
}
|
||||
}
|
||||
|
||||
private val spaLogger = SpaEnvironmentFactory.instance.logger
|
||||
|
||||
val asyncSummary = mutableStateOf("(loading)")
|
||||
val asyncEnable = mutableStateOf(false)
|
||||
|
||||
private val manualUpdater = mutableStateOf(0)
|
||||
|
||||
private val autoUpdater = object : MutableLiveData<String>(" ") {
|
||||
private var tick = 0
|
||||
private var updateJob: Job? = null
|
||||
override fun onActive() {
|
||||
spaLogger.message(TAG, "autoUpdater.active")
|
||||
updateJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
while (true) {
|
||||
delay(1000L)
|
||||
tick++
|
||||
spaLogger.message(TAG, "autoUpdater.value $tick")
|
||||
postValue(tick.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onInactive() {
|
||||
spaLogger.message(TAG, "autoUpdater.inactive")
|
||||
updateJob?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
override fun initialize(arguments: Bundle?) {
|
||||
spaLogger.message(TAG, "initialize with args " + arguments.toString())
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// Loading your data here.
|
||||
delay(2000L)
|
||||
asyncSummary.value = ASYNC_PREFERENCE_SUMMARY
|
||||
asyncEnable.value = true
|
||||
}
|
||||
}
|
||||
|
||||
fun getManualUpdaterSummary(): State<String> {
|
||||
spaLogger.message(TAG, "getManualUpdaterSummary")
|
||||
return derivedStateOf { manualUpdater.value.toString() }
|
||||
}
|
||||
|
||||
fun manualUpdaterOnClick() {
|
||||
spaLogger.message(TAG, "manualUpdaterOnClick")
|
||||
manualUpdater.value = manualUpdater.value + 1
|
||||
}
|
||||
|
||||
fun getAutoUpdaterSummary(): LiveData<String> {
|
||||
spaLogger.message(TAG, "getAutoUpdaterSummary")
|
||||
return autoUpdater
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Autorenew
|
||||
import androidx.compose.material.icons.outlined.DisabledByDefault
|
||||
import androidx.compose.material.icons.outlined.TouchApp
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.EntrySliceData
|
||||
import com.android.settingslib.spa.framework.common.EntryStatusData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.framework.util.createIntent
|
||||
import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_SUMMARY
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.ASYNC_PREFERENCE_TITLE
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.AUTO_UPDATE_PREFERENCE_TITLE
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.DISABLE_PREFERENCE_SUMMARY
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.DISABLE_PREFERENCE_TITLE
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.MANUAL_UPDATE_PREFERENCE_TITLE
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.PAGE_TITLE
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_KEYWORDS
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_SUMMARY
|
||||
import com.android.settingslib.spa.gallery.preference.PreferencePageModel.Companion.SIMPLE_PREFERENCE_TITLE
|
||||
import com.android.settingslib.spa.slice.createBrowsePendingIntent
|
||||
import com.android.settingslib.spa.slice.provider.createDemoActionSlice
|
||||
import com.android.settingslib.spa.slice.provider.createDemoBrowseSlice
|
||||
import com.android.settingslib.spa.slice.provider.createDemoSlice
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro
|
||||
import com.android.settingslib.spa.widget.ui.SettingsIcon
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val TAG = "PreferencePage"
|
||||
|
||||
object PreferencePageProvider : SettingsPageProvider {
|
||||
// Defines all entry name in this page.
|
||||
// Note that entry name would be used in log. DO NOT change it once it is set.
|
||||
// One can still change the display name for better readability if necessary.
|
||||
enum class EntryEnum(val displayName: String) {
|
||||
SIMPLE_PREFERENCE("preference"),
|
||||
SUMMARY_PREFERENCE("preference_with_summary"),
|
||||
SINGLE_LINE_SUMMARY_PREFERENCE("preference_with_single_line_summary"),
|
||||
DISABLED_PREFERENCE("preference_disable"),
|
||||
ASYNC_SUMMARY_PREFERENCE("preference_with_async_summary"),
|
||||
MANUAL_UPDATE_PREFERENCE("preference_actionable"),
|
||||
AUTO_UPDATE_PREFERENCE("preference_auto_update"),
|
||||
}
|
||||
|
||||
override val name = SettingsPageProviderEnum.PREFERENCE.name
|
||||
override val displayName = SettingsPageProviderEnum.PREFERENCE.displayName
|
||||
private val spaLogger = SpaEnvironmentFactory.instance.logger
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
private fun createEntry(entry: EntryEnum): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.create(owner, entry.name, entry.displayName)
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.SIMPLE_PREFERENCE)
|
||||
.setMacro {
|
||||
spaLogger.message(TAG, "create macro for ${EntryEnum.SIMPLE_PREFERENCE}")
|
||||
SimplePreferenceMacro(title = SIMPLE_PREFERENCE_TITLE)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = false) }
|
||||
.build()
|
||||
)
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.SUMMARY_PREFERENCE)
|
||||
.setMacro {
|
||||
spaLogger.message(TAG, "create macro for ${EntryEnum.SUMMARY_PREFERENCE}")
|
||||
SimplePreferenceMacro(
|
||||
title = SIMPLE_PREFERENCE_TITLE,
|
||||
summary = SIMPLE_PREFERENCE_SUMMARY,
|
||||
searchKeywords = SIMPLE_PREFERENCE_KEYWORDS,
|
||||
)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = true) }
|
||||
.build()
|
||||
)
|
||||
entryList.add(singleLineSummaryEntry())
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.DISABLED_PREFERENCE)
|
||||
.setHasMutableStatus(true)
|
||||
.setMacro {
|
||||
spaLogger.message(TAG, "create macro for ${EntryEnum.DISABLED_PREFERENCE}")
|
||||
SimplePreferenceMacro(
|
||||
title = DISABLE_PREFERENCE_TITLE,
|
||||
summary = DISABLE_PREFERENCE_SUMMARY,
|
||||
disabled = true,
|
||||
icon = Icons.Outlined.DisabledByDefault,
|
||||
)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = true) }
|
||||
.build()
|
||||
)
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.ASYNC_SUMMARY_PREFERENCE)
|
||||
.setHasMutableStatus(true)
|
||||
.setSearchDataFn {
|
||||
EntrySearchData(title = ASYNC_PREFERENCE_TITLE)
|
||||
}
|
||||
.setStatusDataFn { EntryStatusData(isDisabled = false) }
|
||||
.setUiLayoutFn {
|
||||
val model = PreferencePageModel.create()
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = ASYNC_PREFERENCE_TITLE
|
||||
override val summary = { model.asyncSummary.value }
|
||||
override val enabled = { model.asyncEnable.value }
|
||||
}
|
||||
)
|
||||
}
|
||||
.setSliceDataFn { sliceUri, _ ->
|
||||
val createSliceImpl = { s: String ->
|
||||
createDemoBrowseSlice(
|
||||
sliceUri = sliceUri,
|
||||
title = ASYNC_PREFERENCE_TITLE,
|
||||
summary = s,
|
||||
)
|
||||
}
|
||||
return@setSliceDataFn object : EntrySliceData() {
|
||||
init {
|
||||
postValue(createSliceImpl("(loading)"))
|
||||
}
|
||||
|
||||
override suspend fun asyncRunner() {
|
||||
spaLogger.message(TAG, "Async entry loading")
|
||||
delay(2000L)
|
||||
postValue(createSliceImpl(ASYNC_PREFERENCE_SUMMARY))
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.MANUAL_UPDATE_PREFERENCE)
|
||||
.setUiLayoutFn {
|
||||
val model = PreferencePageModel.create()
|
||||
val manualUpdaterSummary = remember { model.getManualUpdaterSummary() }
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = MANUAL_UPDATE_PREFERENCE_TITLE
|
||||
override val summary = { manualUpdaterSummary.value }
|
||||
override val onClick = { model.manualUpdaterOnClick() }
|
||||
override val icon = @Composable {
|
||||
SettingsIcon(imageVector = Icons.Outlined.TouchApp)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.setSliceDataFn { sliceUri, args ->
|
||||
val createSliceImpl = { v: Int ->
|
||||
createDemoActionSlice(
|
||||
sliceUri = sliceUri,
|
||||
title = MANUAL_UPDATE_PREFERENCE_TITLE,
|
||||
summary = "manual update value $v",
|
||||
)
|
||||
}
|
||||
|
||||
return@setSliceDataFn object : EntrySliceData() {
|
||||
private var tick = args?.getString("init")?.toInt() ?: 0
|
||||
|
||||
init {
|
||||
postValue(createSliceImpl(tick))
|
||||
}
|
||||
|
||||
override suspend fun asyncAction() {
|
||||
tick++
|
||||
postValue(createSliceImpl(tick))
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
createEntry(EntryEnum.AUTO_UPDATE_PREFERENCE)
|
||||
.setUiLayoutFn {
|
||||
val model = PreferencePageModel.create()
|
||||
val autoUpdaterSummary = remember {
|
||||
model.getAutoUpdaterSummary()
|
||||
}.observeAsState(" ")
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = AUTO_UPDATE_PREFERENCE_TITLE
|
||||
override val summary = { autoUpdaterSummary.value }
|
||||
override val icon = @Composable {
|
||||
SettingsIcon(imageVector = Icons.Outlined.Autorenew)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
.setSliceDataFn { sliceUri, args ->
|
||||
val createSliceImpl = { v: Int ->
|
||||
createDemoBrowseSlice(
|
||||
sliceUri = sliceUri,
|
||||
title = AUTO_UPDATE_PREFERENCE_TITLE,
|
||||
summary = "auto update value $v",
|
||||
)
|
||||
}
|
||||
|
||||
return@setSliceDataFn object : EntrySliceData() {
|
||||
private var tick = args?.getString("init")?.toInt() ?: 0
|
||||
|
||||
init {
|
||||
postValue(createSliceImpl(tick))
|
||||
}
|
||||
|
||||
override suspend fun asyncRunner() {
|
||||
spaLogger.message(TAG, "autoUpdater.active")
|
||||
while (true) {
|
||||
delay(1000L)
|
||||
tick++
|
||||
spaLogger.message(TAG, "autoUpdater.value $tick")
|
||||
postValue(createSliceImpl(tick))
|
||||
}
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
private fun singleLineSummaryEntry() = createEntry(EntryEnum.SINGLE_LINE_SUMMARY_PREFERENCE)
|
||||
.setUiLayoutFn {
|
||||
val summary = stringResource(R.string.single_line_summary_preference_summary)
|
||||
Preference(
|
||||
model = object : PreferenceModel {
|
||||
override val title: String =
|
||||
stringResource(R.string.single_line_summary_preference_title)
|
||||
override val summary = { summary }
|
||||
},
|
||||
singleLineSummary = true,
|
||||
)
|
||||
}
|
||||
.build()
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setMacro {
|
||||
spaLogger.message(TAG, "create macro for INJECT entry")
|
||||
SimplePreferenceMacro(
|
||||
title = PAGE_TITLE,
|
||||
clickRoute = SettingsPageProviderEnum.PREFERENCE.name
|
||||
)
|
||||
}
|
||||
.setSliceDataFn { sliceUri, _ ->
|
||||
val intent = owner.createIntent()?.createBrowsePendingIntent()
|
||||
?: return@setSliceDataFn null
|
||||
return@setSliceDataFn object : EntrySliceData() {
|
||||
init {
|
||||
postValue(
|
||||
createDemoSlice(
|
||||
sliceUri = sliceUri,
|
||||
title = PAGE_TITLE,
|
||||
summary = "Injected Entry",
|
||||
intent = intent,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return PAGE_TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun PreferencePagePreview() {
|
||||
SpaEnvironmentFactory.resetForPreview()
|
||||
SettingsTheme {
|
||||
PreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.AirplanemodeActive
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
import com.android.settingslib.spa.widget.ui.SettingsIcon
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val TITLE = "Sample SwitchPreference"
|
||||
|
||||
object SwitchPreferencePageProvider : SettingsPageProvider {
|
||||
override val name = "SwitchPreference"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "SwitchPreference", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "SwitchPreference with summary", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleSwitchPreferenceWithSummary()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "SwitchPreference with async summary", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleSwitchPreferenceWithAsyncSummary()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "SwitchPreference not changeable", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleNotChangeableSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "SwitchPreference with icon", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleSwitchPreferenceWithIcon()
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(false) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "SwitchPreference"
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleSwitchPreferenceWithSummary() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "SwitchPreference"
|
||||
override val summary = { "With summary" }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleSwitchPreferenceWithAsyncSummary() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
val summary = produceState(initialValue = " ") {
|
||||
delay(1000L)
|
||||
value = "Async summary"
|
||||
}
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "SwitchPreference"
|
||||
override val summary = { summary.value }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleNotChangeableSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "SwitchPreference"
|
||||
override val summary = { "Not changeable" }
|
||||
override val changeable = { false }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleSwitchPreferenceWithIcon() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "SwitchPreference"
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
override val icon = @Composable {
|
||||
SettingsIcon(imageVector = Icons.Outlined.AirplanemodeActive)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
SwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.produceState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.TwoTargetSwitchPreference
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val TITLE = "Sample TwoTargetSwitchPreference"
|
||||
|
||||
object TwoTargetSwitchPreferencePageProvider : SettingsPageProvider {
|
||||
override val name = "TwoTargetSwitchPreference"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "TwoTargetSwitchPreference", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleTwoTargetSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "TwoTargetSwitchPreference with summary", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleTwoTargetSwitchPreferenceWithSummary()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "TwoTargetSwitchPreference with async summary", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleTwoTargetSwitchPreferenceWithAsyncSummary()
|
||||
}.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create( "TwoTargetSwitchPreference not changeable", owner)
|
||||
.setUiLayoutFn {
|
||||
SampleNotChangeableTwoTargetSwitchPreference()
|
||||
}.build()
|
||||
)
|
||||
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleTwoTargetSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(false) }
|
||||
TwoTargetSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "TwoTargetSwitchPreference"
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
}) {}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleTwoTargetSwitchPreferenceWithSummary() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
TwoTargetSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "TwoTargetSwitchPreference"
|
||||
override val summary = { "With summary" }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
}) {}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleTwoTargetSwitchPreferenceWithAsyncSummary() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
val summary = produceState(initialValue = " ") {
|
||||
delay(1000L)
|
||||
value = "Async summary"
|
||||
}
|
||||
TwoTargetSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "TwoTargetSwitchPreference"
|
||||
override val summary = { summary.value }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
}) {}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SampleNotChangeableTwoTargetSwitchPreference() {
|
||||
var checked by rememberSaveable { mutableStateOf(true) }
|
||||
TwoTargetSwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "TwoTargetSwitchPreference"
|
||||
override val summary = { "Not changeable" }
|
||||
override val changeable = { false }
|
||||
override val checked = { checked }
|
||||
override val onCheckedChange = { newChecked: Boolean -> checked = newChecked }
|
||||
}
|
||||
}) {}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun TwoTargetSwitchPreferencePagePreview() {
|
||||
SettingsTheme {
|
||||
TwoTargetSwitchPreferencePageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.scaffold
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.SearchScaffold
|
||||
import com.android.settingslib.spa.widget.ui.PlaceholderTitle
|
||||
|
||||
private const val TITLE = "Sample SearchScaffold"
|
||||
|
||||
object SearchScaffoldPageProvider : SettingsPageProvider {
|
||||
override val name = "SearchScaffold"
|
||||
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
Page()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Page() {
|
||||
SearchScaffold(title = TITLE) { _, searchQuery ->
|
||||
PlaceholderTitle("Search query: ${searchQuery()}")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.scaffold
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.SignalCellularAlt
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.widget.illustration.Illustration
|
||||
import com.android.settingslib.spa.widget.illustration.IllustrationModel
|
||||
import com.android.settingslib.spa.widget.illustration.ResourceType
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.BottomAppBarButton
|
||||
import com.android.settingslib.spa.widget.scaffold.SuwScaffold
|
||||
import com.android.settingslib.spa.widget.ui.SettingsBody
|
||||
|
||||
private const val TITLE = "Sample SuwScaffold"
|
||||
|
||||
object SuwScaffoldPageProvider : SettingsPageProvider {
|
||||
override val name = "SuwScaffold"
|
||||
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
fun buildInjectEntry() = SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
Page()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Page() {
|
||||
SuwScaffold(
|
||||
imageVector = Icons.Outlined.SignalCellularAlt,
|
||||
title = "Connect to mobile network",
|
||||
actionButton = BottomAppBarButton("Next") {},
|
||||
dismissButton = BottomAppBarButton("Cancel") {},
|
||||
) {
|
||||
Column(Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
SettingsBody("To add another SIM, download a new eSIM.")
|
||||
}
|
||||
Illustration(object : IllustrationModel {
|
||||
override val resId = R.drawable.accessibility_captioning_banner
|
||||
override val resourceType = ResourceType.IMAGE
|
||||
})
|
||||
Column(Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
SettingsBody("To add another SIM, download a new eSIM.")
|
||||
}
|
||||
Illustration(object : IllustrationModel {
|
||||
override val resId = R.drawable.accessibility_captioning_banner
|
||||
override val resourceType = ResourceType.IMAGE
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SimplePreferenceMacro
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.Category
|
||||
import com.android.settingslib.spa.widget.ui.CategoryTitle
|
||||
|
||||
private const val TITLE = "Sample Category"
|
||||
|
||||
object CategoryPageProvider : SettingsPageProvider {
|
||||
override val name = "Category"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
.setSearchDataFn { EntrySearchData(title = TITLE) }
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Preference 1", owner)
|
||||
.setMacro { SimplePreferenceMacro(title = "Preference 1", summary = "Summary 1") }
|
||||
.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Preference 2", owner)
|
||||
.setMacro { SimplePreferenceMacro(title = "Preference 2", summary = "Summary 2") }
|
||||
.build()
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Preference 3", owner)
|
||||
.setMacro { SimplePreferenceMacro(title = "Preference 2", summary = "Summary 3") }
|
||||
.build()
|
||||
|
||||
)
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("Preference 4", owner)
|
||||
.setMacro { SimplePreferenceMacro(title = "Preference 4", summary = "Summary 4") }
|
||||
.build()
|
||||
)
|
||||
return entryList
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
val entries = buildEntry(arguments)
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
CategoryTitle("Category A")
|
||||
entries[0].UiLayout()
|
||||
entries[1].UiLayout()
|
||||
|
||||
Category("Category B") {
|
||||
entries[2].UiLayout()
|
||||
entries[3].UiLayout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SpinnerPagePreview() {
|
||||
SettingsTheme {
|
||||
SpinnerPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.CopyableBody
|
||||
|
||||
private const val TITLE = "Sample Copyable"
|
||||
|
||||
object CopyablePageProvider : SettingsPageProvider {
|
||||
override val name = "Copyable"
|
||||
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
.setSearchDataFn { EntrySearchData(title = TITLE) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = TITLE) {
|
||||
Box(modifier = Modifier.padding(SettingsDimension.itemPadding)) {
|
||||
CopyableBody(body = "Copyable body")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 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
|
||||
*
|
||||
* 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.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.Spinner
|
||||
import com.android.settingslib.spa.widget.ui.SpinnerOption
|
||||
|
||||
private const val TITLE = "Sample Spinner"
|
||||
|
||||
object SpinnerPageProvider : SettingsPageProvider {
|
||||
override val name = "Spinner"
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = createSettingsPage())
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
var selectedId by rememberSaveable { mutableIntStateOf(1) }
|
||||
Spinner(
|
||||
options = (1..3).map { SpinnerOption(id = it, text = "Option $it") },
|
||||
selectedId = selectedId,
|
||||
setId = { selectedId = it },
|
||||
)
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = "Selected id"
|
||||
override val summary = { selectedId.toString() }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun SpinnerPagePreview() {
|
||||
SettingsTheme {
|
||||
SpinnerPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
39
SettingsLib/Spa/gradle.properties
Normal file
@@ -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.
|
||||
#
|
||||
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
32
SettingsLib/Spa/gradle/libs.versions.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright (C) 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
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
[versions]
|
||||
agp = "8.2.2"
|
||||
compose-compiler = "1.5.10"
|
||||
dexmaker-mockito = "2.28.3"
|
||||
jvm = "17"
|
||||
kotlin = "1.9.22"
|
||||
truth = "1.1.5"
|
||||
|
||||
[libraries]
|
||||
dexmaker-mockito = { module = "com.linkedin.dexmaker:dexmaker-mockito", version.ref = "dexmaker-mockito" }
|
||||
truth = { module = "com.google.truth:truth", version.ref = "truth" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
android-library = { id = "com.android.library", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
BIN
SettingsLib/Spa/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
23
SettingsLib/Spa/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
249
SettingsLib/Spa/gradlew
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
51
SettingsLib/Spa/screenshot/Android.bp
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// 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 {
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "SpaScreenshotTestRNGFiles",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.kt",
|
||||
],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "SpaScreenshotTests",
|
||||
use_resource_processor: true,
|
||||
test_suites: ["device-tests"],
|
||||
|
||||
asset_dirs: ["assets"],
|
||||
|
||||
srcs: ["src/**/*.kt"],
|
||||
|
||||
certificate: "platform",
|
||||
|
||||
static_libs: [
|
||||
"SpaLib",
|
||||
"SpaLibTestUtils",
|
||||
"androidx.compose.runtime_runtime",
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.runner",
|
||||
"mockito-target-minus-junit4",
|
||||
"platform-parametric-runner-lib",
|
||||
"platform-screenshot-diff-core",
|
||||
],
|
||||
kotlincflags: ["-Xjvm-default=all"],
|
||||
}
|
||||
32
SettingsLib/Spa/screenshot/AndroidManifest.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settingslib.spa.screenshot">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21"/>
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
<activity android:name=".DebugActivity" android:exported="true" />
|
||||
</application>
|
||||
|
||||
<instrumentation
|
||||
android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:label="Screenshot tests for SpaLib"
|
||||
android:targetPackage="com.android.settingslib.spa.screenshot">
|
||||
</instrumentation>
|
||||
</manifest>
|
||||
36
SettingsLib/Spa/screenshot/AndroidTest.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<configuration description="Runs screendiff tests.">
|
||||
<option name="test-suite-tag" value="apct-instrumentation" />
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
|
||||
<option name="optimized-property-setting" value="true" />
|
||||
</target_preparer>
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="test-file-name" value="SpaScreenshotTests.apk" />
|
||||
</target_preparer>
|
||||
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
|
||||
<option name="directory-keys"
|
||||
value="/data/user/0/com.android.settingslib.spa.screenshot/files/settings_screenshots" />
|
||||
<option name="collect-on-run-ended-only" value="true" />
|
||||
</metrics_collector>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="com.android.settingslib.spa.screenshot" />
|
||||
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
|
||||
</test>
|
||||
</configuration>
|
||||
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 29 KiB |