Merge "Fix JavacFiler.writeSource() when the passed package name is empty" into androidx-main
diff --git a/.github/actions/build-single-project/action.yml b/.github/actions/build-single-project/action.yml
index ab4317f1..19a8cb4 100644
--- a/.github/actions/build-single-project/action.yml
+++ b/.github/actions/build-single-project/action.yml
@@ -38,6 +38,9 @@
- name: "Install Cmake"
shell: bash
run: echo "yes" | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install "cmake;3.22.1"
+ - name: "Install Android SDK Build-Tools"
+ shell: bash
+ run: echo "yes" | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install "build-tools;34.0.0-rc3"
- name: "Set environment variables"
shell: bash
run: |
diff --git a/.github/ci-control/ci-config.json b/.github/ci-control/ci-config.json
index 2d07c46..dfb2af6 100644
--- a/.github/ci-control/ci-config.json
+++ b/.github/ci-control/ci-config.json
@@ -7,11 +7,13 @@
],
"compose" : {
"include" : [
+ "compose-runtime"
],
"default": false
},
"main" : {
"exclude" : [
+ "compose-runtime",
"room"
],
"default": true
diff --git a/OWNERS b/OWNERS
index e6c536a..9104654 100644
--- a/OWNERS
+++ b/OWNERS
@@ -27,6 +27,7 @@
per-file *settings.gradle = alanv@google.com, aurimas@google.com
per-file *libraryversions.toml = jnichol@google.com
per-file *libraryversions.toml = diegovela@google.com, akulian@google.com, kchyn@google.com
+per-file *docs-public/build.gradle = juanrdz@google.com
# Copybara can self-approve CLs within synced docs.
per-file docs/** = copybara-worker-blackhole@google.com
\ No newline at end of file
diff --git a/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityResultLaunchDetector.kt b/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityResultLaunchDetector.kt
index ce8a629..07c1e46 100644
--- a/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityResultLaunchDetector.kt
+++ b/activity/activity-compose-lint/src/main/java/androidx/activity/compose/lint/ActivityResultLaunchDetector.kt
@@ -31,8 +31,8 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
/**
* [Detector] that checks `launch` calls to make sure they don't happen inside the body of a
diff --git a/activity/activity-compose/integration-tests/activity-demos/src/main/AndroidManifest.xml b/activity/activity-compose/integration-tests/activity-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/activity/activity-compose/integration-tests/activity-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/activity/activity-compose/samples/build.gradle b/activity/activity-compose/samples/build.gradle
index e76d4bc..3190107 100644
--- a/activity/activity-compose/samples/build.gradle
+++ b/activity/activity-compose/samples/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "AndroidX Compose UI Activity Integration Samples"
+ name = "Compose UI Activity Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2020"
description = "Samples for Compose integration with Activity"
diff --git a/activity/activity-compose/samples/src/main/AndroidManifest.xml b/activity/activity-compose/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/activity/activity-compose/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/activity/activity-compose/samples/src/main/java/androidx/activity/compose/samples/ReportLoadedSamples.kt b/activity/activity-compose/samples/src/main/java/androidx/activity/compose/samples/ReportLoadedSamples.kt
index 22244e9..8a4a86b 100644
--- a/activity/activity-compose/samples/src/main/java/androidx/activity/compose/samples/ReportLoadedSamples.kt
+++ b/activity/activity-compose/samples/src/main/java/androidx/activity/compose/samples/ReportLoadedSamples.kt
@@ -15,8 +15,8 @@
*/
package androidx.activity.compose.samples
-import androidx.activity.compose.ReportDrawnAfter
import androidx.activity.compose.ReportDrawn
+import androidx.activity.compose.ReportDrawnAfter
import androidx.activity.compose.ReportDrawnWhen
import androidx.annotation.Sampled
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/activity/activity-compose/src/main/AndroidManifest.xml b/activity/activity-compose/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/activity/activity-compose/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt b/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
index 0ed7d53..384b780 100644
--- a/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
+++ b/activity/activity-compose/src/main/java/androidx/activity/compose/BackHandler.kt
@@ -16,10 +16,10 @@
package androidx.activity.compose
-import androidx.activity.findViewTreeOnBackPressedDispatcherOwner
import androidx.activity.OnBackPressedCallback
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
+import androidx.activity.findViewTreeOnBackPressedDispatcherOwner
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.ProvidedValue
diff --git a/activity/activity-ktx/src/androidTest/java/androidx/activity/ActivityViewModelLazyTest.kt b/activity/activity-ktx/src/androidTest/java/androidx/activity/ActivityViewModelLazyTest.kt
index c3f7793..6601b128 100644
--- a/activity/activity-ktx/src/androidTest/java/androidx/activity/ActivityViewModelLazyTest.kt
+++ b/activity/activity-ktx/src/androidTest/java/androidx/activity/ActivityViewModelLazyTest.kt
@@ -28,9 +28,9 @@
import androidx.test.annotation.UiThreadTest
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.lang.IllegalArgumentException
import org.junit.Rule
import org.junit.Test
-import java.lang.IllegalArgumentException
@MediumTest
class ActivityViewModelLazyTest {
diff --git a/activity/activity-ktx/src/main/AndroidManifest.xml b/activity/activity-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/activity/activity-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/activity/activity-lint/build.gradle b/activity/activity-lint/build.gradle
index 704ee58..554da78 100644
--- a/activity/activity-lint/build.gradle
+++ b/activity/activity-lint/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Android Activity Lint Checks"
+ name = "Activity Lint Checks"
type = LibraryType.LINT
inceptionYear = "2020"
description = "Android Activity Lint Checks"
diff --git a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityResultFragmentVersionDetector.kt b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityResultFragmentVersionDetector.kt
index edb3b36..8ab79a4 100644
--- a/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityResultFragmentVersionDetector.kt
+++ b/activity/activity-lint/src/main/java/androidx/activity/lint/ActivityResultFragmentVersionDetector.kt
@@ -30,12 +30,12 @@
import com.android.tools.lint.detector.api.Project
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
-import org.jetbrains.uast.UCallExpression
-import org.jetbrains.uast.UElement
import java.util.EnumSet
import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
class ActivityResultFragmentVersionDetector : Detector(), UastScanner, GradleScanner {
companion object {
diff --git a/activity/activity/api/current.ignore b/activity/activity/api/current.ignore
index 3da4564..b9cc6d6 100644
--- a/activity/activity/api/current.ignore
+++ b/activity/activity/api/current.ignore
@@ -7,7 +7,3 @@
Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
-
-
-RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
- Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/api/restricted_current.ignore b/activity/activity/api/restricted_current.ignore
index 3da4564..b9cc6d6 100644
--- a/activity/activity/api/restricted_current.ignore
+++ b/activity/activity/api/restricted_current.ignore
@@ -7,7 +7,3 @@
Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter input in androidx.activity.result.contract.ActivityResultContract.getSynchronousResult(android.content.Context context, I input)
InvalidNullConversion: androidx.activity.result.contract.ActivityResultContract.SynchronousResult#SynchronousResult(T) parameter #0:
Attempted to change parameter from @Nullable to @NonNull: incompatible change for parameter value in androidx.activity.result.contract.ActivityResultContract.SynchronousResult(T value)
-
-
-RemovedMethod: androidx.activity.ComponentActivity#onBackPressed():
- Removed method androidx.activity.ComponentActivity.onBackPressed()
diff --git a/activity/activity/lint-baseline.xml b/activity/activity/lint-baseline.xml
new file mode 100644
index 0000000..d97aee4
--- /dev/null
+++ b/activity/activity/lint-baseline.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
+
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastT()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/activity/ComponentActivity.java"/>
+ </issue>
+
+</issues>
diff --git a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
index e2025c9..48c87c7 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/ComponentActivityResultTest.kt
@@ -31,10 +31,10 @@
import androidx.test.filters.LargeTest
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
-import leakcanary.DetectLeaksAfterTestSuccess
-import org.junit.Rule
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt b/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt
index 45cbfe9..66f30ef 100644
--- a/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt
+++ b/activity/activity/src/main/java/androidx/activity/result/PickVisualMediaRequest.kt
@@ -16,8 +16,8 @@
package androidx.activity.result
-import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType
import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.ImageAndVideo
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia.VisualMediaType
/**
* Creates a request for a
diff --git a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
index d795756..5fe827e 100644
--- a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
+++ b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
@@ -42,8 +42,8 @@
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
import androidx.activity.result.contract.ActivityResultContracts.GetContent
import androidx.activity.result.contract.ActivityResultContracts.OpenMultipleDocuments
-import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.activity.result.contract.ActivityResultContracts.PickMultipleVisualMedia
+import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.activity.result.contract.ActivityResultContracts.TakePicture
import androidx.activity.result.contract.ActivityResultContracts.TakePicturePreview
diff --git a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/experimental/UseJavaPackageFromKt.kt b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/experimental/UseJavaPackageFromKt.kt
index 417b29f..312c3a5 100644
--- a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/experimental/UseJavaPackageFromKt.kt
+++ b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/experimental/UseJavaPackageFromKt.kt
@@ -19,7 +19,6 @@
package sample.experimental
import androidx.annotation.experimental.UseExperimental
-
import sample.experimental.foo.Bar
import sample.experimental.foo.ExperimentalPackage
diff --git a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/UseJavaPackageFromKt.kt b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/UseJavaPackageFromKt.kt
index f995a66..caf4c94 100644
--- a/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/UseJavaPackageFromKt.kt
+++ b/annotation/annotation-experimental-lint/integration-tests/src/main/java/sample/optin/UseJavaPackageFromKt.kt
@@ -17,7 +17,6 @@
package sample.optin
import androidx.annotation.OptIn
-
import sample.optin.foo.AnnotatedJavaPackage
@Suppress("unused", "MemberVisibilityCanBePrivate")
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
index 62fa26e..25567ce 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/ExperimentalDetectorTest.kt
@@ -424,13 +424,13 @@
/* ktlint-disable max-line-length */
val expected = """
-src/sample/experimental/UseJavaPackageFromKt.kt:32: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
+src/sample/experimental/UseJavaPackageFromKt.kt:31: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
val bar = Bar()
~~~
-src/sample/experimental/UseJavaPackageFromKt.kt:33: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
+src/sample/experimental/UseJavaPackageFromKt.kt:32: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
bar.baz()
~~~
-src/sample/experimental/UseJavaPackageFromKt.kt:56: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
+src/sample/experimental/UseJavaPackageFromKt.kt:55: Error: This declaration is opt-in and its usage should be marked with @sample.experimental.foo.ExperimentalPackage or @OptIn(markerClass = sample.experimental.foo.ExperimentalPackage.class) [UnsafeOptInUsageError]
callPackageExperimental()
~~~~~~~~~~~~~~~~~~~~~~~
3 errors, 0 warnings
diff --git a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
index 89a38ed..99ca8e3 100644
--- a/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
+++ b/annotation/annotation-experimental-lint/src/test/kotlin/androidx/annotation/experimental/lint/RequiresOptInDetectorTest.kt
@@ -318,13 +318,13 @@
/* ktlint-disable max-line-length */
val expected = """
-src/sample/optin/UseJavaPackageFromKt.kt:30: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
+src/sample/optin/UseJavaPackageFromKt.kt:29: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
val experimentalObject = AnnotatedJavaPackage()
~~~~~~~~~~~~~~~~~~~~
-src/sample/optin/UseJavaPackageFromKt.kt:31: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
+src/sample/optin/UseJavaPackageFromKt.kt:30: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
experimentalObject.method()
~~~~~~
-src/sample/optin/UseJavaPackageFromKt.kt:64: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
+src/sample/optin/UseJavaPackageFromKt.kt:63: Error: This declaration is opt-in and its usage should be marked with @sample.optin.ExperimentalJavaAnnotation or @OptIn(markerClass = sample.optin.ExperimentalJavaAnnotation.class) [UnsafeOptInUsageError]
callPackageExperimental()
~~~~~~~~~~~~~~~~~~~~~~~
3 errors, 0 warnings
diff --git a/annotation/annotation-experimental/src/main/AndroidManifest.xml b/annotation/annotation-experimental/src/main/AndroidManifest.xml
deleted file mode 100644
index b303288..0000000
--- a/annotation/annotation-experimental/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/annotation/annotation/build.gradle b/annotation/annotation/build.gradle
index e821397..769ac65 100644
--- a/annotation/annotation/build.gradle
+++ b/annotation/annotation/build.gradle
@@ -66,10 +66,10 @@
}
androidx {
- name = "Android Support Library Annotations"
+ name = "Annotation"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.ANNOTATION
mavenMultiplatformVersion = LibraryVersions.ANNOTATION_KMP
inceptionYear = "2013"
- description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs."
+ description = "Provides source annotations for tooling and readability."
}
diff --git a/appactions/builtintypes/builtintypes-core/build.gradle b/appactions/builtintypes/builtintypes-core/build.gradle
index 9d98eb3..828e4de 100644
--- a/appactions/builtintypes/builtintypes-core/build.gradle
+++ b/appactions/builtintypes/builtintypes-core/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "androidx.appactions.builtintypes:builtintypes-core"
+ name = "AppActions Builtin Types Core"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2023"
description = "This library exposes a core set of data types based on schema.org definitions."
diff --git a/appactions/interaction/integration-tests/testapp/src/main/java/androidx/appactions/interaction/testapp/MainActivity.kt b/appactions/interaction/integration-tests/testapp/src/main/java/androidx/appactions/interaction/testapp/MainActivity.kt
index 9f21059..c9fbc82 100644
--- a/appactions/interaction/integration-tests/testapp/src/main/java/androidx/appactions/interaction/testapp/MainActivity.kt
+++ b/appactions/interaction/integration-tests/testapp/src/main/java/androidx/appactions/interaction/testapp/MainActivity.kt
@@ -6,11 +6,9 @@
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
-import java.util.Locale
-import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() {
- private var duration = 59
+ private var duration = 120
private var hasRunningTimer = false
override fun onCreate(savedInstanceState: Bundle?) {
@@ -28,27 +26,16 @@
object : CountDownTimer((duration * 1000).toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {
runOnUiThread {
- val time = String.format(
- Locale.getDefault(),
- "%02d:%02d:%02d",
- TimeUnit.MILLISECONDS.toHours(millisUntilFinished),
- TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) - TimeUnit.HOURS.toMinutes(
- TimeUnit.MILLISECONDS.toHours(millisUntilFinished)
- ),
- TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
- TimeUnit.MILLISECONDS.toHours(millisUntilFinished)
- )
- )
- val hourMinSecArray = time.split(":")
- hours.text = hourMinSecArray[0]
- mins.text = hourMinSecArray[1]
- seconds.text = hourMinSecArray[2]
+ val timeArray = millisecondsToTimeString(millisUntilFinished).split(":")
+ hours.text = timeArray[0]
+ mins.text = timeArray[1]
+ seconds.text = timeArray[2]
}
}
override fun onFinish() {
// Reset timer duration
- duration = 59
+ duration = 120
hasRunningTimer = false
}
}.start()
@@ -57,4 +44,11 @@
}
}
}
+
+ private fun millisecondsToTimeString(milliseconds: Long): String {
+ val hours = milliseconds / 3600000
+ val minutes = (milliseconds % 3600000) / 60000
+ val seconds = (milliseconds % 60000) / 1000
+ return String.format("%02d:%02d:%02d", hours, minutes, seconds)
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
index a58ae85..8fdbdc0 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateCall.kt
@@ -34,56 +34,15 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
private const val CAPABILITY_NAME: String = "actions.intent.CREATE_CALL"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(CreateCall.Arguments::class.java, CreateCall.Arguments::Builder)
- .setOutput(CreateCall.Output::class.java)
- .bindOptionalParameter(
- "call.callFormat",
- { properties ->
- Optional.ofNullable(
- properties[CreateCall.PropertyMapStrings.CALL_FORMAT.key]
- as Property<Call.CanonicalValue.CallFormat>
- )
- },
- CreateCall.Arguments.Builder::setCallFormat,
- TypeConverters.CALL_FORMAT_PARAM_VALUE_CONVERTER,
- TypeConverters.CALL_FORMAT_ENTITY_CONVERTER
- )
- .bindRepeatedParameter(
- "call.participant",
- { properties ->
- Optional.ofNullable(
- properties[CreateCall.PropertyMapStrings.PARTICIPANT.key]
- as Property<Participant>
- )
- },
- CreateCall.Arguments.Builder::setParticipantList,
- ParticipantValue.PARAM_VALUE_CONVERTER,
- EntityConverter.of(PARTICIPANT_TYPE_SPEC)
- )
- .bindOptionalOutput(
- "call",
- { output -> Optional.ofNullable(output.call) },
- ParamValueConverter.of(CALL_TYPE_SPEC)::toParamValue
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- CreateCall.ExecutionStatus::toParamValue
- )
- .build()
-
+/** A capability corresponding to actions.intent.CREATE_CALL */
@CapabilityFactory(name = CAPABILITY_NAME)
class CreateCall private constructor() {
internal enum class PropertyMapStrings(val key: String) {
CALL_FORMAT("call.callFormat"),
- PARTICIPANT("call.participant"),
+ PARTICIPANT("call.participant")
}
class CapabilityBuilder :
@@ -107,7 +66,7 @@
class Arguments
internal constructor(
val callFormat: Call.CanonicalValue.CallFormat?,
- val participantList: List<ParticipantValue>,
+ val participantList: List<ParticipantValue>
) {
override fun toString(): String {
return "Arguments(callFormat=$callFormat, participantList=$participantList)"
@@ -216,4 +175,42 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "call.callFormat",
+ { properties ->
+ properties[PropertyMapStrings.CALL_FORMAT.key]
+ as? Property<Call.CanonicalValue.CallFormat>
+ },
+ Arguments.Builder::setCallFormat,
+ TypeConverters.CALL_FORMAT_PARAM_VALUE_CONVERTER,
+ TypeConverters.CALL_FORMAT_ENTITY_CONVERTER
+ )
+ .bindRepeatedParameter(
+ "call.participant",
+ { properties ->
+ properties[PropertyMapStrings.PARTICIPANT.key] as? Property<Participant>
+ },
+ Arguments.Builder::setParticipantList,
+ ParticipantValue.PARAM_VALUE_CONVERTER,
+ EntityConverter.of(PARTICIPANT_TYPE_SPEC)
+ )
+ .bindOutput(
+ "call",
+ Output::call,
+ ParamValueConverter.of(CALL_TYPE_SPEC)::toParamValue
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
index 806e5ac..b559a71 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/CreateMessage.kt
@@ -35,56 +35,15 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
private const val CAPABILITY_NAME: String = "actions.intent.CREATE_MESSAGE"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(CreateMessage.Arguments::class.java, CreateMessage.Arguments::Builder)
- .setOutput(CreateMessage.Output::class.java)
- .bindRepeatedParameter(
- "message.recipient",
- { properties ->
- Optional.ofNullable(
- properties[CreateMessage.PropertyMapStrings.RECIPIENT.key]
- as Property<Recipient>
- )
- },
- CreateMessage.Arguments.Builder::setRecipientList,
- RecipientValue.PARAM_VALUE_CONVERTER,
- EntityConverter.of(RECIPIENT_TYPE_SPEC)
- )
- .bindOptionalParameter(
- "message.text",
- { properties ->
- Optional.ofNullable(
- properties[CreateMessage.PropertyMapStrings.MESSAGE_TEXT.key]
- as Property<StringValue>
- )
- },
- CreateMessage.Arguments.Builder::setMessageText,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "message",
- { output -> Optional.ofNullable(output.message) },
- ParamValueConverter.of(MESSAGE_TYPE_SPEC)::toParamValue
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- CreateMessage.ExecutionStatus::toParamValue
- )
- .build()
-
+/** A capability corresponding to actions.intent.CREATE_MESSAGE */
@CapabilityFactory(name = CAPABILITY_NAME)
class CreateMessage private constructor() {
internal enum class PropertyMapStrings(val key: String) {
MESSAGE_TEXT("message.text"),
- RECIPIENT("message.recipient"),
+ RECIPIENT("message.recipient")
}
class CapabilityBuilder :
@@ -218,4 +177,41 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindRepeatedParameter(
+ "message.recipient",
+ { properties ->
+ properties[PropertyMapStrings.RECIPIENT.key] as? Property<Recipient>
+ },
+ Arguments.Builder::setRecipientList,
+ RecipientValue.PARAM_VALUE_CONVERTER,
+ EntityConverter.of(RECIPIENT_TYPE_SPEC)
+ )
+ .bindParameter(
+ "message.text",
+ { properties ->
+ properties[PropertyMapStrings.MESSAGE_TEXT.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setMessageText,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "message",
+ Output::message,
+ ParamValueConverter.of(MESSAGE_TYPE_SPEC)::toParamValue
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
index 048d9e5..077274a 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/ParticipantValue.kt
@@ -16,10 +16,10 @@
package androidx.appactions.interaction.capabilities.communication
import androidx.appactions.builtintypes.experimental.properties.Participant
+import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
-import androidx.appactions.interaction.capabilities.core.SearchAction
class ParticipantValue private constructor(
val asParticipant: Participant?,
diff --git a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
index bf3620d..f66ad67 100644
--- a/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
+++ b/appactions/interaction/interaction-capabilities-communication/src/main/java/androidx/appactions/interaction/capabilities/communication/RecipientValue.kt
@@ -17,10 +17,10 @@
package androidx.appactions.interaction.capabilities.communication
import androidx.appactions.builtintypes.experimental.properties.Recipient
+import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
-import androidx.appactions.interaction.capabilities.core.SearchAction
class RecipientValue private constructor(
val asRecipient: Recipient?,
diff --git a/appactions/interaction/interaction-capabilities-core/api/api_lint.ignore b/appactions/interaction/interaction-capabilities-core/api/api_lint.ignore
deleted file mode 100644
index af5cd99..0000000
--- a/appactions/interaction/interaction-capabilities-core/api/api_lint.ignore
+++ /dev/null
@@ -1,15 +0,0 @@
-// Baseline format: 1.0
-BuilderSetStyle: androidx.appactions.interaction.capabilities.core.Capability.Builder#asBuilder():
- Builder methods names should use setFoo() / addFoo() / clearFoo() style: method androidx.appactions.interaction.capabilities.core.Capability.Builder.asBuilder()
-
-
-MissingGetterMatchingBuilder: androidx.appactions.interaction.capabilities.core.Capability.Builder#setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallback<ArgumentsT,OutputT>):
- androidx.appactions.interaction.capabilities.core.Capability does not declare a `getExecutionCallback()` method matching method androidx.appactions.interaction.capabilities.core.Capability.Builder.setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallback<ArgumentsT,OutputT>)
-MissingGetterMatchingBuilder: androidx.appactions.interaction.capabilities.core.Capability.Builder#setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallbackAsync<ArgumentsT,OutputT>):
- androidx.appactions.interaction.capabilities.core.Capability does not declare a `getExecutionCallback()` method matching method androidx.appactions.interaction.capabilities.core.Capability.Builder.setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallbackAsync<ArgumentsT,OutputT>)
-MissingGetterMatchingBuilder: androidx.appactions.interaction.capabilities.core.Capability.Builder#setExecutionSessionFactory(kotlin.jvm.functions.Function1<? super androidx.appactions.interaction.capabilities.core.HostProperties,? extends ExecutionSessionT>):
- androidx.appactions.interaction.capabilities.core.Capability does not declare a `getExecutionSessionFactory()` method matching method androidx.appactions.interaction.capabilities.core.Capability.Builder.setExecutionSessionFactory(kotlin.jvm.functions.Function1<? super androidx.appactions.interaction.capabilities.core.HostProperties,? extends ExecutionSessionT>)
-
-
-StaticFinalBuilder: androidx.appactions.interaction.capabilities.core.Capability.Builder:
- Builder must be final: androidx.appactions.interaction.capabilities.core.Capability.Builder
diff --git a/appactions/interaction/interaction-capabilities-core/api/current.txt b/appactions/interaction/interaction-capabilities-core/api/current.txt
index b2e08cf..4045e23 100644
--- a/appactions/interaction/interaction-capabilities-core/api/current.txt
+++ b/appactions/interaction/interaction-capabilities-core/api/current.txt
@@ -14,7 +14,6 @@
}
public abstract static class Capability.Builder<BuilderT extends androidx.appactions.interaction.capabilities.core.Capability.Builder<BuilderT, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT>, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT extends androidx.appactions.interaction.capabilities.core.BaseExecutionSession<ArgumentsT, OutputT>> {
- method public final BuilderT asBuilder();
method public androidx.appactions.interaction.capabilities.core.Capability build();
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallback<ArgumentsT,OutputT> executionCallback);
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallbackAsync<ArgumentsT,OutputT> executionCallbackAsync);
diff --git a/appactions/interaction/interaction-capabilities-core/api/public_plus_experimental_current.txt b/appactions/interaction/interaction-capabilities-core/api/public_plus_experimental_current.txt
index b2e08cf..4045e23 100644
--- a/appactions/interaction/interaction-capabilities-core/api/public_plus_experimental_current.txt
+++ b/appactions/interaction/interaction-capabilities-core/api/public_plus_experimental_current.txt
@@ -14,7 +14,6 @@
}
public abstract static class Capability.Builder<BuilderT extends androidx.appactions.interaction.capabilities.core.Capability.Builder<BuilderT, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT>, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT extends androidx.appactions.interaction.capabilities.core.BaseExecutionSession<ArgumentsT, OutputT>> {
- method public final BuilderT asBuilder();
method public androidx.appactions.interaction.capabilities.core.Capability build();
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallback<ArgumentsT,OutputT> executionCallback);
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallbackAsync<ArgumentsT,OutputT> executionCallbackAsync);
diff --git a/appactions/interaction/interaction-capabilities-core/api/restricted_current.txt b/appactions/interaction/interaction-capabilities-core/api/restricted_current.txt
index b2e08cf..4045e23 100644
--- a/appactions/interaction/interaction-capabilities-core/api/restricted_current.txt
+++ b/appactions/interaction/interaction-capabilities-core/api/restricted_current.txt
@@ -14,7 +14,6 @@
}
public abstract static class Capability.Builder<BuilderT extends androidx.appactions.interaction.capabilities.core.Capability.Builder<BuilderT, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT>, ArgumentsT, OutputT, ConfirmationT, ExecutionSessionT extends androidx.appactions.interaction.capabilities.core.BaseExecutionSession<ArgumentsT, OutputT>> {
- method public final BuilderT asBuilder();
method public androidx.appactions.interaction.capabilities.core.Capability build();
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallback<ArgumentsT,OutputT> executionCallback);
method public final BuilderT setExecutionCallback(androidx.appactions.interaction.capabilities.core.ExecutionCallbackAsync<ArgumentsT,OutputT> executionCallbackAsync);
diff --git a/appactions/interaction/interaction-capabilities-core/build.gradle b/appactions/interaction/interaction-capabilities-core/build.gradle
index 6683d10..5bca53c 100644
--- a/appactions/interaction/interaction-capabilities-core/build.gradle
+++ b/appactions/interaction/interaction-capabilities-core/build.gradle
@@ -25,8 +25,6 @@
dependencies {
api(project(path: ":appactions:interaction:interaction-proto", configuration: "shadowJar"))
- annotationProcessor(libs.autoValue)
-
api(libs.autoValueAnnotations)
implementation(libs.guavaListenableFuture)
implementation(libs.kotlinCoroutinesCore)
@@ -34,7 +32,6 @@
implementation("androidx.concurrent:concurrent-futures:1.1.0")
implementation("androidx.concurrent:concurrent-futures-ktx:1.1.0")
- testAnnotationProcessor(libs.autoValue)
testImplementation(project(":appactions:interaction:interaction-capabilities-testing"))
testImplementation(libs.junit)
testImplementation(libs.truth)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
index fa8d0d8..95d92df 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/CalendarEvent.kt
@@ -17,10 +17,10 @@
package androidx.appactions.builtintypes.experimental.types
// TODO(b/271634410): Update Attendee references
+import androidx.appactions.builtintypes.experimental.properties.Attendee
import androidx.appactions.builtintypes.experimental.properties.EndDate
import androidx.appactions.builtintypes.experimental.properties.Name
import androidx.appactions.builtintypes.experimental.properties.StartDate
-import androidx.appactions.builtintypes.experimental.properties.Attendee
import java.time.LocalDate
import java.time.ZonedDateTime
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
index e2308b6..df7d88a 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/builtintypes/experimental/types/ItemList.kt
@@ -16,8 +16,8 @@
package androidx.appactions.builtintypes.experimental.types
-import androidx.appactions.builtintypes.experimental.properties.Name
import androidx.appactions.builtintypes.experimental.properties.ItemListElement
+import androidx.appactions.builtintypes.experimental.properties.Name
interface ItemList : Thing {
val itemListElements: List<ItemListElement>
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/Capability.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/Capability.kt
index 6fc55f2..a720034 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/Capability.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/Capability.kt
@@ -16,6 +16,7 @@
package androidx.appactions.interaction.capabilities.core
+import android.annotation.SuppressLint
import androidx.annotation.RestrictTo
import androidx.appactions.interaction.capabilities.core.impl.CapabilitySession
import androidx.appactions.interaction.capabilities.core.impl.SingleTurnCapabilityImpl
@@ -58,6 +59,7 @@
/**
* An abstract Builder class for Capability.
*/
+ @SuppressLint("StaticFinalBuilder")
abstract class Builder<
BuilderT :
Builder<
@@ -76,7 +78,7 @@
private var property: Map<String, Property<*>>? = null
private var executionCallback: ExecutionCallback<ArgumentsT, OutputT>? = null
private var sessionFactory:
- (hostProperties: HostProperties?) -> ExecutionSessionT? = { _ -> null }
+ (hostProperties: HostProperties?) -> ExecutionSessionT? = { _ -> null }
private var actionSpec: ActionSpec<ArgumentsT, OutputT>? = null
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@@ -91,10 +93,14 @@
* @suppress
*/
@get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- protected open val sessionBridge: SessionBridge<ExecutionSessionT, ConfirmationT>? = null
+ protected open val sessionBridge: SessionBridge<
+ ExecutionSessionT,
+ ArgumentsT,
+ ConfirmationT
+ >? = null
@Suppress("UNCHECKED_CAST")
- fun asBuilder(): BuilderT {
+ private fun asBuilder(): BuilderT {
return this as BuilderT
}
@@ -123,6 +129,7 @@
* This method accepts a coroutine-based ExecutionCallback instance. There is also an
* overload which accepts the ExecutionCallbackAsync instead.
*/
+ @SuppressLint("MissingGetterMatchingBuilder")
fun setExecutionCallback(executionCallback: ExecutionCallback<ArgumentsT, OutputT>) =
asBuilder().apply {
this.executionCallback = executionCallback
@@ -137,6 +144,7 @@
* This method accepts the ExecutionCallbackAsync interface which returns a
* [ListenableFuture].
*/
+ @SuppressLint("MissingGetterMatchingBuilder")
fun setExecutionCallback(
executionCallbackAsync: ExecutionCallbackAsync<ArgumentsT, OutputT>
) = asBuilder().apply {
@@ -144,12 +152,13 @@
}
/**
- * Sets the lambda used to create [ExecutionSession] instances for this
+ * Sets the lambda used to create [ExecutionSessionT] instances for this
* capability.
*
* [setExecutionSessionFactory] and [setExecutionCallback] are mutually exclusive, so
* calling one will nullify the other.
*/
+ @SuppressLint("MissingGetterMatchingBuilder")
open fun setExecutionSessionFactory(
sessionFactory: (hostProperties: HostProperties?) -> ExecutionSessionT
): BuilderT = asBuilder().apply {
@@ -168,15 +177,11 @@
executionCallback!!
)
} else {
- val checkedSessionFactory = requireNotNull(sessionFactory) {
- "either setExecutionCallback or setExecutionSessionFactory" +
- " must be called before build"
- }
return TaskCapabilityImpl(
checkedId,
actionSpec!!,
checkedProperty,
- checkedSessionFactory,
+ sessionFactory,
sessionBridge!!,
::EmptyTaskUpdater
)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/LibInfo.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/LibInfo.kt
index c1c053c..8157944 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/LibInfo.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/LibInfo.kt
@@ -18,9 +18,8 @@
import android.content.Context
import androidx.annotation.RestrictTo
-
-import java.util.regex.Pattern
import java.util.Objects.requireNonNull
+import java.util.regex.Pattern
/** @suppress */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
index 121b582..2e62623 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/entity/EntityProvider.kt
@@ -17,14 +17,14 @@
package androidx.appactions.interaction.capabilities.core.entity
import androidx.annotation.RestrictTo
-import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
+import androidx.appactions.builtintypes.experimental.types.Thing
+import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures
+import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.SearchActionConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeSpec
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
-import androidx.appactions.interaction.capabilities.core.SearchAction
-import androidx.appactions.builtintypes.experimental.types.Thing
import androidx.appactions.interaction.proto.GroundingRequest
import androidx.appactions.interaction.proto.GroundingResponse
import androidx.concurrent.futures.await
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
index 3eece1d..8aaadae 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ArgumentsWrapper.kt
@@ -54,7 +54,7 @@
) {
null
} else {
- RequestMetadata.newBuilder().setRequestType(fulfillment.type).build()
+ RequestMetadata(fulfillment.type)
}
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ErrorStatusInternal.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ErrorStatusInternal.java
index d983859..0600dbb 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ErrorStatusInternal.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/ErrorStatusInternal.java
@@ -27,10 +27,6 @@
UNCHANGED_DISAMBIG_STATE(3),
INVALID_RESOLVER(4),
STRUCT_CONVERSION_FAILURE(5),
- // TODO(b/276354491): remove SYNC / CONFIRM / TOUCH_EVENT failure codes
- SYNC_REQUEST_FAILURE(6),
- CONFIRMATION_REQUEST_FAILURE(7),
- TOUCH_EVENT_REQUEST_FAILURE(8),
EXTERNAL_EXCEPTION(9),
SESSION_ALREADY_DESTROYED(10);
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java
deleted file mode 100644
index 868a7d8..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RestrictTo;
-import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment;
-
-import com.google.auto.value.AutoValue;
-
-/** Represents metadata from the Assistant FulfillmentRequest. */
-@AutoValue
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public abstract class RequestMetadata {
-
- /** Create a Builder instance for building a RequestMetadata instance. */
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_RequestMetadata.Builder();
- }
-
- /** The Type of request Assistant is sending on this FulfillmentRequest. */
- @NonNull
- public abstract Fulfillment.Type requestType();
-
- /** Builder for RequestMetadata. */
- @AutoValue.Builder
- public abstract static class Builder {
- /** Sets the FulfillmentRequest.Type. */
- @NonNull
- public abstract Builder setRequestType(@NonNull Fulfillment.Type requestType);
-
- /** Builds the RequestMetadata instance. */
- @NonNull
- public abstract RequestMetadata build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt
new file mode 100644
index 0000000..37be7ca
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/RequestMetadata.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl
+
+import androidx.annotation.RestrictTo
+import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment
+
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+data class RequestMetadata internal constructor(
+ val requestType: Fulfillment.Type
+) {
+ companion object {
+ @JvmStatic
+ fun create(requestType: Fulfillment.Type): RequestMetadata {
+ return RequestMetadata(requestType)
+ }
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt
index 32f3753..4c74879 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilitySession.kt
@@ -20,10 +20,10 @@
import androidx.appactions.interaction.capabilities.core.ExecutionCallback
import androidx.appactions.interaction.capabilities.core.ExecutionResult
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec
+import androidx.appactions.interaction.capabilities.core.impl.utils.CapabilityLogger
+import androidx.appactions.interaction.capabilities.core.impl.utils.LoggerInternal
+import androidx.appactions.interaction.capabilities.core.impl.utils.handleExceptionFromRequestProcessing
import androidx.appactions.interaction.capabilities.core.impl.utils.invokeExternalSuspendBlock
-import androidx.appactions.interaction.capabilities.core.impl.utils.isCausedBy
-import androidx.appactions.interaction.capabilities.core.impl.utils.toErrorStatusInternal
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.InvalidRequestException
import androidx.appactions.interaction.proto.AppActionsContext.AppDialogState
import androidx.appactions.interaction.proto.FulfillmentResponse
import androidx.appactions.interaction.proto.ParamValue
@@ -84,11 +84,12 @@
}
callback.onSuccess(convertToFulfillmentResponse(output))
} catch (t: Throwable) {
- callback.onError(t.toErrorStatusInternal())
- // if the exception is caused by a bad request, do not crash the app
- if (!t.isCausedBy(InvalidRequestException::class)) {
- throw t
- }
+ LoggerInternal.log(
+ CapabilityLogger.LogLevel.ERROR,
+ LOG_TAG,
+ "single-turn capability execution failed."
+ )
+ handleExceptionFromRequestProcessing(t, callback::onError)
} finally {
UiHandleRegistry.unregisterUiHandle(uiHandle)
mutex.unlock(owner = this@SingleTurnCapabilitySession)
@@ -109,4 +110,8 @@
}
return fulfillmentResponseBuilder.build()
}
+
+ companion object {
+ private const val LOG_TAG = "SingleTurnCapability"
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
index 056c6e8..eba3f11 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/CheckedInterfaces.java
@@ -37,7 +37,7 @@
* @param <R>
*/
@FunctionalInterface
- public interface Function<T, R> {
+ interface Function<T, R> {
R apply(T t) throws StructConversionException;
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java
deleted file mode 100644
index 2e2f22a..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.converters;
-
-import androidx.appactions.interaction.protobuf.Value;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-import java.util.function.Function;
-
-@AutoValue
-abstract class FieldBinding<T, BuilderT> {
-
- static <T, BuilderT> FieldBinding<T, BuilderT> create(
- String name,
- Function<T, Optional<Value>> valueGetter,
- CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>> valueSetter) {
- return new AutoValue_FieldBinding<>(name, valueGetter, valueSetter);
- }
-
- abstract String name();
-
- abstract Function<T, Optional<Value>> valueGetter();
-
- abstract CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>> valueSetter();
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt
new file mode 100644
index 0000000..9ca198c
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/FieldBinding.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.converters
+
+import androidx.appactions.interaction.protobuf.Value
+import java.util.function.Function
+
+internal data class FieldBinding<T, BuilderT> constructor(
+ val name: String,
+ val valueGetter: Function<T, Value?>,
+ val valueSetter: CheckedInterfaces.BiConsumer<BuilderT, Value>
+) {
+ companion object {
+ @JvmStatic
+ fun <T, BuilderT> create(
+ name: String,
+ valueGetter: Function<T, Value?>,
+ valueSetter: CheckedInterfaces.BiConsumer<BuilderT, Value>
+ ): FieldBinding<T, BuilderT> {
+ return FieldBinding(name, valueGetter, valueSetter)
+ }
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
index efacbfb4..a963bf6 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeConverters.java
@@ -18,9 +18,13 @@
import androidx.annotation.NonNull;
import androidx.appactions.builtintypes.experimental.properties.Attendee;
+import androidx.appactions.builtintypes.experimental.properties.EndDate;
import androidx.appactions.builtintypes.experimental.properties.ItemListElement;
+import androidx.appactions.builtintypes.experimental.properties.Name;
import androidx.appactions.builtintypes.experimental.properties.Participant;
import androidx.appactions.builtintypes.experimental.properties.Recipient;
+import androidx.appactions.builtintypes.experimental.properties.StartDate;
+import androidx.appactions.builtintypes.experimental.properties.Text;
import androidx.appactions.builtintypes.experimental.types.Alarm;
import androidx.appactions.builtintypes.experimental.types.CalendarEvent;
import androidx.appactions.builtintypes.experimental.types.Call;
@@ -73,20 +77,17 @@
.build();
public static final TypeSpec<Person> PERSON_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing(
- "Person",
- Person::Builder,
- Person.Builder::build)
- .bindStringField("email",
- person -> Optional.ofNullable(person.getEmail()),
- Person.Builder::setEmail)
+ TypeSpecBuilder.newBuilderForThing("Person", Person::Builder, Person.Builder::build)
+ .bindStringField("email", Person::getEmail, Person.Builder::setEmail)
.bindStringField(
- "telephone",
- person -> Optional.ofNullable(person.getTelephone()),
- Person.Builder::setTelephone)
- .bindStringField("name",
- person -> Optional.ofNullable(person.getName())
- .flatMap(name -> Optional.ofNullable(name.asText())),
+ "telephone", Person::getTelephone, Person.Builder::setTelephone)
+ .bindStringField(
+ "name",
+ person ->
+ Optional.ofNullable(person)
+ .map(Person::getName)
+ .map(Name::asText)
+ .orElse(null),
Person.Builder::setName)
.build();
public static final TypeSpec<Alarm> ALARM_TYPE_SPEC =
@@ -109,13 +110,19 @@
CalendarEvent.Builder::build)
.bindZonedDateTimeField(
"startDate",
- calendarEvent -> Optional.ofNullable(
- calendarEvent.getStartDate().asZonedDateTime()),
+ calendarEvent ->
+ Optional.ofNullable(calendarEvent)
+ .map(CalendarEvent::getStartDate)
+ .map(StartDate::asZonedDateTime)
+ .orElse(null),
CalendarEvent.Builder::setStartDate)
.bindZonedDateTimeField(
"endDate",
- calendarEvent -> Optional.ofNullable(
- calendarEvent.getEndDate().asZonedDateTime()),
+ calendarEvent ->
+ Optional.ofNullable(calendarEvent)
+ .map(CalendarEvent::getEndDate)
+ .map(EndDate::asZonedDateTime)
+ .orElse(null),
CalendarEvent.Builder::setEndDate)
.bindRepeatedSpecField(
"attendee",
@@ -130,11 +137,11 @@
SafetyCheck.Builder::build)
.bindDurationField(
"duration",
- safetyCheck -> Optional.ofNullable(safetyCheck.getDuration()),
+ SafetyCheck::getDuration,
SafetyCheck.Builder::setDuration)
.bindZonedDateTimeField(
"checkInTime",
- safetyCheck -> Optional.ofNullable(safetyCheck.getCheckInTime()),
+ SafetyCheck::getCheckInTime,
SafetyCheck.Builder::setCheckInTime)
.build();
public static final TypeSpec<Recipient> RECIPIENT_TYPE_SPEC =
@@ -152,11 +159,8 @@
PERSON_TYPE_SPEC)
.build();
public static final TypeSpec<Message> MESSAGE_TYPE_SPEC =
- TypeSpecBuilder.newBuilderForThing(
- "Message",
- Message::Builder,
- Message.Builder::build)
- .bindIdentifier(message -> Optional.ofNullable(message.getIdentifier()))
+ TypeSpecBuilder.newBuilderForThing("Message", Message::Builder, Message.Builder::build)
+ .bindIdentifier(Message::getIdentifier)
.bindRepeatedSpecField(
"recipient",
Message::getRecipientList,
@@ -164,7 +168,11 @@
RECIPIENT_TYPE_SPEC)
.bindStringField(
"text",
- message -> Optional.of(message.getText().asText()),
+ message ->
+ Optional.ofNullable(message)
+ .map(Message::getText)
+ .map(Text::asText)
+ .orElse(null),
Message.Builder::setText)
.build();
public static final TypeSpec<Call> CALL_TYPE_SPEC =
@@ -172,7 +180,7 @@
"Call",
Call::Builder,
Call.Builder::build)
- .bindIdentifier(call -> Optional.ofNullable(call.getIdentifier()))
+ .bindIdentifier(Call::getIdentifier)
.bindRepeatedSpecField(
"participant",
Call::getParticipantList,
@@ -368,11 +376,11 @@
SearchAction.Builder<T>::build)
.bindStringField(
"query",
- (searchAction) -> Optional.ofNullable(searchAction.getQuery()),
+ SearchAction::getQuery,
SearchAction.Builder<T>::setQuery)
.bindSpecField(
"filter",
- (searchAction) -> Optional.ofNullable(searchAction.getFilter()),
+ SearchAction::getFilter,
SearchAction.Builder<T>::setFilter,
nestedTypeSpec)
.build();
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
index 5222d8a..21c30a6 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecBuilder.java
@@ -19,20 +19,18 @@
import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
import androidx.appactions.builtintypes.experimental.types.Thing;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
import androidx.appactions.interaction.protobuf.ListValue;
import androidx.appactions.interaction.protobuf.Struct;
import androidx.appactions.interaction.protobuf.Value;
import java.time.Duration;
-import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Optional;
+import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -43,7 +41,7 @@
private final Supplier<BuilderT> mBuilderSupplier;
private final Function<BuilderT, T> mBuilderFinalizer;
private CheckedInterfaces.Consumer<Struct> mStructValidator;
- private Function<T, Optional<String>> mIdentifierGetter = (unused) -> Optional.empty();
+ private Function<T, String> mIdentifierGetter = (unused) -> null;
private TypeSpecBuilder(
String typeName,
@@ -51,7 +49,7 @@
Function<BuilderT, T> builderFinalizer) {
this.mBuilderSupplier = builderSupplier;
this.mBuilderFinalizer = builderFinalizer;
- this.bindStringField("@type", (unused) -> Optional.of(typeName), (builder, val) -> {})
+ this.bindStringField("@type", (unused) -> typeName, (builder, val) -> {})
.setStructValidator(
struct -> {
if (!getFieldFromStruct(struct, "@type")
@@ -92,11 +90,6 @@
}
}
- static <T, BuilderT extends BuilderOf<T>> TypeSpecBuilder<T, BuilderT> newBuilder(
- String typeName, Supplier<BuilderT> builderSupplier) {
- return new TypeSpecBuilder<>(typeName, builderSupplier, BuilderT::build);
- }
-
static <T, BuilderT> TypeSpecBuilder<T, BuilderT> newBuilder(
String typeName,
Supplier<BuilderT> builderSupplier,
@@ -115,16 +108,16 @@
Supplier<BuilderT> builderSupplier,
Function<BuilderT, T> builderFinalizer) {
return new TypeSpecBuilder<>(typeName, builderSupplier, builderFinalizer)
- .bindIdentifier(thing -> Optional.ofNullable(thing.getIdentifier()))
- .bindStringField(
- "identifier",
- thing -> Optional.ofNullable(thing.getIdentifier()),
- BuilderT::setIdentifier)
+ .bindIdentifier(Thing::getIdentifier)
+ .bindStringField("identifier", Thing::getIdentifier, BuilderT::setIdentifier)
.bindStringField(
"name",
- thing ->
- Optional.ofNullable(thing.getName())
- .flatMap(name -> Optional.ofNullable(name.asText())),
+ thing -> {
+ if (thing.getName() == null) {
+ return null;
+ }
+ return thing.getName().asText();
+ },
BuilderT::setName);
}
@@ -134,15 +127,15 @@
return this;
}
- TypeSpecBuilder<T, BuilderT> bindIdentifier(Function<T, Optional<String>> identifierGetter) {
+ TypeSpecBuilder<T, BuilderT> bindIdentifier(Function<T, String> identifierGetter) {
this.mIdentifierGetter = identifierGetter;
return this;
}
private TypeSpecBuilder<T, BuilderT> bindFieldInternal(
String name,
- Function<T, Optional<Value>> valueGetter,
- CheckedInterfaces.BiConsumer<BuilderT, Optional<Value>> valueSetter) {
+ Function<T, Value> valueGetter,
+ CheckedInterfaces.BiConsumer<BuilderT, Value> valueSetter) {
mBindings.add(FieldBinding.create(name, valueGetter, valueSetter));
return this;
}
@@ -151,30 +144,28 @@
String name,
Function<T, List<V>> valueGetter,
BiConsumer<BuilderT, List<V>> valueSetter,
- Function<V, Optional<Value>> toValue,
+ Function<V, Value> toValue,
CheckedInterfaces.Function<Value, V> fromValue) {
return bindFieldInternal(
name,
/** valueGetter= */
object -> {
- if (valueGetter.apply(object).isEmpty()) {
- return Optional.empty();
+ List<V> valueList = valueGetter.apply(object);
+ if (valueList == null) {
+ return null;
}
- return Optional.of(
- getListValue(
- valueGetter.apply(object).stream()
- .map(toValue)
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(toImmutableList())));
+ return getListValue(
+ valueList.stream()
+ .map(toValue)
+ .filter(Objects::nonNull)
+ .collect(toImmutableList()));
},
/** valueSetter= */
(builder, repeatedValue) -> {
- List<Value> values =
- repeatedValue
- .map(Value::getListValue)
- .map(ListValue::getValuesList)
- .orElseGet(Collections::emptyList);
+ if (repeatedValue.getListValue() == null) {
+ return;
+ }
+ List<Value> values = repeatedValue.getListValue().getValuesList();
List<V> convertedValues = new ArrayList<>();
for (Value value : values) {
convertedValues.add(fromValue.apply(value));
@@ -186,15 +177,22 @@
/** binds a String field to read from / write to Struct */
TypeSpecBuilder<T, BuilderT> bindStringField(
String name,
- Function<T, Optional<String>> stringGetter,
+ Function<T, String> stringGetter,
BiConsumer<BuilderT, String> stringSetter) {
return bindFieldInternal(
name,
- (object) -> stringGetter.apply(object).map(TypeSpecBuilder::getStringValue),
- (builder, value) ->
- value.map(Value::getStringValue)
- .ifPresent(
- stringValue -> stringSetter.accept(builder, stringValue)));
+ (object) -> {
+ String value = stringGetter.apply(object);
+ if (value == null) {
+ return null;
+ }
+ return TypeSpecBuilder.getStringValue(value);
+ },
+ (builder, value) -> {
+ if (value.hasStringValue()) {
+ stringSetter.accept(builder, value.getStringValue());
+ }
+ });
}
/**
@@ -203,19 +201,21 @@
*/
<E extends Enum<E>> TypeSpecBuilder<T, BuilderT> bindEnumField(
String name,
- Function<T, Optional<E>> valueGetter,
+ Function<T, E> valueGetter,
BiConsumer<BuilderT, E> valueSetter,
Class<E> enumClass) {
return bindFieldInternal(
name,
- (object) ->
- valueGetter
- .apply(object)
- .map(Enum::toString)
- .map(TypeSpecBuilder::getStringValue),
+ (object) -> {
+ E enumVal = valueGetter.apply(object);
+ if (enumVal == null) {
+ return null;
+ }
+ return TypeSpecBuilder.getStringValue(enumVal.toString());
+ },
(builder, value) -> {
- if (value.isPresent()) {
- String stringValue = value.get().getStringValue();
+ if (value.hasStringValue()) {
+ String stringValue = value.getStringValue();
E[] enumValues = enumClass.getEnumConstants();
if (enumValues != null) {
for (E enumValue : enumValues) {
@@ -237,24 +237,24 @@
*/
TypeSpecBuilder<T, BuilderT> bindDurationField(
String name,
- Function<T, Optional<Duration>> valueGetter,
+ Function<T, Duration> valueGetter,
BiConsumer<BuilderT, Duration> valueSetter) {
return bindFieldInternal(
name,
- (object) ->
- valueGetter
- .apply(object)
- .map(Duration::toString)
- .map(TypeSpecBuilder::getStringValue),
+ (object) -> {
+ Duration duration = valueGetter.apply(object);
+ if (duration == null) {
+ return null;
+ }
+ return TypeSpecBuilder.getStringValue(duration.toString());
+ },
(builder, value) -> {
- if (value.isPresent()) {
- try {
- valueSetter.accept(
- builder, Duration.parse(value.get().getStringValue()));
- } catch (DateTimeParseException e) {
- throw new StructConversionException(
- "Failed to parse ISO 8601 string to Duration", e);
- }
+ try {
+ valueSetter.accept(
+ builder, Duration.parse(value.getStringValue()));
+ } catch (DateTimeParseException e) {
+ throw new StructConversionException(
+ "Failed to parse ISO 8601 string to Duration", e);
}
});
}
@@ -265,21 +265,23 @@
*/
TypeSpecBuilder<T, BuilderT> bindZonedDateTimeField(
String name,
- Function<T, Optional<ZonedDateTime>> valueGetter,
+ Function<T, ZonedDateTime> valueGetter,
BiConsumer<BuilderT, ZonedDateTime> valueSetter) {
return bindFieldInternal(
name,
- (object) ->
- valueGetter
- .apply(object)
- .map(ZonedDateTime::toOffsetDateTime)
- .map(OffsetDateTime::toString)
- .map(TypeSpecBuilder::getStringValue),
+ (object) -> {
+ ZonedDateTime zonedDateTime = valueGetter.apply(object);
+ if (zonedDateTime == null) {
+ return null;
+ }
+ return TypeSpecBuilder.getStringValue(
+ zonedDateTime.toOffsetDateTime().toString());
+ },
(builder, value) -> {
- if (value.isPresent()) {
+ if (value.hasStringValue()) {
try {
valueSetter.accept(
- builder, ZonedDateTime.parse(value.get().getStringValue()));
+ builder, ZonedDateTime.parse(value.getStringValue()));
} catch (DateTimeParseException e) {
throw new StructConversionException(
"Failed to parse ISO 8601 string to ZonedDateTime", e);
@@ -291,23 +293,20 @@
/** Binds a spec field to read from / write to Struct. */
<V> TypeSpecBuilder<T, BuilderT> bindSpecField(
String name,
- Function<T, Optional<V>> valueGetter,
+ Function<T, V> valueGetter,
BiConsumer<BuilderT, V> valueSetter,
TypeSpec<V> spec) {
return bindFieldInternal(
name,
- (object) ->
- valueGetter
- .apply(object)
- .map(Function.identity()) // Static analyzer incorrectly
- // throws error stating that the
- // input to toStruct is nullable. This is a workaround to avoid
- // the error from the analyzer.
- .map(spec::toValue),
- (builder, value) -> {
- if (value.isPresent()) {
- valueSetter.accept(builder, spec.fromValue(value.get()));
+ (object) -> {
+ V value = valueGetter.apply(object);
+ if (value == null) {
+ return null;
}
+ return spec.toValue(value);
+ },
+ (builder, value) -> {
+ valueSetter.accept(builder, spec.fromValue(value));
});
}
@@ -321,16 +320,16 @@
name,
valueGetter,
valueSetter,
- (element) -> Optional.ofNullable(element).map(spec::toValue),
+ spec::toValue,
(value) -> spec.fromValue(value));
}
TypeSpec<T> build() {
- return new TypeSpecImpl<T, BuilderT>(
+ return new TypeSpecImpl<>(
mIdentifierGetter,
mBindings,
mBuilderSupplier,
mBuilderFinalizer,
- Optional.ofNullable(mStructValidator));
+ mStructValidator);
}
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
index 48f5a0c..da4488c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImpl.java
@@ -25,7 +25,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -35,26 +34,31 @@
*/
final class TypeSpecImpl<T, BuilderT> implements TypeSpec<T> {
/* The function to retrieve the identifier. */
- final Function<T, Optional<String>> mIdentifierGetter;
+ @NonNull
+ final Function<T, String> mIdentifierGetter;
/** The list of FieldBinding objects. */
+ @NonNull
final List<FieldBinding<T, BuilderT>> mBindings;
/** Validates the Struct during conversion to java object. */
- final Optional<CheckedInterfaces.Consumer<Struct>> mStructValidator;
+ @Nullable
+ final CheckedInterfaces.Consumer<Struct> mStructValidator;
/** Supplies BuilderT instances. */
+ @NonNull
final Supplier<BuilderT> mBuilderSupplier;
/** Builds the object instance. */
+ @NonNull
final Function<BuilderT, T> mBuilderFinalizer;
TypeSpecImpl(
- Function<T, Optional<String>> identifierGetter,
- List<FieldBinding<T, BuilderT>> bindings,
- Supplier<BuilderT> builderSupplier,
- Function<BuilderT, T> builderFinalizer,
- Optional<CheckedInterfaces.Consumer<Struct>> structValidator) {
+ @NonNull Function<T, String> identifierGetter,
+ @NonNull List<FieldBinding<T, BuilderT>> bindings,
+ @NonNull Supplier<BuilderT> builderSupplier,
+ @NonNull Function<BuilderT, T> builderFinalizer,
+ @Nullable CheckedInterfaces.Consumer<Struct> structValidator) {
this.mIdentifierGetter = identifierGetter;
this.mBindings = Collections.unmodifiableList(bindings);
this.mBuilderSupplier = builderSupplier;
@@ -65,7 +69,7 @@
@Nullable
@Override
public String getIdentifier(T obj) {
- return mIdentifierGetter.apply(obj).orElse(null);
+ return mIdentifierGetter.apply(obj);
}
/** Converts a java object into a Struct proto using List of FieldBinding. */
@@ -74,9 +78,10 @@
public Value toValue(@NonNull T obj) {
Struct.Builder structBuilder = Struct.newBuilder();
for (FieldBinding<T, BuilderT> binding : mBindings) {
- binding.valueGetter()
- .apply(obj)
- .ifPresent(value -> structBuilder.putFields(binding.name(), value));
+ Value value = binding.getValueGetter().apply(obj);
+ if (value != null) {
+ structBuilder.putFields(binding.getName(), value);
+ }
}
return Value.newBuilder().setStructValue(structBuilder).build();
}
@@ -94,15 +99,17 @@
throw new StructConversionException(
String.format("TypeSpecImpl cannot deserializes non-Struct value: %s", value));
}
- if (mStructValidator.isPresent()) {
- mStructValidator.get().accept(struct);
+ if (mStructValidator != null) {
+ mStructValidator.accept(struct);
}
BuilderT builder = mBuilderSupplier.get();
Map<String, Value> fieldsMap = struct.getFieldsMap();
for (FieldBinding<T, BuilderT> binding : mBindings) {
- Optional<Value> fieldValue = Optional.ofNullable(fieldsMap.get(binding.name()));
- binding.valueSetter().accept(builder, fieldValue);
+ Value fieldValue = fieldsMap.get(binding.getName());
+ if (fieldValue != null) {
+ binding.getValueSetter().accept(builder, fieldValue);
+ }
}
return mBuilderFinalizer.apply(builder);
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/exceptions/InvalidRequestException.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/exceptions/InvalidRequestException.kt
index b060fc8..557cc1c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/exceptions/InvalidRequestException.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/exceptions/InvalidRequestException.kt
@@ -17,7 +17,7 @@
package androidx.appactions.interaction.capabilities.core.impl.exceptions
/** Represents exceptions that happen as a result of some incoming request that is invalid. */
-sealed class InvalidRequestException : Exception {
+open class InvalidRequestException : Exception {
constructor(message: String?) : super(message)
constructor(message: String?, cause: Throwable?) : super(message, cause)
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java
deleted file mode 100644
index eb8d0ad..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * A specification for an action, describing it from the app's point of view.
- *
- * @param <ArgumentsT> typed representation of action's arguments.
- * @param <OutputT> typed action's execution output.
- */
-public interface ActionSpec<ArgumentsT, OutputT> {
-
- /** Converts the property to the {@code AppAction} proto. */
- @NonNull
- AppAction convertPropertyToProto(@NonNull Map<String,
- Property<?>> property);
-
- /** Builds this action's arguments from an ArgumentsWrapper instance. */
- @NonNull
- ArgumentsT buildArguments(@NonNull Map<String, List<ParamValue>> args)
- throws StructConversionException;
-
- /** Converts the output to the {@code StructuredOutput} proto. */
- @NonNull
- StructuredOutput convertOutputToProto(OutputT output);
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt
new file mode 100644
index 0000000..450d3d3
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpec.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.ParamValue
+
+/**
+ * A specification for an action, describing it from the app's point of view.
+ *
+ * @param ArgumentsT typed representation of action's arguments.
+ * @param OutputT typed action's execution output.
+ */
+interface ActionSpec<ArgumentsT, OutputT> {
+
+ /** Converts the property to the `AppAction` proto. */
+ fun convertPropertyToProto(property: Map<String, Property<*>>): AppActionsContext.AppAction
+
+ /** Builds this action's arguments from an ArgumentsWrapper instance. */
+ @Throws(StructConversionException::class)
+ fun buildArguments(args: Map<String, List<ParamValue>>): ArgumentsT
+
+ /** Converts the output to the `StructuredOutput` proto. */
+ fun convertOutputToProto(output: OutputT): FulfillmentResponse.StructuredOutput
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java
deleted file mode 100644
index df268de..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.SlotTypeConverter;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.ArgumentSetter;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/**
- * A builder for the {@code ActionSpec}.
- */
-public final class ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>,
- OutputT> {
-
- private final String mCapabilityName;
- private final Supplier<ArgumentsBuilderT> mArgumentBuilderSupplier;
- private final ArrayList<ParamBinding<ArgumentsT, ArgumentsBuilderT>>
- mParamBindingList = new ArrayList<>();
- private final Map<String, Function<OutputT, List<ParamValue>>> mOutputBindings =
- new HashMap<>();
-
- private ActionSpecBuilder(
- String capabilityName, Supplier<ArgumentsBuilderT> argumentBuilderSupplier) {
- this.mCapabilityName = capabilityName;
- this.mArgumentBuilderSupplier = argumentBuilderSupplier;
- }
-
- /**
- * Creates an empty {@code ActionSpecBuilder} with the given capability name. ArgumentsT is set
- * to Object as a placeholder, which must be replaced by calling setArgument.
- */
- @NonNull
- public static ActionSpecBuilder<Object, BuilderOf<Object>, Void> ofCapabilityNamed(
- @NonNull String capabilityName) {
- return new ActionSpecBuilder<>(capabilityName, () -> Object::new);
- }
-
- /** Sets the property type and returns a new {@code ActionSpecBuilder}. */
-
- /** Sets the argument type and its builder and returns a new {@code ActionSpecBuilder}. */
- @NonNull
- public <NewArgumentsT, NewArgumentsBuilderT extends BuilderOf<NewArgumentsT>>
- ActionSpecBuilder<NewArgumentsT, NewArgumentsBuilderT, OutputT> setArguments(
- @NonNull Class<NewArgumentsT> unused,
- @NonNull Supplier<NewArgumentsBuilderT> argumentBuilderSupplier) {
- return new ActionSpecBuilder<>(this.mCapabilityName, argumentBuilderSupplier);
- }
-
- @NonNull
- public <NewOutputT>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, NewOutputT> setOutput(
- @NonNull Class<NewOutputT> unused) {
- return new ActionSpecBuilder<>(this.mCapabilityName, this.mArgumentBuilderSupplier);
- }
-
- /**
- * Binds the parameter name, getter and setter.
- *
- * @param paramName the name of this action' parameter.
- * @param paramGetter a getter of the param-specific info from the property.
- * @param argumentSetter a setter to the argument with the input from {@code ParamValue}.
- * @return the builder itself.
- */
- @NonNull
- private ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
- bindParameterInternal(
- @NonNull String paramName,
- @NonNull Function<Map<String, Property<?>>,
- Optional<IntentParameter>> paramGetter,
- @NonNull ArgumentSetter<ArgumentsBuilderT> argumentSetter) {
- mParamBindingList.add(ParamBinding.create(paramName, paramGetter, argumentSetter));
- return this;
- }
-
- /**
- * Binds the parameter name, getter, and setter for a {@link Property}.
- *
- * <p>This parameter is required for any capability built from the generated {@link ActionSpec}.
- *
- * @param paramName the name of this action' parameter.
- * @param propertyGetter a getter of the Property from the property, which must be able to
- * fetch a non-null {@code Property} from {@code PropertyT}.
- * @param paramConsumer a setter to set the string value in the argument builder.
- * @param paramValueConverter converter FROM assistant ParamValue proto
- * @param entityConverter converter TO assistant Entity proto
- * @return the builder itself.
- */
- @NonNull
- public <T, PossibleValueT>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindParameter(
- @NonNull String paramName,
- @NonNull
- Function<Map<String, Property<?>>,
- Property<PossibleValueT>>
- propertyGetter,
- @NonNull BiConsumer<? super ArgumentsBuilderT, T> paramConsumer,
- @NonNull ParamValueConverter<T> paramValueConverter,
- @NonNull EntityConverter<PossibleValueT> entityConverter) {
- return bindOptionalParameter(
- paramName,
- property -> Optional.of(propertyGetter.apply(property)),
- paramConsumer,
- paramValueConverter,
- entityConverter);
- }
-
- /**
- * Binds the parameter name, getter, and setter for a {@link Property}.
- *
- * <p>This parameter is optional for any capability built from the generated {@link ActionSpec}.
- * If the Property Optional is not set, this parameter will not exist in the parameter
- * definition of the capability.
- *
- * @param paramName the name of this action' parameter.
- * @param optionalPropertyGetter an optional getter of the Property from the property,
- * which may be able to fetch a non-null {@code Property} from {@code PropertyT},
- * or get {@link Optional#empty}.
- * @param paramConsumer a setter to set the string value in the argument builder.
- * @param paramValueConverter converter FROM assistant ParamValue proto
- * @param entityConverter converter TO assistant Entity proto
- * @return the builder itself.
- */
- @NonNull
- public <T, PossibleValueT>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
- bindOptionalParameter(
- @NonNull String paramName,
- @NonNull
- Function<
- Map<String, Property<?>>,
- Optional<Property<PossibleValueT>>>
- optionalPropertyGetter,
- @NonNull BiConsumer<? super ArgumentsBuilderT, T> paramConsumer,
- @NonNull ParamValueConverter<T> paramValueConverter,
- @NonNull EntityConverter<PossibleValueT> entityConverter) {
- return bindParameterInternal(
- paramName,
- property ->
- optionalPropertyGetter
- .apply(property)
- .map(p -> buildIntentParameter(paramName, p, entityConverter)),
- (argBuilder, paramList) -> {
- if (!paramList.isEmpty()) {
- paramConsumer.accept(
- argBuilder,
- SlotTypeConverter.ofSingular(paramValueConverter)
- .convert(paramList));
- }
- });
- }
-
- /**
- * This is similar to {@link ActionSpecBuilder#bindOptionalParameter} but for setting a list of
- * entities instead.
- *
- * <p>This parameter is optional for any capability built from the generated {@link ActionSpec}.
- * If the Property Optional is not set, this parameter will not exist in the parameter
- * definition of the capability.
- */
- @NonNull
- public <T, PossibleValueT>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT>
- bindRepeatedParameter(
- @NonNull String paramName,
- @NonNull
- Function<
- Map<String, Property<?>>,
- Optional<Property<PossibleValueT>>>
- optionalPropertyGetter,
- @NonNull BiConsumer<? super ArgumentsBuilderT, List<T>> paramConsumer,
- @NonNull ParamValueConverter<T> paramValueConverter,
- @NonNull EntityConverter<PossibleValueT> entityConverter) {
- return bindParameterInternal(
- paramName,
- property ->
- optionalPropertyGetter
- .apply(property)
- .map(p -> buildIntentParameter(paramName, p, entityConverter)),
- (argBuilder, paramList) ->
- paramConsumer.accept(
- argBuilder,
- SlotTypeConverter.ofRepeated(paramValueConverter)
- .convert(paramList)));
- }
-
- /**
- * Binds an optional output.
- *
- * @param name the BII output slot name of this parameter.
- * @param outputGetter a getter of the output from the {@code OutputT} instance.
- * @param converter a converter from an output object to a ParamValue.
- */
- @NonNull
- @SuppressWarnings("JdkCollectors")
- public <T>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindOptionalOutput(
- @NonNull String name,
- @NonNull Function<OutputT, Optional<T>> outputGetter,
- @NonNull Function<T, ParamValue> converter) {
- mOutputBindings.put(
- name,
- output -> {
- Optional<T> optionalOut = outputGetter.apply(output);
- List<ParamValue> paramValues = new ArrayList<>();
- if (optionalOut.isPresent()) {
- paramValues.add(converter.apply(optionalOut.get()));
- }
- return Collections.unmodifiableList(paramValues);
- });
- return this;
- }
-
- /**
- * Binds a repeated output.
- *
- * @param name the BII output slot name of this parameter.
- * @param outputGetter a getter of the output from the {@code OutputT} instance.
- * @param converter a converter from an output object to a ParamValue.
- */
- @NonNull
- @SuppressWarnings("JdkCollectors")
- public <T>
- ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> bindRepeatedOutput(
- @NonNull String name,
- @NonNull Function<OutputT, List<T>> outputGetter,
- @NonNull Function<T, ParamValue> converter) {
- mOutputBindings.put(
- name,
- output ->
- outputGetter.apply(output).stream()
- .map(converter)
- .collect(toImmutableList()));
- return this;
- }
-
- /** Builds an {@code ActionSpec} from this builder. */
- @NonNull
- public ActionSpec<ArgumentsT, OutputT> build() {
- return new ActionSpecImpl<>(
- mCapabilityName,
- mArgumentBuilderSupplier,
- Collections.unmodifiableList(mParamBindingList),
- mOutputBindings);
- }
-
- /** Create IntentParameter proto from a Property. */
- @NonNull
- private static <T> IntentParameter buildIntentParameter(
- @NonNull String paramName,
- @NonNull Property<T> property,
- @NonNull EntityConverter<T> entityConverter) {
- IntentParameter.Builder builder = IntentParameter.newBuilder()
- .setName(paramName)
- .setIsRequired(property.isRequired())
- .setEntityMatchRequired(property.isValueMatchRequired())
- .setIsProhibited(property.isProhibited());
- property.getPossibleValues().stream()
- .map(entityConverter::convert)
- .forEach(builder::addPossibleEntities);
- return builder.build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt
new file mode 100644
index 0000000..ad4b7b6
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecBuilder.kt
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.SlotTypeConverter
+import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.ArgumentSetter
+import androidx.appactions.interaction.capabilities.core.impl.spec.ParamBinding.Companion.create
+import androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.function.BiConsumer
+import java.util.function.Function
+import java.util.function.Supplier
+
+/**
+ * A builder for the `ActionSpec`.
+ */
+class ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>, OutputT>
+private constructor(
+ private val capabilityName: String,
+ private val argumentBuilderSupplier: Supplier<ArgumentsBuilderT>
+) {
+ private val paramBindingList: MutableList<ParamBinding<ArgumentsT, ArgumentsBuilderT>> =
+ ArrayList()
+ private val outputBindings: MutableMap<String, Function<OutputT, List<ParamValue>>> = HashMap()
+
+ /** Sets the property type and returns a new `ActionSpecBuilder`. */
+ /** Sets the argument type and its builder and returns a new `ActionSpecBuilder`. */
+ @Suppress("UNUSED_PARAMETER")
+ fun <NewArgumentsT, NewArgumentsBuilderT : BuilderOf<NewArgumentsT>> setArguments(
+ unused: Class<NewArgumentsT>,
+ argumentBuilderSupplier: Supplier<NewArgumentsBuilderT>
+ ): ActionSpecBuilder<NewArgumentsT, NewArgumentsBuilderT, OutputT> {
+ return ActionSpecBuilder(this.capabilityName, argumentBuilderSupplier)
+ }
+
+ @Suppress("UNUSED_PARAMETER")
+ fun <NewOutputT> setOutput(
+ unused: Class<NewOutputT>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, NewOutputT> {
+ return ActionSpecBuilder(this.capabilityName, this.argumentBuilderSupplier)
+ }
+
+ /**
+ * Binds the parameter name, getter and setter.
+ *
+ * @param paramName the name of this action' parameter.
+ * @param paramGetter a getter of the param-specific info from the property.
+ * @param argumentSetter a setter to the argument with the input from `ParamValue`.
+ * @return the builder itself.
+ */
+ private fun bindParameterInternal(
+ paramName: String,
+ paramGetter: Function<Map<String, Property<*>>, AppActionsContext.IntentParameter?>,
+ argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+ paramBindingList.add(create(paramName, paramGetter, argumentSetter))
+ return this
+ }
+
+ /**
+ * Binds the parameter name, getter, and setter for a [Property].
+ *
+ * If the Property getter returns a null value, this parameter will not exist in the parameter
+ * definition of the capability.
+ *
+ * @param paramName the name of this action' parameter.
+ * @param propertyGetter a getter of the Property from the property, which must be able to
+ * fetch a non-null `Property` from `PropertyT`.
+ * @param paramConsumer a setter to set the string value in the argument builder.
+ * @param paramValueConverter converter FROM assistant ParamValue proto
+ * @param entityConverter converter TO assistant Entity proto
+ * @return the builder itself.
+ */
+ fun <T, PossibleValueT> bindParameter(
+ paramName: String,
+ propertyGetter: Function<Map<String, Property<*>>, Property<PossibleValueT>?>,
+ paramConsumer: BiConsumer<in ArgumentsBuilderT, T>,
+ paramValueConverter: ParamValueConverter<T>,
+ entityConverter: EntityConverter<PossibleValueT>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+ return bindParameterInternal(
+ paramName,
+ { propertyMap ->
+ propertyGetter.apply(propertyMap)?.let {
+ buildIntentParameter(paramName, it, entityConverter)
+ }
+ },
+ { argBuilder: ArgumentsBuilderT, paramList: List<ParamValue> ->
+ if (paramList.isNotEmpty()) {
+ paramConsumer.accept(
+ argBuilder,
+ SlotTypeConverter.ofSingular(paramValueConverter).convert(paramList)
+ )
+ }
+ }
+ )
+ }
+
+ /**
+ * This is similar to [ActionSpecBuilder.bindParameter] but for setting a list of
+ * entities instead.
+ *
+ * If the Property getter returns a null value, this parameter will not exist in the parameter
+ * definition of the capability.
+ */
+ fun <T, PossibleValueT> bindRepeatedParameter(
+ paramName: String,
+ propertyGetter: Function<Map<String, Property<*>>, Property<PossibleValueT>?>,
+ paramConsumer: BiConsumer<in ArgumentsBuilderT, List<T>>,
+ paramValueConverter: ParamValueConverter<T>,
+ entityConverter: EntityConverter<PossibleValueT>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+ return bindParameterInternal(
+ paramName,
+ { propertyMap ->
+ propertyGetter.apply(propertyMap)?.let {
+ buildIntentParameter(paramName, it, entityConverter)
+ }
+ },
+ { argBuilder: ArgumentsBuilderT, paramList: List<ParamValue?>? ->
+ paramConsumer.accept(
+ argBuilder,
+ SlotTypeConverter.ofRepeated(paramValueConverter).convert(paramList!!)
+ )
+ }
+ )
+ }
+
+ /**
+ * Binds an optional output.
+ *
+ * @param name the BII output slot name of this parameter.
+ * @param outputFieldGetter a getter of the output from the `OutputT` instance.
+ * @param converter a converter from an output object to a ParamValue.
+ */
+ fun <T> bindOutput(
+ name: String,
+ outputFieldGetter: Function<OutputT, T?>,
+ converter: Function<T, ParamValue>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+ outputBindings[name] = Function { output: OutputT ->
+ val outputField: T? = outputFieldGetter.apply(output)
+ val paramValues: MutableList<ParamValue> =
+ ArrayList()
+ if (outputField != null) {
+ paramValues.add(converter.apply(outputField))
+ }
+ paramValues.toList()
+ }
+ return this
+ }
+
+ /**
+ * Binds a repeated output.
+ *
+ * @param name the BII output slot name of this parameter.
+ * @param outputGetter a getter of the output from the `OutputT` instance.
+ * @param converter a converter from an output object to a ParamValue.
+ */
+ fun <T> bindRepeatedOutput(
+ name: String,
+ outputGetter: Function<OutputT, List<T>>,
+ converter: Function<T, ParamValue>
+ ): ActionSpecBuilder<ArgumentsT, ArgumentsBuilderT, OutputT> {
+ outputBindings[name] = Function { output: OutputT ->
+ outputGetter.apply(output).stream()
+ .map(converter)
+ .collect(ImmutableCollectors.toImmutableList())
+ }
+ return this
+ }
+
+ /** Builds an `ActionSpec` from this builder. */
+ fun build(): ActionSpec<ArgumentsT, OutputT> {
+ return ActionSpecImpl(
+ capabilityName,
+ argumentBuilderSupplier,
+ paramBindingList.toList(),
+ outputBindings.toMap()
+ )
+ }
+
+ companion object {
+ /**
+ * Creates an empty `ActionSpecBuilder` with the given capability name. ArgumentsT is set
+ * to Object as a placeholder, which must be replaced by calling setArgument.
+ */
+ fun ofCapabilityNamed(
+ capabilityName: String
+ ): ActionSpecBuilder<Any, BuilderOf<Any>, Any> {
+ return ActionSpecBuilder(capabilityName) { BuilderOf { Object() } }
+ }
+
+ /** Create IntentParameter proto from a Property. */
+ internal fun <T> buildIntentParameter(
+ paramName: String,
+ property: Property<T>,
+ entityConverter: EntityConverter<T>
+ ): AppActionsContext.IntentParameter {
+ val builder = AppActionsContext.IntentParameter.newBuilder()
+ .setName(paramName)
+ .setIsRequired(property.isRequired)
+ .setEntityMatchRequired(property.isValueMatchRequired)
+ .setIsProhibited(property.isProhibited)
+ property.possibleValues.stream()
+ .map { possibleValue ->
+ entityConverter.convert(possibleValue)
+ }
+ .forEach { entityProto ->
+ builder.addPossibleEntities(entityProto)
+ }
+ return builder.build()
+ }
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
deleted file mode 100644
index 8dfdb19..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors.toImmutableList;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
-import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.function.Supplier;
-
-/** The implementation of {@code ActionSpec} interface. */
-final class ActionSpecImpl<
- ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>, OutputT>
- implements ActionSpec<ArgumentsT, OutputT> {
-
- private final String mCapabilityName;
- private final Supplier<ArgumentsBuilderT> mArgumentBuilderSupplier;
- private final List<ParamBinding<ArgumentsT, ArgumentsBuilderT>> mParamBindingList;
- private final Map<String, Function<OutputT, List<ParamValue>>> mOutputBindings;
-
- ActionSpecImpl(
- String capabilityName,
- Supplier<ArgumentsBuilderT> argumentBuilderSupplier,
- List<ParamBinding<ArgumentsT, ArgumentsBuilderT>> paramBindingList,
- Map<String, Function<OutputT, List<ParamValue>>> outputBindings) {
- this.mCapabilityName = capabilityName;
- this.mArgumentBuilderSupplier = argumentBuilderSupplier;
- this.mParamBindingList = paramBindingList;
- this.mOutputBindings = outputBindings;
- }
-
- @NonNull
- @Override
- public AppAction convertPropertyToProto(@NonNull Map<String, Property<?>> property) {
- return AppAction.newBuilder()
- .setName(mCapabilityName)
- .addAllParams(
- mParamBindingList.stream()
- .map(binding -> binding.paramGetter().apply(property))
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(toImmutableList()))
- .build();
- }
-
- @NonNull
- @Override
- public ArgumentsT buildArguments(@NonNull Map<String, List<ParamValue>> args)
- throws StructConversionException {
- ArgumentsBuilderT argumentBuilder = mArgumentBuilderSupplier.get();
- for (ParamBinding<ArgumentsT, ArgumentsBuilderT> binding : mParamBindingList) {
- List<ParamValue> paramValues = args.get(binding.name());
- if (paramValues == null) {
- continue;
- }
- try {
- binding.argumentSetter().setArguments(argumentBuilder, paramValues);
- } catch (StructConversionException e) {
- // Wrap the exception with a more meaningful error message.
- throw new StructConversionException(
- String.format(
- "Failed to parse parameter '%s' from assistant because of "
- + "failure: %s",
- binding.name(), e.getMessage()));
- }
- }
- return argumentBuilder.build();
- }
-
- @NonNull
- @Override
- public StructuredOutput convertOutputToProto(OutputT output) {
- StructuredOutput.Builder outputBuilder = StructuredOutput.newBuilder();
- for (Map.Entry<String, Function<OutputT, List<ParamValue>>> entry :
- mOutputBindings.entrySet()) {
- List<ParamValue> values = entry.getValue().apply(output);
- if (!values.isEmpty()) {
- outputBuilder.addOutputValues(
- StructuredOutput.OutputValue.newBuilder()
- .setName(entry.getKey())
- .addAllValues(values)
- .build());
- }
- }
- return outputBuilder.build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt
new file mode 100644
index 0000000..a05c8ed
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecImpl.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.impl.utils.ImmutableCollectors
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext
+import androidx.appactions.interaction.proto.FulfillmentResponse
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.function.Function
+import java.util.function.Supplier
+
+/** The implementation of `ActionSpec` interface. */
+internal class ActionSpecImpl<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>, OutputT>(
+ private val capabilityName: String,
+ private val argumentBuilderSupplier: Supplier<ArgumentsBuilderT>,
+ private val paramBindingList: List<ParamBinding<ArgumentsT, ArgumentsBuilderT>>,
+ private val outputBindings: Map<String, Function<OutputT, List<ParamValue>>>
+) : ActionSpec<ArgumentsT, OutputT> {
+
+ override fun convertPropertyToProto(
+ property: Map<String, Property<*>>
+ ): AppActionsContext.AppAction {
+ return AppActionsContext.AppAction.newBuilder()
+ .setName(capabilityName)
+ .addAllParams(
+ paramBindingList.stream()
+ .map { binding -> binding.propertyConverter.apply(property) }
+ .filter { intentParam -> intentParam != null }
+ .collect(ImmutableCollectors.toImmutableList())
+ )
+ .build()
+ }
+
+ @Throws(StructConversionException::class)
+ override fun buildArguments(args: Map<String, List<ParamValue>>): ArgumentsT {
+ val argumentBuilder = argumentBuilderSupplier.get()
+ paramBindingList.forEach { binding ->
+ val paramValues = args[binding.name] ?: return@forEach
+ try {
+ binding.argumentSetter.setArguments(argumentBuilder, paramValues)
+ } catch (e: StructConversionException) {
+ // Wrap the exception with a more meaningful error message.
+ throw StructConversionException(
+ "Failed to parse parameter '${binding.name}' from assistant because of" +
+ " failure: ${e.message}"
+ )
+ }
+ }
+ return argumentBuilder.build()
+ }
+
+ override fun convertOutputToProto(output: OutputT): FulfillmentResponse.StructuredOutput {
+ val outputBuilder = FulfillmentResponse.StructuredOutput.newBuilder()
+ outputBindings.entries.forEach { entry ->
+ val paramValues = entry.value.apply(output)
+ if (paramValues.isNotEmpty()) {
+ outputBuilder.addOutputValues(
+ FulfillmentResponse.StructuredOutput.OutputValue.newBuilder()
+ .setName(entry.key)
+ .addAllValues(paramValues)
+ .build()
+ )
+ }
+ }
+ return outputBuilder.build()
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java
deleted file mode 100644
index 87ce323..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-
-/**
- * A binding between a parameter and its Property converter / Argument setter.
- */
-@AutoValue
-public abstract class ParamBinding<
- ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>> {
-
- static <ArgumentsT, ArgumentsBuilderT extends BuilderOf<ArgumentsT>>
- ParamBinding<ArgumentsT, ArgumentsBuilderT> create(
- String name,
- Function<Map<String, Property<?>>,
- Optional<IntentParameter>> paramGetter,
- ArgumentSetter<ArgumentsBuilderT> argumentSetter) {
- return new AutoValue_ParamBinding<>(name, paramGetter, argumentSetter);
- }
-
- /** Returns the name of this param. */
- @NonNull
- public abstract String name();
-
- /**
- * Converts a {@code Property Map} to an {@code IntentParameter} proto. The resulting proto is
- * the
- * format which we send the current params to Assistant (via. app actions context).
- */
- @NonNull
- public abstract Function<Map<String, Property<?>>,
- Optional<IntentParameter>> paramGetter();
-
- /**
- * Populates the {@code ArgumentsBuilderT} for this param with the {@code ParamValue} sent from
- * Assistant in Fulfillment.
- */
- @NonNull
- public abstract ArgumentSetter<ArgumentsBuilderT> argumentSetter();
-
- /**
- * Given a {@code List<ParamValue>}, convert it to user-visible type and set it into
- * ArgumentBuilder.
- *
- * @param <ArgumentsBuilderT>
- */
- @FunctionalInterface
- public interface ArgumentSetter<ArgumentsBuilderT> {
-
- /** Conversion from protos to user-visible type. */
- void setArguments(@NonNull ArgumentsBuilderT builder, @NonNull List<ParamValue> paramValues)
- throws StructConversionException;
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt
new file mode 100644
index 0000000..7e57ead
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/spec/ParamBinding.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter
+import androidx.appactions.interaction.proto.ParamValue
+import java.util.function.Function
+
+data class ParamBinding<ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>>
+internal constructor(
+ val name: String,
+ val propertyConverter: Function<Map<String, Property<*>>, IntentParameter?>,
+ val argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+) {
+ /**
+ * Given a `List<ParamValue>`, convert it to user-visible type and set it into
+ * ArgumentBuilder.
+ */
+ fun interface ArgumentSetter<ArgumentsBuilderT> {
+ /** Conversion from protos to user-visible type. */
+ @Throws(StructConversionException::class)
+ fun setArguments(builder: ArgumentsBuilderT, paramValues: List<ParamValue>)
+ }
+
+ companion object {
+ @JvmStatic
+ fun <ArgumentsT, ArgumentsBuilderT : BuilderOf<ArgumentsT>> create(
+ name: String,
+ paramGetter: Function<Map<String, Property<*>>, IntentParameter?>,
+ argumentSetter: ArgumentSetter<ArgumentsBuilderT>
+ ): ParamBinding<ArgumentsT, ArgumentsBuilderT> {
+ return ParamBinding(name, paramGetter, argumentSetter)
+ }
+ }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java
deleted file mode 100644
index 9145141..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.task;
-
-import androidx.appactions.interaction.proto.CurrentValue;
-import androidx.appactions.interaction.proto.ParamValue;
-
-import com.google.auto.value.AutoOneOf;
-
-/**
- * Helper object to express if the grounding step of argument processing was successul for a single
- * ParamValue.
- */
-@AutoOneOf(AppGroundingResult.Kind.class)
-abstract class AppGroundingResult {
- static AppGroundingResult ofSuccess(ParamValue paramValue) {
- return AutoOneOf_AppGroundingResult.success(paramValue);
- }
-
- static AppGroundingResult ofFailure(CurrentValue currentValue) {
- return AutoOneOf_AppGroundingResult.failure(currentValue);
- }
-
- public abstract Kind getKind();
-
- abstract ParamValue success();
-
- abstract CurrentValue failure();
-
- enum Kind {
- SUCCESS,
- FAILURE
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt
new file mode 100644
index 0000000..f2463cd
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/AppGroundingResult.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.task
+
+import androidx.appactions.interaction.proto.CurrentValue
+import androidx.appactions.interaction.proto.ParamValue
+
+data class AppGroundingResult private constructor(
+ val kind: Kind,
+ val success: ParamValue?,
+ val failure: CurrentValue?
+) {
+ enum class Kind {
+ SUCCESS,
+ FAILURE
+ }
+
+ companion object {
+ @JvmStatic
+ fun ofSuccess(paramValue: ParamValue) = AppGroundingResult(Kind.SUCCESS, paramValue, null)
+
+ @JvmStatic
+ fun ofFailure(currentValue: CurrentValue) =
+ AppGroundingResult(Kind.FAILURE, null, currentValue)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/GenericResolverInternal.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/GenericResolverInternal.kt
index 591d9bb..32813dc 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/GenericResolverInternal.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/GenericResolverInternal.kt
@@ -94,20 +94,16 @@
paramValues: List<ParamValue>,
converter: ParamValueConverter<ValueTypeT>
): ValidationResult {
- val singularConverter = SlotTypeConverter.ofSingular(converter)
- val repeatedConverter = SlotTypeConverter.ofRepeated(converter)
+ val singularValue = SlotTypeConverter.ofSingular(converter).convert(paramValues)
+ val repeatedValues = SlotTypeConverter.ofRepeated(converter).convert(paramValues)
return invokeExternalSuspendBlock("onReceived") {
when {
- value != null -> value.onReceived(singularConverter.convert(paramValues))
- valueList != null -> valueList.onReceived(repeatedConverter.convert(paramValues))
- appEntity != null ->
- appEntity.onReceived(singularConverter.convert(paramValues))
- appEntityList != null ->
- appEntityList.onReceived(repeatedConverter.convert(paramValues))
- inventory != null ->
- inventory.onReceived(singularConverter.convert(paramValues))
- inventoryList != null ->
- inventoryList.onReceived(repeatedConverter.convert(paramValues))
+ value != null -> value.onReceived(singularValue)
+ valueList != null -> valueList.onReceived(repeatedValues)
+ appEntity != null -> appEntity.onReceived(singularValue)
+ appEntityList != null -> appEntityList.onReceived(repeatedValues)
+ inventory != null -> inventory.onReceived(singularValue)
+ inventoryList != null -> inventoryList.onReceived(repeatedValues)
else -> throw IllegalStateException("unreachable")
}
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListener.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListener.kt
new file mode 100644
index 0000000..ed30805
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListener.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.impl.task
+
+import androidx.annotation.RestrictTo
+import androidx.appactions.interaction.capabilities.core.ConfirmationOutput
+
+/**
+ * Generic onReadyToConfirm listener for a task capability.
+ * This should wrap only the external Session#onReadyToConfirm and nothing else.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface OnReadyToConfirmListener<ArgumentsT, ConfirmationT> {
+ /** onReadyToConfirm callback for a task session. */
+ suspend fun onReadyToConfirm(arguments: ArgumentsT): ConfirmationOutput<ConfirmationT>
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListenerInternal.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListenerInternal.kt
deleted file mode 100644
index e9adb16..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/OnReadyToConfirmListenerInternal.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.task
-
-import androidx.appactions.interaction.capabilities.core.ConfirmationOutput
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
-import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.MissingRequiredArgException
-import androidx.appactions.interaction.proto.ParamValue
-
-/**
- * Generic onReadyToConfirm listener for a task capability. This is the entry point to specific
- * onReadyToConfirm listeners. For example, Search/Update sub-BIIs factories may invoke specific
- * onReadyToConfirm listeners for that BII.
- */
-interface OnReadyToConfirmListenerInternal<ConfirmationT> {
- /** onReadyToConfirm callback for a task capability. */
- @Throws(StructConversionException::class, MissingRequiredArgException::class)
- suspend fun onReadyToConfirm(
- args: Map<String, List<ParamValue>>
- ): ConfirmationOutput<ConfirmationT>
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/SessionBridge.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/SessionBridge.kt
index 6242b6f8..a31759c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/SessionBridge.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/SessionBridge.kt
@@ -26,7 +26,10 @@
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun interface SessionBridge<
ExecutionSessionT,
+ ArgumentsT,
ConfirmationT
> {
- fun createTaskHandler(externalSession: ExecutionSessionT): TaskHandler<ConfirmationT>
+ fun createTaskHandler(
+ externalSession: ExecutionSessionT
+ ): TaskHandler<ArgumentsT, ConfirmationT>
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImpl.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImpl.kt
index fc9eeaf..4dee5fa 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImpl.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImpl.kt
@@ -46,7 +46,7 @@
private val actionSpec: ActionSpec<ArgumentsT, OutputT>,
private val property: Map<String, Property<*>>,
private val sessionFactory: (hostProperties: HostProperties?) -> ExecutionSessionT?,
- private val sessionBridge: SessionBridge<ExecutionSessionT, ConfirmationT>,
+ private val sessionBridge: SessionBridge<ExecutionSessionT, ArgumentsT, ConfirmationT>,
private val sessionUpdaterSupplier: Supplier<SessionUpdaterT>
) : Capability(id) {
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilitySession.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilitySession.kt
index 1f577f5..6ef8d2b 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilitySession.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilitySession.kt
@@ -41,7 +41,7 @@
override val sessionId: String,
actionSpec: ActionSpec<ArgumentsT, OutputT>,
appAction: AppAction,
- taskHandler: TaskHandler<ConfirmationT>,
+ taskHandler: TaskHandler<ArgumentsT, ConfirmationT>,
externalSession: BaseExecutionSession<ArgumentsT, OutputT>,
private val scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
) : CapabilitySession, TaskUpdateHandler {
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskHandler.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskHandler.kt
index 8b71429..9601c24 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskHandler.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskHandler.kt
@@ -29,28 +29,28 @@
/** Container of multi-turn Task related function references. */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-data class TaskHandler<ConfirmationT>
+data class TaskHandler<ArgumentsT, ConfirmationT>
internal constructor(
internal val taskParamMap: Map<String, TaskParamBinding<*>>,
internal val confirmationDataBindings: Map<String, (ConfirmationT) -> List<ParamValue>>,
- internal val onReadyToConfirmListener: OnReadyToConfirmListenerInternal<ConfirmationT>?,
+ internal val onReadyToConfirmListener: OnReadyToConfirmListener<ArgumentsT, ConfirmationT>?,
) {
- class Builder<ConfirmationT>() {
+ class Builder<ArgumentsT, ConfirmationT>() {
private val mutableTaskParamMap = mutableMapOf<String, TaskParamBinding<*>>()
private val confirmationDataBindings =
mutableMapOf<String, (ConfirmationT) -> List<ParamValue>>()
- private var onReadyToConfirmListener: OnReadyToConfirmListenerInternal<ConfirmationT>? =
+ private var onReadyToConfirmListener: OnReadyToConfirmListener<ArgumentsT, ConfirmationT>? =
null
fun <ValueTypeT> registerInventoryTaskParam(
paramName: String,
listener: InventoryListener<ValueTypeT>,
converter: ParamValueConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
- GROUND_IF_NO_IDENTIFIER,
+ GROUND_NEVER,
GenericResolverInternal.fromInventoryListener(listener),
converter,
null,
@@ -62,11 +62,11 @@
paramName: String,
listener: InventoryListListener<ValueTypeT>,
converter: ParamValueConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
- GROUND_IF_NO_IDENTIFIER,
+ GROUND_NEVER,
GenericResolverInternal.fromInventoryListListener(listener),
converter,
null,
@@ -80,7 +80,7 @@
converter: ParamValueConverter<ValueTypeT>,
entityConverter: EntityConverter<ValueTypeT>,
searchActionConverter: SearchActionConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
@@ -98,7 +98,7 @@
converter: ParamValueConverter<ValueTypeT>,
entityConverter: EntityConverter<ValueTypeT>,
searchActionConverter: SearchActionConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
@@ -114,7 +114,7 @@
paramName: String,
listener: ValueListener<ValueTypeT>,
converter: ParamValueConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
@@ -130,7 +130,7 @@
paramName: String,
listener: ValueListener<List<ValueTypeT>>,
converter: ParamValueConverter<ValueTypeT>,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
mutableTaskParamMap[paramName] =
TaskParamBinding(
paramName,
@@ -154,26 +154,25 @@
paramName: String,
confirmationGetter: (ConfirmationT) -> T?,
converter: (T) -> ParamValue,
- ): Builder<ConfirmationT> = apply {
+ ) = apply {
confirmationDataBindings[paramName] = { output: ConfirmationT ->
listOfNotNull(confirmationGetter(output)).map(converter)
}
}
- /** Sets the onReadyToConfirmListener for this capability. */
- fun setOnReadyToConfirmListenerInternal(
- onReadyToConfirmListener: OnReadyToConfirmListenerInternal<ConfirmationT>,
- ): Builder<ConfirmationT> = apply {
+ /** Sets the onReadyToConfirmListener for this session. */
+ fun setOnReadyToConfirmListener(
+ onReadyToConfirmListener: OnReadyToConfirmListener<ArgumentsT, ConfirmationT>,
+ ) = apply {
this.onReadyToConfirmListener = onReadyToConfirmListener
}
- fun build(): TaskHandler<ConfirmationT> {
- return TaskHandler(
- mutableTaskParamMap.toMap(),
- confirmationDataBindings,
- onReadyToConfirmListener,
- )
- }
+ fun build() = TaskHandler(
+ mutableTaskParamMap.toMap(),
+ confirmationDataBindings,
+ onReadyToConfirmListener,
+ )
+
companion object {
val GROUND_IF_NO_IDENTIFIER = { paramValue: ParamValue -> !paramValue.hasIdentifier() }
val GROUND_NEVER = { _: ParamValue -> false }
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
index 5b51ac3..3b4ca84 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskOrchestrator.kt
@@ -29,10 +29,10 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec
import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.InvalidResolverException
import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.MissingEntityConverterException
-import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.MissingRequiredArgException
import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.MissingSearchActionConverterException
import androidx.appactions.interaction.capabilities.core.impl.utils.CapabilityLogger
import androidx.appactions.interaction.capabilities.core.impl.utils.LoggerInternal
+import androidx.appactions.interaction.capabilities.core.impl.utils.handleExceptionFromRequestProcessing
import androidx.appactions.interaction.capabilities.core.impl.utils.invokeExternalBlock
import androidx.appactions.interaction.capabilities.core.impl.utils.invokeExternalSuspendBlock
import androidx.appactions.interaction.proto.AppActionsContext
@@ -60,7 +60,7 @@
private val sessionId: String,
private val actionSpec: ActionSpec<ArgumentsT, OutputT>,
private val appAction: AppActionsContext.AppAction,
- private val taskHandler: TaskHandler<ConfirmationT>,
+ private val taskHandler: TaskHandler<ArgumentsT, ConfirmationT>,
private val externalSession: BaseExecutionSession<ArgumentsT, OutputT>,
private val scope: CoroutineScope,
) {
@@ -181,27 +181,27 @@
) = withUiHandleRegistered {
val argumentsWrapper = assistantUpdateRequest.argumentsWrapper
val callback = assistantUpdateRequest.callbackInternal
- val fulfillmentResult: FulfillmentResult
- if (argumentsWrapper.requestMetadata == null) {
- fulfillmentResult = FulfillmentResult(ErrorStatusInternal.INVALID_REQUEST)
- } else {
- fulfillmentResult = when (argumentsWrapper.requestMetadata.requestType()) {
- FulfillmentRequest.Fulfillment.Type.UNRECOGNIZED,
- FulfillmentRequest.Fulfillment.Type.UNKNOWN_TYPE,
- ->
- FulfillmentResult(ErrorStatusInternal.INVALID_REQUEST)
-
+ try {
+ val fulfillmentResult: FulfillmentResult = when (
+ argumentsWrapper.requestMetadata?.requestType
+ ) {
FulfillmentRequest.Fulfillment.Type.SYNC -> handleSync(argumentsWrapper)
FulfillmentRequest.Fulfillment.Type.CONFIRM -> handleConfirm()
- FulfillmentRequest.Fulfillment.Type.CANCEL
- -> {
+ FulfillmentRequest.Fulfillment.Type.CANCEL -> {
terminate()
FulfillmentResult(FulfillmentResponse.getDefaultInstance())
}
else -> FulfillmentResult(ErrorStatusInternal.INVALID_REQUEST)
}
+ fulfillmentResult.applyToCallback(callback)
+ } catch (t: Throwable) {
+ LoggerInternal.log(
+ CapabilityLogger.LogLevel.ERROR,
+ LOG_TAG,
+ "Assistant request processing failed",
+ )
+ handleExceptionFromRequestProcessing(t, callback::onError)
}
- fulfillmentResult.applyToCallback(callback)
}
private suspend fun processTouchEventUpdateRequest(
@@ -248,15 +248,16 @@
}
} catch (t: Throwable) {
LoggerInternal.log(CapabilityLogger.LogLevel.ERROR, LOG_TAG, "Manual input fail")
- if (touchEventCallback != null) {
- touchEventCallback!!.onError(ErrorStatusInternal.TOUCH_EVENT_REQUEST_FAILURE)
- } else {
+ if (touchEventCallback == null) {
LoggerInternal.log(
CapabilityLogger.LogLevel.ERROR,
LOG_TAG,
"Manual input null callback",
)
}
+ handleExceptionFromRequestProcessing(t) {
+ touchEventCallback?.onError(it)
+ }
}
}
@@ -270,7 +271,7 @@
*
* Otherwise, the future contains a FulfillmentResponse containing BIC or BIO data.
*/
- @Throws(StructConversionException::class, MissingRequiredArgException::class)
+ @Throws(StructConversionException::class)
private suspend fun maybeConfirmOrExecute(): FulfillmentResponse {
val finalArguments = getCurrentAcceptedArguments()
if (
@@ -288,8 +289,9 @@
private fun maybeInitializeTask() {
if (status === Status.UNINITIATED) {
+ val sessionConfig = SessionConfig()
invokeExternalBlock("onCreate") {
- externalSession.onCreate(SessionConfig())
+ externalSession.onCreate(sessionConfig)
}
}
status = Status.IN_PROGRESS
@@ -302,18 +304,12 @@
* turn, so the logic should include onEnter, arg validation, and onExit.
*/
private suspend fun handleSync(argumentsWrapper: ArgumentsWrapper): FulfillmentResult {
- return try {
- maybeInitializeTask()
- clearMissingArgs(argumentsWrapper)
- processFulfillmentValues(argumentsWrapper.paramValues)
- val fulfillmentResponse = maybeConfirmOrExecute()
- LoggerInternal.log(CapabilityLogger.LogLevel.INFO, LOG_TAG, "Task sync success")
- FulfillmentResult(fulfillmentResponse)
- } catch (t: Throwable) {
- // TODO(b/276354491) implement fine-grained exception handling
- LoggerInternal.log(CapabilityLogger.LogLevel.ERROR, LOG_TAG, "Task sync fail", t)
- FulfillmentResult(ErrorStatusInternal.SYNC_REQUEST_FAILURE)
- }
+ maybeInitializeTask()
+ clearMissingArgs(argumentsWrapper)
+ processFulfillmentValues(argumentsWrapper.paramValues)
+ val fulfillmentResponse = maybeConfirmOrExecute()
+ LoggerInternal.log(CapabilityLogger.LogLevel.INFO, LOG_TAG, "Task sync success")
+ return FulfillmentResult(fulfillmentResponse)
}
/**
@@ -322,15 +318,9 @@
*/
private suspend fun handleConfirm(): FulfillmentResult {
val finalArguments = getCurrentAcceptedArguments()
- return try {
- val fulfillmentResponse = getFulfillmentResponseForExecution(finalArguments)
- LoggerInternal.log(CapabilityLogger.LogLevel.INFO, LOG_TAG, "Task confirm success")
- FulfillmentResult(fulfillmentResponse)
- } catch (t: Throwable) {
- // TODO(b/276354491) implement fine-grained exception handling
- LoggerInternal.log(CapabilityLogger.LogLevel.ERROR, LOG_TAG, "Task confirm fail")
- FulfillmentResult(ErrorStatusInternal.CONFIRMATION_REQUEST_FAILURE)
- }
+ val fulfillmentResponse = getFulfillmentResponseForExecution(finalArguments)
+ LoggerInternal.log(CapabilityLogger.LogLevel.INFO, LOG_TAG, "Task confirm success")
+ return FulfillmentResult(fulfillmentResponse)
}
private fun clearMissingArgs(assistantArgs: ArgumentsWrapper) {
@@ -351,7 +341,6 @@
* validation) are executed asynchronously.
*/
@Throws(
- MissingEntityConverterException::class,
MissingSearchActionConverterException::class,
StructConversionException::class,
InvalidResolverException::class,
@@ -457,12 +446,16 @@
}
}
- @Throws(StructConversionException::class, MissingRequiredArgException::class)
+ @Throws(StructConversionException::class)
private suspend fun getFulfillmentResponseForConfirmation(
finalArguments: Map<String, List<ParamValue>>,
): FulfillmentResponse {
+ val arguments = actionSpec.buildArguments(finalArguments)
+ requireNotNull(taskHandler.onReadyToConfirmListener) {
+ "caller must ensure TaskHandler.onReadyToConfirmListener is not null"
+ }
val result = invokeExternalSuspendBlock("onReadyToConfirm") {
- taskHandler.onReadyToConfirmListener!!.onReadyToConfirm(finalArguments)
+ taskHandler.onReadyToConfirmListener.onReadyToConfirm(arguments)
}
val fulfillmentResponse = FulfillmentResponse.newBuilder()
convertToConfirmationOutput(result)?.let { fulfillmentResponse.confirmationData = it }
@@ -473,8 +466,9 @@
private suspend fun getFulfillmentResponseForExecution(
finalArguments: Map<String, List<ParamValue>>,
): FulfillmentResponse {
+ val arguments = actionSpec.buildArguments(finalArguments)
val result = invokeExternalSuspendBlock("onExecute") {
- externalSession.onExecute(actionSpec.buildArguments(finalArguments))
+ externalSession.onExecute(arguments)
}
terminate()
val fulfillmentResponse =
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
index 1ab2990..fee2fd0 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessor.kt
@@ -25,7 +25,6 @@
import androidx.appactions.interaction.proto.CurrentValue
import androidx.appactions.interaction.proto.DisambiguationData
import androidx.appactions.interaction.proto.ParamValue
-import kotlin.IllegalStateException
import kotlin.String
import kotlin.Throws
@@ -114,7 +113,6 @@
)
}
AppGroundingResult.Kind.FAILURE -> AppGroundingResult.ofFailure(pendingValue)
- else -> throw IllegalStateException("unreachable")
}
/** enqueues processing of a pending value that requires app-driven grounding. */
@@ -132,7 +130,6 @@
when (groundingResult.kind) {
AppGroundingResult.Kind.SUCCESS -> ground(pendingValue.value, taskParamBinding)
AppGroundingResult.Kind.FAILURE -> AppGroundingResult.ofFailure(pendingValue)
- else -> throw IllegalStateException("unreachable")
}
/**
@@ -149,9 +146,8 @@
ungroundedValues: MutableList<CurrentValue>,
): AppGroundingResult {
when (groundingResult.kind) {
- AppGroundingResult.Kind.SUCCESS -> groundedValues.add(groundingResult.success())
- AppGroundingResult.Kind.FAILURE -> ungroundedValues.add(groundingResult.failure())
- else -> throw IllegalStateException("unreachable")
+ AppGroundingResult.Kind.SUCCESS -> groundedValues.add(groundingResult.success!!)
+ AppGroundingResult.Kind.FAILURE -> ungroundedValues.add(groundingResult.failure!!)
}
return groundingResult
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/DisambigStateException.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/DisambigStateException.java
index 9f06580..af225a1 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/DisambigStateException.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/DisambigStateException.java
@@ -17,13 +17,14 @@
package androidx.appactions.interaction.capabilities.core.impl.task.exceptions;
import androidx.annotation.NonNull;
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.InvalidRequestException;
/**
* Represents an internal issue with the state sync between the SDK and Assistant. One example is
* when the SDK places an argument in dismabig state, but then Assistant sends the same argument
* data again without any grounding.
*/
-public final class DisambigStateException extends Exception {
+public final class DisambigStateException extends InvalidRequestException {
public DisambigStateException(@NonNull String message) {
super(message);
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/InvalidResolverException.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/InvalidResolverException.java
index 543840c..e6f5328 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/InvalidResolverException.java
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/InvalidResolverException.java
@@ -20,8 +20,8 @@
/**
* Represents an internal issue with Resolvers, such as an "app-driven" method being invoked on a
- * "assistant-driven" resolver.
- */
+* "assistant-driven" resolver.
+*/
public final class InvalidResolverException extends Exception {
public InvalidResolverException(@NonNull String message) {
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/MissingRequiredArgException.java b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/MissingRequiredArgException.java
deleted file mode 100644
index 32b3fda..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/task/exceptions/MissingRequiredArgException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.impl.task.exceptions;
-
-import androidx.annotation.NonNull;
-
-/**
- * During the onExecuteListener handling, all required params should be present in the Map sent to
- * the listener. If they are not for some reason, this is an internal error.
- */
-public final class MissingRequiredArgException extends Exception {
-
- public MissingRequiredArgException(@NonNull String message) {
- super(message);
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/utils/CallbackUtils.kt b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/utils/CallbackUtils.kt
index 1811abd..4410f42 100644
--- a/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/utils/CallbackUtils.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/main/java/androidx/appactions/interaction/capabilities/core/impl/utils/CallbackUtils.kt
@@ -18,9 +18,14 @@
import androidx.appactions.interaction.capabilities.core.impl.ErrorStatusInternal
import androidx.appactions.interaction.capabilities.core.impl.exceptions.ExternalException
-import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
import androidx.appactions.interaction.capabilities.core.impl.exceptions.InvalidRequestException
+import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException
+import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.DisambigStateException
+import androidx.appactions.interaction.capabilities.core.impl.task.exceptions.InvalidResolverException
import kotlin.reflect.KClass
+import kotlinx.coroutines.withTimeout
+
+private const val LOG_TAG = "CallbackUtils"
/** invoke an externally implemented method, wrapping any exceptions with ExternalException.
*/
@@ -35,26 +40,33 @@
/** invoke an externally implemented suspend method, wrapping any exceptions with
* ExternalException.
*/
+
+private const val TIMEOUT_MILLIS = 3000L
internal suspend fun <T> invokeExternalSuspendBlock(
description: String,
block: suspend () -> T
): T {
- try {
- return block()
- } catch (t: Throwable) {
- throw ExternalException("exception occurred during '$description'", t)
+ return withTimeout(TIMEOUT_MILLIS) {
+ try {
+ block()
+ } catch (t: Throwable) {
+ throw ExternalException("exception occurred during '$description'", t)
+ }
}
}
/** Determines whether or not this exception is caused by some type, directly or indirectly. */
-internal fun <T : Throwable> Throwable.isCausedBy(clazz: KClass<T>): Boolean {
+private fun <T : Throwable> Throwable.isCausedBy(clazz: KClass<T>): Boolean {
if (clazz.isInstance(this)) {
return true
}
return this.cause?.isCausedBy(clazz) == true
}
-internal fun Throwable.toErrorStatusInternal(): ErrorStatusInternal {
+/**
+ * Returns an ErrorStatusInternal corresponding to this Throwable.
+ */
+private fun Throwable.toErrorStatusInternal(): ErrorStatusInternal {
return when {
this.isCausedBy(
ExternalException::class
@@ -63,8 +75,40 @@
StructConversionException::class
) -> ErrorStatusInternal.STRUCT_CONVERSION_FAILURE
this.isCausedBy(
+ InvalidResolverException::class
+ ) -> ErrorStatusInternal.INVALID_RESOLVER
+ this.isCausedBy(
+ DisambigStateException::class
+ ) -> ErrorStatusInternal.UNCHANGED_DISAMBIG_STATE
+ this.isCausedBy(
InvalidRequestException::class
) -> ErrorStatusInternal.INVALID_REQUEST
else -> ErrorStatusInternal.CANCELLED
}
+}
+
+/**
+ * Handles an exception encountered during request proessing (one-shot or multi-turn).
+ * Includes reporting an ErrorStatusInternal to some callback based on the exception.
+ */
+internal fun handleExceptionFromRequestProcessing(
+ t: Throwable,
+ errorCallback: (ErrorStatusInternal) -> Unit
+) {
+ LoggerInternal.log(
+ CapabilityLogger.LogLevel.ERROR,
+ LOG_TAG,
+ "exception encountered during request processing, this exception.",
+ t
+ )
+ errorCallback.invoke(t.toErrorStatusInternal())
+ if (!t.isCausedBy(InvalidRequestException::class)) {
+ LoggerInternal.log(
+ CapabilityLogger.LogLevel.ERROR,
+ LOG_TAG,
+ "Rethrowing exception because it is not caused by InvalidRequestException.",
+ t
+ )
+ throw t
+ }
}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/LibInfoTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/LibInfoTest.kt
index 8bed86d..f564983 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/LibInfoTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/LibInfoTest.kt
@@ -17,9 +17,7 @@
package androidx.appactions.interaction.capabilities.core
import androidx.appactions.interaction.capabilities.core.LibInfo.Version
-
import com.google.common.truth.Truth.assertThat
-
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
index a1513d9..322f1d7 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/SingleTurnCapabilityTest.kt
@@ -42,7 +42,6 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.proto.TaskInfo
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull
@@ -123,7 +122,7 @@
ExecutionCallback<Arguments, Output> {
ExecutionResult.Builder<Output>()
.setOutput(
- Output.builder().setOptionalStringField("stringOutput").build()
+ Output.Builder().setOptionalStringField("stringOutput").build()
)
.build()
}
@@ -305,7 +304,7 @@
// verify ExecutionCallback receives 1st request.
assertThat(argumentChannel.receive()).isEqualTo(
- Arguments.newBuilder().setOptionalStringField("string value 1").build()
+ Arguments.Builder().setOptionalStringField("string value 1").build()
)
// verify the 2nd request cannot be received due to mutex.
assertThat(withTimeoutOrNull(BLOCKING_TIMEOUT) { argumentChannel.receive() }).isNull()
@@ -317,7 +316,7 @@
)
assertThat(argumentChannel.receive()).isEqualTo(
- Arguments.newBuilder().setOptionalStringField("string value 2").build()
+ Arguments.Builder().setOptionalStringField("string value 2").build()
)
executionResultChannel.send(ExecutionResult.Builder<Output>().build())
assertThat(callbackInternal2.receiveResponse().fulfillmentResponse).isEqualTo(
@@ -327,31 +326,26 @@
companion object {
val ACTION_SPEC: ActionSpec<Arguments, Output> =
- ActionSpecBuilder.ofCapabilityNamed(
- "actions.intent.TEST"
- )
- .setArguments(Arguments::class.java, Arguments::newBuilder)
+ ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
+ .setArguments(Arguments::class.java, Arguments::Builder)
.setOutput(Output::class.java)
.bindParameter(
"requiredString",
- { properties -> properties["requiredEntity"] as Property<StringValue>? },
+ { properties -> properties["requiredEntity"] as Property<StringValue> },
Arguments.Builder::setRequiredStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER
)
- .bindOptionalParameter(
+ .bindParameter(
"optionalString",
{ properties ->
- properties["optionalString"]
- ?.let { it as Property<StringValue> }
- ?.let { Optional.of(it) }
- ?: Optional.ofNullable(null)
+ properties["optionalString"] as? Property<StringValue>
},
Arguments.Builder::setOptionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER
)
- .bindOptionalOutput(
+ .bindOutput(
"optionalStringOutput",
Output::optionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/FuturesTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/FuturesTest.kt
index 6d9de02..d0c26db 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/FuturesTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/FuturesTest.kt
@@ -21,13 +21,13 @@
import androidx.concurrent.futures.CallbackToFutureAdapter
import androidx.concurrent.futures.CallbackToFutureAdapter.Completer
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeUnit.MILLISECONDS
import kotlinx.coroutines.CompletableDeferred
import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.TimeUnit.MILLISECONDS
@RunWith(JUnit4::class)
class FuturesTest {
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/ListenableFutureHelperTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/ListenableFutureHelperTest.kt
index 310078e..9b7b0b91 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/ListenableFutureHelperTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/concurrent/ListenableFutureHelperTest.kt
@@ -17,6 +17,8 @@
package androidx.appactions.interaction.capabilities.core.impl.concurrent
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.cancellation.CancellationException
+import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.SendChannel
@@ -25,8 +27,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.coroutines.cancellation.CancellationException
-import kotlin.time.Duration.Companion.seconds
@RunWith(JUnit4::class)
class ListenableFutureHelperTest {
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
index a6615bf..291bcb0 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/converters/TypeSpecImplTest.java
@@ -24,6 +24,7 @@
import androidx.appactions.builtintypes.experimental.types.Thing;
import androidx.appactions.interaction.capabilities.core.impl.exceptions.StructConversionException;
import androidx.appactions.interaction.capabilities.core.testing.spec.TestEntity;
+import androidx.appactions.interaction.capabilities.core.testing.spec.TestEnum;
import androidx.appactions.interaction.protobuf.Struct;
import androidx.appactions.interaction.protobuf.Value;
@@ -45,27 +46,29 @@
@Test
public void bindIdentifier_success() {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindIdentifier(TestEntity::getId)
.build();
assertThat(
entityTypeSpec.getIdentifier(
- TestEntity.newBuilder().setId("identifier1").build()))
+ new TestEntity.Builder().setId("identifier1").build()))
.isEqualTo("identifier1");
- assertThat(entityTypeSpec.getIdentifier(TestEntity.newBuilder().build())).isNull();
+ assertThat(entityTypeSpec.getIdentifier(new TestEntity.Builder().build())).isNull();
}
@Test
public void bindEnumField_convertsSuccessfully() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindEnumField(
"enum",
TestEntity::getEnum,
TestEntity.Builder::setEnum,
- TestEntity.TestEnum.class)
+ TestEnum.class)
.build();
- TestEntity entity = TestEntity.newBuilder().setEnum(TestEntity.TestEnum.VALUE_1).build();
+ TestEntity entity = new TestEntity.Builder().setEnum(TestEnum.VALUE_1).build();
Value entityValue =
structToValue(
Struct.newBuilder()
@@ -74,7 +77,7 @@
Value.newBuilder().setStringValue("TestEntity").build())
.putFields(
"enum",
- Value.newBuilder().setStringValue("value_1").build())
+ Value.newBuilder().setStringValue("VALUE_1").build())
.build());
assertThat(entityTypeSpec.toValue(entity)).isEqualTo(entityValue);
@@ -84,12 +87,13 @@
@Test
public void bindEnumField_throwsException() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindEnumField(
"enum",
TestEntity::getEnum,
TestEntity.Builder::setEnum,
- TestEntity.TestEnum.class)
+ TestEnum.class)
.build();
Value malformedValue =
structToValue(
@@ -109,13 +113,14 @@
@Test
public void bindDurationField_convertsSuccessfully() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindDurationField(
"duration",
TestEntity::getDuration,
TestEntity.Builder::setDuration)
.build();
- TestEntity entity = TestEntity.newBuilder().setDuration(Duration.ofMinutes(5)).build();
+ TestEntity entity = new TestEntity.Builder().setDuration(Duration.ofMinutes(5)).build();
Value entityValue =
structToValue(
Struct.newBuilder()
@@ -134,14 +139,15 @@
@Test
public void bindZonedDateTimeField_convertsSuccessfully() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindZonedDateTimeField(
"date",
TestEntity::getZonedDateTime,
TestEntity.Builder::setZonedDateTime)
.build();
TestEntity entity =
- TestEntity.newBuilder()
+ new TestEntity.Builder()
.setZonedDateTime(ZonedDateTime.of(2022, 1, 1, 8, 0, 0, 0, ZoneOffset.UTC))
.build();
Value entityValue =
@@ -164,14 +170,15 @@
@Test
public void bindZonedDateTimeField_zoneId_convertsSuccessfully() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindZonedDateTimeField(
"date",
TestEntity::getZonedDateTime,
TestEntity.Builder::setZonedDateTime)
.build();
TestEntity entity =
- TestEntity.newBuilder()
+ new TestEntity.Builder()
.setZonedDateTime(
ZonedDateTime.of(2022, 1, 1, 8, 0, 0, 0, ZoneId.of("UTC+01:00")))
.build();
@@ -188,7 +195,7 @@
.build())
.build());
TestEntity expectedEntity =
- TestEntity.newBuilder()
+ new TestEntity.Builder()
.setZonedDateTime(
ZonedDateTime.of(2022, 1, 1, 8, 0, 0, 0, ZoneOffset.of("+01:00")))
.build();
@@ -200,7 +207,8 @@
@Test
public void bindZonedDateTimeField_throwsException() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindZonedDateTimeField(
"date",
TestEntity::getZonedDateTime,
@@ -224,12 +232,16 @@
@Test
public void bindSpecField_convertsSuccessfully() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindSpecField(
"entity",
TestEntity::getEntity,
TestEntity.Builder::setEntity,
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity",
+ TestEntity.Builder::new,
+ TestEntity.Builder::build)
.bindStringField(
"name",
TestEntity::getName,
@@ -237,8 +249,8 @@
.build())
.build();
TestEntity entity =
- TestEntity.newBuilder()
- .setEntity(TestEntity.newBuilder().setName("entity name").build())
+ new TestEntity.Builder()
+ .setEntity(new TestEntity.Builder().setName("entity name").build())
.build();
Value entityValue = structToValue(
Struct.newBuilder()
@@ -274,12 +286,16 @@
@Test
public void bindSpecField_throwsException() throws Exception {
TypeSpec<TestEntity> entityTypeSpec =
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity", TestEntity.Builder::new, TestEntity.Builder::build)
.bindSpecField(
"entity",
TestEntity::getEntity,
TestEntity.Builder::setEntity,
- TypeSpecBuilder.newBuilder("TestEntity", TestEntity::newBuilder)
+ TypeSpecBuilder.newBuilder(
+ "TestEntity",
+ TestEntity.Builder::new,
+ TestEntity.Builder::build)
.bindStringField(
"name",
TestEntity::getName,
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
index 6b7243a..899825f 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/spec/ActionSpecTest.java
@@ -19,20 +19,22 @@
import static com.google.common.truth.Truth.assertThat;
import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter;
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter;
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters;
import androidx.appactions.interaction.capabilities.core.properties.Property;
import androidx.appactions.interaction.capabilities.core.properties.StringValue;
+import androidx.appactions.interaction.capabilities.core.testing.spec.Arguments;
+import androidx.appactions.interaction.capabilities.core.testing.spec.GenericEntityArguments;
import androidx.appactions.interaction.capabilities.core.testing.spec.Output;
+import androidx.appactions.interaction.capabilities.core.testing.spec.TestEntity;
import androidx.appactions.interaction.proto.AppActionsContext.AppAction;
import androidx.appactions.interaction.proto.AppActionsContext.IntentParameter;
import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput;
import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput.OutputValue;
import androidx.appactions.interaction.proto.ParamValue;
-
-import com.google.auto.value.AutoValue;
+import androidx.appactions.interaction.protobuf.Struct;
+import androidx.appactions.interaction.protobuf.Value;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -41,32 +43,31 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
@RunWith(JUnit4.class)
@SuppressWarnings("unchecked")
public final class ActionSpecTest {
private static final ActionSpec<Arguments, Output> ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
- .setArguments(Arguments.class, Arguments::newBuilder)
+ ActionSpecBuilder.Companion.ofCapabilityNamed("actions.intent.TEST")
+ .setArguments(Arguments.class, Arguments.Builder::new)
.setOutput(Output.class)
.bindParameter(
"requiredString",
properties ->
{
- return (Property<StringValue>) (properties.get(
- "requiredString"));
+ Property<?> property = properties.get("requiredString");
+ return (property == null) ? null : (Property<StringValue>) property;
},
Arguments.Builder::setRequiredStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
- .bindOptionalParameter(
+ .bindParameter(
"optionalString",
properties ->
{
- return Optional.ofNullable((Property<StringValue>) (properties.get(
- "optionalString")));
+ Property<?> property = properties.get("optionalString");
+ return (property == null) ? null : (Property<StringValue>) property;
},
Arguments.Builder::setOptionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
@@ -75,95 +76,108 @@
"repeatedString",
properties ->
{
- return Optional.ofNullable((Property<StringValue>) (properties.get(
- "repeatedString")));
+ Property<?> property = properties.get("repeatedString");
+ return (property == null) ? null : (Property<StringValue>) property;
},
Arguments.Builder::setRepeatedStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
- .bindOptionalOutput(
+ .bindOutput(
"optionalStringOutput",
- Output::optionalStringField,
+ Output::getOptionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue)
.bindRepeatedOutput(
"repeatedStringOutput",
- Output::repeatedStringField,
+ Output::getRepeatedStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue)
.build();
- private static final ParamValueConverter<String> STRING_PARAM_VALUE_CONVERTER =
- new ParamValueConverter<String>() {
+ private static final ParamValueConverter<TestEntity> TEST_ENTITY_PARAM_VALUE_CONVERTER =
+ new ParamValueConverter<TestEntity>() {
@NonNull
@Override
- public ParamValue toParamValue(String type) {
- return ParamValue.newBuilder().setStringValue(type).build();
+ public ParamValue toParamValue(TestEntity type) {
+ return ParamValue.newBuilder()
+ .setStructValue(
+ Struct.newBuilder()
+ .putFields(
+ "name",
+ Value.newBuilder()
+ .setStringValue(type.getName())
+ .build())
+ .build())
+ .build();
}
@Override
- public String fromParamValue(@NonNull ParamValue paramValue) {
- return "test";
+ public TestEntity fromParamValue(@NonNull ParamValue paramValue) {
+ String name =
+ paramValue.getStructValue().getFieldsOrThrow("name").getStringValue();
+ return new TestEntity.Builder().setName(name).build();
}
};
- private static final EntityConverter<String> STRING_ENTITY_CONVERTER =
- (theString) ->
+ private static final EntityConverter<TestEntity> TEST_ENTITY_CONVERTER =
+ (testEntity) ->
androidx.appactions.interaction.proto.Entity.newBuilder()
- .setIdentifier(theString)
- .setName(theString)
+ .setIdentifier(testEntity.getId())
+ .setName(testEntity.getName())
.build();
- private static final ActionSpec<GenericEntityArguments, Output>
- GENERIC_TYPES_ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed("actions.intent.TEST")
- .setArguments(GenericEntityArguments.class,
- GenericEntityArguments::newBuilder)
+ private static final ActionSpec<GenericEntityArguments, Output> GENERIC_TYPES_ACTION_SPEC =
+ ActionSpecBuilder.Companion.ofCapabilityNamed("actions.intent.TEST")
+ .setArguments(GenericEntityArguments.class, GenericEntityArguments.Builder::new)
.setOutput(Output.class)
.bindParameter(
"requiredEntity",
- properties ->
- {
- return (Property<String>) (properties.get(
- "requiredEntity"));
+ properties -> {
+ Property<?> property = properties.get("requiredEntity");
+ return (property == null) ? null : (Property<TestEntity>) property;
},
GenericEntityArguments.Builder::setSingularField,
- STRING_PARAM_VALUE_CONVERTER,
- STRING_ENTITY_CONVERTER)
- .bindOptionalParameter("optionalEntity",
- properties ->
- {
- return Optional.of((Property<String>) (properties.get(
- "optionalEntity")));
+ TEST_ENTITY_PARAM_VALUE_CONVERTER,
+ TEST_ENTITY_CONVERTER)
+ .bindParameter(
+ "optionalEntity",
+ properties -> {
+ Property<?> property = properties.get("optionalEntity");
+ return (property == null) ? null : (Property<TestEntity>) property;
},
GenericEntityArguments.Builder::setOptionalField,
- STRING_PARAM_VALUE_CONVERTER,
- STRING_ENTITY_CONVERTER)
- .bindRepeatedParameter("repeatedEntities",
- properties ->
- {
- return Optional.of((Property<String>) (properties.get(
- "repeatedEntities")));
+ TEST_ENTITY_PARAM_VALUE_CONVERTER,
+ TEST_ENTITY_CONVERTER)
+ .bindRepeatedParameter(
+ "repeatedEntities",
+ properties -> {
+ Property<?> property = properties.get("repeatedEntities");
+ return (property == null) ? null : (Property<TestEntity>) property;
},
GenericEntityArguments.Builder::setRepeatedField,
- STRING_PARAM_VALUE_CONVERTER,
- STRING_ENTITY_CONVERTER)
+ TEST_ENTITY_PARAM_VALUE_CONVERTER,
+ TEST_ENTITY_CONVERTER)
.build();
@Test
public void getAppAction_genericParameters() {
Map<String, Property<?>> property = new HashMap<>();
- property.put("requiredEntity",
- new Property.Builder<String>()
+ property.put(
+ "requiredEntity",
+ new Property.Builder<TestEntity>()
.setRequired(true)
- .setPossibleValues("one")
+ .setPossibleValues(
+ new TestEntity.Builder().setId("one").setName("one").build())
.build());
- property.put("optionalEntity",
- new Property.Builder<String>()
+ property.put(
+ "optionalEntity",
+ new Property.Builder<TestEntity>()
.setRequired(true)
- .setPossibleValues("two")
- .build()
- );
- property.put("repeatedEntities",
- new Property.Builder<String>()
+ .setPossibleValues(
+ new TestEntity.Builder().setId("two").setName("two").build())
+ .build());
+ property.put(
+ "repeatedEntities",
+ new Property.Builder<TestEntity>()
.setRequired(true)
- .setPossibleValues("three")
+ .setPossibleValues(
+ new TestEntity.Builder().setId("three").setName("three").build())
.build());
assertThat(GENERIC_TYPES_ACTION_SPEC.convertPropertyToProto(property))
@@ -264,7 +278,7 @@
@Test
public void convertOutputToProto_string() {
Output output =
- Output.builder()
+ new Output.Builder()
.setOptionalStringField("test2")
.setRepeatedStringField(List.of("test3", "test4"))
.build();
@@ -301,7 +315,8 @@
@Test
public void convertOutputToProto_emptyOutput() {
- Output output = Output.builder().setRepeatedStringField(List.of("test3", "test4")).build();
+ Output output =
+ new Output.Builder().setRepeatedStringField(List.of("test3", "test4")).build();
// No optionalStringOutput since it is not in the output above.
StructuredOutput expectedExecutionOutput =
StructuredOutput.newBuilder()
@@ -324,116 +339,4 @@
assertThat(executionOutput.getOutputValuesList())
.containsExactlyElementsIn(expectedExecutionOutput.getOutputValuesList());
}
-
- enum TestEnum {
- VALUE_1,
- VALUE_2,
- }
-
- @AutoValue
- abstract static class Arguments {
-
- static Builder newBuilder() {
- return new AutoValue_ActionSpecTest_Arguments.Builder();
- }
-
- abstract String requiredStringField();
-
- abstract String optionalStringField();
-
- abstract List<String> repeatedStringField();
-
- @AutoValue.Builder
- abstract static class Builder implements BuilderOf<Arguments> {
-
- abstract Builder setRequiredStringField(String value);
-
- abstract Builder setOptionalStringField(String value);
-
- abstract Builder setRepeatedStringField(List<String> repeated);
-
- @NonNull
- @Override
- public abstract Arguments build();
- }
- }
-
- @AutoValue
- abstract static class Properties {
-
- static Properties create(
- Optional<Property<TestEnum>> optionalEnumField,
- Property<StringValue> requiredStringField,
- Optional<Property<StringValue>> optionalStringField,
- Optional<Property<StringValue>> repeatedStringField) {
- return new AutoValue_ActionSpecTest_Properties(
- optionalEnumField,
- requiredStringField,
- optionalStringField,
- repeatedStringField);
- }
-
- static Properties create(
- Property<StringValue> requiredStringField) {
- return create(
- Optional.empty(),
- requiredStringField,
- Optional.empty(),
- Optional.empty());
- }
-
- abstract Optional<Property<TestEnum>> optionalEnumField();
-
- abstract Property<StringValue> requiredStringField();
-
- abstract Optional<Property<StringValue>> optionalStringField();
-
- abstract Optional<Property<StringValue>> repeatedStringField();
- }
-
- @AutoValue
- abstract static class GenericEntityArguments {
-
- static Builder newBuilder() {
- return new AutoValue_ActionSpecTest_GenericEntityArguments.Builder();
- }
-
- abstract String singularField();
-
- abstract String optionalField();
-
- abstract List<String> repeatedField();
-
- @AutoValue.Builder
- abstract static class Builder implements BuilderOf<GenericEntityArguments> {
-
- abstract Builder setSingularField(String value);
-
- abstract Builder setOptionalField(String value);
-
- abstract Builder setRepeatedField(List<String> value);
-
- @NonNull
- @Override
- public abstract GenericEntityArguments build();
- }
- }
-
- @AutoValue
- abstract static class GenericEntityProperty {
-
- static GenericEntityProperty create(
- Property<String> singularField,
- Optional<Property<String>> optionalField,
- Optional<Property<String>> repeatedField) {
- return new AutoValue_ActionSpecTest_GenericEntityProperty(
- singularField, optionalField, repeatedField);
- }
-
- abstract Property<String> singularField();
-
- abstract Optional<Property<String>> optionalField();
-
- abstract Optional<Property<String>> repeatedField();
- }
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImplTest.kt
similarity index 82%
rename from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
rename to appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImplTest.kt
index 18c1cab..bcd5ef1 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityImplTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityImplTest.kt
@@ -58,8 +58,8 @@
import androidx.appactions.interaction.proto.CurrentValue
import androidx.appactions.interaction.proto.DisambiguationData
import androidx.appactions.interaction.proto.Entity
-import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type.CANCEL
import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type
+import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type.CANCEL
import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type.SYNC
import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type.UNKNOWN_TYPE
import androidx.appactions.interaction.proto.FulfillmentResponse.StructuredOutput
@@ -70,7 +70,6 @@
import androidx.concurrent.futures.CallbackToFutureAdapter.Completer
import com.google.common.truth.Truth.assertThat
import com.google.common.util.concurrent.ListenableFuture
-import java.util.Optional
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Supplier
@@ -93,7 +92,7 @@
Futures.immediateFuture(ExecutionResult.Builder<Output>().build())
}
},
- sessionBridge = { TaskHandler.Builder<Confirmation>().build() },
+ sessionBridge = { TaskHandler.Builder<Arguments, Confirmation>().build() },
sessionUpdaterSupplier = ::EmptyTaskUpdater
)
private val hostProperties: HostProperties =
@@ -139,7 +138,7 @@
Futures.immediateFuture(ExecutionResult.Builder<Output>().build())
}
},
- sessionBridge = { TaskHandler.Builder<Confirmation>().build() },
+ sessionBridge = { TaskHandler.Builder<Arguments, Confirmation>().build() },
sessionUpdaterSupplier = ::EmptyTaskUpdater
)
mutableEntityList.add(StringValue.of("entity1"))
@@ -186,7 +185,7 @@
createCapability(
SINGLE_REQUIRED_FIELD_PROPERTY,
{ externalSession },
- { TaskHandler.Builder<Confirmation>().build() },
+ { TaskHandler.Builder<Arguments, Confirmation>().build() },
::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
@@ -201,7 +200,8 @@
createCapability(
SINGLE_REQUIRED_FIELD_PROPERTY,
sessionFactory =
- { _ -> object : ExecutionSession {
+ { _ ->
+ object : ExecutionSession {
override fun onCreate(sessionConfig: SessionConfig) {
onCreateInvocationCount.incrementAndGet()
}
@@ -210,8 +210,11 @@
Futures.immediateFuture(
ExecutionResult.Builder<Output>().build()
)
- } },
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
+ }
+ },
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
sessionUpdaterSupplier = ::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
@@ -288,7 +291,9 @@
val capability: Capability = createCapability(
SINGLE_REQUIRED_FIELD_PROPERTY,
sessionFactory = { _ -> externalSession },
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
sessionUpdaterSupplier = ::RequiredTaskUpdater
)
val session = capability.createSession("mySessionId", hostProperties)
@@ -326,7 +331,9 @@
)
}
},
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
sessionUpdaterSupplier = ::RequiredTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
@@ -360,20 +367,27 @@
.build(),
"stringSlotB" to Property.Builder<StringValue>()
.setRequired(true)
- .build(),
+ .build()
)
val sessionFactory:
- (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
+ (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
{ _ ->
object : CapabilityTwoStrings.ExecutionSession {
override suspend fun onExecute(
arguments: CapabilityTwoStrings.Arguments
- ): ExecutionResult<Void> = ExecutionResult.Builder<Void>().build()
+ ): ExecutionResult<CapabilityTwoStrings.Output> =
+ ExecutionResult.Builder<CapabilityTwoStrings.Output>().build()
}
}
val sessionBridge =
- SessionBridge<CapabilityTwoStrings.ExecutionSession, Void> {
- TaskHandler.Builder<Void>()
+ SessionBridge<
+ CapabilityTwoStrings.ExecutionSession,
+ CapabilityTwoStrings.Arguments,
+ CapabilityTwoStrings.Confirmation> {
+ TaskHandler.Builder<
+ CapabilityTwoStrings.Arguments,
+ CapabilityTwoStrings.Confirmation
+ >()
.registerValueTaskParam(
"stringSlotA",
AUTO_ACCEPT_STRING_VALUE,
@@ -446,23 +460,29 @@
.build(),
"stringSlotB" to Property.Builder<StringValue>()
.setRequired(false)
- .build(),
+ .build()
)
val sessionFactory:
- (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
+ (hostProperties: HostProperties?) -> CapabilityTwoStrings.ExecutionSession =
{ _ ->
object : CapabilityTwoStrings.ExecutionSession {
override suspend fun onExecute(
arguments: CapabilityTwoStrings.Arguments
- ): ExecutionResult<Void> {
+ ): ExecutionResult<CapabilityTwoStrings.Output> {
onExecuteInvocationCount.incrementAndGet()
- return ExecutionResult.Builder<Void>().build()
+ return ExecutionResult.Builder<CapabilityTwoStrings.Output>().build()
}
}
}
val sessionBridge =
- SessionBridge<CapabilityTwoStrings.ExecutionSession, Void> {
- TaskHandler.Builder<Void>()
+ SessionBridge<
+ CapabilityTwoStrings.ExecutionSession,
+ CapabilityTwoStrings.Arguments,
+ CapabilityTwoStrings.Confirmation> {
+ TaskHandler.Builder<
+ CapabilityTwoStrings.Arguments,
+ CapabilityTwoStrings.Confirmation
+ >()
.registerValueTaskParam(
"stringSlotA",
AUTO_ACCEPT_STRING_VALUE,
@@ -531,13 +551,15 @@
"optionalEnum" to Property.Builder<TestEnum>()
.setPossibleValues(TestEnum.VALUE_1, TestEnum.VALUE_2)
.setRequired(true)
- .build(),
+ .build()
)
val capability: Capability =
createCapability(
property,
sessionFactory = { _ -> ExecutionSession.DEFAULT },
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
sessionUpdaterSupplier = ::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
@@ -593,7 +615,7 @@
override suspend fun onExecute(arguments: Arguments) =
ExecutionResult.Builder<Output>().build()
- override fun getRequiredStringListener() =
+ override val requiredStringListener =
object : AppEntityListener<String> {
override fun lookupAndRenderAsync(
searchAction: SearchAction<String>
@@ -615,18 +637,18 @@
}
},
sessionBridge =
- SessionBridge<ExecutionSession, Confirmation> { session ->
- val builder = TaskHandler.Builder<Confirmation>()
- session.getRequiredStringListener()
- ?.let { listener: AppEntityListener<String> ->
- builder.registerAppEntityTaskParam(
- "required",
- listener,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
- getTrivialSearchActionConverter()
- )
- }
+ SessionBridge<ExecutionSession, Arguments, Confirmation> { session ->
+ val builder = TaskHandler.Builder<Arguments, Confirmation>()
+ session.requiredStringListener?.let {
+ listener: AppEntityListener<String> ->
+ builder.registerAppEntityTaskParam(
+ "required",
+ listener,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
+ getTrivialSearchActionConverter()
+ )
+ }
builder.build()
},
sessionUpdaterSupplier = ::EmptyTaskUpdater
@@ -720,13 +742,13 @@
fun identifierOnly_refillsStruct() = runBlocking<Unit> {
val property = mapOf(
"listItem" to Property.Builder<
- ListItem,
+ ListItem
>()
.setRequired(true)
.build(),
"anyString" to Property.Builder<StringValue>()
.setRequired(true)
- .build(),
+ .build()
)
val item1: ListItem = ListItem.Builder().setName("red apple").setIdentifier("item1").build()
val item2: ListItem =
@@ -736,20 +758,18 @@
val onExecuteStringDeferred = CompletableDeferred<String>()
val sessionFactory:
- (hostProperties: HostProperties?) -> CapabilityStructFill.ExecutionSession =
+ (hostProperties: HostProperties?) -> CapabilityStructFill.ExecutionSession =
{ _ ->
object : CapabilityStructFill.ExecutionSession {
override suspend fun onExecute(
arguments: CapabilityStructFill.Arguments
- ): ExecutionResult<Void> {
- val listItem: ListItem = arguments.listItem().orElse(null)
- val string: String = arguments.anyString().orElse(null)
- onExecuteListItemDeferred.complete(listItem)
- onExecuteStringDeferred.complete(string)
- return ExecutionResult.Builder<Void>().build()
+ ): ExecutionResult<CapabilityStructFill.Output> {
+ arguments.listItem?.let { onExecuteListItemDeferred.complete(it) }
+ arguments.anyString?.let { onExecuteStringDeferred.complete(it) }
+ return ExecutionResult.Builder<CapabilityStructFill.Output>().build()
}
- override fun getListItemListener() =
+ override val listItemListener =
object : AppEntityListener<ListItem> {
override fun onReceivedAsync(
value: ListItem
@@ -771,8 +791,14 @@
}
}
val sessionBridge =
- SessionBridge<CapabilityStructFill.ExecutionSession, Void> { session ->
- TaskHandler.Builder<Void>()
+ SessionBridge<
+ CapabilityStructFill.ExecutionSession,
+ CapabilityStructFill.Arguments,
+ CapabilityStructFill.Confirmation> { session ->
+ TaskHandler.Builder<
+ CapabilityStructFill.Arguments,
+ CapabilityStructFill.Confirmation
+ >()
.registerAppEntityTaskParam(
"listItem",
session.listItemListener,
@@ -878,7 +904,7 @@
override suspend fun onExecute(arguments: Arguments) =
ExecutionResult.Builder<Output>()
.setOutput(
- Output.builder()
+ Output.Builder()
.setOptionalStringField("bar")
.setRepeatedStringField(
listOf("bar1", "bar2")
@@ -977,8 +1003,10 @@
createCapability(
property,
sessionFactory = sessionFactory,
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
- sessionUpdaterSupplier = ::EmptyTaskUpdater,
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
+ sessionUpdaterSupplier = ::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
@@ -986,7 +1014,7 @@
val callback = FakeCallbackInternal()
session.execute(
buildRequestArgs(SYNC),
- callback,
+ callback
)
assertThat(callback.receiveResponse()).isNotNull()
assertThat(getCurrentValues("required", session.state!!)).isEmpty()
@@ -995,11 +1023,12 @@
// TURN 2. Providing the required slots so that the task completes and the state gets cleared
val callback2 = FakeCallbackInternal()
session.execute(
- buildRequestArgs(SYNC,
+ buildRequestArgs(
+ SYNC,
"required",
ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
),
- callback2,
+ callback2
)
assertThat(callback2.receiveResponse().fulfillmentResponse).isNotNull()
assertThat(session.isActive).isEqualTo(false)
@@ -1017,13 +1046,15 @@
}
}
var onReadyToConfirm =
- object : OnReadyToConfirmListenerInternal<Confirmation> {
- override suspend fun onReadyToConfirm(args: Map<String, List<ParamValue>>):
+ object : OnReadyToConfirmListener<Arguments, Confirmation> {
+ override suspend fun onReadyToConfirm(arguments: Arguments):
ConfirmationOutput<Confirmation> {
return ConfirmationOutput.Builder<Confirmation>()
- .setConfirmation(Confirmation.builder().setOptionalStringField("bar")
- .build())
- .build()
+ .setConfirmation(
+ Confirmation.Builder().setOptionalStringField("bar")
+ .build()
+ )
+ .build()
}
}
val property = mapOf(
@@ -1034,21 +1065,23 @@
property,
sessionFactory = sessionFactory,
sessionBridge = SessionBridge {
- TaskHandler.Builder<Confirmation>()
- .setOnReadyToConfirmListenerInternal(onReadyToConfirm)
- .build() },
- sessionUpdaterSupplier = ::EmptyTaskUpdater,
+ TaskHandler.Builder<Arguments, Confirmation>()
+ .setOnReadyToConfirmListener(onReadyToConfirm)
+ .build()
+ },
+ sessionUpdaterSupplier = ::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
// TURN 1. Providing all the required slots in the SYNC Request
val callback = FakeCallbackInternal()
session.execute(
- buildRequestArgs(SYNC,
+ buildRequestArgs(
+ SYNC,
"required",
ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
),
- callback,
+ callback
)
assertThat(callback.receiveResponse()).isNotNull()
assertThat(session.isActive).isEqualTo(true)
@@ -1081,19 +1114,22 @@
createCapability(
property,
sessionFactory = sessionFactory,
- sessionBridge = SessionBridge { TaskHandler.Builder<Confirmation>().build() },
- sessionUpdaterSupplier = ::EmptyTaskUpdater,
+ sessionBridge = SessionBridge {
+ TaskHandler.Builder<Arguments, Confirmation>().build()
+ },
+ sessionUpdaterSupplier = ::EmptyTaskUpdater
)
val session = capability.createSession(fakeSessionId, hostProperties)
// TURN 1. Providing the required slots so that the task completes and the state gets cleared
val callback = FakeCallbackInternal()
session.execute(
- buildRequestArgs(SYNC,
+ buildRequestArgs(
+ SYNC,
"required",
ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
),
- callback,
+ callback
)
assertThat(callback.receiveResponse().fulfillmentResponse).isNotNull()
assertThat(session.isActive).isEqualTo(false)
@@ -1101,17 +1137,111 @@
// TURN 2. Trying to sync after the session is destroyed
val callback2 = FakeCallbackInternal()
session.execute(
- buildRequestArgs(SYNC,
+ buildRequestArgs(
+ SYNC,
"required",
ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
),
- callback2,
+ callback2
)
assertThat(session.isActive).isEqualTo(false)
assertThat(callback2.receiveResponse().errorStatus)
.isEqualTo(ErrorStatusInternal.SESSION_ALREADY_DESTROYED)
}
+ @Test
+ fun structConversionException_shouldReportStructConversionFailure() {
+ val sessionFactory: (hostProperties: HostProperties?) -> ExecutionSession =
+ { _ ->
+ object : ExecutionSession {
+ override val requiredStringListener = object : AppEntityListener<String> {
+ override fun lookupAndRenderAsync(
+ searchAction: SearchAction<String>
+ ): ListenableFuture<EntitySearchResult<String>> {
+ return Futures.immediateFuture(
+ EntitySearchResult.Builder<String>().build()
+ )
+ }
+
+ override fun onReceivedAsync(
+ value: String
+ ): ListenableFuture<ValidationResult> {
+ return Futures.immediateFuture(ValidationResult.newAccepted())
+ }
+ }
+ override suspend fun onExecute(arguments: Arguments) =
+ ExecutionResult.Builder<Output>()
+ .setShouldStartDictation(true)
+ .build()
+ }
+ }
+ val capability = CapabilityBuilder()
+ .setId("fakeId")
+ .setExecutionSessionFactory(sessionFactory)
+ .build()
+ val session = capability.createSession(fakeSessionId, hostProperties)
+ val callback = FakeCallbackInternal()
+
+ session.execute(
+ buildRequestArgs(
+ SYNC,
+ "required",
+ // this ParamValue can't be parsed as String, and causes StructConversionException
+ ParamValue.newBuilder().setIdentifier("foo").setBoolValue(false).build()
+ ),
+ callback
+ )
+
+ assertThat(
+ callback.receiveResponse().errorStatus
+ ).isEqualTo(ErrorStatusInternal.STRUCT_CONVERSION_FAILURE)
+ }
+
+ @Test
+ fun slotListenerException_shouldReportExternalException() {
+ val sessionFactory: (hostProperties: HostProperties?) -> ExecutionSession =
+ { _ ->
+ object : ExecutionSession {
+ override val requiredStringListener = object : AppEntityListener<String> {
+ override fun lookupAndRenderAsync(
+ searchAction: SearchAction<String>
+ ): ListenableFuture<EntitySearchResult<String>> {
+ throw IllegalStateException("error in lookupAndRender")
+ }
+
+ override fun onReceivedAsync(
+ value: String
+ ): ListenableFuture<ValidationResult> {
+ throw IllegalStateException("error in onReceivedAsync")
+ }
+ }
+ override suspend fun onExecute(arguments: Arguments) =
+ ExecutionResult.Builder<Output>()
+ .setShouldStartDictation(true)
+ .build()
+ }
+ }
+ val capability = CapabilityBuilder()
+ .setId("fakeId")
+ .setExecutionSessionFactory(sessionFactory)
+ .build()
+ val session = capability.createSession(fakeSessionId, hostProperties)
+ val callback = FakeCallbackInternal()
+
+ session.execute(
+ buildRequestArgs(
+ SYNC, /* args...= */
+ "required",
+ ParamValue.newBuilder().setIdentifier("foo").setStringValue("foo").build()
+ ),
+ callback
+ )
+
+ assertThat(
+ callback.receiveResponse().errorStatus
+ ).isEqualTo(ErrorStatusInternal.EXTERNAL_EXCEPTION)
+ }
+
/**
* an implementation of Capability.Builder using Argument. Output, etc. defined under
* testing/spec
@@ -1129,8 +1259,24 @@
setProperty(SINGLE_REQUIRED_FIELD_PROPERTY)
}
- override val sessionBridge: SessionBridge<ExecutionSession, Confirmation> = SessionBridge {
- TaskHandler.Builder<Confirmation>().build()
+ override val sessionBridge: SessionBridge<
+ ExecutionSession,
+ Arguments,
+ Confirmation
+ > = SessionBridge {
+ session ->
+ val builder = TaskHandler.Builder<Arguments, Confirmation>()
+ session.requiredStringListener?.let {
+ listener: AppEntityListener<String> ->
+ builder.registerAppEntityTaskParam(
+ "required",
+ listener,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ EntityConverter.of(TypeSpec.STRING_TYPE_SPEC),
+ getTrivialSearchActionConverter()
+ )
+ }
+ builder.build()
}
}
@@ -1192,38 +1338,30 @@
ActionSpecBuilder.ofCapabilityNamed(
CAPABILITY_NAME
)
- .setArguments(Arguments::class.java, Arguments::newBuilder)
+ .setArguments(Arguments::class.java, Arguments::Builder)
.setOutput(Output::class.java)
.bindParameter(
"required",
{ properties ->
- properties["required"]
- as
- Property<StringValue>?
+ properties["required"] as Property<StringValue>
},
Arguments.Builder::setRequiredStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER
)
- .bindOptionalParameter(
+ .bindParameter(
"optional",
{ properties ->
- properties["optional"]
- ?.let { it as Property<StringValue> }
- ?.let { Optional.of(it) }
- ?: Optional.ofNullable(null)
+ properties["optional"] as? Property<StringValue>
},
Arguments.Builder::setOptionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER
)
- .bindOptionalParameter(
+ .bindParameter(
"optionalEnum",
{ properties ->
- properties["optionalEnum"]
- ?.let { it as Property<TestEnum> }
- ?.let { Optional.of(it) }
- ?: Optional.ofNullable(null)
+ properties["optionalEnum"] as? Property<TestEnum>
},
Arguments.Builder::setEnumField,
ENUM_CONVERTER,
@@ -1232,16 +1370,13 @@
.bindRepeatedParameter(
"repeated",
{ properties ->
- properties["repeated"]
- ?.let { it as Property<StringValue> }
- ?.let { Optional.of(it) }
- ?: Optional.ofNullable(null)
+ properties["repeated"] as? Property<StringValue>
},
Arguments.Builder::setRepeatedStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER,
TypeConverters.STRING_VALUE_ENTITY_CONVERTER
)
- .bindOptionalOutput(
+ .bindOutput(
"optionalStringOutput",
Output::optionalStringField,
TypeConverters.STRING_PARAM_VALUE_CONVERTER::toParamValue
@@ -1279,7 +1414,7 @@
private fun <SessionUpdaterT : AbstractTaskUpdater> createCapability(
property: Map<String, Property<*>>,
sessionFactory: (hostProperties: HostProperties?) -> ExecutionSession,
- sessionBridge: SessionBridge<ExecutionSession, Confirmation>,
+ sessionBridge: SessionBridge<ExecutionSession, Arguments, Confirmation>,
sessionUpdaterSupplier: Supplier<SessionUpdaterT>
): TaskCapabilityImpl<
Arguments,
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityUtilsTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityUtilsTest.kt
similarity index 100%
rename from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskCapabilityUtilsTest.kt
rename to appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskCapabilityUtilsTest.kt
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessorTest.kt
similarity index 99%
rename from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
rename to appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessorTest.kt
index bd0a338..eca8de0 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/task/impl/TaskSlotProcessorTest.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/impl/task/TaskSlotProcessorTest.kt
@@ -18,11 +18,11 @@
import androidx.appactions.interaction.capabilities.core.AppEntityListener
import androidx.appactions.interaction.capabilities.core.EntitySearchResult
import androidx.appactions.interaction.capabilities.core.InventoryListener
+import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.core.ValidationResult
import androidx.appactions.interaction.capabilities.core.ValueListener
import androidx.appactions.interaction.capabilities.core.impl.concurrent.Futures
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
-import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils
import androidx.appactions.interaction.capabilities.testing.internal.TestingUtils.awaitSync
import androidx.appactions.interaction.proto.CurrentValue
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.java
deleted file mode 100644
index 79532a1..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.List;
-import java.util.Optional;
-
-/** Testing implementation of a capability Argument. */
-@AutoValue
-public abstract class Arguments {
-
- public static Builder newBuilder() {
- return new AutoValue_Arguments.Builder();
- }
-
- public abstract Optional<String> requiredStringField();
-
- public abstract Optional<String> optionalStringField();
-
- public abstract Optional<TestEnum> enumField();
-
- public abstract Optional<List<String>> repeatedStringField();
-
- /** Builder for the testing Argument. */
- @AutoValue.Builder
- public abstract static class Builder implements BuilderOf<Arguments> {
-
- public abstract Builder setRequiredStringField(String value);
-
- public abstract Builder setOptionalStringField(String value);
-
- public abstract Builder setEnumField(TestEnum value);
-
- public abstract Builder setRepeatedStringField(List<String> value);
-
- @NonNull
- @Override
- public abstract Arguments build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.kt
new file mode 100644
index 0000000..cc0a5e4
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Arguments.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+
+class Arguments internal constructor(
+ val requiredStringField: String?,
+ val optionalStringField: String?,
+ val enumField: TestEnum?,
+ val repeatedStringField: List<String>
+) {
+ override fun toString(): String {
+ return "Arguments(requiredStringField=$requiredStringField, " +
+ "optionalStringField=$optionalStringField, " +
+ "enumField=$enumField, " +
+ "repeatedStringField=$repeatedStringField, " +
+ ")"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Arguments
+
+ if (requiredStringField != other.requiredStringField) return false
+ if (optionalStringField != other.optionalStringField) return false
+ if (enumField != other.enumField) return false
+ if (repeatedStringField != other.repeatedStringField) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = requiredStringField.hashCode()
+ result += 31 * optionalStringField.hashCode()
+ result += 31 * enumField.hashCode()
+ result += 31 * repeatedStringField.hashCode()
+ return result
+ }
+
+ class Builder : BuilderOf<Arguments> {
+ private var requiredStringField: String? = null
+ private var optionalStringField: String? = null
+ private var enumField: TestEnum? = null
+ private var repeatedStringField: List<String> = listOf()
+
+ fun setRequiredStringField(requiredStringField: String): Builder =
+ apply { this.requiredStringField = requiredStringField }
+
+ fun setOptionalStringField(optionalStringField: String): Builder =
+ apply { this.optionalStringField = optionalStringField }
+
+ fun setEnumField(enumField: TestEnum): Builder =
+ apply { this.enumField = enumField }
+
+ fun setRepeatedStringField(repeatedStringField: List<String>): Builder =
+ apply { this.repeatedStringField = repeatedStringField }
+
+ override fun build(): Arguments =
+ Arguments(requiredStringField, optionalStringField, enumField, repeatedStringField)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
deleted file mode 100644
index 586145d..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import static androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters.LIST_ITEM_TYPE_SPEC;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.builtintypes.experimental.types.ListItem;
-import androidx.appactions.interaction.capabilities.core.AppEntityListener;
-import androidx.appactions.interaction.capabilities.core.BaseExecutionSession;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter;
-import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/** Used to test the filling behavior of structured entities (e.g. ListItem) */
-@SuppressWarnings("unchecked")
-public final class CapabilityStructFill {
-
- private static final String CAPABILITY_NAME = "actions.intent.TEST";
- public static final ActionSpec<Arguments, Void> ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(Arguments.class, Arguments::newBuilder)
- .bindOptionalParameter(
- "listItem",
- properties ->
- {
- return Optional.ofNullable((Property<ListItem>) (properties.get(
- "listItem")));
- },
- Arguments.Builder::setListItem,
- ParamValueConverter.Companion.of(LIST_ITEM_TYPE_SPEC),
- EntityConverter.Companion.of(LIST_ITEM_TYPE_SPEC)::convert)
- .bindOptionalParameter(
- "string",
- properties ->
- {
- return Optional.ofNullable((Property<StringValue>) (properties.get(
- "anyString")));
- },
- Arguments.Builder::setAnyString,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
- .build();
-
- private CapabilityStructFill() {}
-
- /** Two required strings */
- @AutoValue
- public abstract static class Arguments {
- public static Builder newBuilder() {
- return new AutoValue_CapabilityStructFill_Arguments.Builder();
- }
-
- public abstract Optional<ListItem> listItem();
-
- public abstract Optional<String> anyString();
-
- /** Builder for the testing Arguments. */
- @AutoValue.Builder
- public abstract static class Builder implements BuilderOf<Arguments> {
-
- public abstract Builder setListItem(@NonNull ListItem value);
-
- public abstract Builder setAnyString(@NonNull String value);
-
- @NonNull
- @Override
- public abstract Arguments build();
- }
- }
-
- /** Two required strings */
- @AutoValue
- public abstract static class Properties {
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_CapabilityStructFill_Properties.Builder();
- }
-
- public abstract Optional<Property<ListItem>> listItem();
-
- public abstract Optional<Property<StringValue>> anyString();
-
- /** Builder for {@link Property} */
- @AutoValue.Builder
- public abstract static class Builder {
-
- @NonNull
- public abstract Builder setListItem(@NonNull Property<ListItem> value);
-
- @NonNull
- public abstract Builder setAnyString(@NonNull Property<StringValue> value);
-
- @NonNull
- public abstract Properties build();
- }
- }
-
- public interface ExecutionSession extends BaseExecutionSession<Arguments, Void> {
- @NonNull
- AppEntityListener<ListItem> getListItemListener();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt
new file mode 100644
index 0000000..40d0f99
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityStructFill.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import androidx.appactions.builtintypes.experimental.types.ListItem
+import androidx.appactions.interaction.capabilities.core.AppEntityListener
+import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.capabilities.core.properties.StringValue
+
+private const val CAPABILITY_NAME = "actions.intent.TEST"
+
+/** Used to test the filling behavior of structured entities (e.g. ListItem) */
+class CapabilityStructFill {
+
+ class Arguments internal constructor(
+ val listItem: ListItem?,
+ val anyString: String?
+ ) {
+ override fun toString(): String {
+ return "Arguments(listItem=$listItem, " +
+ "anyString=$anyString)"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Arguments
+
+ if (listItem != other.listItem) return false
+ if (anyString != other.anyString) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = listItem.hashCode()
+ result += 31 * anyString.hashCode()
+ return result
+ }
+
+ class Builder : BuilderOf<Arguments> {
+ private var listItem: ListItem? = null
+ private var anyString: String? = null
+
+ fun setListItem(listItem: ListItem): Builder =
+ apply { this.listItem = listItem }
+
+ fun setAnyString(stringSlotB: String): Builder =
+ apply { this.anyString = stringSlotB }
+
+ override fun build(): Arguments = Arguments(listItem, anyString)
+ }
+ }
+
+ class Output internal constructor()
+
+ class Confirmation internal constructor()
+
+ interface ExecutionSession : BaseExecutionSession<Arguments, Output> {
+ val listItemListener: AppEntityListener<ListItem>
+ }
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "listItem",
+ { properties ->
+ properties["listItem"] as? Property<ListItem>
+ },
+ Arguments.Builder::setListItem,
+ ParamValueConverter.of(TypeConverters.LIST_ITEM_TYPE_SPEC),
+ EntityConverter.of(TypeConverters.LIST_ITEM_TYPE_SPEC)::convert
+ )
+ .bindParameter(
+ "string",
+ { properties ->
+ properties["anyString"] as? Property<StringValue>
+ },
+ Arguments.Builder::setAnyString,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.java
deleted file mode 100644
index 76cf08d..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.BaseExecutionSession;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpec;
-import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-@SuppressWarnings("unchecked")
-public final class CapabilityTwoStrings {
- private static final String CAPABILITY_NAME = "actions.intent.TEST";
- public static final ActionSpec<Arguments, Void> ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(Arguments.class, Arguments::newBuilder)
- .bindOptionalParameter(
- "stringSlotA",
- properties -> {
- return Optional.ofNullable(
- (Property<StringValue>) properties.get("stringSlotA")
- );
- },
- Arguments.Builder::setStringSlotA,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
- .bindOptionalParameter(
- "stringSlotB",
- properties -> {
- return Optional.ofNullable(
- (Property<StringValue>) properties.get("stringSlotB")
- );
- },
- Arguments.Builder::setStringSlotB,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER)
- .build();
-
- private CapabilityTwoStrings() {
- }
-
- /** Two required strings */
- @AutoValue
- public abstract static class Arguments {
- public static Builder newBuilder() {
- return new AutoValue_CapabilityTwoStrings_Arguments.Builder();
- }
-
- public abstract Optional<String> stringSlotA();
-
- public abstract Optional<String> stringSlotB();
-
- /** Builder for the testing Arguments. */
- @AutoValue.Builder
- public abstract static class Builder implements BuilderOf<Arguments> {
-
- public abstract Builder setStringSlotA(@NonNull String value);
-
- public abstract Builder setStringSlotB(@NonNull String value);
-
- @NonNull
- @Override
- public abstract Arguments build();
- }
- }
-
- /** Two required strings */
- @AutoValue
- public abstract static class Properties {
- @NonNull
- public static Builder newBuilder() {
- return new AutoValue_CapabilityTwoStrings_Properties.Builder();
- }
-
- public abstract Optional<Property<StringValue>> stringSlotA();
-
- public abstract Optional<Property<StringValue>> stringSlotB();
-
- /** Builder for {@link Property} */
- @AutoValue.Builder
- public abstract static class Builder {
-
- @NonNull
- public abstract Builder setStringSlotA(@NonNull Property<StringValue> value);
-
- @NonNull
- public abstract Builder setStringSlotB(@NonNull Property<StringValue> value);
-
- @NonNull
- public abstract Properties build();
- }
- }
-
- public interface ExecutionSession extends BaseExecutionSession<Arguments, Void> {}
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt
new file mode 100644
index 0000000..612d3ca
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/CapabilityTwoStrings.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
+import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
+import androidx.appactions.interaction.capabilities.core.properties.Property
+import androidx.appactions.interaction.capabilities.core.properties.StringValue
+
+private const val CAPABILITY_NAME = "actions.intent.TEST"
+
+@CapabilityFactory(name = CAPABILITY_NAME)
+class CapabilityTwoStrings {
+
+ class Arguments internal constructor(
+ val stringSlotA: String?,
+ val stringSlotB: String?
+ ) {
+ override fun toString(): String {
+ return "Arguments(stringSlotA=$stringSlotA, " +
+ "stringSlotB=$stringSlotB)"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Arguments
+
+ if (stringSlotA != other.stringSlotA) return false
+ if (stringSlotB != other.stringSlotB) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = stringSlotA.hashCode()
+ result += 31 * stringSlotB.hashCode()
+ return result
+ }
+
+ class Builder : BuilderOf<Arguments> {
+ private var stringSlotA: String? = null
+ private var stringSlotB: String? = null
+
+ fun setStringSlotA(stringSlotA: String): Builder =
+ apply { this.stringSlotA = stringSlotA }
+
+ fun setStringSlotB(stringSlotB: String): Builder =
+ apply { this.stringSlotB = stringSlotB }
+
+ override fun build(): Arguments = Arguments(stringSlotA, stringSlotB)
+ }
+ }
+
+ class Output internal constructor()
+
+ class Confirmation internal constructor()
+
+ interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "stringSlotA",
+ { properties ->
+ properties["stringSlotA"] as? Property<StringValue>
+ },
+ Arguments.Builder::setStringSlotA,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "stringSlotB",
+ { properties ->
+ properties["stringSlotB"] as? Property<StringValue>
+ },
+ Arguments.Builder::setStringSlotB,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.java
deleted file mode 100644
index 491a282..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/** Testing implementation of a capability Confirmation. */
-@AutoValue
-public abstract class Confirmation {
-
- public static Builder builder() {
- return new AutoValue_Confirmation.Builder();
- }
-
- public abstract Optional<String> optionalStringField();
-
- @AutoValue.Builder
- public abstract static class Builder {
-
- public abstract Builder setOptionalStringField(String value);
-
- public abstract Confirmation build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.kt
new file mode 100644
index 0000000..c66fce5
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Confirmation.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+class Confirmation internal constructor(
+ val optionalStringField: String?
+) {
+ override fun toString(): String {
+ return "Confirmation(optionalStringField=$optionalStringField)"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Confirmation
+
+ if (optionalStringField != other.optionalStringField) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ return optionalStringField.hashCode()
+ }
+
+ class Builder {
+ private var optionalStringField: String? = null
+
+ fun setOptionalStringField(optionalStringField: String): Builder =
+ apply { this.optionalStringField = optionalStringField }
+
+ fun build(): Confirmation = Confirmation(optionalStringField)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/ExecutionSession.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/ExecutionSession.kt
index 936f2b9..354a117 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/ExecutionSession.kt
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/ExecutionSession.kt
@@ -23,7 +23,7 @@
interface ExecutionSession : BaseExecutionSession<Arguments, Output> {
- fun getRequiredStringListener(): AppEntityListener<String>? = null
+ val requiredStringListener: AppEntityListener<String>? get() = null
companion object {
@JvmStatic
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/GenericEntityArguments.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/GenericEntityArguments.kt
new file mode 100644
index 0000000..5c61176
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/GenericEntityArguments.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
+
+class GenericEntityArguments internal constructor(
+ val singularField: TestEntity?,
+ val optionalField: TestEntity?,
+ val repeatedField: List<TestEntity>
+) {
+ override fun toString(): String {
+ return "GenericEntityArguments(singularField=$singularField, " +
+ "optionalField=$optionalField, " +
+ "repeatedField=$repeatedField, " +
+ ")"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as GenericEntityArguments
+
+ if (singularField != other.singularField) return false
+ if (optionalField != other.optionalField) return false
+ if (repeatedField != other.repeatedField) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = singularField.hashCode()
+ result += 31 * optionalField.hashCode()
+ result += 31 * repeatedField.hashCode()
+ return result
+ }
+
+ class Builder : BuilderOf<GenericEntityArguments> {
+ private var singularField: TestEntity? = null
+ private var optionalField: TestEntity? = null
+ private var repeatedField: List<TestEntity> = listOf()
+
+ fun setSingularField(singularField: TestEntity): Builder =
+ apply { this.singularField = singularField }
+
+ fun setOptionalField(optionalField: TestEntity): Builder =
+ apply { this.optionalField = optionalField }
+
+ fun setRepeatedField(repeatedField: List<TestEntity>): Builder =
+ apply { this.repeatedField = repeatedField }
+
+ override fun build(): GenericEntityArguments =
+ GenericEntityArguments(singularField, optionalField, repeatedField)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java
deleted file mode 100644
index 5464ff6..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-
-/** Testing implementation of a capability Output. */
-@AutoValue
-public abstract class Output {
-
- public static Builder builder() {
- return new AutoValue_Output.Builder().setRepeatedStringField(Collections.emptyList());
- }
-
- public abstract Optional<String> optionalStringField();
-
- public abstract List<String> repeatedStringField();
-
- @AutoValue.Builder
- public abstract static class Builder {
-
- public abstract Builder setOptionalStringField(String value);
-
- public abstract Builder setRepeatedStringField(List<String> value);
-
- public abstract Output build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.kt
new file mode 100644
index 0000000..1cc424f
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Output.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+class Output internal constructor(
+ val optionalStringField: String?,
+ val repeatedStringField: List<String>
+) {
+ override fun toString(): String {
+ return "Output(optionalStringField=$optionalStringField, " +
+ "repeatedStringField=$repeatedStringField)"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Output
+
+ if (optionalStringField != other.optionalStringField) return false
+ if (repeatedStringField != other.repeatedStringField) return false
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = optionalStringField.hashCode()
+ result += 31 * repeatedStringField.hashCode()
+ return result
+ }
+
+ class Builder {
+ private var optionalStringField: String? = null
+ private var repeatedStringField: List<String> = listOf()
+
+ fun setOptionalStringField(optionalStringField: String): Builder =
+ apply { this.optionalStringField = optionalStringField }
+
+ fun setRepeatedStringField(repeatedStringField: List<String>): Builder = apply {
+ this.repeatedStringField = repeatedStringField
+ }
+
+ fun build(): Output = Output(optionalStringField, repeatedStringField)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Properties.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Properties.java
deleted file mode 100644
index ee4846d..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/Properties.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-import androidx.appactions.interaction.capabilities.core.properties.Property;
-import androidx.appactions.interaction.capabilities.core.properties.StringValue;
-
-import com.google.auto.value.AutoValue;
-
-import java.util.Optional;
-
-/** Testing implementation of a capability Property. */
-@AutoValue
-public abstract class Properties {
-
- public static Builder newBuilder() {
- return new AutoValue_Properties.Builder();
- }
-
- public abstract Property<StringValue> requiredStringField();
-
- public abstract Optional<Property<StringValue>> optionalStringField();
-
- public abstract Optional<Property<TestEnum>> enumField();
-
- public abstract Optional<Property<StringValue>> repeatedStringField();
-
- /** Builder for the testing Property. */
- @AutoValue.Builder
- public abstract static class Builder implements BuilderOf<Properties> {
-
- public abstract Builder setRequiredStringField(Property<StringValue> property);
-
- public abstract Builder setOptionalStringField(Property<StringValue> property);
-
- public abstract Builder setEnumField(Property<TestEnum> property);
-
- public abstract Builder setRepeatedStringField(Property<StringValue> property);
-
- @NonNull
- @Override
- public abstract Properties build();
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java
deleted file mode 100644
index a8d103c..0000000
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.appactions.interaction.capabilities.core.testing.spec;
-
-import androidx.annotation.NonNull;
-import androidx.appactions.interaction.capabilities.core.impl.BuilderOf;
-
-import com.google.auto.value.AutoValue;
-
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.util.Optional;
-
-/** A test class for capability value. */
-@AutoValue
-public abstract class TestEntity {
-
- public static Builder newBuilder() {
- return new AutoValue_TestEntity.Builder();
- }
-
- public abstract Optional<String> getId();
-
- public abstract Optional<String> getName();
-
- public abstract Optional<Duration> getDuration();
-
- public abstract Optional<ZonedDateTime> getZonedDateTime();
-
- public abstract Optional<TestEnum> getEnum();
-
- public abstract Optional<TestEntity> getEntity();
-
- public enum TestEnum {
- VALUE_1("value_1"),
- VALUE_2("value_2");
-
- private final String mStringValue;
-
- TestEnum(String stringValue) {
- this.mStringValue = stringValue;
- }
-
- @NonNull
- @Override
- public String toString() {
- return mStringValue;
- }
- }
-
- @AutoValue.Builder
- public abstract static class Builder implements BuilderOf<TestEntity> {
-
- public abstract Builder setId(String id);
-
- public abstract Builder setName(String name);
-
- public abstract Builder setDuration(Duration duration);
-
- public abstract Builder setZonedDateTime(ZonedDateTime date);
-
- public abstract Builder setEnum(TestEnum enumValue);
-
- public abstract Builder setEntity(TestEntity entity);
- }
-}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.kt b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.kt
new file mode 100644
index 0000000..aa478c4
--- /dev/null
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEntity.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.appactions.interaction.capabilities.core.testing.spec
+
+import java.time.Duration
+import java.time.ZonedDateTime
+
+class TestEntity internal constructor(
+ val id: String?,
+ val name: String?,
+ val duration: Duration?,
+ val zonedDateTime: ZonedDateTime?,
+ val enum: TestEnum?,
+ val entity: TestEntity?
+) {
+ override fun toString(): String {
+ return "TestEntity(identifier=$id, name=$name, duration=$duration, " +
+ "zonedDateTime=$zonedDateTime, enum=$enum, entity=$entity)"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as TestEntity
+
+ if (id != other.id) return false
+ if (name != other.name) return false
+ if (duration != other.duration) return false
+ if (zonedDateTime != other.zonedDateTime) return false
+ if (enum != other.enum) return false
+ if (entity != other.entity) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = id.hashCode()
+ result += 31 * name.hashCode()
+ result += 31 * duration.hashCode()
+ result += 31 * zonedDateTime.hashCode()
+ result += 31 * enum.hashCode()
+ result += 31 * entity.hashCode()
+ return result
+ }
+
+ class Builder {
+ private var id: String? = null
+ private var name: String? = null
+ private var duration: Duration? = null
+ private var zonedDateTime: ZonedDateTime? = null
+ private var enum: TestEnum? = null
+ private var entity: TestEntity? = null
+
+ fun setId(id: String): Builder = apply { this.id = id }
+ fun setName(name: String): Builder = apply { this.name = name }
+ fun setDuration(duration: Duration): Builder = apply { this.duration = duration }
+ fun setZonedDateTime(zonedDateTime: ZonedDateTime): Builder = apply {
+ this.zonedDateTime = zonedDateTime
+ }
+ fun setEnum(enum: TestEnum): Builder = apply { this.enum = enum }
+ fun setEntity(entity: TestEntity): Builder = apply { this.entity = entity }
+
+ fun build(): TestEntity = TestEntity(id, name, duration, zonedDateTime, enum, entity)
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.kt
similarity index 78%
rename from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
rename to appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.kt
index c325c57..7c81862 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.kt
@@ -14,10 +14,13 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+package androidx.appactions.interaction.capabilities.core.testing.spec
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
-}
+enum class TestEnum(private val mStringValue: String) {
+ VALUE_1("VALUE_1"),
+ VALUE_2("VALUE_2");
+
+ override fun toString(): String {
+ return mStringValue
+ }
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
index d530c21..4fd5dc7 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetExerciseObservation.kt
@@ -24,51 +24,15 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
import java.time.LocalTime
-import java.util.Optional
-/** GetExerciseObservation.kt in interaction-capabilities-fitness */
-private const val CAPABILITY_NAME = "actions.intent.START_EXERCISE"
+private const val CAPABILITY_NAME = "actions.intent.GET_EXERCISE_OBSERVATION"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(
- GetExerciseObservation.Arguments::class.java,
- GetExerciseObservation.Arguments::Builder
- )
- .setOutput(GetExerciseObservation.Output::class.java)
- .bindOptionalParameter(
- "exerciseObservation.startTime",
- { properties ->
- Optional.ofNullable(
- properties[GetExerciseObservation.PropertyMapStrings.START_TIME.key]
- as Property<LocalTime>
- )
- },
- GetExerciseObservation.Arguments.Builder::setStartTime,
- TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
- TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
- )
- .bindOptionalParameter(
- "exerciseObservation.endTime",
- { properties ->
- Optional.ofNullable(
- properties[GetExerciseObservation.PropertyMapStrings.END_TIME.key]
- as Property<LocalTime>
- )
- },
- GetExerciseObservation.Arguments.Builder::setEndTime,
- TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
- TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.GET_EXERCISE_OBSERVATION */
@CapabilityFactory(name = CAPABILITY_NAME)
class GetExerciseObservation private constructor() {
internal enum class PropertyMapStrings(val key: String) {
START_TIME("exerciseObservation.startTime"),
- END_TIME("exerciseObservation.endTime"),
+ END_TIME("exerciseObservation.endTime")
}
class CapabilityBuilder :
@@ -134,4 +98,35 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(
+ Arguments::class.java,
+ Arguments::Builder
+ )
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "exerciseObservation.startTime",
+ { properties ->
+ properties[PropertyMapStrings.START_TIME.key] as? Property<LocalTime>
+ },
+ Arguments.Builder::setStartTime,
+ TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
+ TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "exerciseObservation.endTime",
+ { properties ->
+ properties[PropertyMapStrings.END_TIME.key] as? Property<LocalTime>
+ },
+ Arguments.Builder::setEndTime,
+ TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
+ TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
index c7482e1..7d843ac 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/GetHealthObservation.kt
@@ -24,51 +24,16 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
import java.time.LocalTime
-import java.util.Optional
-/** GetHealthObservation.kt in interaction-capabilities-fitness */
-private const val CAPABILITY_NAME = "actions.intent.START_EXERCISE"
+private const val CAPABILITY_NAME = "actions.intent.GET_HEALTH_OBSERVATION"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(
- GetHealthObservation.Arguments::class.java,
- GetHealthObservation.Arguments::Builder
- )
- .setOutput(GetHealthObservation.Output::class.java)
- .bindOptionalParameter(
- "healthObservation.startTime",
- { properties ->
- Optional.ofNullable(
- properties[GetHealthObservation.PropertyMapStrings.START_TIME.key]
- as Property<LocalTime>
- )
- },
- GetHealthObservation.Arguments.Builder::setStartTime,
- TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
- TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
- )
- .bindOptionalParameter(
- "healthObservation.endTime",
- { properties ->
- Optional.ofNullable(
- properties[GetHealthObservation.PropertyMapStrings.END_TIME.key]
- as Property<LocalTime>
- )
- },
- GetHealthObservation.Arguments.Builder::setEndTime,
- TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
- TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.GET_HEALTH_OBSERVATION */
@CapabilityFactory(name = CAPABILITY_NAME)
class GetHealthObservation private constructor() {
+
internal enum class PropertyMapStrings(val key: String) {
START_TIME("healthObservation.startTime"),
- END_TIME("healthObservation.endTime"),
+ END_TIME("healthObservation.endTime")
}
class CapabilityBuilder :
@@ -138,4 +103,35 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(
+ Arguments::class.java,
+ Arguments::Builder
+ )
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "healthObservation.startTime",
+ { properties ->
+ properties[PropertyMapStrings.START_TIME.key] as? Property<LocalTime>
+ },
+ Arguments.Builder::setStartTime,
+ TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
+ TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "healthObservation.endTime",
+ { properties ->
+ properties[PropertyMapStrings.END_TIME.key] as? Property<LocalTime>
+ },
+ Arguments.Builder::setEndTime,
+ TypeConverters.LOCAL_TIME_PARAM_VALUE_CONVERTER,
+ TypeConverters.LOCAL_TIME_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
index f04ceee..8a94643d 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/PauseExercise.kt
@@ -24,35 +24,14 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.properties.StringValue
-import java.util.Optional
-/** PauseExercise.kt in interaction-capabilities-fitness */
private const val CAPABILITY_NAME = "actions.intent.PAUSE_EXERCISE"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(PauseExercise.Arguments::class.java, PauseExercise.Arguments::Builder)
- .setOutput(PauseExercise.Output::class.java)
- .bindOptionalParameter(
- "exercise.name",
- { properties ->
- Optional.ofNullable(
- properties[PauseExercise.PropertyMapStrings.NAME.key]
- as Property<StringValue>
- )
- },
- PauseExercise.Arguments.Builder::setName,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.PAUSE_EXERCISE */
@CapabilityFactory(name = CAPABILITY_NAME)
class PauseExercise private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- NAME("exercise.name"),
+ NAME("exercise.name")
}
class CapabilityBuilder :
@@ -110,4 +89,23 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "exercise.name",
+ { properties ->
+ properties[PropertyMapStrings.NAME.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setName,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
index 1881a7c..963f7ad 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/ResumeExercise.kt
@@ -24,35 +24,14 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.properties.StringValue
-import java.util.Optional
-/** ResumeExercise.kt in interaction-capabilities-fitness */
private const val CAPABILITY_NAME = "actions.intent.RESUME_EXERCISE"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(ResumeExercise.Arguments::class.java, ResumeExercise.Arguments::Builder)
- .setOutput(ResumeExercise.Output::class.java)
- .bindOptionalParameter(
- "exercise.name",
- { properties ->
- Optional.ofNullable(
- properties[ResumeExercise.PropertyMapStrings.NAME.key]
- as Property<StringValue>
- )
- },
- ResumeExercise.Arguments.Builder::setName,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.RESUME_EXERCISE */
@CapabilityFactory(name = CAPABILITY_NAME)
class ResumeExercise private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- NAME("exercise.name"),
+ NAME("exercise.name")
}
class CapabilityBuilder :
@@ -110,4 +89,23 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "exercise.name",
+ { properties ->
+ properties[PropertyMapStrings.NAME.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setName,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
index 0847d33..3de87ec 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StartExercise.kt
@@ -25,48 +25,15 @@
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.properties.StringValue
import java.time.Duration
-import java.util.Optional
-/** StartExercise.kt in interaction-capabilities-fitness */
private const val CAPABILITY_NAME = "actions.intent.START_EXERCISE"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StartExercise.Arguments::class.java, StartExercise.Arguments::Builder)
- .setOutput(StartExercise.Output::class.java)
- .bindOptionalParameter(
- "exercise.duration",
- { properties ->
- Optional.ofNullable(
- properties[StartExercise.PropertyMapStrings.DURATION.key]
- as Property<Duration>
- )
- },
- StartExercise.Arguments.Builder::setDuration,
- TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
- TypeConverters.DURATION_ENTITY_CONVERTER
- )
- .bindOptionalParameter(
- "exercise.name",
- { properties ->
- Optional.ofNullable(
- properties[StartExercise.PropertyMapStrings.NAME.key]
- as Property<StringValue>
- )
- },
- StartExercise.Arguments.Builder::setName,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.START_EXERCISE */
@CapabilityFactory(name = CAPABILITY_NAME)
class StartExercise private constructor() {
internal enum class PropertyMapStrings(val key: String) {
NAME("exercise.name"),
- DURATION("exercise.duration"),
+ DURATION("exercise.duration")
}
class CapabilityBuilder :
@@ -136,4 +103,32 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "exercise.duration",
+ { properties ->
+ properties[PropertyMapStrings.DURATION.key] as? Property<Duration>
+ },
+ Arguments.Builder::setDuration,
+ TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
+ TypeConverters.DURATION_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "exercise.name",
+ { properties ->
+ properties[PropertyMapStrings.NAME.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setName,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
index 18efde0..e257fac 100644
--- a/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
+++ b/appactions/interaction/interaction-capabilities-fitness/src/main/java/androidx/appactions/interaction/capabilities/fitness/fitness/StopExercise.kt
@@ -24,35 +24,14 @@
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.properties.StringValue
-import java.util.Optional
-/** StopExercise.kt in interaction-capabilities-fitness */
-private const val CAPABILITY_NAME = "actions.intent.PAUSE_EXERCISE"
+private const val CAPABILITY_NAME = "actions.intent.STOP_EXERCISE"
-// TODO(b/273602015): Update to use Name property from builtintype library.
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StopExercise.Arguments::class.java, StopExercise.Arguments::Builder)
- .setOutput(StopExercise.Output::class.java)
- .bindOptionalParameter(
- "exercise.name",
- { properties ->
- Optional.ofNullable(
- properties[StopExercise.PropertyMapStrings.NAME.key]
- as Property<StringValue>
- )
- },
- StopExercise.Arguments.Builder::setName,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER
- )
- .build()
-
+/** A capability corresponding to actions.intent.STOP_EXERCISE */
@CapabilityFactory(name = CAPABILITY_NAME)
class StopExercise private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- NAME("exercise.name"),
+ NAME("exercise.name")
}
class CapabilityBuilder :
@@ -111,4 +90,23 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ // TODO(b/273602015): Update to use Name property from builtintype library.
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "exercise.name",
+ { properties ->
+ properties[PropertyMapStrings.NAME.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setName,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
index 528a497..260c074 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/PauseTimer.kt
@@ -20,6 +20,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -27,39 +28,14 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** PauseTimer.kt in interaction-capabilities-productivity */
private const val CAPABILITY_NAME = "actions.intent.PAUSE_TIMER"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(PauseTimer.Arguments::class.java, PauseTimer.Arguments::Builder)
- .setOutput(PauseTimer.Output::class.java)
- .bindRepeatedParameter(
- "timer",
- { properties ->
- Optional.ofNullable(
- properties[PauseTimer.PropertyMapStrings.TIMER_LIST.key]
- as Property<TimerValue>
- )
- },
- PauseTimer.Arguments.Builder::setTimerList,
- TimerValue.PARAM_VALUE_CONVERTER,
- TimerValue.ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- PauseTimer.ExecutionStatus::toParamValue,
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.PAUSE_TIMER */
+@CapabilityFactory(name = CAPABILITY_NAME)
class PauseTimer private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- TIMER_LIST("timer.timerList"),
+ TIMER_LIST("timer.timerList")
}
class CapabilityBuilder :
@@ -83,7 +59,7 @@
class Arguments
internal constructor(
- val timerList: List<TimerValue>?,
+ val timerList: List<TimerValue>?
) {
override fun toString(): String {
return "Arguments(timerList=$timerList)"
@@ -169,7 +145,7 @@
val value: Value = Value.newBuilder().setStringValue(status).build()
return ParamValue.newBuilder()
.setStructValue(
- Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build(),
+ Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build()
)
.build()
}
@@ -178,4 +154,27 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindRepeatedParameter(
+ "timer",
+ { properties ->
+ properties[PropertyMapStrings.TIMER_LIST.key] as? Property<TimerValue>
+ },
+ Arguments.Builder::setTimerList,
+ TimerValue.PARAM_VALUE_CONVERTER,
+ TimerValue.ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
index 94d203b..8fb648c 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResetTimer.kt
@@ -20,6 +20,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -27,39 +28,14 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** ResetTimer.kt in interaction-capabilities-productivity */
private const val CAPABILITY_NAME = "actions.intent.RESET_TIMER"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(ResetTimer.Arguments::class.java, ResetTimer.Arguments::Builder)
- .setOutput(ResetTimer.Output::class.java)
- .bindRepeatedParameter(
- "timer",
- { properties ->
- Optional.ofNullable(
- properties[ResetTimer.PropertyMapStrings.TIMER_LIST.key]
- as Property<TimerValue>
- )
- },
- ResetTimer.Arguments.Builder::setTimerList,
- TimerValue.PARAM_VALUE_CONVERTER,
- TimerValue.ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- ResetTimer.ExecutionStatus::toParamValue
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.RESET_TIMER */
+@CapabilityFactory(name = CAPABILITY_NAME)
class ResetTimer private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- TIMER_LIST("timer.timerList"),
+ TIMER_LIST("timer.timerList")
}
class CapabilityBuilder :
@@ -105,7 +81,7 @@
private var timerList: List<TimerValue>? = null
fun setTimerList(
- timerList: List<TimerValue>,
+ timerList: List<TimerValue>
): Builder = apply { this.timerList = timerList }
override fun build(): Arguments = Arguments(timerList)
@@ -166,7 +142,7 @@
val value: Value = Value.newBuilder().setStringValue(status).build()
return ParamValue.newBuilder()
.setStructValue(
- Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build(),
+ Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build()
)
.build()
}
@@ -175,4 +151,27 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindRepeatedParameter(
+ "timer",
+ { properties ->
+ properties[PropertyMapStrings.TIMER_LIST.key] as? Property<TimerValue>
+ },
+ Arguments.Builder::setTimerList,
+ TimerValue.PARAM_VALUE_CONVERTER,
+ TimerValue.ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
index d967e45..702d431 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/ResumeTimer.kt
@@ -20,6 +20,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -27,39 +28,14 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** ResumeTimer.kt in interaction-capabilities-productivity */
private const val CAPABILITY_NAME = "actions.intent.RESUME_TIMER"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(ResumeTimer.Arguments::class.java, ResumeTimer.Arguments::Builder)
- .setOutput(ResumeTimer.Output::class.java)
- .bindRepeatedParameter(
- "timer",
- { properties ->
- Optional.ofNullable(
- properties[ResumeTimer.PropertyMapStrings.TIMER_LIST.key]
- as Property<TimerValue>
- )
- },
- ResumeTimer.Arguments.Builder::setTimerList,
- TimerValue.PARAM_VALUE_CONVERTER,
- TimerValue.ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- ResumeTimer.ExecutionStatus::toParamValue
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.RESUME_TIMER */
+@CapabilityFactory(name = CAPABILITY_NAME)
class ResumeTimer private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- TIMER_LIST("timer.timerList"),
+ TIMER_LIST("timer.timerList")
}
class CapabilityBuilder :
@@ -105,7 +81,7 @@
private var timerList: List<TimerValue>? = null
fun setTimerList(
- timerList: List<TimerValue>,
+ timerList: List<TimerValue>
): Builder = apply { this.timerList = timerList }
override fun build(): Arguments = Arguments(timerList)
@@ -166,7 +142,7 @@
val value: Value = Value.newBuilder().setStringValue(status).build()
return ParamValue.newBuilder()
.setStructValue(
- Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build(),
+ Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build()
)
.build()
}
@@ -175,4 +151,27 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindRepeatedParameter(
+ "timer",
+ { properties ->
+ properties[PropertyMapStrings.TIMER_LIST.key] as? Property<TimerValue>
+ },
+ Arguments.Builder::setTimerList,
+ TimerValue.PARAM_VALUE_CONVERTER,
+ TimerValue.ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
index fcd211c..6ffb63a 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StartTimer.kt
@@ -20,6 +20,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.HostProperties
import androidx.appactions.interaction.capabilities.core.ValueListener
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
@@ -33,86 +34,17 @@
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
import java.time.Duration
-import java.util.Optional
-/** StartTimer.kt in interaction-capabilities-productivity */
private const val CAPABILITY_NAME = "actions.intent.START_TIMER"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StartTimer.Arguments::class.java, StartTimer.Arguments::Builder)
- .setOutput(StartTimer.Output::class.java)
- .bindOptionalParameter(
- "timer.identifier",
- { properties ->
- Optional.ofNullable(
- properties[StartTimer.PropertyMapStrings.IDENTIFIER.key]
- as Property<StringValue>
- )
- },
- StartTimer.Arguments.Builder::setIdentifier,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER,
- )
- .bindOptionalParameter(
- "timer.name",
- { properties ->
- Optional.ofNullable(
- properties[StartTimer.PropertyMapStrings.NAME.key]
- as Property<StringValue>
- )
- },
- StartTimer.Arguments.Builder::setName,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER,
- )
- .bindOptionalParameter(
- "timer.duration",
- { properties ->
- Optional.ofNullable(
- properties[StartTimer.PropertyMapStrings.DURATION.key]
- as Property<Duration>
- )
- },
- StartTimer.Arguments.Builder::setDuration,
- TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
- TypeConverters.DURATION_ENTITY_CONVERTER,
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StartTimer.ExecutionStatus::toParamValue,
- )
- .build()
-
-private val SESSION_BRIDGE = SessionBridge<StartTimer.ExecutionSession, StartTimer.Confirmation> {
- session ->
- val taskHandlerBuilder = TaskHandler.Builder<StartTimer.Confirmation>()
- session.nameListener?.let {
- taskHandlerBuilder.registerValueTaskParam(
- "timer.name",
- it,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- )
- }
- session.durationListener?.let {
- taskHandlerBuilder.registerValueTaskParam(
- "timer.duration",
- it,
- TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
- )
- }
- taskHandlerBuilder.build()
-}
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.START_TIMER */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StartTimer private constructor() {
internal enum class PropertyMapStrings(val key: String) {
TIMER_LIST("timer.timerList"),
IDENTIFIER("timer.identifier"),
NAME("timer.name"),
- DURATION("timer.duration"),
+ DURATION("timer.duration")
}
class CapabilityBuilder :
@@ -125,10 +57,14 @@
>(ACTION_SPEC) {
private var properties = mutableMapOf<String, Property<*>>()
- override val sessionBridge: SessionBridge<ExecutionSession, Confirmation> = SESSION_BRIDGE
+ override val sessionBridge: SessionBridge<
+ ExecutionSession,
+ Arguments,
+ Confirmation
+ > = SESSION_BRIDGE
override fun setExecutionSessionFactory(
- sessionFactory: (hostProperties: HostProperties?) -> ExecutionSession,
+ sessionFactory: (hostProperties: HostProperties?) -> ExecutionSession
): CapabilityBuilder = super.setExecutionSessionFactory(sessionFactory)
fun setTimerList(timerList: Property<TimerValue>): CapabilityBuilder = apply {
@@ -163,7 +99,7 @@
class Arguments internal constructor(
val identifier: String?,
val name: String?,
- val duration: Duration?,
+ val duration: Duration?
) {
override fun toString(): String {
return "Arguments(identifier=$identifier,name=$name,duration=$duration)"
@@ -258,11 +194,72 @@
val value: Value = Value.newBuilder().setStringValue(status).build()
return ParamValue.newBuilder()
.setStructValue(
- Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build(),
+ Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build()
)
.build()
}
}
class Confirmation internal constructor()
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "timer.identifier",
+ { properties ->
+ properties[PropertyMapStrings.IDENTIFIER.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setIdentifier,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "timer.name",
+ { properties ->
+ properties[PropertyMapStrings.NAME.key] as? Property<StringValue>
+ },
+ Arguments.Builder::setName,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "timer.duration",
+ { properties ->
+ properties[PropertyMapStrings.DURATION.key] as? Property<Duration>
+ },
+ Arguments.Builder::setDuration,
+ TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
+ TypeConverters.DURATION_ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+
+ private val SESSION_BRIDGE = SessionBridge<ExecutionSession, Arguments, Confirmation> {
+ session ->
+ val taskHandlerBuilder = TaskHandler.Builder<Arguments, Confirmation>()
+ session.nameListener?.let {
+ taskHandlerBuilder.registerValueTaskParam(
+ "timer.name",
+ it,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER
+ )
+ }
+ session.durationListener?.let {
+ taskHandlerBuilder.registerValueTaskParam(
+ "timer.duration",
+ it,
+ TypeConverters.DURATION_PARAM_VALUE_CONVERTER
+ )
+ }
+ taskHandlerBuilder.build()
+ }
}
+}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
index 93f5b75..4c279e2 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/StopTimer.kt
@@ -20,6 +20,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -27,39 +28,14 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** StopTimer.kt in interaction-capabilities-productivity */
private const val CAPABILITY_NAME = "actions.intent.STOP_TIMER"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StopTimer.Arguments::class.java, StopTimer.Arguments::Builder)
- .setOutput(StopTimer.Output::class.java)
- .bindRepeatedParameter(
- "timer",
- { properties ->
- Optional.ofNullable(
- properties[StopTimer.PropertyMapStrings.TIMER_LIST.key]
- as Property<TimerValue>
- )
- },
- StopTimer.Arguments.Builder::setTimerList,
- TimerValue.PARAM_VALUE_CONVERTER,
- TimerValue.ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StopTimer.ExecutionStatus::toParamValue
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.STOP_TIMER */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StopTimer private constructor() {
internal enum class PropertyMapStrings(val key: String) {
- TIMER_LIST("timer.timerList"),
+ TIMER_LIST("timer.timerList")
}
class CapabilityBuilder :
@@ -105,7 +81,7 @@
private var timerList: List<TimerValue>? = null
fun setTimerList(
- timerList: List<TimerValue>,
+ timerList: List<TimerValue>
): Builder = apply { this.timerList = timerList }
override fun build(): Arguments = Arguments(timerList)
@@ -166,7 +142,7 @@
val value: Value = Value.newBuilder().setStringValue(status).build()
return ParamValue.newBuilder()
.setStructValue(
- Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build(),
+ Struct.newBuilder().putFields(TypeConverters.FIELD_NAME_TYPE, value).build()
)
.build()
}
@@ -175,4 +151,27 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindRepeatedParameter(
+ "timer",
+ { properties ->
+ properties[PropertyMapStrings.TIMER_LIST.key] as? Property<TimerValue>
+ },
+ Arguments.Builder::setTimerList,
+ TimerValue.PARAM_VALUE_CONVERTER,
+ TimerValue.ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
index 7f21f96..b16d175 100644
--- a/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
+++ b/appactions/interaction/interaction-capabilities-productivity/src/main/java/androidx/appactions/interaction/capabilities/productivity/TimerValue.kt
@@ -17,11 +17,11 @@
package androidx.appactions.interaction.capabilities.productivity
import androidx.appactions.builtintypes.experimental.types.Timer
+import androidx.appactions.interaction.capabilities.core.SearchAction
import androidx.appactions.interaction.capabilities.core.impl.converters.EntityConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.converters.UnionTypeSpec
-import androidx.appactions.interaction.capabilities.core.SearchAction
import java.util.Objects
class TimerValue
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
index 11e0682..908051a 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartEmergencySharing.kt
@@ -21,6 +21,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -31,26 +32,11 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** StartEmergencySharing.kt in interaction-capabilities-safety */
private const val CAPABILITY_NAME = "actions.intent.START_EMERGENCY_SHARING"
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(
- StartEmergencySharing.Arguments::class.java,
- StartEmergencySharing.Arguments::Builder
- )
- .setOutput(StartEmergencySharing.Output::class.java)
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StartEmergencySharing.ExecutionStatus::toParamValue,
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.START_EMERGENCY_SHARING */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StartEmergencySharing private constructor() {
// TODO(b/267805819): Update to include the SessionFactory once Session API is ready.
class CapabilityBuilder :
@@ -167,4 +153,20 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(
+ Arguments::class.java,
+ Arguments::Builder
+ )
+ .setOutput(Output::class.java)
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue,
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
index 9bb6f01..5a9a6e2 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StartSafetyCheck.kt
@@ -23,6 +23,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.ParamValueConverter
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
@@ -37,57 +38,15 @@
import androidx.appactions.interaction.protobuf.Value
import java.time.Duration
import java.time.ZonedDateTime
-import java.util.Optional
-/** StartSafetyCheck.kt in interaction-capabilities-safety */
private const val CAPABILITY_NAME = "actions.intent.START_SAFETY_CHECK"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StartSafetyCheck.Arguments::class.java, StartSafetyCheck.Arguments::Builder)
- .setOutput(StartSafetyCheck.Output::class.java)
- .bindOptionalParameter(
- "safetyCheck.duration",
- { properties ->
- Optional.ofNullable(
- properties[StartSafetyCheck.PropertyMapStrings.DURATION.key]
- as Property<Duration>
- )
- },
- StartSafetyCheck.Arguments.Builder::setDuration,
- TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
- TypeConverters.DURATION_ENTITY_CONVERTER
- )
- .bindOptionalParameter(
- "safetyCheck.checkInTime",
- { property ->
- Optional.ofNullable(
- property[StartSafetyCheck.PropertyMapStrings.CHECK_IN_TIME.key]
- as Property<ZonedDateTime>
- )
- },
- StartSafetyCheck.Arguments.Builder::setCheckInTime,
- TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER,
- TypeConverters.ZONED_DATETIME_ENTITY_CONVERTER
- )
- .bindOptionalOutput(
- "safetyCheck",
- { output -> Optional.ofNullable(output.safetyCheck) },
- ParamValueConverter.of(SAFETY_CHECK_TYPE_SPEC)::toParamValue
- )
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StartSafetyCheck.ExecutionStatus::toParamValue
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.START_SAFETY_CHECK */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StartSafetyCheck private constructor() {
internal enum class PropertyMapStrings(val key: String) {
DURATION("safetycheck.duration"),
- CHECK_IN_TIME("safetycheck.checkInTime"),
+ CHECK_IN_TIME("safetycheck.checkInTime")
}
// TODO(b/267805819): Update to include the SessionFactory once Session API is ready.
@@ -256,7 +215,7 @@
.setStructValue(
Struct.newBuilder()
.putFields(TypeConverters.FIELD_NAME_TYPE, value)
- .build(),
+ .build()
)
.build()
}
@@ -265,4 +224,41 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "safetyCheck.duration",
+ { properties ->
+ properties[PropertyMapStrings.DURATION.key] as? Property<Duration>
+ },
+ Arguments.Builder::setDuration,
+ TypeConverters.DURATION_PARAM_VALUE_CONVERTER,
+ TypeConverters.DURATION_ENTITY_CONVERTER
+ )
+ .bindParameter(
+ "safetyCheck.checkInTime",
+ { properties ->
+ properties[PropertyMapStrings.CHECK_IN_TIME.key] as? Property<ZonedDateTime>
+ },
+ Arguments.Builder::setCheckInTime,
+ TypeConverters.ZONED_DATETIME_PARAM_VALUE_CONVERTER,
+ TypeConverters.ZONED_DATETIME_ENTITY_CONVERTER
+ )
+ .bindOutput(
+ "safetyCheck",
+ Output::safetyCheck,
+ ParamValueConverter.of(SAFETY_CHECK_TYPE_SPEC)::toParamValue
+ )
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
index 731aff5..28967d6 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopEmergencySharing.kt
@@ -22,6 +22,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -31,26 +32,11 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** StopEmergencySharing.kt in interaction-capabilities-safety */
private const val CAPABILITY_NAME = "actions.intent.STOP_EMERGENCY_SHARING"
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(
- StopEmergencySharing.Arguments::class.java,
- StopEmergencySharing.Arguments::Builder
- )
- .setOutput(StopEmergencySharing.Output::class.java)
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StopEmergencySharing.ExecutionStatus::toParamValue,
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.STOP_EMERGENCY_SHARING */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StopEmergencySharing private constructor() {
// TODO(b/267805819): Update to include the SessionFactory once Session API is ready.
class CapabilityBuilder :
@@ -168,4 +154,20 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(
+ Arguments::class.java,
+ Arguments::Builder
+ )
+ .setOutput(Output::class.java)
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue,
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
index 3d3ffed..53893f4 100644
--- a/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
+++ b/appactions/interaction/interaction-capabilities-safety/src/main/java/androidx/appactions/interaction/capabilities/safety/StopSafetyCheck.kt
@@ -22,6 +22,7 @@
import androidx.appactions.builtintypes.experimental.types.SuccessStatus
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
import androidx.appactions.interaction.capabilities.core.Capability
+import androidx.appactions.interaction.capabilities.core.CapabilityFactory
import androidx.appactions.interaction.capabilities.core.impl.BuilderOf
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
import androidx.appactions.interaction.capabilities.core.impl.spec.ActionSpecBuilder
@@ -31,23 +32,11 @@
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.protobuf.Struct
import androidx.appactions.interaction.protobuf.Value
-import java.util.Optional
-/** StopSafetyCheck.kt in interaction-capabilities-safety */
private const val CAPABILITY_NAME = "actions.intent.STOP_SAFETY_CHECK"
-private val ACTION_SPEC =
- ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(StopSafetyCheck.Arguments::class.java, StopSafetyCheck.Arguments::Builder)
- .setOutput(StopSafetyCheck.Output::class.java)
- .bindOptionalOutput(
- "executionStatus",
- { output -> Optional.ofNullable(output.executionStatus) },
- StopSafetyCheck.ExecutionStatus::toParamValue
- )
- .build()
-
-// TODO(b/267806701): Add capability factory annotation once the testing library is fully migrated.
+/** A capability corresponding to actions.intent.STOP_SAFETY_CHECK */
+@CapabilityFactory(name = CAPABILITY_NAME)
class StopSafetyCheck private constructor() {
// TODO(b/267805819): Update to include the SessionFactory once Session API is ready.
class CapabilityBuilder :
@@ -164,4 +153,17 @@
class Confirmation internal constructor()
sealed interface ExecutionSession : BaseExecutionSession<Arguments, Output>
+
+ companion object {
+ private val ACTION_SPEC =
+ ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindOutput(
+ "executionStatus",
+ Output::executionStatus,
+ ExecutionStatus::toParamValue
+ )
+ .build()
+ }
}
diff --git a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiSessions.kt b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiSessions.kt
index 1774fa6..4214766 100644
--- a/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiSessions.kt
+++ b/appactions/interaction/interaction-service/src/main/java/androidx/appactions/interaction/service/UiSessions.kt
@@ -18,8 +18,8 @@
package androidx.appactions.interaction.service
import androidx.annotation.GuardedBy
-import androidx.appactions.interaction.capabilities.core.ExecutionCallback
import androidx.appactions.interaction.capabilities.core.BaseExecutionSession
+import androidx.appactions.interaction.capabilities.core.ExecutionCallback
import androidx.appactions.interaction.capabilities.core.impl.UiHandleRegistry
import androidx.appactions.interaction.service.UiSessions.removeUiCache
import javax.annotation.concurrent.ThreadSafe
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
index b24255e..0e955b2 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/AppInteractionServiceGrpcImplTest.kt
@@ -17,8 +17,8 @@
package androidx.appactions.interaction.service
import androidx.appactions.interaction.capabilities.core.Capability
-import androidx.appactions.interaction.capabilities.core.impl.CapabilitySession
import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal
+import androidx.appactions.interaction.capabilities.core.impl.CapabilitySession
import androidx.appactions.interaction.proto.AppActionsContext.AppAction
import androidx.appactions.interaction.proto.AppActionsContext.AppDialogState
import androidx.appactions.interaction.proto.FulfillmentRequest
@@ -30,24 +30,15 @@
import androidx.appactions.interaction.service.AppInteractionServiceGrpcImpl.Companion.ERROR_NO_FULFILLMENT_REQUEST
import androidx.appactions.interaction.service.AppInteractionServiceGrpcImpl.Companion.ERROR_NO_SESSION
import androidx.appactions.interaction.service.AppInteractionServiceGrpcImpl.Companion.ERROR_SESSION_ENDED
-import androidx.appactions.interaction.service.testing.internal.FakeAppInteractionService
import androidx.appactions.interaction.service.proto.AppInteractionServiceGrpc
import androidx.appactions.interaction.service.proto.AppInteractionServiceGrpc.AppInteractionServiceStub
import androidx.appactions.interaction.service.proto.AppInteractionServiceProto.Request
import androidx.appactions.interaction.service.proto.AppInteractionServiceProto.StartSessionRequest
import androidx.appactions.interaction.service.proto.AppInteractionServiceProto.StartSessionResponse
+import androidx.appactions.interaction.service.testing.internal.FakeAppInteractionService
import androidx.concurrent.futures.await
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.doAnswer
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.never
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
-import org.robolectric.Robolectric
import io.grpc.BindableService
import io.grpc.ManagedChannel
import io.grpc.Server
@@ -67,6 +58,15 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import org.robolectric.Robolectric
// TODO(b/271929200) Implement tests for the 2 UI related RPCs
@RunWith(AndroidJUnit4::class)
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/SessionManagerTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/SessionManagerTest.kt
index 95e16b9..ebc1d73 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/SessionManagerTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/SessionManagerTest.kt
@@ -16,9 +16,9 @@
package androidx.appactions.interaction.service
-import androidx.appactions.interaction.capabilities.core.impl.CapabilitySession
import androidx.appactions.interaction.capabilities.core.impl.ArgumentsWrapper
import androidx.appactions.interaction.capabilities.core.impl.CallbackInternal
+import androidx.appactions.interaction.capabilities.core.impl.CapabilitySession
import androidx.appactions.interaction.capabilities.core.impl.TouchEventCallback
import androidx.appactions.interaction.proto.AppActionsContext
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
index 64335ff..970860c 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/UiSessionsTest.kt
@@ -22,17 +22,17 @@
import androidx.appactions.interaction.capabilities.core.ExecutionCallback
import androidx.appactions.interaction.capabilities.core.ExecutionResult
import androidx.appactions.interaction.capabilities.core.HostProperties
+import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildArgs
+import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildRequestArgs
+import androidx.appactions.interaction.capabilities.testing.internal.FakeCallbackInternal
+import androidx.appactions.interaction.capabilities.testing.internal.TestingUtils.CB_TIMEOUT
import androidx.appactions.interaction.proto.FulfillmentRequest.Fulfillment.Type.SYNC
import androidx.appactions.interaction.proto.ParamValue
import androidx.appactions.interaction.service.test.R
-import androidx.appactions.interaction.capabilities.testing.internal.FakeCallbackInternal
-import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildRequestArgs
-import androidx.appactions.interaction.capabilities.testing.internal.ArgumentUtils.buildArgs
-import androidx.appactions.interaction.capabilities.testing.internal.TestingUtils.CB_TIMEOUT
import androidx.appactions.interaction.service.testing.internal.FakeCapability
import androidx.appactions.interaction.service.testing.internal.FakeCapability.Arguments
-import androidx.appactions.interaction.service.testing.internal.FakeCapability.Output
import androidx.appactions.interaction.service.testing.internal.FakeCapability.ExecutionSession
+import androidx.appactions.interaction.service.testing.internal.FakeCapability.Output
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
index fd99a27..e0151be 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAlarmEntityProvider.kt
@@ -17,10 +17,10 @@
package androidx.appactions.interaction.service.testing.internal
import androidx.appactions.builtintypes.experimental.types.Alarm
-import androidx.appactions.interaction.capabilities.core.entity.EntityProvider
+import androidx.appactions.interaction.capabilities.core.entity.EntityLookupCandidate
import androidx.appactions.interaction.capabilities.core.entity.EntityLookupRequest
import androidx.appactions.interaction.capabilities.core.entity.EntityLookupResponse
-import androidx.appactions.interaction.capabilities.core.entity.EntityLookupCandidate
+import androidx.appactions.interaction.capabilities.core.entity.EntityProvider
import androidx.appactions.interaction.capabilities.core.impl.converters.TypeConverters
class FakeAlarmEntityProvider(
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAppInteractionService.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAppInteractionService.kt
index 9521309..e4e6f44 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAppInteractionService.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeAppInteractionService.kt
@@ -16,10 +16,10 @@
package androidx.appactions.interaction.service.testing.internal
-import androidx.appactions.interaction.service.AppInteractionService
-import androidx.appactions.interaction.service.AppVerificationInfo
import androidx.appactions.interaction.capabilities.core.Capability
import androidx.appactions.interaction.capabilities.core.entity.EntityProvider
+import androidx.appactions.interaction.service.AppInteractionService
+import androidx.appactions.interaction.service.AppVerificationInfo
import io.grpc.binder.SecurityPolicies
import io.grpc.binder.SecurityPolicy
diff --git a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeCapability.kt b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeCapability.kt
index 9708c4a..1105d83 100644
--- a/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeCapability.kt
+++ b/appactions/interaction/interaction-service/src/test/java/androidx/appactions/interaction/service/testing/internal/FakeCapability.kt
@@ -26,19 +26,8 @@
import androidx.appactions.interaction.capabilities.core.impl.task.TaskHandler
import androidx.appactions.interaction.capabilities.core.properties.Property
import androidx.appactions.interaction.capabilities.core.properties.StringValue
-import java.util.Optional
private const val CAPABILITY_NAME = "actions.intent.FAKE_CAPABILITY"
-@Suppress("UNCHECKED_CAST")
-private val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
- .setArguments(FakeCapability.Arguments::class.java, FakeCapability.Arguments::Builder)
- .setOutput(FakeCapability.Output::class.java).bindOptionalParameter(
- "fieldOne",
- { property -> Optional.ofNullable(property["fieldOne"] as Property<StringValue>) },
- FakeCapability.Arguments.Builder::setFieldOne,
- TypeConverters.STRING_PARAM_VALUE_CONVERTER,
- TypeConverters.STRING_VALUE_ENTITY_CONVERTER,
- ).build()
class FakeCapability private constructor() {
class Properties(
@@ -73,9 +62,9 @@
Confirmation,
ExecutionSession,
>(ACTION_SPEC) {
- override val sessionBridge = SessionBridge<ExecutionSession, Confirmation> {
+ override val sessionBridge = SessionBridge<ExecutionSession, Arguments, Confirmation> {
session ->
- val builder = TaskHandler.Builder<Confirmation>()
+ val builder = TaskHandler.Builder<Arguments, Confirmation>()
session.fieldOneListener?.let {
builder.registerValueTaskParam(
"fieldOne",
@@ -103,4 +92,19 @@
return super.build()
}
}
+
+ companion object {
+ @Suppress("UNCHECKED_CAST")
+ private val ACTION_SPEC = ActionSpecBuilder.ofCapabilityNamed(CAPABILITY_NAME)
+ .setArguments(Arguments::class.java, Arguments::Builder)
+ .setOutput(Output::class.java)
+ .bindParameter(
+ "fieldOne",
+ { properties -> properties["fieldOne"] as? Property<StringValue> },
+ Arguments.Builder::setFieldOne,
+ TypeConverters.STRING_PARAM_VALUE_CONVERTER,
+ TypeConverters.STRING_VALUE_ENTITY_CONVERTER,
+ )
+ .build()
+ }
}
diff --git a/appcompat/appcompat-resources/build.gradle b/appcompat/appcompat-resources/build.gradle
index cd96606..7686cb1 100644
--- a/appcompat/appcompat-resources/build.gradle
+++ b/appcompat/appcompat-resources/build.gradle
@@ -59,8 +59,9 @@
}
androidx {
- name = "Android Resources Library"
+ name = "AppCompat Resources"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
- description = "The Resources Library is a static library that you can add to your Android application in order to use resource APIs that backport the latest APIs to older versions of the platform. Compatible on devices running API 14 or later."
+ description = "Provides backward-compatible implementations of resource-related Android SDK" +
+ "functionality, including color state list theming."
}
diff --git a/appcompat/appcompat-resources/src/main/AndroidManifest.xml b/appcompat/appcompat-resources/src/main/AndroidManifest.xml
deleted file mode 100644
index 2766785..0000000
--- a/appcompat/appcompat-resources/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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 />
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index 614c612..22296ee 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -104,9 +104,10 @@
}
androidx {
- name = "Android AppCompat Library"
+ name = "AppCompat"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2011"
- description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+ description = "Provides backwards-compatible implementations of UI-related Android SDK " +
+ "functionality, including dark mode and Material theming."
failOnDeprecationWarnings = false
}
diff --git a/appcompat/appcompat/lint-baseline.xml b/appcompat/appcompat/lint-baseline.xml
index 0936e35..dc8d901 100644
--- a/appcompat/appcompat/lint-baseline.xml
+++ b/appcompat/appcompat/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.0.0-beta03" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.0.0-beta03">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
<issue
id="NewApi"
@@ -434,6 +434,24 @@
</issue>
<issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastT()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/appcompat/widget/DropDownListView.java"/>
+ </issue>
+
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastT()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/appcompat/widget/DropDownListView.java"/>
+ </issue>
+
+ <issue
id="KotlinPropertyAccess"
message="The getter return type (`View`) and setter parameter type (`ScrollingTabContainerView`) getter and setter methods for property `tabContainer` should have exactly the same type to allow be accessed as a property from Kotlin; see https://android.github.io/kotlin-guides/interop.html#property-prefixes"
errorLine1=" public View getTabContainer() {"
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatActivityViewTreeTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatActivityViewTreeTest.kt
index e3dafc5..050577f 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatActivityViewTreeTest.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatActivityViewTreeTest.kt
@@ -16,10 +16,10 @@
package androidx.appcompat.app
-import androidx.lifecycle.findViewTreeLifecycleOwner
-import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.activity.findViewTreeOnBackPressedDispatcherOwner
+import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatDialogTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatDialogTest.kt
index ceb8677..c82b2ce 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatDialogTest.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/AppCompatDialogTest.kt
@@ -17,8 +17,8 @@
package androidx.appcompat.app
import android.view.View
-import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRtlTestUtilsRegressionTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRtlTestUtilsRegressionTestCase.kt
index d395ac9..3144e25 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRtlTestUtilsRegressionTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeRtlTestUtilsRegressionTestCase.kt
@@ -25,13 +25,13 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
+import java.util.Locale
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Locale
/**
* This is one approach to customizing Activity configuration that's used in google3.
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
index c0139a5..501bcfc 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NightModeTestCase.kt
@@ -42,6 +42,7 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.LifecycleOwnerUtils.waitForRecreation
import androidx.testutils.waitForExecution
+import java.util.concurrent.CountDownLatch
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
@@ -49,7 +50,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
@Suppress("DEPRECATION")
@LargeTest
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NoThemeAppCompatActivity.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NoThemeAppCompatActivity.kt
index e0a6fb8..f894124 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NoThemeAppCompatActivity.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/NoThemeAppCompatActivity.kt
@@ -17,7 +17,6 @@
package androidx.appcompat.app
import android.os.Bundle
-
import androidx.appcompat.test.R
class NoThemeAppCompatActivity : AppCompatActivity() {
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
index 38d9ab2..5d3fbee 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTest.kt
@@ -30,6 +30,7 @@
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.TimeUnit
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -53,6 +54,7 @@
}
@Test
+ @Ignore("b/280630647")
fun testConfigurationUpdatedOnLandscapeMode() {
// Wait for the activity to fully start before rotating,
// otherwise we won't receive onConfigurationChanged.
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
index 45357c5..eba4c96 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/g3/FilternatorTestWithCustomDefault.kt
@@ -32,6 +32,7 @@
import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -70,6 +71,7 @@
}
@Test
+ @Ignore("b/280630647")
fun testConfigurationUpdatedOnLandscapeMode() {
// Wait for the activity to fully start before rotating,
// otherwise we won't receive onConfigurationChanged.
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatAttributeTest.kt b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatAttributeTest.kt
index 715a55e..aa2e0f5 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatAttributeTest.kt
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/widget/AppCompatAttributeTest.kt
@@ -22,8 +22,8 @@
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
-import androidx.appcompat.test.R
import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.test.R
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
diff --git a/appcompat/appcompat/src/main/AndroidManifest.xml b/appcompat/appcompat/src/main/AndroidManifest.xml
deleted file mode 100644
index 2766785..0000000
--- a/appcompat/appcompat/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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 />
diff --git a/appcompat/appcompat/src/main/res/values-or/strings.xml b/appcompat/appcompat/src/main/res/values-or/strings.xml
index 2ce1a310..ad5622b 100644
--- a/appcompat/appcompat/src/main/res/values-or/strings.xml
+++ b/appcompat/appcompat/src/main/res/values-or/strings.xml
@@ -43,5 +43,5 @@
<string name="abc_menu_function_shortcut_label" msgid="375214403600139847">"Function+"</string>
<string name="abc_menu_space_shortcut_label" msgid="5473865519181928982">"ସ୍ପେସ୍"</string>
<string name="abc_menu_enter_shortcut_label" msgid="7986526966204849475">"ଏଣ୍ଟର୍"</string>
- <string name="abc_menu_delete_shortcut_label" msgid="838001238306846836">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
+ <string name="abc_menu_delete_shortcut_label" msgid="838001238306846836">"ଡିଲିଟ କରନ୍ତୁ"</string>
</resources>
diff --git a/appsearch/appsearch-builtin-types/build.gradle b/appsearch/appsearch-builtin-types/build.gradle
index 892b427..369bdb7 100644
--- a/appsearch/appsearch-builtin-types/build.gradle
+++ b/appsearch/appsearch-builtin-types/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = 'AppSearch Builtin Types'
+ name = "AppSearch Builtin Types"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = '2021'
description = 'Contains AppSearch Document classes and builders for a variety of common ' +
diff --git a/appsearch/appsearch-builtin-types/src/main/AndroidManifest.xml b/appsearch/appsearch-builtin-types/src/main/AndroidManifest.xml
deleted file mode 100644
index a270226..0000000
--- a/appsearch/appsearch-builtin-types/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-
-<manifest />
\ No newline at end of file
diff --git a/appsearch/appsearch-debug-view/build.gradle b/appsearch/appsearch-debug-view/build.gradle
index 1b0c3f2..91cc056 100644
--- a/appsearch/appsearch-debug-view/build.gradle
+++ b/appsearch/appsearch-debug-view/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "AndroidX AppSearch Debug View"
+ name = "AppSearch Debug View"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "A support library for AndroidX AppSearch that contains activities and views " +
diff --git a/appsearch/appsearch-debug-view/samples/build.gradle b/appsearch/appsearch-debug-view/samples/build.gradle
index 6724661..532b284 100644
--- a/appsearch/appsearch-debug-view/samples/build.gradle
+++ b/appsearch/appsearch-debug-view/samples/build.gradle
@@ -46,7 +46,7 @@
}
androidx {
- name = "AndroidX AppSearch Debug View Sample App"
+ name = "AppSearch Debug View Sample App"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains a sample app for integrating the Androidx AppSearch Debug View"
diff --git a/appsearch/appsearch-debug-view/src/main/AndroidManifest.xml b/appsearch/appsearch-debug-view/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/appsearch/appsearch-debug-view/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/appsearch/appsearch-ktx/build.gradle b/appsearch/appsearch-ktx/build.gradle
index fd812db..7b75083 100644
--- a/appsearch/appsearch-ktx/build.gradle
+++ b/appsearch/appsearch-ktx/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = 'AndroidX AppSearch - Kotlin Extensions'
+ name = "AppSearch - Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = '2021'
description = 'AndroidX AppSearch - Kotlin Extensions'
diff --git a/appsearch/appsearch-ktx/src/main/AndroidManifest.xml b/appsearch/appsearch-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index adbf0a8..0000000
--- a/appsearch/appsearch-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-
-<manifest />
diff --git a/appsearch/appsearch-local-storage/src/main/AndroidManifest.xml b/appsearch/appsearch-local-storage/src/main/AndroidManifest.xml
deleted file mode 100644
index e95a361..0000000
--- a/appsearch/appsearch-local-storage/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 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 />
diff --git a/appsearch/appsearch-platform-storage/lint-baseline.xml b/appsearch/appsearch-platform-storage/lint-baseline.xml
index 279ab97..d82c712 100644
--- a/appsearch/appsearch-platform-storage/lint-baseline.xml
+++ b/appsearch/appsearch-platform-storage/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha07" type="baseline" client="gradle" dependencies="false" name="AGP (8.0.0-beta03)" variant="all" version="8.1.0-alpha07">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
<issue
id="WrongConstant"
@@ -244,4 +244,31 @@
file="src/main/java/androidx/appsearch/platformstorage/converter/SetSchemaRequestToPlatformConverter.java"/>
</issue>
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" return BuildCompat.isAtLeastT();"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/appsearch/platformstorage/FeaturesImpl.java"/>
+ </issue>
+
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastT()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/appsearch/platformstorage/converter/GetSchemaResponseToPlatformConverter.java"/>
+ </issue>
+
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastT cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastT()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/appsearch/platformstorage/converter/SearchResultToPlatformConverter.java"/>
+ </issue>
+
</issues>
diff --git a/appsearch/appsearch-platform-storage/src/main/AndroidManifest.xml b/appsearch/appsearch-platform-storage/src/main/AndroidManifest.xml
deleted file mode 100644
index adbf0a8..0000000
--- a/appsearch/appsearch-platform-storage/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-
-<manifest />
diff --git a/appsearch/appsearch/build.gradle b/appsearch/appsearch/build.gradle
index 7c0365c..f991e23 100644
--- a/appsearch/appsearch/build.gradle
+++ b/appsearch/appsearch/build.gradle
@@ -55,7 +55,7 @@
}
androidx {
- name = 'AndroidX AppSearch'
+ name = "AppSearch"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = '2019'
description = 'AndroidX AppSearch - App Indexing'
diff --git a/appsearch/appsearch/src/main/AndroidManifest.xml b/appsearch/appsearch/src/main/AndroidManifest.xml
deleted file mode 100644
index 19e768b..0000000
--- a/appsearch/appsearch/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 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 />
\ No newline at end of file
diff --git a/appsearch/compiler/build.gradle b/appsearch/compiler/build.gradle
index f2c72b7..cb9caf4 100644
--- a/appsearch/compiler/build.gradle
+++ b/appsearch/compiler/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = 'AndroidX AppSearch Compiler'
+ name = "AppSearch Compiler"
type = LibraryType.ANNOTATION_PROCESSOR
inceptionYear = '2019'
description = 'Compiler for classes annotated with @androidx.appsearch.annotation.Document'
diff --git a/arch/core/core-common/build.gradle b/arch/core/core-common/build.gradle
index 8a60844..f8d646f7 100644
--- a/arch/core/core-common/build.gradle
+++ b/arch/core/core-common/build.gradle
@@ -29,7 +29,7 @@
}
androidx {
- name = "Android Arch-Common"
+ name = "Arch-Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Arch-Common"
diff --git a/arch/core/core-runtime/build.gradle b/arch/core/core-runtime/build.gradle
index 6652bdf..f1d60e1 100644
--- a/arch/core/core-runtime/build.gradle
+++ b/arch/core/core-runtime/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "Android Arch-Runtime"
+ name = "Arch-Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Arch-Runtime"
diff --git a/arch/core/core-testing/build.gradle b/arch/core/core-testing/build.gradle
index 0476e53..4b071ea 100644
--- a/arch/core/core-testing/build.gradle
+++ b/arch/core/core-testing/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Core-Testing"
+ name = "Core-Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Core-Testing"
diff --git a/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle b/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
index 8f08e8c..a6034b9 100644
--- a/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
+++ b/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
@@ -13,10 +13,11 @@
}
androidx {
- name = "AsyncLayoutInflater integration for AppCompat"
+ name = "AsyncLayoutInflater AppCompat"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2022"
- description = "A thread-safe LayoutInflater Factory that provides compatibility between AsyncLayoutInflater and AppCompat."
+ description = "A thread-safe LayoutInflater Factory that provides compatibility between " +
+ "AsyncLayoutInflater and AppCompat."
}
android {
diff --git a/asynclayoutinflater/asynclayoutinflater-appcompat/src/main/AndroidManifest.xml b/asynclayoutinflater/asynclayoutinflater-appcompat/src/main/AndroidManifest.xml
deleted file mode 100644
index 2d12952..0000000
--- a/asynclayoutinflater/asynclayoutinflater-appcompat/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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 />
diff --git a/asynclayoutinflater/asynclayoutinflater/build.gradle b/asynclayoutinflater/asynclayoutinflater/build.gradle
index 713ec8e..44ec7c0 100644
--- a/asynclayoutinflater/asynclayoutinflater/build.gradle
+++ b/asynclayoutinflater/asynclayoutinflater/build.gradle
@@ -19,10 +19,10 @@
}
androidx {
- name = "Android Support Library Async Layout Inflater"
+ name = "AsyncLayoutInflater"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
- description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+ description = "Provides support for inflating layouts off the UI thread."
}
android {
diff --git a/asynclayoutinflater/asynclayoutinflater/src/main/AndroidManifest.xml b/asynclayoutinflater/asynclayoutinflater/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/asynclayoutinflater/asynclayoutinflater/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/autofill/autofill/build.gradle b/autofill/autofill/build.gradle
index c4a5853..e5bbb65 100644
--- a/autofill/autofill/build.gradle
+++ b/autofill/autofill/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Autofill"
+ name = "Autofill"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "AndroidX Autofill"
diff --git a/autofill/autofill/src/main/AndroidManifest.xml b/autofill/autofill/src/main/AndroidManifest.xml
deleted file mode 100644
index 19e768b..0000000
--- a/autofill/autofill/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 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 />
\ No newline at end of file
diff --git a/benchmark/baseline-profile-gradle-plugin/build.gradle b/benchmark/baseline-profile-gradle-plugin/build.gradle
index 057bc2d1..e4884b6 100644
--- a/benchmark/baseline-profile-gradle-plugin/build.gradle
+++ b/benchmark/baseline-profile-gradle-plugin/build.gradle
@@ -22,6 +22,15 @@
id("java-gradle-plugin")
}
+// This custom configuration ensures that dependencies used in tests with gradle test kit with
+// generated build.gradle are considered when determining which tests to run on CI due to a change.
+// For reference: b/281515796
+configurations {
+ neededForGradleTestKit {
+ canBeResolved = true
+ }
+}
+
dependencies {
implementation(gradleApi())
implementation(libs.androidGradlePluginz)
@@ -35,6 +44,8 @@
testImplementation(libs.junit)
testImplementation(libs.kotlinTest)
testImplementation(libs.truth)
+
+ neededForGradleTestKit(libs.androidGradlePluginz)
}
SdkResourceGenerator.generateForHostTest(project)
@@ -61,7 +72,7 @@
}
androidx {
- name = "Android Baseline Profile Gradle Plugin"
+ name = "Baseline Profile Gradle Plugin"
publish = Publish.SNAPSHOT_AND_RELEASE
type = LibraryType.GRADLE_PLUGIN
inceptionYear = "2022"
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerExtension.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerExtension.kt
index 0ae17d0..00934a5 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerExtension.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerExtension.kt
@@ -54,19 +54,30 @@
// These are the default global settings.
it.mergeIntoMain = null
it.baselineProfileOutputDir = "generated/baselineProfiles"
- it.enableR8BaselineProfileRewrite = false
+ it.baselineProfileRulesRewrite = null
+ it.dexLayoutOptimization = null
it.saveInSrc = true
it.automaticGenerationDuringBuild = false
}
/**
- * Controls the global [BaselineProfileVariantConfiguration.enableR8BaselineProfileRewrite].
+ * Controls the global [BaselineProfileVariantConfiguration.baselineProfileRulesRewrite].
* Note that this value is overridden by per variant configurations.
*/
- override var enableR8BaselineProfileRewrite: Boolean?
- get() = main.enableR8BaselineProfileRewrite
+ override var baselineProfileRulesRewrite: Boolean?
+ get() = main.baselineProfileRulesRewrite
set(value) {
- main.enableR8BaselineProfileRewrite = value
+ main.baselineProfileRulesRewrite = value
+ }
+
+ /**
+ * Controls the global [BaselineProfileVariantConfiguration.dexLayoutOptimization].
+ * Note that this value is overridden by per variant configurations.
+ */
+ override var dexLayoutOptimization: Boolean?
+ get() = main.dexLayoutOptimization
+ set(value) {
+ main.dexLayoutOptimization = value
}
/**
@@ -182,7 +193,13 @@
* TODO: This feature is experimental and currently not working properly.
* https://issuetracker.google.com/issue?id=271172067.
*/
- var enableR8BaselineProfileRewrite: Boolean?
+ var baselineProfileRulesRewrite: Boolean?
+
+ /**
+ * Enables R8 to optimize the primary dex file used to contain only classes utilized for
+ * startup.
+ */
+ var dexLayoutOptimization: Boolean?
/**
* Specifies whether generated baseline profiles should be stored in the src folder.
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
index 995c84d..b2792c6 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPlugin.kt
@@ -20,6 +20,7 @@
import androidx.baselineprofile.gradle.consumer.task.MainGenerateBaselineProfileTask
import androidx.baselineprofile.gradle.consumer.task.MergeBaselineProfileTask
import androidx.baselineprofile.gradle.consumer.task.PrintConfigurationForVariantTask
+import androidx.baselineprofile.gradle.consumer.task.PrintMapPropertiesForVariantTask
import androidx.baselineprofile.gradle.consumer.task.maybeCreateGenerateTask
import androidx.baselineprofile.gradle.utils.AgpFeature
import androidx.baselineprofile.gradle.utils.AgpPlugin
@@ -169,10 +170,19 @@
variant = variant,
variantConfig = variantConfiguration
)
+ PrintMapPropertiesForVariantTask.registerForVariant(
+ project = project,
+ variant = variant
+ )
// Sets the r8 rewrite baseline profile for the non debuggable variant.
- if (variantConfiguration.enableR8BaselineProfileRewrite) {
- r8Utils.enableR8RulesRewriteForVariant(variant)
+ variantConfiguration.baselineProfileRulesRewrite?.let {
+ r8Utils.setRulesRewriteForVariantEnabled(variant, it)
+ }
+
+ // Sets the r8 startup dex optimization profile for the non debuggable variant.
+ variantConfiguration.dexLayoutOptimization?.let {
+ r8Utils.setDexLayoutOptimizationEnabled(variant, it)
}
// Check if this variant has any direct dependency
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/PerVariantConsumerExtensionManager.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/PerVariantConsumerExtensionManager.kt
index 6168f23..eb7b035 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/PerVariantConsumerExtensionManager.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/PerVariantConsumerExtensionManager.kt
@@ -52,8 +52,11 @@
val dependencies: List<Pair<Project, String?>>
get() = getMergedListForVariant(variant) { dependencies }
- val enableR8BaselineProfileRewrite: Boolean
- get() = getOverriddenValueForVariant(variant) { enableR8BaselineProfileRewrite }
+ val baselineProfileRulesRewrite: Boolean?
+ get() = getOverriddenValueForVariantAllowNull(variant) { baselineProfileRulesRewrite }
+
+ val dexLayoutOptimization: Boolean?
+ get() = getOverriddenValueForVariantAllowNull(variant) { dexLayoutOptimization }
val saveInSrc: Boolean
get() = getOverriddenValueForVariant(variant) { saveInSrc }
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintConfigurationForVariantTask.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintConfigurationForVariantTask.kt
index c9e2d08..d33f08a 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintConfigurationForVariantTask.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintConfigurationForVariantTask.kt
@@ -49,7 +49,8 @@
"""
mergeIntoMain=`${variantConfig.mergeIntoMain}`
baselineProfileOutputDir=`${variantConfig.baselineProfileOutputDir}`
- enableR8BaselineProfileRewrite=`${variantConfig.enableR8BaselineProfileRewrite}`
+ baselineProfileRulesRewrite=`${variantConfig.baselineProfileRulesRewrite}`
+ dexLayoutOptimization=`${variantConfig.dexLayoutOptimization}`
saveInSrc=`${variantConfig.saveInSrc}`
automaticGenerationDuringBuild=`${variantConfig.automaticGenerationDuringBuild}`
""".trimIndent()
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintMapPropertiesForVariantTask.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintMapPropertiesForVariantTask.kt
new file mode 100644
index 0000000..2318a42
--- /dev/null
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/consumer/task/PrintMapPropertiesForVariantTask.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.baselineprofile.gradle.consumer.task
+
+import androidx.baselineprofile.gradle.utils.maybeRegister
+import com.android.build.api.variant.Variant
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.provider.MapProperty
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.TaskAction
+import org.gradle.work.DisableCachingByDefault
+
+/**
+ * Only used for testing, this task does not have description or group so that it doesn't show up
+ * in the task list. It prints internal properties to facilitate assertions in integration tests.
+ */
+@DisableCachingByDefault(because = "Not worth caching. Used only for tests.")
+abstract class PrintMapPropertiesForVariantTask : DefaultTask() {
+
+ companion object {
+
+ private const val TASK_NAME_PREFIX = "printExperimentalPropertiesForVariant"
+
+ internal fun registerForVariant(
+ project: Project,
+ variant: Variant,
+ ) {
+ project
+ .tasks
+ .maybeRegister<PrintMapPropertiesForVariantTask>(TASK_NAME_PREFIX, variant.name) {
+ it.properties.set(variant.experimentalProperties)
+ }
+ }
+ }
+
+ @get: Input
+ abstract val properties: MapProperty<String, Any>
+
+ @TaskAction
+ fun exec() {
+ properties.get().forEach { logger.warn("${it.key}=${it.value}") }
+ }
+}
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/AgpPlugin.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/AgpPlugin.kt
index 413406a..19d2d8d 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/AgpPlugin.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/AgpPlugin.kt
@@ -50,16 +50,6 @@
private val maxAgpVersion: AndroidPluginVersion,
) {
- companion object {
- private val gradleSyncProps by lazy {
- listOf(
- "android.injected.build.model.v2",
- "android.injected.build.model.only",
- "android.injected.build.model.only.advanced",
- )
- }
- }
-
protected val logger: Logger
get() = project.logger
@@ -175,9 +165,7 @@
}
}
- protected fun isGradleSyncRunning() = gradleSyncProps.any {
- it in project.properties && project.properties[it].toString().toBoolean()
- }
+ protected fun isGradleSyncRunning() = project.isGradleSyncRunning()
protected fun afterVariants(block: () -> (Unit)) = afterVariantBlocks.add(block)
@@ -277,6 +265,18 @@
.findByType(com.android.build.gradle.TestExtension::class.java)
}
+private val gradleSyncProps by lazy {
+ listOf(
+ "android.injected.build.model.v2",
+ "android.injected.build.model.only",
+ "android.injected.build.model.only.advanced",
+ )
+}
+
+internal fun Project.isGradleSyncRunning() = gradleSyncProps.any {
+ it in project.properties && project.properties[it].toString().toBoolean()
+}
+
/**
* Enumerates the supported android plugins.
*/
diff --git a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/R8Utils.kt b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/R8Utils.kt
index 121dc35..a56a3de 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/R8Utils.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/main/kotlin/androidx/baselineprofile/gradle/utils/R8Utils.kt
@@ -32,26 +32,56 @@
companion object {
private const val PROPERTY_R8_REWRITE_BASELINE_PROFILE_RULES =
"android.experimental.art-profile-r8-rewriting"
- private val AGP_MIN_VERSION = AndroidPluginVersion(8, 1, 0).alpha(8)
+ private const val PROPERTY_R8_DEX_LAYOUT_OPTIMIZATION =
+ "android.experimental.r8.dex-startup-optimization"
}
@Suppress("UnstableApiUsage")
- fun enableR8RulesRewriteForVariant(variant: Variant) {
+ fun setRulesRewriteForVariantEnabled(variant: Variant, value: Boolean) {
// Checks the AGP min version to support this.
- if (project.agpVersion() < AGP_MIN_VERSION) {
+ if (project.agpVersion() < AndroidPluginVersion(8, 1, 0).alpha(8)) {
+ if (!project.isGradleSyncRunning()) {
+ throw IllegalStateException(
+ """
+ Unable to set baseline profile rules rewrite property in module `${project.path}`
+ due to minimum AGP version requirement not met. This functionality requires at
+ least AGP version 8.1.0. Please check your module build.gradle file and ensure
+ the property `baselineProfileRulesRewrite` is not set.
+ """.trimIndent()
+ )
+ }
return
}
- // TODO: Checks the R8 version to support this.
-
// TODO: Note that currently there needs to be at least a baseline profile,
// even if empty. For this reason we always add a src set that points to
// an empty file. This can removed after b/271158087 is fixed.
- GenerateDummyBaselineProfileTask.setupForVariant(project, variant)
+ if (value) GenerateDummyBaselineProfileTask.setupForVariant(project, variant)
// Sets the experimental property
- variant.experimentalProperties.put(PROPERTY_R8_REWRITE_BASELINE_PROFILE_RULES, true)
+ variant.experimentalProperties.put(PROPERTY_R8_REWRITE_BASELINE_PROFILE_RULES, value)
+ }
+
+ @Suppress("UnstableApiUsage")
+ fun setDexLayoutOptimizationEnabled(variant: Variant, value: Boolean) {
+
+ // Checks the AGP min version to support this.
+ if (project.agpVersion() < AndroidPluginVersion(8, 1, 0).alpha(11)) {
+ if (!project.isGradleSyncRunning()) {
+ throw IllegalStateException(
+ """
+ Unable to set dex layout optimization property in module `${project.path}` due to
+ minimum AGP version requirement not met. This functionality requires at least AGP
+ version 8.1.0. Please check your module build.gradle file and ensure the property
+ `dexLayoutOptimization` is not set.
+ """.trimIndent()
+ )
+ }
+ }
+
+ // Sets the experimental property
+ variant.experimentalProperties.put(PROPERTY_R8_DEX_LAYOUT_OPTIMIZATION, value)
}
}
diff --git a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
index a7e1cdf..2ab457a 100644
--- a/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
+++ b/benchmark/baseline-profile-gradle-plugin/src/test/kotlin/androidx/baselineprofile/gradle/consumer/BaselineProfileConsumerPluginTest.kt
@@ -27,6 +27,7 @@
import androidx.baselineprofile.gradle.utils.VariantProfile
import androidx.baselineprofile.gradle.utils.build
import androidx.baselineprofile.gradle.utils.buildAndAssertThatOutput
+import androidx.baselineprofile.gradle.utils.buildAndFailAndAssertThatOutput
import androidx.baselineprofile.gradle.utils.require
import androidx.baselineprofile.gradle.utils.requireInOrder
import com.google.common.truth.Truth.assertThat
@@ -286,9 +287,6 @@
androidPlugin = ANDROID_APPLICATION_PLUGIN,
flavors = true,
dependencyOnProducerProject = true,
- baselineProfileBlock = """
- enableR8BaselineProfileRewrite = false
- """.trimIndent(),
additionalGradleCodeBlock = """
androidComponents {
onVariants(selector()) { variant ->
@@ -343,7 +341,7 @@
}
@Test
- fun testR8RewriteBaselineProfilePropertySet() {
+ fun testExperimentalPropertiesNotSet() {
projectSetup.producer.setupWithFreeAndPaidFlavors(
freeReleaseProfileLines = listOf(Fixtures.CLASS_1_METHOD_1, Fixtures.CLASS_1),
paidReleaseProfileLines = listOf(Fixtures.CLASS_2_METHOD_1, Fixtures.CLASS_2)
@@ -352,31 +350,20 @@
androidPlugin = ANDROID_LIBRARY_PLUGIN,
dependencyOnProducerProject = true,
flavors = true,
- buildTypeAnotherRelease = true,
- additionalGradleCodeBlock = """
- androidComponents {
- onVariants(selector()) { variant ->
- println(variant.name)
- tasks.register("print" + variant.name, PrintTask) { t ->
- def prop = "android.experimental.art-profile-r8-rewriting"
- if (prop in variant.experimentalProperties) {
- def value = variant.experimentalProperties[prop].get().toString()
- t.text.set( "r8-rw=" + value)
- } else {
- t.text.set( "r8-rw=false")
- }
- }
- }
- }
- """.trimIndent()
+ buildTypeAnotherRelease = true
)
arrayOf(
- "printFreeRelease",
- "printPaidRelease",
- "printFreeAnotherRelease",
- "printPaidAnotherRelease",
- ).forEach { gradleRunner.buildAndAssertThatOutput(it) { contains("r8-rw=false") } }
+ "printExperimentalPropertiesForVariantFreeRelease",
+ "printExperimentalPropertiesForVariantPaidRelease",
+ "printExperimentalPropertiesForVariantFreeAnotherRelease",
+ "printExperimentalPropertiesForVariantPaidAnotherRelease",
+ ).forEach {
+ gradleRunner.buildAndAssertThatOutput(it) {
+ doesNotContain("android.experimental.art-profile-r8-rewriting=")
+ doesNotContain("android.experimental.r8.dex-startup-optimization=")
+ }
+ }
}
@Test
@@ -672,7 +659,6 @@
baselineProfileBlock = """
// Global configuration
- enableR8BaselineProfileRewrite = false
saveInSrc = true
automaticGenerationDuringBuild = false
baselineProfileOutputDir = "generated/baselineProfiles"
@@ -681,14 +667,12 @@
// Per variant configuration overrides global configuration.
variants {
free {
- enableR8BaselineProfileRewrite = true
saveInSrc = false
automaticGenerationDuringBuild = true
baselineProfileOutputDir = "somefolder"
mergeIntoMain = false
}
paidRelease {
- enableR8BaselineProfileRewrite = true
saveInSrc = false
automaticGenerationDuringBuild = true
baselineProfileOutputDir = "someOtherfolder"
@@ -702,7 +686,6 @@
gradleRunner.buildAndAssertThatOutput(
"printBaselineProfileExtensionForVariantFreeRelease"
) {
- contains("enableR8BaselineProfileRewrite=`true`")
contains("saveInSrc=`false`")
contains("automaticGenerationDuringBuild=`true`")
contains("baselineProfileOutputDir=`somefolder`")
@@ -712,7 +695,6 @@
gradleRunner.buildAndAssertThatOutput(
"printBaselineProfileExtensionForVariantPaidRelease"
) {
- contains("enableR8BaselineProfileRewrite=`true`")
contains("saveInSrc=`false`")
contains("automaticGenerationDuringBuild=`true`")
contains("baselineProfileOutputDir=`someOtherfolder`")
@@ -732,7 +714,6 @@
baselineProfileBlock = """
// Global configuration
- enableR8BaselineProfileRewrite = false
saveInSrc = true
automaticGenerationDuringBuild = false
baselineProfileOutputDir = "generated/baselineProfiles"
@@ -741,14 +722,12 @@
// Per variant configuration overrides global configuration.
variants {
release {
- enableR8BaselineProfileRewrite = true
saveInSrc = false
automaticGenerationDuringBuild = true
baselineProfileOutputDir = "myReleaseFolder"
mergeIntoMain = false
}
paidRelease {
- enableR8BaselineProfileRewrite = true
saveInSrc = false
automaticGenerationDuringBuild = true
baselineProfileOutputDir = "someOtherfolder"
@@ -762,7 +741,6 @@
gradleRunner.buildAndAssertThatOutput(
"printBaselineProfileExtensionForVariantFreeRelease"
) {
- contains("enableR8BaselineProfileRewrite=`true`")
contains("saveInSrc=`false`")
contains("automaticGenerationDuringBuild=`true`")
contains("baselineProfileOutputDir=`myReleaseFolder`")
@@ -772,7 +750,6 @@
gradleRunner.buildAndAssertThatOutput(
"printBaselineProfileExtensionForVariantPaidRelease"
) {
- contains("enableR8BaselineProfileRewrite=`true`")
contains("saveInSrc=`false`")
contains("automaticGenerationDuringBuild=`true`")
contains("baselineProfileOutputDir=`someOtherfolder`")
@@ -1108,6 +1085,60 @@
assertThat(notFound).isEmpty()
}
}
+
+ @Test
+ fun testRulesRewriteExperimentalPropertiesSet() {
+ projectSetup.producer.setupWithFreeAndPaidFlavors(
+ freeReleaseProfileLines = listOf(Fixtures.CLASS_1_METHOD_1, Fixtures.CLASS_1),
+ paidReleaseProfileLines = listOf(Fixtures.CLASS_2_METHOD_1, Fixtures.CLASS_2)
+ )
+ projectSetup.consumer.setup(
+ androidPlugin = ANDROID_LIBRARY_PLUGIN,
+ dependencyOnProducerProject = true,
+ flavors = true,
+ buildTypeAnotherRelease = true,
+ baselineProfileBlock = """
+ baselineProfileRulesRewrite = true
+ """.trimIndent()
+ )
+ arrayOf(
+ "printExperimentalPropertiesForVariantFreeRelease",
+ "printExperimentalPropertiesForVariantPaidRelease",
+ "printExperimentalPropertiesForVariantFreeAnotherRelease",
+ "printExperimentalPropertiesForVariantPaidAnotherRelease",
+ ).forEach {
+ projectSetup.consumer.gradleRunner.buildAndFailAndAssertThatOutput(it) {
+ contains("Unable to set baseline profile rules rewrite property")
+ }
+ }
+ }
+
+ @Test
+ fun testDexLayoutOptimizationExperimentalPropertiesSet() {
+ projectSetup.producer.setupWithFreeAndPaidFlavors(
+ freeReleaseProfileLines = listOf(Fixtures.CLASS_1_METHOD_1, Fixtures.CLASS_1),
+ paidReleaseProfileLines = listOf(Fixtures.CLASS_2_METHOD_1, Fixtures.CLASS_2)
+ )
+ projectSetup.consumer.setup(
+ androidPlugin = ANDROID_LIBRARY_PLUGIN,
+ dependencyOnProducerProject = true,
+ flavors = true,
+ buildTypeAnotherRelease = true,
+ baselineProfileBlock = """
+ dexLayoutOptimization = true
+ """.trimIndent()
+ )
+ arrayOf(
+ "printExperimentalPropertiesForVariantFreeRelease",
+ "printExperimentalPropertiesForVariantPaidRelease",
+ "printExperimentalPropertiesForVariantFreeAnotherRelease",
+ "printExperimentalPropertiesForVariantPaidAnotherRelease",
+ ).forEach {
+ projectSetup.consumer.gradleRunner.buildAndFailAndAssertThatOutput(it) {
+ contains(" Unable to set dex layout optimization property")
+ }
+ }
+ }
}
@RunWith(JUnit4::class)
@@ -1253,4 +1284,35 @@
assertThat(notFound).isEmpty()
}
}
+
+ @Test
+ fun testExperimentalPropertiesSet() {
+ projectSetup.producer.setupWithFreeAndPaidFlavors(
+ freeReleaseProfileLines = listOf(Fixtures.CLASS_1_METHOD_1, Fixtures.CLASS_1),
+ paidReleaseProfileLines = listOf(Fixtures.CLASS_2_METHOD_1, Fixtures.CLASS_2)
+ )
+ projectSetup.consumer.setup(
+ androidPlugin = ANDROID_LIBRARY_PLUGIN,
+ dependencyOnProducerProject = true,
+ flavors = true,
+ buildTypeAnotherRelease = true,
+ baselineProfileBlock = """
+ baselineProfileRulesRewrite = true
+ dexLayoutOptimization = true
+ """.trimIndent()
+ )
+
+ arrayOf(
+ "printExperimentalPropertiesForVariantFreeRelease",
+ "printExperimentalPropertiesForVariantPaidRelease",
+ "printExperimentalPropertiesForVariantFreeAnotherRelease",
+ "printExperimentalPropertiesForVariantPaidAnotherRelease",
+ ).forEach {
+ projectSetup.consumer.gradleRunner.buildAndAssertThatOutput(it) {
+ // These properties are ignored in agp 8.0
+ contains("android.experimental.art-profile-r8-rewriting=true")
+ contains("android.experimental.r8.dex-startup-optimization=true")
+ }
+ }
+ }
}
diff --git a/benchmark/benchmark-common/api/public_plus_experimental_current.txt b/benchmark/benchmark-common/api/public_plus_experimental_current.txt
index a5a3dc8..c948ed9 100644
--- a/benchmark/benchmark-common/api/public_plus_experimental_current.txt
+++ b/benchmark/benchmark-common/api/public_plus_experimental_current.txt
@@ -31,6 +31,21 @@
@kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface ExperimentalPerfettoCaptureApi {
}
+ @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public abstract sealed class PerfettoConfig {
+ }
+
+ public static final class PerfettoConfig.Binary extends androidx.benchmark.perfetto.PerfettoConfig {
+ ctor public PerfettoConfig.Binary(byte[] bytes);
+ method public byte[] getBytes();
+ property public final byte[] bytes;
+ }
+
+ public static final class PerfettoConfig.Text extends androidx.benchmark.perfetto.PerfettoConfig {
+ ctor public PerfettoConfig.Text(String text);
+ method public String getText();
+ property public final String text;
+ }
+
@RequiresApi(23) @androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi public final class PerfettoTrace {
ctor public PerfettoTrace(String path);
method public String getPath();
@@ -38,6 +53,10 @@
method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public static void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public static void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public static void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
property public final String path;
field public static final androidx.benchmark.perfetto.PerfettoTrace.Companion Companion;
}
@@ -47,6 +66,10 @@
method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void record(String fileLabel, optional java.util.List<java.lang.String> appTagPackages, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void record(String fileLabel, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, optional kotlin.jvm.functions.Function1<? super androidx.benchmark.perfetto.PerfettoTrace,kotlin.Unit>? traceCallback, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, optional String? userspaceTracingPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, optional String highlightPackage, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void record(String fileLabel, androidx.benchmark.perfetto.PerfettoConfig config, kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
}
diff --git a/benchmark/benchmark-common/build.gradle b/benchmark/benchmark-common/build.gradle
index ab830a8..b66a11b 100644
--- a/benchmark/benchmark-common/build.gradle
+++ b/benchmark/benchmark-common/build.gradle
@@ -66,12 +66,21 @@
}
androidx {
- name = "Android Benchmark - Common"
+ name = "Benchmark - Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Benchmark - Common"
}
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions {
+ // Enable using experimental APIs from within same version group
+ freeCompilerArgs += [
+ "-opt-in=androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi"
+ ]
+ }
+}
+
// https://github.com/square/wire/issues/1947
// Remove when we upgrade to fixed wire library
afterEvaluate {
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
index 3164fcc..ceb4d5e 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
@@ -23,18 +23,19 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.test.rule.GrantPermissionRule
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Assume.assumeTrue
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
-import kotlin.test.assertFailsWith
-import kotlin.test.assertTrue
@LargeTest
@RunWith(AndroidJUnit4::class)
@@ -189,7 +190,7 @@
assumeTrue(
CpuInfo.locked ||
IsolationActivity.sustainedPerformanceModeInUse ||
- Errors.isEmulator
+ DeviceInfo.isEmulator
)
iterationCheck(checkingForThermalThrottling = false)
}
@@ -380,6 +381,7 @@
}
@Test
+ @Ignore("b/278737712")
fun experimentalIters() {
validateIters(
warmupCount = 1,
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ConfigurationErrorTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ConfigurationErrorTest.kt
index 7342c236..80df5f0 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ConfigurationErrorTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ConfigurationErrorTest.kt
@@ -18,13 +18,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertNotNull
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt
index 95b10d3..5e509d3 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoHelperTest.kt
@@ -17,20 +17,21 @@
package androidx.benchmark
import androidx.benchmark.perfetto.PerfettoCapture
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoHelper
import androidx.benchmark.perfetto.PerfettoHelper.Companion.LOWEST_BUNDLED_VERSION_SUPPORTED
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotEquals
+import kotlin.test.assertTrue
import org.junit.After
import org.junit.Assume
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertNotEquals
-import kotlin.test.assertTrue
@LargeTest
@SdkSuppress(minSdkVersion = 23)
@@ -52,7 +53,7 @@
// start perfetto
val capture = PerfettoCapture(unbundled)
- capture.start(listOf(Packages.TEST))
+ capture.start(PerfettoConfig.Benchmark(listOf(Packages.TEST)))
// should be at least one perfetto process
assertNotEquals(illegal = listOf(), actual = getPerfettoPids())
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt
index 8eba619..affb068 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt
@@ -17,13 +17,19 @@
package androidx.benchmark
import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoHelper
import androidx.benchmark.perfetto.PerfettoTrace
+import androidx.benchmark.perfetto.perfettoConfig
+import androidx.benchmark.perfetto.validateAndEncode
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
import kotlin.test.fail
import org.junit.Assume.assumeTrue
import org.junit.Test
@@ -34,6 +40,7 @@
@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 23)
class PerfettoTraceTest {
+
@Test
fun record_basic() {
assumeTrue(PerfettoHelper.isAbiSupported())
@@ -51,6 +58,94 @@
"$perfettoTrace didn't match!"
}
}
+
+ private fun verifyRecordSuccess(
+ config: PerfettoConfig
+ ) {
+ var perfettoTrace: PerfettoTrace? = null
+ val label = "successTrace${config.javaClass.simpleName}"
+ PerfettoTrace.record(
+ fileLabel = label,
+ config = config,
+ traceCallback = { trace ->
+ perfettoTrace = trace
+ }
+ ) {
+ // noop
+ }
+ assertNotNull(perfettoTrace)
+ assert(perfettoTrace!!.path.matches(Regex(".*/${label}_[0-9-]+.perfetto-trace"))) {
+ "$perfettoTrace didn't match!"
+ }
+ }
+
+ private fun verifyRecordFails(
+ config: PerfettoConfig
+ ) {
+ var perfettoTrace: PerfettoTrace? = null
+ val exception = assertFailsWith<IllegalStateException> {
+ PerfettoTrace.record(
+ fileLabel = "failTrace",
+ config = config,
+ traceCallback = { trace ->
+ perfettoTrace = trace
+ }
+ ) {
+ // noop
+ }
+ }
+ assertTrue(exception.message!!.contains("Perfetto unexpected exit code"))
+ assertNull(perfettoTrace)
+ }
+
+ @Test
+ fun record_invalidText() = verifyRecordFails(PerfettoConfig.Text("INVALID"))
+
+ @Test
+ fun record_invalidBinary() = verifyRecordFails(PerfettoConfig.Binary(byteArrayOf(1, 0, 1)))
+
+ @Test
+ fun record_validText() = verifyRecordSuccess(PerfettoConfig.Text("""
+ # basic config generated from https://ui.perfetto.dev/#!/record
+ buffers: {
+ size_kb: 63488
+ fill_policy: RING_BUFFER
+ }
+ buffers: {
+ size_kb: 2048
+ fill_policy: RING_BUFFER
+ }
+ data_sources: {
+ config {
+ name: "linux.ftrace"
+ ftrace_config {
+ ftrace_events: "ftrace/print"
+ atrace_categories: "am"
+ atrace_categories: "dalvik"
+ atrace_categories: "gfx"
+ atrace_categories: "view"
+ atrace_categories: "wm"
+ }
+ }
+ }
+ duration_ms: 10000
+ flush_period_ms: 30000
+ incremental_state_config {
+ clear_period_ms: 5000
+ }
+ """.trimIndent()))
+
+ @Test
+ fun record_validBinary() = verifyRecordSuccess(
+ PerfettoConfig.Binary(
+ perfettoConfig(
+ atraceApps = listOf(
+ InstrumentationRegistry.getInstrumentation().targetContext.packageName
+ )
+ ).validateAndEncode()
+ )
+ )
+
@Test
fun record_reentrant() {
assumeTrue(PerfettoHelper.isAbiSupported())
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ResultWriterTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ResultWriterTest.kt
index 02231c1d..73a35d4 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ResultWriterTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/ResultWriterTest.kt
@@ -19,12 +19,12 @@
import android.os.Build
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import kotlin.test.assertTrue
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
-import kotlin.test.assertTrue
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/UserspaceTracingTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/UserspaceTracingTest.kt
index 73f5067..8b8bfb0 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/UserspaceTracingTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/UserspaceTracingTest.kt
@@ -19,6 +19,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import java.io.File
+import kotlin.test.assertNotNull
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@@ -28,8 +30,6 @@
import perfetto.protos.TracePacket
import perfetto.protos.TrackDescriptor
import perfetto.protos.TrackEvent
-import java.io.File
-import kotlin.test.assertNotNull
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/WarmupManagerTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/WarmupManagerTest.kt
index 9b2eac8..8ab7d68 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/WarmupManagerTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/WarmupManagerTest.kt
@@ -18,11 +18,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/AtraceTagTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/AtraceTagTest.kt
index c5f13d6..749c4f5 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/AtraceTagTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/AtraceTagTest.kt
@@ -20,12 +20,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
-import org.junit.Assume
-import org.junit.Test
-import org.junit.runner.RunWith
import kotlin.test.assertContains
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
+import org.junit.Assume
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SdkSuppress(minSdkVersion = 21)
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/PerfettoConfigTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/PerfettoConfigTest.kt
index f1815b3..7aac3c7 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/PerfettoConfigTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/PerfettoConfigTest.kt
@@ -20,16 +20,16 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import perfetto.protos.DataSourceConfig
import perfetto.protos.FtraceConfig
import perfetto.protos.TraceConfig
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertNotNull
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/UiStateTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/UiStateTest.kt
index 101ea48..9bf3860 100644
--- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/UiStateTest.kt
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/perfetto/UiStateTest.kt
@@ -19,6 +19,8 @@
import androidx.benchmark.createTempFileFromAsset
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.io.File
+import kotlin.test.assertEquals
import okio.ByteString
import org.junit.Assert.assertTrue
import org.junit.Test
@@ -26,8 +28,6 @@
import perfetto.protos.Trace
import perfetto.protos.TracePacket
import perfetto.protos.UiState
-import java.io.File
-import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
index b336117..19d5d66 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/DeviceInfo.kt
@@ -32,8 +32,7 @@
Build.MODEL.contains("google_sdk") ||
Build.MODEL.contains("sdk_gphone64") ||
Build.MODEL.contains("Emulator") ||
- Build.MODEL.contains("Android SDK built for x86") ||
- Build.MODEL.contains("Android SDK built for arm64") ||
+ Build.MODEL.contains("Android SDK built for") ||
Build.MANUFACTURER.contains("Genymotion") ||
Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
"google_sdk" == Build.PRODUCT
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
index 9919011..6403312 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Errors.kt
@@ -64,15 +64,6 @@
return ret
}
- val isEmulator = Build.FINGERPRINT.startsWith("generic") ||
- Build.FINGERPRINT.startsWith("unknown") ||
- Build.MODEL.contains("google_sdk") ||
- Build.MODEL.contains("Emulator") ||
- Build.MODEL.contains("Android SDK built for x86") ||
- Build.MANUFACTURER.contains("Genymotion") ||
- Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") ||
- "google_sdk" == Build.PRODUCT
-
private val isDeviceRooted =
arrayOf(
"/system/app/Superuser.apk",
@@ -110,7 +101,7 @@
| real user's experience (or even regress release performance).
""".trimMarginWrapNewlines()
}
- if (isEmulator) {
+ if (DeviceInfo.isEmulator) {
warningPrefix += "EMULATOR_"
warningString += """
|WARNING: Running on Emulator
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
index e6fcaba..a074e20 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/ThrottleDetector.kt
@@ -64,7 +64,7 @@
initNs == 0.0 && // first time
!CpuInfo.locked && // CPU locked (presumably to stable values), should be no throttling
!IsolationActivity.sustainedPerformanceModeInUse && // trust sustained perf
- !Errors.isEmulator // don't bother with emulators, will always be unpredicatable
+ !DeviceInfo.isEmulator // don't bother with emulators, will always be unpredictable
) {
initNs = measureWorkNs()
}
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
index 26a4da0..e99d5a1 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCapture.kt
@@ -53,31 +53,24 @@
private val helper: PerfettoHelper = PerfettoHelper(unbundled)
- public fun isRunning() = helper.isRunning()
+ fun isRunning() = helper.isRunning()
/**
* Start collecting perfetto trace.
- *
- * TODO: provide configuration options
*/
- public fun start(packages: List<String>) = userspaceTrace("start perfetto") {
- // Write binary proto to dir that shell can read
- // TODO: cache on disk
+ fun start(config: PerfettoConfig) = userspaceTrace("start perfetto") {
+ // Write config proto to dir that shell can read
+ // We use `.pb` even with textproto so we'll only ever have one file
val configProtoFile = File(Outputs.dirUsableByAppAndShell, "trace_config.pb")
try {
userspaceTrace("write config") {
- val atraceApps = if (Build.VERSION.SDK_INT <= 28 || packages.isEmpty()) {
- packages
- } else {
- listOf("*")
- }
- configProtoFile.writeBytes(perfettoConfig(atraceApps).validateAndEncode())
+ config.writeTo(configProtoFile)
if (Outputs.forceFilesForShellAccessible) {
configProtoFile.setReadable(true, /* ownerOnly = */ false)
}
}
userspaceTrace("start perfetto process") {
- helper.startCollecting(configProtoFile.absolutePath, false)
+ helper.startCollecting(configProtoFile.absolutePath, config.isTextProto)
}
} finally {
configProtoFile.delete()
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCaptureWrapper.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCaptureWrapper.kt
index 010cde4..bb1e825 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCaptureWrapper.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoCaptureWrapper.kt
@@ -54,23 +54,21 @@
@RequiresApi(23)
private fun start(
- appTagPackages: List<String>,
+ config: PerfettoConfig,
userspaceTracingPackage: String?
): Boolean {
capture?.apply {
- if (Build.VERSION.SDK_INT >= 23) {
- Log.d(LOG_TAG, "Recording perfetto trace")
- if (userspaceTracingPackage != null &&
- Build.VERSION.SDK_INT >= 30
- ) {
- val result = enableAndroidxTracingPerfetto(
- targetPackage = userspaceTracingPackage,
- provideBinariesIfMissing = true
- ) ?: "Success"
- Log.d(LOG_TAG, "Enable full tracing result=$result")
- }
- start(appTagPackages)
+ Log.d(LOG_TAG, "Recording perfetto trace")
+ if (userspaceTracingPackage != null &&
+ Build.VERSION.SDK_INT >= 30
+ ) {
+ val result = enableAndroidxTracingPerfetto(
+ targetPackage = userspaceTracingPackage,
+ provideBinariesIfMissing = true
+ ) ?: "Success"
+ Log.d(LOG_TAG, "Enable full tracing result=$result")
}
+ start(config)
}
return true
@@ -94,7 +92,7 @@
fun record(
fileLabel: String,
- appTagPackages: List<String>,
+ config: PerfettoConfig,
userspaceTracingPackage: String?,
traceCallback: ((String) -> Unit)? = null,
block: () -> Unit
@@ -125,7 +123,7 @@
val path: String
try {
propOverride?.forceValue()
- start(appTagPackages, userspaceTracingPackage)
+ start(config, userspaceTracingPackage)
try {
block()
} finally {
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
index 6a2283e..bb09ace 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
@@ -20,8 +20,9 @@
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.benchmark.Shell
-import perfetto.protos.DataSourceConfig
+import java.io.File
import perfetto.protos.AndroidPowerConfig
+import perfetto.protos.DataSourceConfig
import perfetto.protos.FtraceConfig
import perfetto.protos.MeminfoCounters
import perfetto.protos.ProcessStatsConfig
@@ -30,6 +31,73 @@
import perfetto.protos.TraceConfig.BufferConfig
import perfetto.protos.TraceConfig.BufferConfig.FillPolicy
+/**
+ * Configuration for Perfetto trace recording.
+ *
+ * For more info, see https://perfetto.dev/docs/concepts/config
+ */
+@ExperimentalPerfettoCaptureApi
+sealed class PerfettoConfig constructor(
+ internal val isTextProto: Boolean
+) {
+ @RequiresApi(23)
+ internal abstract fun writeTo(file: File)
+
+ /**
+ * Binary representation of a Perfetto config proto.
+ *
+ * This can be generated by a proto library, together with the definition here:
+ */
+ class Binary(
+ val bytes: ByteArray
+ ) : PerfettoConfig(isTextProto = false) {
+ @RequiresApi(23)
+ override fun writeTo(file: File) {
+ file.writeBytes(bytes)
+ }
+ }
+
+ /**
+ * TextProto representation of a Perfetto config.
+ *
+ * This can be generated with https://ui.perfetto.dev/#!/record/
+ *
+ * Note: this format is not recommended for long term use - the [Binary] proto
+ * representation is more likely to remain stable over time, across Perfetto/Android OS
+ * versions. For more information, see
+ * [the Perfetto documentation](https://perfetto.dev/docs/concepts/config#pbtx-vs-binary-format).
+ */
+ class Text(
+ val text: String
+ ) : PerfettoConfig(isTextProto = true) {
+ @RequiresApi(23)
+ override fun writeTo(file: File) {
+ file.writeText(text)
+ }
+ }
+
+ /**
+ * Benchmark defined config for perfetto trace capture, used by benchmark/macrobenchmark.
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ class Benchmark(
+ private val appTagPackages: List<String>
+ ) : PerfettoConfig(isTextProto = false) {
+ @RequiresApi(23)
+ override fun writeTo(file: File) {
+ file.writeBytes(
+ perfettoConfig(
+ atraceApps = if (Build.VERSION.SDK_INT <= 28 || appTagPackages.isEmpty()) {
+ appTagPackages
+ } else {
+ listOf("*")
+ }
+ ).validateAndEncode()
+ )
+ }
+ }
+}
+
private fun ftraceDataSource(
atraceApps: List<String>
) = TraceConfig.DataSource(
@@ -165,7 +233,7 @@
* @suppress
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-fun perfettoConfig(
+internal fun perfettoConfig(
atraceApps: List<String>
) = TraceConfig(
buffers = listOf(
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoTrace.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoTrace.kt
index 5e2c29a..656ba2f 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoTrace.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoTrace.kt
@@ -83,15 +83,79 @@
* Block to be traced.
*/
block: () -> Unit
+ ) = record(
+ fileLabel = fileLabel,
+ config = PerfettoConfig.Benchmark(appTagPackages),
+ userspaceTracingPackage = userspaceTracingPackage,
+ traceCallback = traceCallback,
+ block = block
+ )
+
+ /**
+ * Record a Perfetto System Trace for the specified [block], with a fully custom Perfetto
+ * config, either text or binary.
+ *
+ * ```
+ * PerfettoTrace.record("myTrace", config = """...""") {
+ * // content in here is traced to myTrace_<timestamp>.perfetto_trace
+ * }
+ * ```
+ *
+ * Reentrant Perfetto trace capture is not supported, so this API may not be combined with
+ * `BenchmarkRule`, `MacrobenchmarkRule`, or `PerfettoTraceRule`.
+ *
+ * If the block throws, the trace is still captured and passed to [traceCallback].
+ */
+ @JvmStatic
+ @JvmOverloads
+ fun record(
+ /**
+ * Output trace file names are labelled `<fileLabel>_<timestamp>.perfetto_trace`
+ *
+ * This timestamp is used for uniqueness when trace files are pulled automatically to
+ * Studio.
+ */
+ fileLabel: String,
+ /**
+ * Trace recording configuration.
+ */
+ config: PerfettoConfig,
+ /**
+ * Process to emphasize in the tracing UI.
+ *
+ * Used to emphasize the target process, e.g. by pre-populating Studio trace viewer
+ * process selection.
+ *
+ * Defaults to the test's target process. Note that for self-instrumenting tests that
+ * measure another app, you must pass that target app package.
+ */
+ highlightPackage: String =
+ InstrumentationRegistry.getInstrumentation().targetContext.packageName,
+ /**
+ * Process to trace with userspace tracing, i.e. `androidx.tracing:tracing-perfetto`,
+ * ignored below API 30.
+ *
+ * This tracing is lower overhead than standard `android.os.Trace` tracepoints, but is
+ * currently experimental.
+ */
+ userspaceTracingPackage: String? = null,
+ /**
+ * Callback for trace capture.
+ *
+ * This callback allows you to process the trace even if the block throws, e.g. during
+ * a test failure.
+ */
+ traceCallback: ((PerfettoTrace) -> Unit)? = null,
+ /**
+ * Block to be traced.
+ */
+ block: () -> Unit
) {
PerfettoCaptureWrapper().record(
fileLabel = fileLabel,
- appTagPackages = appTagPackages,
- userspaceTracingPackage = userspaceTracingPackage,
+ config,
+ userspaceTracingPackage,
traceCallback = { path ->
- // emphasize the first package in the package list, or target package otherwise
- val highlightPackage = appTagPackages.firstOrNull()
- ?: InstrumentationRegistry.getInstrumentation().targetContext.packageName
File(path).appendUiState(
UiState(
timelineStart = null,
diff --git a/benchmark/benchmark-darwin-core/build.gradle b/benchmark/benchmark-darwin-core/build.gradle
index ac9243d..12b8a6b 100644
--- a/benchmark/benchmark-darwin-core/build.gradle
+++ b/benchmark/benchmark-darwin-core/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "AndroidX Benchmarks - Darwin Core"
+ name = "Benchmarks - Darwin Core"
inceptionYear = "2022"
description = "AndroidX Benchmarks - Darwin Core"
}
diff --git a/benchmark/benchmark-darwin-gradle-plugin/build.gradle b/benchmark/benchmark-darwin-gradle-plugin/build.gradle
index 7a16cf9..5c3aa31 100644
--- a/benchmark/benchmark-darwin-gradle-plugin/build.gradle
+++ b/benchmark/benchmark-darwin-gradle-plugin/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "AndroidX Benchmarks - Darwin Gradle Plugin"
+ name = "Benchmarks - Darwin Gradle Plugin"
publish = Publish.SNAPSHOT_ONLY
type = LibraryType.GRADLE_PLUGIN
inceptionYear = "2022"
diff --git a/benchmark/benchmark-darwin-samples/build.gradle b/benchmark/benchmark-darwin-samples/build.gradle
index c297722..3684119 100644
--- a/benchmark/benchmark-darwin-samples/build.gradle
+++ b/benchmark/benchmark-darwin-samples/build.gradle
@@ -60,7 +60,7 @@
}
androidx {
- name = "AndroidX Benchmarks - Darwin Samples"
+ name = "Benchmarks - Darwin Samples"
inceptionYear = "2022"
description = "AndroidX Benchmarks - Darwin Samples"
}
diff --git a/benchmark/benchmark-darwin/build.gradle b/benchmark/benchmark-darwin/build.gradle
index 473a5c3..e192b8f 100644
--- a/benchmark/benchmark-darwin/build.gradle
+++ b/benchmark/benchmark-darwin/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "AndroidX Benchmarks - Darwin"
+ name = "Benchmarks - Darwin"
inceptionYear = "2022"
description = "AndroidX Benchmarks - Darwin"
}
diff --git a/benchmark/benchmark-junit4/build.gradle b/benchmark/benchmark-junit4/build.gradle
index baf3b33..cfb08c2 100644
--- a/benchmark/benchmark-junit4/build.gradle
+++ b/benchmark/benchmark-junit4/build.gradle
@@ -15,6 +15,7 @@
*/
import androidx.build.Publish
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -46,8 +47,17 @@
}
androidx {
- name = "Android Benchmark - JUnit4"
+ name = "Benchmark - JUnit4"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android Benchmark - JUnit4"
}
+
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions {
+ // Enable using experimental APIs from within same version group
+ freeCompilerArgs += [
+ "-opt-in=androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi"
+ ]
+ }
+}
diff --git a/benchmark/benchmark-junit4/src/androidTest/java/androidx/benchmark/junit4/BenchmarkRuleTest.kt b/benchmark/benchmark-junit4/src/androidTest/java/androidx/benchmark/junit4/BenchmarkRuleTest.kt
index 9b4f1f3..3c34893 100644
--- a/benchmark/benchmark-junit4/src/androidTest/java/androidx/benchmark/junit4/BenchmarkRuleTest.kt
+++ b/benchmark/benchmark-junit4/src/androidTest/java/androidx/benchmark/junit4/BenchmarkRuleTest.kt
@@ -18,11 +18,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.concurrent.TimeUnit
import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/benchmark/benchmark-junit4/src/main/AndroidManifest.xml b/benchmark/benchmark-junit4/src/main/AndroidManifest.xml
deleted file mode 100644
index cf0d807..0000000
--- a/benchmark/benchmark-junit4/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/BenchmarkRule.kt b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/BenchmarkRule.kt
index 1be0375..0c686fe 100644
--- a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/BenchmarkRule.kt
+++ b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/BenchmarkRule.kt
@@ -23,6 +23,7 @@
import androidx.benchmark.BenchmarkState
import androidx.benchmark.UserspaceTracing
import androidx.benchmark.perfetto.PerfettoCaptureWrapper
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.UiState
import androidx.benchmark.perfetto.appendUiState
import androidx.test.platform.app.InstrumentationRegistry
@@ -212,7 +213,7 @@
val tracePath = PerfettoCaptureWrapper().record(
fileLabel = uniqueName,
- appTagPackages = packages,
+ config = PerfettoConfig.Benchmark(packages),
userspaceTracingPackage = null
) {
UserspaceTracing.commitToTrace() // clear buffer
diff --git a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/InstrumentationResultsRunListener.kt b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/InstrumentationResultsRunListener.kt
index 752f230..db192f8 100644
--- a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/InstrumentationResultsRunListener.kt
+++ b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/InstrumentationResultsRunListener.kt
@@ -20,8 +20,8 @@
import androidx.annotation.RestrictTo
import androidx.benchmark.InstrumentationResults
import androidx.test.internal.runner.listener.InstrumentationRunListener
-import org.junit.runner.Result
import java.io.PrintStream
+import org.junit.runner.Result
/**
* Used to register files to copy at the end of the entire test run in CI.
diff --git a/benchmark/benchmark-macro-junit4/build.gradle b/benchmark/benchmark-macro-junit4/build.gradle
index cd4804f..5fa8211 100644
--- a/benchmark/benchmark-macro-junit4/build.gradle
+++ b/benchmark/benchmark-macro-junit4/build.gradle
@@ -53,7 +53,7 @@
}
androidx {
- name = "Android Benchmark - Macrobenchmark JUnit4"
+ name = "Benchmark - Macrobenchmark JUnit4"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Benchmark - Macrobenchmark JUnit4"
diff --git a/benchmark/benchmark-macro-junit4/src/main/AndroidManifest.xml b/benchmark/benchmark-macro-junit4/src/main/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/benchmark/benchmark-macro-junit4/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
index 8a0d906..c6dd32b 100644
--- a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
+++ b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/BaselineProfileRule.kt
@@ -55,6 +55,7 @@
* startActivityAndWait()
* }
* }
+ * ```
*
* Note that you can filter captured rules, for example, if you're generating rules for a library,
* and don't want to record profiles from outside that library:
diff --git a/benchmark/benchmark-macro/build.gradle b/benchmark/benchmark-macro/build.gradle
index a6b3f2f..bc6c8e3 100644
--- a/benchmark/benchmark-macro/build.gradle
+++ b/benchmark/benchmark-macro/build.gradle
@@ -80,7 +80,7 @@
}
androidx {
- name = "Android Benchmark - Macrobenchmark"
+ name = "Benchmark - Macrobenchmark"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Benchmark - Macrobenchmark"
@@ -150,14 +150,21 @@
// https://github.com/square/wire/issues/1947
// Remove when we upgrade to fixed wire library
afterEvaluate {
- tasks.named("compileReleaseKotlin").configure {
+ tasks.named("compileDebugKotlin").configure {
it.dependsOn("generateDebugProtos")
}
- tasks.named("compileDebugKotlin").configure {
+ tasks.named("compileReleaseKotlin").configure {
it.dependsOn("generateReleaseProtos")
}
}
+androidx {
+ deviceTests {
+ targetAppProject = project(":benchmark:integration-tests:macrobenchmark-target")
+ targetAppVariant = "release"
+ }
+}
+
// Define a task dependency so the app is installed before we run macro benchmarks.
afterEvaluate {
// `:benchmark:integration-tests:macrobenchmark-target:installRelease` is not in the compose
diff --git a/benchmark/benchmark-macro/lint-baseline.xml b/benchmark/benchmark-macro/lint-baseline.xml
index fb8dd8f..9433540 100644
--- a/benchmark/benchmark-macro/lint-baseline.xml
+++ b/benchmark/benchmark-macro/lint-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.1.0-alpha11" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-alpha11)" variant="all" version="8.1.0-alpha11">
+<issues format="6" by="lint 8.1.0-beta01" type="baseline" client="gradle" dependencies="false" name="AGP (8.1.0-beta01)" variant="all" version="8.1.0-beta01">
<issue
id="BanThreadSleep"
@@ -22,15 +22,6 @@
<issue
id="BanThreadSleep"
message="Uses Thread.sleep()"
- errorLine1=" Thread.sleep(Arguments.killProcessDelayMillis)"
- errorLine2=" ~~~~~">
- <location
- file="src/main/java/androidx/benchmark/macro/BaselineProfiles.kt"/>
- </issue>
-
- <issue
- id="BanThreadSleep"
- message="Uses Thread.sleep()"
errorLine1=" Thread.sleep(5000)"
errorLine2=" ~~~~~">
<location
@@ -118,4 +109,13 @@
file="src/main/java/androidx/benchmark/macro/ProfileInstallBroadcast.kt"/>
</issue>
+ <issue
+ id="PrereleaseSdkCoreDependency"
+ message="Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core"
+ errorLine1=" if (BuildCompat.isAtLeastU() || Shell.isSessionRooted()) {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="src/main/java/androidx/benchmark/macro/CompilationMode.kt"/>
+ </issue>
+
</issues>
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/FileLinkingRule.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/FileLinkingRule.kt
index 8ce14941..e3560f6 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/FileLinkingRule.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/FileLinkingRule.kt
@@ -21,11 +21,11 @@
import androidx.benchmark.Outputs
import androidx.benchmark.perfetto.UiState
import androidx.benchmark.perfetto.appendUiState
+import java.io.File
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
-import java.io.File
/**
* Rule to enable linking files and traces to Studio UI for macrobench correctness tests.
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/IdeSummaryStringTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/IdeSummaryStringTest.kt
index a150eee..1a07546 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/IdeSummaryStringTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/IdeSummaryStringTest.kt
@@ -21,11 +21,11 @@
import androidx.benchmark.Outputs
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.io.File
+import kotlin.test.assertFailsWith
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
-import kotlin.test.assertFailsWith
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
index de94880..337128e 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/MacrobenchmarkTest.kt
@@ -24,14 +24,14 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.tracing.trace
-import org.junit.Assume.assumeTrue
-import org.junit.Test
-import org.junit.runner.RunWith
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/PowerRailTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/PowerRailTest.kt
index 5cf3d0a..0d729e3 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/PowerRailTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/PowerRailTest.kt
@@ -23,7 +23,6 @@
import kotlin.test.assertFalse
import kotlin.test.assertTrue
import org.junit.Assume.assumeTrue
-
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
index 9e98054..cf8d947 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/StartupTimingMetricTest.kt
@@ -23,6 +23,7 @@
import androidx.benchmark.DeviceInfo
import androidx.benchmark.Outputs
import androidx.benchmark.perfetto.PerfettoCaptureWrapper
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
import androidx.benchmark.perfetto.PerfettoTraceProcessor
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -48,6 +49,7 @@
class StartupTimingMetricTest {
@MediumTest
@Test
+ @Ignore("b/258335082")
fun noResults() {
assumeTrue(isAbiSupported())
val packageName = "fake.package.fiction.nostartups"
@@ -170,12 +172,14 @@
@LargeTest
@Test
+ @Ignore("b/258335082")
fun startup_fullyDrawn_immediate() {
validateStartup_fullyDrawn(delayMs = 0)
}
@LargeTest
@Test
+ @Ignore("b/258335082")
fun startup_fullyDrawn_delayed() {
validateStartup_fullyDrawn(delayMs = 100)
}
@@ -290,13 +294,16 @@
metric.configure(packageName)
val tracePath = PerfettoCaptureWrapper().record(
fileLabel = packageName,
- // note - packageName may be this package, so we convert to set then list to make unique
- // and on API 23 and below, we use reflection to trace instead within this process
- appTagPackages = if (Build.VERSION.SDK_INT >= 24 && packageName != Packages.TEST) {
- listOf(packageName, Packages.TEST)
- } else {
- listOf(packageName)
- },
+ config = PerfettoConfig.Benchmark(
+ // note - packageName may be this package, so we convert to set then list to make unique
+ // and on API 23 and below, we use reflection to trace instead within this process
+ appTagPackages = if (Build.VERSION.SDK_INT >= 24 && packageName != Packages.TEST) {
+ listOf(packageName, Packages.TEST)
+ } else {
+ listOf(packageName)
+ },
+
+ ),
userspaceTracingPackage = packageName,
block = measureBlock
)!!
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
index 657a201..ec0e17c 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/AndroidxTracingTraceTest.kt
@@ -19,6 +19,7 @@
import androidx.benchmark.macro.FileLinkingRule
import androidx.benchmark.macro.Packages
import androidx.benchmark.perfetto.PerfettoCapture
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoHelper
import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
import androidx.benchmark.perfetto.PerfettoTraceProcessor
@@ -66,7 +67,7 @@
verifyTraceEnable(false)
- perfettoCapture.start(listOf(Packages.TEST))
+ perfettoCapture.start(PerfettoConfig.Benchmark(listOf(Packages.TEST)))
assertTrue(
Trace.isEnabled(),
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
index 8797a72..a8fb5bf 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureSweepTest.kt
@@ -16,10 +16,12 @@
package androidx.benchmark.macro.perfetto
+import android.annotation.SuppressLint
import android.os.Build
import androidx.benchmark.macro.FileLinkingRule
import androidx.benchmark.macro.Packages
import androidx.benchmark.perfetto.PerfettoCapture
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoHelper
import androidx.benchmark.perfetto.PerfettoHelper.Companion.LOWEST_BUNDLED_VERSION_SUPPORTED
import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
@@ -85,6 +87,7 @@
captureAndValidateTrace(unbundled = true)
}
+ @SuppressLint("BanThreadSleep")
private fun captureAndValidateTrace(unbundled: Boolean) {
assumeTrue(isAbiSupported())
@@ -93,7 +96,7 @@
verifyTraceEnable(false)
- perfettoCapture.start(listOf(Packages.TEST))
+ perfettoCapture.start(PerfettoConfig.Benchmark(listOf(Packages.TEST)))
if (!Trace.isEnabled()) {
// Should be available immediately, but let's wait a while to see if it works slowly.
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
index c9c8608..e56cb23 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoCaptureTest.kt
@@ -22,10 +22,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import kotlin.test.assertFailsWith
import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertFailsWith
/**
* Tests for PerfettoCapture
diff --git a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
index ac15ffe..5251a9c 100644
--- a/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
+++ b/benchmark/benchmark-macro/src/androidTest/java/androidx/benchmark/macro/perfetto/PerfettoSdkHandshakeTest.kt
@@ -31,10 +31,10 @@
import androidx.tracing.perfetto.PerfettoHandshake
import androidx.tracing.perfetto.PerfettoHandshake.ExternalLibraryProvider
import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_ALREADY_ENABLED
-import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
-import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_CANCELLED
+import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_ERROR_BINARY_MISSING
import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
+import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_SUCCESS
import com.google.common.truth.Truth.assertThat
import java.io.File
import java.io.StringReader
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
index c220445..2a4020b 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/Macrobenchmark.kt
@@ -33,6 +33,7 @@
import androidx.benchmark.checkAndGetSuppressionState
import androidx.benchmark.conditionalError
import androidx.benchmark.perfetto.PerfettoCaptureWrapper
+import androidx.benchmark.perfetto.PerfettoConfig
import androidx.benchmark.perfetto.PerfettoTrace
import androidx.benchmark.perfetto.PerfettoTraceProcessor
import androidx.benchmark.perfetto.UiState
@@ -214,22 +215,23 @@
val iterString = iteration.toString().padStart(3, '0')
val tracePath = perfettoCollector.record(
fileLabel = "${uniqueName}_iter$iterString",
-
- /**
- * Prior to API 24, every package name was joined into a single setprop which
- * can overflow, and disable *ALL* app level tracing.
- *
- * For safety here, we only trace the macrobench package on newer platforms,
- * and use reflection in the macrobench test process to trace important
- * sections
- *
- * @see androidx.benchmark.macro.perfetto.ForceTracing
- */
- appTagPackages = if (Build.VERSION.SDK_INT >= 24) {
- listOf(packageName, macrobenchPackageName)
- } else {
- listOf(packageName)
- },
+ config = PerfettoConfig.Benchmark(
+ /**
+ * Prior to API 24, every package name was joined into a single setprop
+ * which can overflow, and disable *ALL* app level tracing.
+ *
+ * For safety here, we only trace the macrobench package on newer platforms,
+ * and use reflection in the macrobench test process to trace important
+ * sections
+ *
+ * @see androidx.benchmark.macro.perfetto.ForceTracing
+ */
+ appTagPackages = if (Build.VERSION.SDK_INT >= 24) {
+ listOf(packageName, macrobenchPackageName)
+ } else {
+ listOf(packageName)
+ },
+ ),
userspaceTracingPackage = userspaceTracingPackage
) {
try {
diff --git a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/SynchronizedBenchmark.kt b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/SynchronizedBenchmark.kt
index a890b12..0a84a30 100644
--- a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/SynchronizedBenchmark.kt
+++ b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/SynchronizedBenchmark.kt
@@ -20,10 +20,10 @@
import androidx.benchmark.junit4.measureRepeated
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.concurrent.atomic.AtomicInteger
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.atomic.AtomicInteger
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/benchmark/gradle-plugin/build.gradle b/benchmark/gradle-plugin/build.gradle
index fdf95af..11bf133 100644
--- a/benchmark/gradle-plugin/build.gradle
+++ b/benchmark/gradle-plugin/build.gradle
@@ -58,7 +58,7 @@
}
androidx {
- name = "Android Benchmark Gradle Plugin"
+ name = "Benchmark Gradle Plugin"
type = LibraryType.GRADLE_PLUGIN
inceptionYear = "2019"
description = "Android Benchmark Gradle Plugin"
diff --git a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
index 2c25293..e78a7a0 100644
--- a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
+++ b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/Adb.kt
@@ -16,10 +16,10 @@
package androidx.benchmark.gradle
+import java.util.concurrent.TimeUnit
import org.gradle.api.GradleException
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.Logger
-import java.util.concurrent.TimeUnit
/**
* Helper class wrapping the adb cli tool.
diff --git a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
index 5c02ad4..89f09cb 100644
--- a/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
+++ b/benchmark/gradle-plugin/src/main/kotlin/androidx/benchmark/gradle/LockClocksTask.kt
@@ -16,6 +16,9 @@
package androidx.benchmark.gradle
+import java.nio.file.Files
+import java.nio.file.Paths
+import java.nio.file.StandardCopyOption
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.provider.Property
@@ -23,9 +26,6 @@
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.property
import org.gradle.work.DisableCachingByDefault
-import java.nio.file.Files
-import java.nio.file.Paths
-import java.nio.file.StandardCopyOption
@Suppress("UnstableApiUsage")
@DisableCachingByDefault(
diff --git a/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt b/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
index 4decc0a..01f9af5 100644
--- a/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
+++ b/benchmark/gradle-plugin/src/test/kotlin/androidx/benchmark/gradle/BenchmarkPluginTest.kt
@@ -17,6 +17,10 @@
package androidx.benchmark.gradle
import androidx.testutils.gradle.ProjectSetupRule
+import java.io.File
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.UnexpectedBuildFailure
import org.junit.Before
@@ -24,10 +28,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.File
-import kotlin.test.assertFailsWith
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
private val PLUGINS_HEADER = """
plugins {
diff --git a/benchmark/integration-tests/baselineprofile-flavors-producer/build.gradle b/benchmark/integration-tests/baselineprofile-flavors-producer/build.gradle
index 0634f31..05d1c99 100644
--- a/benchmark/integration-tests/baselineprofile-flavors-producer/build.gradle
+++ b/benchmark/integration-tests/baselineprofile-flavors-producer/build.gradle
@@ -61,5 +61,7 @@
}
androidx {
- disableDeviceTests = true
+ deviceTests {
+ enabled = false
+ }
}
diff --git a/benchmark/integration-tests/baselineprofile-flavors-producer/src/free/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-flavors-producer/src/free/AndroidManifest.xml
deleted file mode 100644
index bae036b..0000000
--- a/benchmark/integration-tests/baselineprofile-flavors-producer/src/free/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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 />
diff --git a/benchmark/integration-tests/baselineprofile-flavors-producer/src/main/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-flavors-producer/src/main/AndroidManifest.xml
deleted file mode 100644
index d4c1970..0000000
--- a/benchmark/integration-tests/baselineprofile-flavors-producer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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 />
diff --git a/benchmark/integration-tests/baselineprofile-flavors-producer/src/paid/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-flavors-producer/src/paid/AndroidManifest.xml
deleted file mode 100644
index bae036b..0000000
--- a/benchmark/integration-tests/baselineprofile-flavors-producer/src/paid/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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 />
diff --git a/benchmark/integration-tests/baselineprofile-library-consumer/src/main/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-library-consumer/src/main/AndroidManifest.xml
deleted file mode 100644
index 7c52910..0000000
--- a/benchmark/integration-tests/baselineprofile-library-consumer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- ~ 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.
- -->
-<manifest />
diff --git a/benchmark/integration-tests/baselineprofile-library-producer/build.gradle b/benchmark/integration-tests/baselineprofile-library-producer/build.gradle
index b6cee42..44b3bda 100644
--- a/benchmark/integration-tests/baselineprofile-library-producer/build.gradle
+++ b/benchmark/integration-tests/baselineprofile-library-producer/build.gradle
@@ -56,5 +56,7 @@
}
androidx {
- disableDeviceTests = true
+ deviceTests {
+ enabled = false
+ }
}
diff --git a/benchmark/integration-tests/baselineprofile-library-producer/src/main/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-library-producer/src/main/AndroidManifest.xml
deleted file mode 100644
index bae036b..0000000
--- a/benchmark/integration-tests/baselineprofile-library-producer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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 />
diff --git a/benchmark/integration-tests/baselineprofile-producer/build.gradle b/benchmark/integration-tests/baselineprofile-producer/build.gradle
index a696a90..e04a270 100644
--- a/benchmark/integration-tests/baselineprofile-producer/build.gradle
+++ b/benchmark/integration-tests/baselineprofile-producer/build.gradle
@@ -56,5 +56,7 @@
}
androidx {
- disableDeviceTests = true
+ deviceTests {
+ enabled = false
+ }
}
diff --git a/benchmark/integration-tests/baselineprofile-producer/src/main/AndroidManifest.xml b/benchmark/integration-tests/baselineprofile-producer/src/main/AndroidManifest.xml
deleted file mode 100644
index bae036b..0000000
--- a/benchmark/integration-tests/baselineprofile-producer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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 />
diff --git a/benchmark/integration-tests/macrobenchmark-target/src/main/java/androidx/benchmark/integration/macrobenchmark/target/BackgroundWorkActivity.kt b/benchmark/integration-tests/macrobenchmark-target/src/main/java/androidx/benchmark/integration/macrobenchmark/target/BackgroundWorkActivity.kt
index 9ccde18..64abbf4 100644
--- a/benchmark/integration-tests/macrobenchmark-target/src/main/java/androidx/benchmark/integration/macrobenchmark/target/BackgroundWorkActivity.kt
+++ b/benchmark/integration-tests/macrobenchmark-target/src/main/java/androidx/benchmark/integration/macrobenchmark/target/BackgroundWorkActivity.kt
@@ -23,12 +23,12 @@
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.tracing.trace
-import kotlin.concurrent.thread
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkInfo
import androidx.work.WorkManager
import java.util.concurrent.CountDownLatch
+import kotlin.concurrent.thread
class BackgroundWorkActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
diff --git a/benchmark/integration-tests/macrobenchmark/build.gradle b/benchmark/integration-tests/macrobenchmark/build.gradle
index a62c063..58d7ee0 100644
--- a/benchmark/integration-tests/macrobenchmark/build.gradle
+++ b/benchmark/integration-tests/macrobenchmark/build.gradle
@@ -19,7 +19,7 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -28,34 +28,31 @@
minSdkVersion 23
}
sourceSets {
- androidTest.assets.srcDirs += new File(
+ main.assets.srcDirs += new File(
SupportConfigKt.getPrebuiltsRoot(project),
"androidx/traceprocessor/testdata"
)
}
namespace "androidx.benchmark.integration.macrobenchmark"
+ targetProjectPath = ":benchmark:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(project(":tracing:tracing-ktx"))
- androidTestImplementation(libs.kotlinTest)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
- androidTestImplementation(libs.testExtTruth)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":benchmark:integration-tests:macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":benchmark:integration-tests:macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":benchmark:benchmark-junit4"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(project(":tracing:tracing-ktx"))
+ implementation(libs.kotlinTest)
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
+ implementation(libs.testExtTruth)
}
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index ed173d5..0000000
--- a/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2020 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 />
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/AudioUnderrunBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/AudioUnderrunBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/AudioUnderrunBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/AudioUnderrunBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/BaselineProfileRuleTest.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/CompilationModeTest.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/CompilationModeTest.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/CompilationModeTest.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/CompilationModeTest.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/GithubBrowserBaselineProfile.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/GithubBrowserBaselineProfile.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/GithubBrowserBaselineProfile.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/GithubBrowserBaselineProfile.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/GridBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/GridBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/GridBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/GridBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/PerfettoTraceProcessorBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/PerfettoTraceProcessorBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/PerfettoTraceProcessorBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/PerfettoTraceProcessorBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SeparateProcessBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SeparateProcessBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SeparateProcessBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SeparateProcessBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt
similarity index 99%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt
index 70de30b..daff320 100644
--- a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt
+++ b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SingleColorPowerBenchmark.kt
@@ -16,9 +16,9 @@
package androidx.benchmark.integration.macrobenchmark
-import android.os.Bundle
import android.content.Intent
import android.graphics.Color
+import android.os.Bundle
import androidx.benchmark.macro.BatteryCharge
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.ExperimentalMetricApi
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SmallListStartupBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SmallListStartupBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SmallListStartupBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SmallListStartupBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/StartupPressHomeBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/StartupPressHomeBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/StartupPressHomeBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/StartupPressHomeBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SystemUiBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SystemUiBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/SystemUiBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/SystemUiBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBaselineProfile.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialListScrollBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt
similarity index 99%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt
index 8917e0e..abd49e50 100644
--- a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt
+++ b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialPowerBenchmark.kt
@@ -18,10 +18,10 @@
import android.content.Intent
import androidx.benchmark.macro.BatteryCharge
-import androidx.benchmark.macro.PowerCategory
-import androidx.benchmark.macro.PowerCategoryDisplayLevel
import androidx.benchmark.macro.CompilationMode
import androidx.benchmark.macro.ExperimentalMetricApi
+import androidx.benchmark.macro.PowerCategory
+import androidx.benchmark.macro.PowerCategoryDisplayLevel
import androidx.benchmark.macro.PowerMetric
import androidx.benchmark.macro.PowerRail
import androidx.benchmark.macro.StartupMode
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBaselineProfile.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBaselineProfile.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBaselineProfile.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBaselineProfile.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupFullyDrawnBenchmark.kt b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupFullyDrawnBenchmark.kt
similarity index 100%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupFullyDrawnBenchmark.kt
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupFullyDrawnBenchmark.kt
diff --git a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java
similarity index 92%
rename from benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java
rename to benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java
index 2e75f3a..8090aa3 100644
--- a/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java
+++ b/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialStartupJavaBenchmark.java
@@ -20,19 +20,27 @@
import androidx.benchmark.macro.StartupMode;
import androidx.benchmark.macro.StartupTimingMetric;
import androidx.benchmark.macro.junit4.MacrobenchmarkRule;
+import androidx.test.filters.LargeTest;
import androidx.test.filters.SdkSuppress;
+import kotlin.Unit;
+
import org.junit.Rule;
import org.junit.Test;
import java.util.Collections;
-import kotlin.Unit;
-
+/**
+ * Simple benchmark for startup in java.
+ */
+@LargeTest
public class TrivialStartupJavaBenchmark {
@Rule
public MacrobenchmarkRule mBenchmarkRule = new MacrobenchmarkRule();
+ /**
+ * Benchmark for startup.
+ */
@Test
@SdkSuppress(minSdkVersion = 29)
public void startup() {
diff --git a/benchmark/integration-tests/test-module-sample/build.gradle b/benchmark/integration-tests/test-module-sample/build.gradle
deleted file mode 100644
index 5351938..0000000
--- a/benchmark/integration-tests/test-module-sample/build.gradle
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.
- */
-
-plugins {
- id("AndroidXPlugin")
- id("com.android.test")
- id("kotlin-android")
-}
-
-android {
- targetProjectPath = ":benchmark:integration-tests:macrobenchmark-target"
- experimentalProperties["android.experimental.self-instrumenting"] = true
-
- // note: below is optional, mimicing eventual benchmark module setup
- buildTypes {
- release {
- debuggable = true
- }
- }
-
- defaultConfig {
- minSdkVersion 28
- }
- namespace "androidx.benchmark.integration.testmodulesample"
-}
-
-// note: below is optional, mimicing eventual benchmark module setup
-androidComponents {
- beforeVariants(selector().all()) {
- // Enable only the release buildType, since we only want to measure
- // release build performance
- getLogger().info("setting enable for variant" + name + ", buildType " + buildType)
- enabled = buildType == 'release'
- }
-}
-
-dependencies {
- implementation(libs.kotlinStdlib)
- implementation(libs.testRules)
- implementation(libs.testExtJunit)
- implementation(libs.testCore)
- implementation(libs.testRunner)
-}
diff --git a/benchmark/integration-tests/test-module-sample/src/main/AndroidManifest.xml b/benchmark/integration-tests/test-module-sample/src/main/AndroidManifest.xml
deleted file mode 100644
index 37fa920..0000000
--- a/benchmark/integration-tests/test-module-sample/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?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.
- -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
- <queries>
- <!--
- Enables querying application info with packageManager.getApplicationInfo, to verify
- the target package is present
- -->
- <package android:name="androidx.benchmark.integration.macrobenchmark.target" />
- </queries>
-</manifest>
diff --git a/benchmark/integration-tests/test-module-sample/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialTestModuleTest.kt b/benchmark/integration-tests/test-module-sample/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialTestModuleTest.kt
deleted file mode 100644
index aac7497..0000000
--- a/benchmark/integration-tests/test-module-sample/src/main/java/androidx/benchmark/integration/macrobenchmark/TrivialTestModuleTest.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/*
- * Copyright 2020 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 androidx.benchmark.integration.macrobenchmark
-
-import android.content.pm.PackageManager
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.LargeTest
-import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.Assert.assertEquals
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@LargeTest
-@RunWith(AndroidJUnit4::class)
-class TrivialTestModuleTest {
- @Test
- fun targetPackage() {
- // if self-instrumenting wasn't used, this would instrument the target app,
- // and we'd see TargetPackage instead
- assertEquals(
- TestPackage,
- InstrumentationRegistry.getInstrumentation().targetContext.packageName
- )
- }
-
- @Test
- fun testPackage() {
- assertEquals(
- TestPackage,
- InstrumentationRegistry.getInstrumentation().context.packageName
- )
- }
-
- @Ignore // b/202321897
- @Test
- @Suppress("DEPRECATION")
- fun targetPackageInstalled() {
- val pm = InstrumentationRegistry.getInstrumentation().context.packageManager
- try {
- pm.getApplicationInfo(TargetPackage, 0)
- } catch (notFoundException: PackageManager.NameNotFoundException) {
- throw AssertionError(
- "Unable to find target package $TargetPackage, is it installed?",
- notFoundException
- )
- }
- }
-
- companion object {
- const val TargetPackage = "androidx.benchmark.integration.macrobenchmark.target"
- const val TestPackage = "androidx.benchmark.integration.testmodulesample"
- }
-}
diff --git a/biometric/biometric-ktx/samples/build.gradle b/biometric/biometric-ktx/samples/build.gradle
index 0f995ee..5d20e55 100644
--- a/biometric/biometric-ktx/samples/build.gradle
+++ b/biometric/biometric-ktx/samples/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "AndroidX Biometric Samples"
+ name = "Biometric Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the AndroidX Biometric library"
diff --git a/biometric/biometric-ktx/src/main/AndroidManifest.xml b/biometric/biometric-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 227314e..0000000
--- a/biometric/biometric-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-<manifest />
\ No newline at end of file
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricAuthExtensions.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricAuthExtensions.kt
index a940f035..df6709e 100755
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricAuthExtensions.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricAuthExtensions.kt
@@ -18,8 +18,8 @@
import androidx.biometric.BiometricPrompt.AuthenticationResult
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.Executor
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Shows an authentication prompt to the user.
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricOrCredentialAuthExtensions.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricOrCredentialAuthExtensions.kt
index a41bf5d..39a9372 100755
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricOrCredentialAuthExtensions.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class2BiometricOrCredentialAuthExtensions.kt
@@ -18,8 +18,8 @@
import androidx.biometric.BiometricPrompt.AuthenticationResult
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.Executor
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Shows an authentication prompt to the user.
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricAuthExtensions.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricAuthExtensions.kt
index f5d0ee3..5808509 100755
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricAuthExtensions.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricAuthExtensions.kt
@@ -19,8 +19,8 @@
import androidx.biometric.BiometricPrompt.CryptoObject
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.Executor
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Shows an authentication prompt to the user.
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricOrCredentialAuthExtensions.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricOrCredentialAuthExtensions.kt
index e26acf4..3da017d 100755
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricOrCredentialAuthExtensions.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/Class3BiometricOrCredentialAuthExtensions.kt
@@ -21,8 +21,8 @@
import androidx.biometric.BiometricPrompt.CryptoObject
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.Executor
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Shows an authentication prompt to the user.
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CoroutineAuthPromptCallback.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CoroutineAuthPromptCallback.kt
index fb6de45..f07c3ef 100644
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CoroutineAuthPromptCallback.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CoroutineAuthPromptCallback.kt
@@ -18,8 +18,8 @@
import androidx.biometric.BiometricPrompt.AuthenticationResult
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.CancellableContinuation
import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.CancellableContinuation
/**
* Implementation of [AuthPromptCallback] used to transform callback results for coroutine APIs.
diff --git a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CredentialAuthExtensions.kt b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CredentialAuthExtensions.kt
index fe98720..d37eb21 100755
--- a/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CredentialAuthExtensions.kt
+++ b/biometric/biometric-ktx/src/main/java/androidx/biometric/auth/CredentialAuthExtensions.kt
@@ -21,8 +21,8 @@
import androidx.biometric.BiometricPrompt.AuthenticationResult
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.Executor
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Shows an authentication prompt to the user.
diff --git a/biometric/integration-tests/testapp/src/main/java/androidx/biometric/integration/testapp/AuthPromptTestActivity.kt b/biometric/integration-tests/testapp/src/main/java/androidx/biometric/integration/testapp/AuthPromptTestActivity.kt
index 0e92e2a..ef20273 100755
--- a/biometric/integration-tests/testapp/src/main/java/androidx/biometric/integration/testapp/AuthPromptTestActivity.kt
+++ b/biometric/integration-tests/testapp/src/main/java/androidx/biometric/integration/testapp/AuthPromptTestActivity.kt
@@ -24,9 +24,9 @@
import androidx.biometric.BiometricPrompt
import androidx.biometric.auth.AuthPrompt
import androidx.biometric.auth.AuthPromptCallback
+import androidx.biometric.auth.authenticateWithClass3Biometrics
import androidx.biometric.auth.startClass2BiometricAuthentication
import androidx.biometric.auth.startClass2BiometricOrCredentialAuthentication
-import androidx.biometric.auth.authenticateWithClass3Biometrics
import androidx.biometric.auth.startClass3BiometricOrCredentialAuthentication
import androidx.biometric.auth.startCredentialAuthentication
import androidx.biometric.integration.testapp.R.string.biometric_prompt_description
diff --git a/bluetooth/bluetooth-testing/build.gradle b/bluetooth/bluetooth-testing/build.gradle
index a9ac8a5..e0f587c 100644
--- a/bluetooth/bluetooth-testing/build.gradle
+++ b/bluetooth/bluetooth-testing/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "AndroidX Bluetooth Testing"
+ name = "Bluetooth Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2022"
description = "Test utilities for AndroidX Bluetooth"
diff --git a/bluetooth/bluetooth-testing/src/androidTest/AndroidManifest.xml b/bluetooth/bluetooth-testing/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index a9bb124..0000000
--- a/bluetooth/bluetooth-testing/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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.
- -->
-<manifest />
diff --git a/bluetooth/bluetooth-testing/src/main/AndroidManifest.xml b/bluetooth/bluetooth-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index 9ac1b77..0000000
--- a/bluetooth/bluetooth-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<manifest />
diff --git a/bluetooth/bluetooth/build.gradle b/bluetooth/bluetooth/build.gradle
index c455f0b..8e7f695 100644
--- a/bluetooth/bluetooth/build.gradle
+++ b/bluetooth/bluetooth/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "AndroidX Bluetooth"
+ name = "Bluetooth"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2022"
description = "AndroidX Bluetooth Library"
diff --git a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothGattServiceTest.kt b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothGattServiceTest.kt
index 0ac236b..eb01e73 100644
--- a/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothGattServiceTest.kt
+++ b/bluetooth/bluetooth/src/androidTest/java/androidx/bluetooth/BluetoothGattServiceTest.kt
@@ -16,8 +16,8 @@
package androidx.bluetooth
-import android.bluetooth.BluetoothGattService as FwkBluetoothGattService
import android.bluetooth.BluetoothGattCharacteristic as FwkBluetoothGattCharacteristic
+import android.bluetooth.BluetoothGattService as FwkBluetoothGattService
import android.bluetooth.BluetoothGattService.SERVICE_TYPE_PRIMARY
import java.util.UUID
import org.junit.Assert.assertEquals
diff --git a/bluetooth/integration-tests/testapp/build.gradle b/bluetooth/integration-tests/testapp/build.gradle
index 55523d6..c99f4b1 100644
--- a/bluetooth/integration-tests/testapp/build.gradle
+++ b/bluetooth/integration-tests/testapp/build.gradle
@@ -50,7 +50,7 @@
implementation("androidx.appcompat:appcompat:1.6.1")
implementation(libs.constraintLayout)
implementation("androidx.core:core-ktx:1.10.0")
- implementation("androidx.fragment:fragment-ktx:1.5.6")
+ implementation("androidx.fragment:fragment-ktx:1.5.7")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
index e5f71ad..e22e999 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/advertiser/AdvertiserFragment.kt
@@ -23,7 +23,6 @@
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
-
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.PopupMenu
import androidx.bluetooth.AdvertiseResult
@@ -36,14 +35,12 @@
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
-
+import java.util.UUID
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import java.util.UUID
-
class AdvertiserFragment : Fragment() {
private companion object {
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/ScanResultAdapter.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/ScanResultAdapter.kt
index ed937a5..0762fa9 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/ScanResultAdapter.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/common/ScanResultAdapter.kt
@@ -21,7 +21,6 @@
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
-
import androidx.bluetooth.integration.testapp.R
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeFragment.kt
index 593f46b..f4e7d85 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeFragment.kt
@@ -66,11 +66,7 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
- Log.d(
- TAG, "onCreateView() called with: inflater = $inflater, " +
- "container = $container, savedInstanceState = $savedInstanceState"
- )
- mHomeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
+ mHomeViewModel = ViewModelProvider(this)[HomeViewModel::class.java]
_binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeViewModel.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeViewModel.kt
index 4d85a68..88b1c1c 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeViewModel.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/home/HomeViewModel.kt
@@ -21,7 +21,7 @@
class HomeViewModel : ViewModel() {
- companion object {
+ private companion object {
private const val TAG = "HomeViewModel"
}
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerAdapter.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerAdapter.kt
index 7641f8a..9cf5027 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerAdapter.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerAdapter.kt
@@ -23,7 +23,6 @@
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
-
import androidx.bluetooth.integration.testapp.R
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
diff --git a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
index dc9536e..5bfc8f0 100644
--- a/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
+++ b/bluetooth/integration-tests/testapp/src/main/java/androidx/bluetooth/integration/testapp/ui/scanner/ScannerFragment.kt
@@ -16,10 +16,9 @@
package androidx.bluetooth.integration.testapp.ui.scanner
-// TODO(ofy) Migrate from androidx.bluetooth.integration.testapp.experimental.BluetoothLe to
-// androidx.bluetooth.BluetoothDevice once in place
-// TODO(ofy) Migrate from androidx.bluetooth.integration.testapp.experimental.BluetoothLe to
-// androidx.bluetooth.BluetoothLe once scan API is in place
+// TODO(ofy) Migrate from androidx.bluetooth.integration.testapp.experimental.BluetoothLe
+// to androidx.bluetooth.BluetoothLe once scan API is in place
+import android.annotation.SuppressLint
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.os.Bundle
@@ -28,10 +27,8 @@
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
-
import androidx.bluetooth.integration.testapp.R
import androidx.bluetooth.integration.testapp.databinding.FragmentScannerBinding
-import android.annotation.SuppressLint
import androidx.bluetooth.integration.testapp.experimental.BluetoothLe
import androidx.bluetooth.integration.testapp.ui.common.getColor
import androidx.core.view.isVisible
@@ -39,15 +36,13 @@
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
-
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.Tab
-
+import java.lang.Exception
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import java.lang.Exception
class ScannerFragment : Fragment() {
@@ -138,8 +133,6 @@
DividerItemDecoration(context, LinearLayoutManager.VERTICAL)
)
- initData()
-
binding.buttonScan.setOnClickListener {
if (scanJob?.isActive == true) {
isScanning = false
@@ -148,6 +141,8 @@
}
}
+ initData()
+
return binding.root
}
@@ -155,8 +150,6 @@
super.onDestroyView()
_binding = null
isScanning = false
- scanJob?.cancel()
- scanJob = null
}
private fun initData() {
@@ -197,7 +190,7 @@
binding.tabLayout.getTabAt(index)
}
- // To prevent TabSelectedListener being triggered when a tab is promatically selected.
+ // To prevent TabSelectedListener being triggered when a tab is programmatically selected.
binding.tabLayout.removeOnTabSelectedListener(onTabSelectedListener)
binding.tabLayout.selectTab(deviceTab)
binding.tabLayout.addOnTabSelectedListener(onTabSelectedListener)
@@ -217,7 +210,9 @@
val customView = newTab.customView
customView?.findViewById<TextView>(R.id.text_view_address)?.text = deviceAddress
- customView?.findViewById<TextView>(R.id.text_view_name)?.text = deviceName
+ val textViewName = customView?.findViewById<TextView>(R.id.text_view_name)
+ textViewName?.text = deviceName
+ textViewName?.isVisible = deviceName.isNullOrEmpty().not()
binding.tabLayout.addTab(newTab)
return newTab
diff --git a/browser/browser/build.gradle b/browser/browser/build.gradle
index de7fa00..195ec5c 100644
--- a/browser/browser/build.gradle
+++ b/browser/browser/build.gradle
@@ -51,8 +51,8 @@
}
androidx {
- name = "Android Support Custom Tabs"
+ name = "Browser"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2015"
- description = "Android Support Custom Tabs"
+ description = "Provides support for embedding Custom Tabs in an app."
}
diff --git a/browser/browser/src/main/AndroidManifest.xml b/browser/browser/src/main/AndroidManifest.xml
deleted file mode 100644
index 3e475b2..0000000
--- a/browser/browser/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2015 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 />
diff --git a/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle b/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
index 06e9e6e..eae2213 100644
--- a/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
+++ b/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
@@ -11,7 +11,7 @@
}
androidx {
- name = "Sample Library"
+ name = "Sample"
publish = Publish.SNAPSHOT_AND_RELEASE
type = LibraryType.SAMPLES
inceptionYear = "2020"
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
index 32f63ba..c596da5 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
@@ -153,6 +153,7 @@
error.add("ComposableLambdaParameterPosition")
error.add("CompositionLocalNaming")
error.add("ComposableModifierFactory")
+ error.add("AutoboxingStateCreation")
error.add("AutoboxingStateValueProperty")
error.add("InvalidColorHexValue")
error.add("MissingColorAlphaChannel")
@@ -161,6 +162,7 @@
error.add("ModifierNodeInspectableProperties")
error.add("ModifierParameter")
error.add("MutableCollectionMutableState")
+ error.add("OpaqueUnitKey")
error.add("UnnecessaryComposedModifier")
error.add("FrequentlyChangedStateReadInComposition")
error.add("ReturnFromAwaitPointerEventScope")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeMultiplatformExtensionImpl.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeMultiplatformExtensionImpl.kt
index 54ccdca..c628d7f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeMultiplatformExtensionImpl.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeMultiplatformExtensionImpl.kt
@@ -16,11 +16,11 @@
package androidx.build
+import javax.inject.Inject
+import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-import org.gradle.api.Project
-import javax.inject.Inject
open class AndroidXComposeMultiplatformExtensionImpl @Inject constructor(
project: Project
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXExtension.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXExtension.kt
index 8c0a117..242b964 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXExtension.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXExtension.kt
@@ -23,13 +23,16 @@
import java.io.File
import org.gradle.api.GradleException
import org.gradle.api.Project
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.api.plugins.ExtensionContainer
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
/**
* Extension for [AndroidXImplPlugin] that's responsible for holding configuration options.
*/
-open class AndroidXExtension(val project: Project) {
+abstract class AndroidXExtension(val project: Project) : ExtensionAware {
+
@JvmField
val LibraryVersions: Map<String, Version>
@@ -45,6 +48,8 @@
private val versionService: LibraryVersionsService
+ val deviceTests = DeviceTests.register(project.extensions)
+
init {
val tomlFileName = "libraryversions.toml"
val toml = lazyReadFile(tomlFileName)
@@ -376,8 +381,6 @@
var metalavaK2UastEnabled = false
- var disableDeviceTests = false
-
val additionalDeviceTestApkKeys = mutableListOf<String>()
val additionalDeviceTestTags: MutableList<String> by lazy {
@@ -422,3 +425,18 @@
var name: String? = null
var url: String? = null
}
+
+abstract class DeviceTests {
+
+ companion object {
+ private const val EXTENSION_NAME = "deviceTests"
+ internal fun register(extensions: ExtensionContainer): DeviceTests {
+ return extensions.findByType(DeviceTests::class.java)
+ ?: extensions.create(EXTENSION_NAME, DeviceTests::class.java)
+ }
+ }
+
+ var enabled = true
+ var targetAppProject: Project? = null
+ var targetAppVariant = "debug"
+}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index f868506..bb7940d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -29,15 +29,15 @@
import androidx.build.checkapi.LibraryApiTaskConfig
import androidx.build.checkapi.configureProjectForApiTasks
import androidx.build.dependencies.KOTLIN_VERSION
-import androidx.build.dependencyTracker.AffectedModuleDetector
import androidx.build.docs.AndroidXKmpDocsImplPlugin
import androidx.build.gradle.isRoot
import androidx.build.license.configureExternalDependencyLicenseCheck
import androidx.build.resources.configurePublicResourcesStub
import androidx.build.sbom.validateAllArchiveInputsRecognized
import androidx.build.studio.StudioTask
+import androidx.build.testConfiguration.ModuleInfoGenerator
+import androidx.build.testConfiguration.TestModule
import androidx.build.testConfiguration.addAppApkToTestConfigGeneration
-import androidx.build.testConfiguration.addToTestZips
import androidx.build.testConfiguration.configureTestConfigGeneration
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.dsl.ManagedVirtualDevice
@@ -54,7 +54,6 @@
import com.android.build.gradle.TestExtension
import com.android.build.gradle.TestPlugin
import com.android.build.gradle.TestedExtension
-import com.android.build.gradle.internal.tasks.ListingFileRedirectTask
import java.io.File
import java.time.Duration
import java.util.Locale
@@ -230,7 +229,19 @@
task.inputs.property("ignoreFailures", ignoreFailures)
val xmlReportDestDir = project.getHostTestResultDirectory()
- val archiveName = "${project.path}:${task.name}.zip"
+ val testName = "${project.path}:${task.name}"
+ project.rootProject.tasks.named("createModuleInfo").configure {
+ it as ModuleInfoGenerator
+ it.testModules.add(
+ TestModule(
+ name = testName,
+ path = listOf(
+ project.projectDir.toRelativeString(project.getSupportRootFolder())
+ )
+ )
+ )
+ }
+ val archiveName = "$testName.zip"
if (project.isDisplayTestOutput()) {
// Enable tracing to see results in command line
task.testLogging.apply {
@@ -326,7 +337,7 @@
private fun configureWithAppPlugin(project: Project, androidXExtension: AndroidXExtension) {
project.extensions.getByType<AppExtension>().apply {
configureAndroidBaseOptions(project, androidXExtension)
- configureAndroidApplicationOptions(project)
+ configureAndroidApplicationOptions(project, androidXExtension)
}
project.extensions.getByType<ApplicationAndroidComponentsExtension>().apply {
@@ -350,6 +361,7 @@
) {
project.extensions.getByType<TestExtension>().apply {
configureAndroidBaseOptions(project, androidXExtension)
+ project.addAppApkToTestConfigGeneration(androidXExtension)
}
project.configureJavaCompilationWarnings(androidXExtension)
@@ -413,6 +425,7 @@
) {
val libraryExtension = project.extensions.getByType<LibraryExtension>().apply {
configureAndroidBaseOptions(project, androidXExtension)
+ project.addAppApkToTestConfigGeneration(androidXExtension)
configureAndroidLibraryOptions(project, androidXExtension)
// Make sure the main Kotlin source set doesn't contain anything under src/main/kotlin.
@@ -573,6 +586,7 @@
extension.type == LibraryType.UNSET
if (mavenGroup != null && isProbablyPublished && extension.shouldPublish()) {
validateProjectStructure(mavenGroup.group)
+ validateProjectMavenName(extension.name.get(), mavenGroup.group)
}
}
}
@@ -702,19 +716,6 @@
project.configureTestConfigGeneration(this)
project.configureFtlRunner()
- val buildTestApksTask = project.rootProject.tasks.named(BUILD_TEST_APKS_TASK)
- when (this) {
- is TestedExtension -> testVariants
- // app module defines variants for test module
- is TestExtension -> applicationVariants
- else -> throw IllegalStateException("Unsupported plugin type")
- }.all { variant ->
- buildTestApksTask.configure {
- it.dependsOn(variant.assembleProvider)
- }
- variant.configureApkZipping(project)
- }
-
// AGP warns if we use project.buildDir (or subdirs) for CMake's generated
// build files (ninja build files, CMakeCache.txt, etc.). Use a staging directory that
// lives alongside the project's buildDir.
@@ -722,24 +723,6 @@
File(project.buildDir, "../nativeBuildStaging")
}
- /**
- * Configures the ZIP_TEST_CONFIGS_WITH_APKS_TASK to include the test apk if applicable
- */
- @Suppress("DEPRECATION") // ApkVariant
- private fun com.android.build.gradle.api.ApkVariant.configureApkZipping(
- project: Project
- ) {
- packageApplicationProvider.get().let { packageTask ->
- AffectedModuleDetector.configureTaskGuard(packageTask)
- addToTestZips(project, packageTask)
- }
- // This task needs to be guarded by AffectedModuleDetector due to guarding test
- // APK building above. It can only be removed if we stop using AMD for test APKs.
- project.tasks.withType(ListingFileRedirectTask::class.java).forEach {
- AffectedModuleDetector.configureTaskGuard(it)
- }
- }
-
private fun LibraryExtension.configureAndroidLibraryOptions(
project: Project,
androidXExtension: AndroidXExtension
@@ -842,25 +825,17 @@
}
}
- private fun AppExtension.configureAndroidApplicationOptions(project: Project) {
+ private fun AppExtension.configureAndroidApplicationOptions(
+ project: Project,
+ androidXExtension: AndroidXExtension
+ ) {
defaultConfig.apply {
versionCode = 1
versionName = "1.0"
}
- project.addAppApkToTestConfigGeneration()
+ project.addAppApkToTestConfigGeneration(androidXExtension)
project.addAppApkToFtlRunner()
-
- val buildTestApksTask = project.rootProject.tasks.named(BUILD_TEST_APKS_TASK)
- applicationVariants.all { variant ->
- // Using getName() instead of name due to b/150427408
- if (variant.buildType.name == "debug") {
- buildTestApksTask.configure {
- it.dependsOn(variant.assembleProvider)
- }
- }
- variant.configureApkZipping(project)
- }
}
private fun Project.configureDependencyVerification(
@@ -1001,7 +976,6 @@
}
companion object {
- const val BUILD_TEST_APKS_TASK = "buildTestApks"
const val CREATE_LIBRARY_BUILD_INFO_FILES_TASK = "createLibraryBuildInfoFiles"
const val GENERATE_TEST_CONFIGURATION_TASK = "GenerateTestConfiguration"
const val ZIP_TEST_CONFIGS_WITH_APKS_TASK = "zipTestConfigsWithApks"
@@ -1097,14 +1071,6 @@
}
}
-/**
- * Guarantees unique names for the APKs, and modifies some of the suffixes. The APK name is used
- * to determine what gets run by our test runner
- */
-fun String.renameApkForTesting(projectPath: String): String {
- return "${projectPath.asFilenamePrefix()}_$this"
-}
-
fun Project.hasBenchmarkPlugin(): Boolean {
return this.plugins.hasPlugin(BenchmarkPlugin::class.java)
}
@@ -1170,46 +1136,6 @@
return false
}
-private const val GROUP_PREFIX = "androidx."
-
-/**
- * Validates the project structure against Jetpack guidelines.
- */
-fun Project.validateProjectStructure(groupId: String) {
- if (!project.isValidateProjectStructureEnabled()) {
- return
- }
-
- val shortGroupId = if (groupId.startsWith(GROUP_PREFIX)) {
- groupId.substring(GROUP_PREFIX.length)
- } else {
- groupId
- }
-
- // Fully-qualified Gradle project name should match the Maven coordinate.
- val expectName = ":${shortGroupId.replace(".",":")}:${project.name}"
- val actualName = project.path
- if (expectName != actualName) {
- throw GradleException(
- "Invalid project structure! Expected $expectName as project name, found $actualName"
- )
- }
-
- // Project directory should match the Maven coordinate.
- val expectDir = shortGroupId.replace(".", File.separator) +
- "${File.separator}${project.name}"
- // Canonical projectDir is needed because sometimes, at least in tests, on OSX, supportRoot
- // starts with /var, and projectDir starts with /private/var (which are the same thing)
- val canonicalProjectDir = project.projectDir.canonicalFile
- val actualDir =
- canonicalProjectDir.toRelativeString(project.getSupportRootFolder().canonicalFile)
- if (expectDir != actualDir) {
- throw GradleException(
- "Invalid project structure! Expected $expectDir as project directory, found $actualDir"
- )
- }
-}
-
fun Project.validateMultiplatformPluginHasNotBeenApplied() {
if (plugins.hasPlugin(KotlinMultiplatformPluginWrapper::class.java)) {
throw GradleException(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
index f6c6252..db8882a 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXMultiplatformExtension.kt
@@ -24,8 +24,8 @@
import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
-import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetPreset
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetWithHostTests
import org.jetbrains.kotlin.gradle.targets.js.dsl.KotlinJsTargetDsl
@@ -90,7 +90,7 @@
fun desktop(
block: Action<KotlinJvmTarget>? = null
): KotlinJvmTarget? {
- return if (project.enableJvm()) {
+ return if (project.enableDesktop()) {
kotlinExtension.jvm("desktop") {
block?.execute(this)
}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXPlaygroundRootImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXPlaygroundRootImplPlugin.kt
index 96d19f7..c2c4d54 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXPlaygroundRootImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXPlaygroundRootImplPlugin.kt
@@ -18,12 +18,12 @@
import androidx.build.gradle.isRoot
import groovy.xml.DOMBuilder
+import java.net.URI
+import java.net.URL
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
-import java.net.URI
-import java.net.URL
/**
* This plugin is used in Playground projects and adds functionality like resolving to snapshot
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
index f7bd29a..7a4f3c0 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXRootImplPlugin.kt
@@ -136,8 +136,6 @@
}
}
- tasks.register(AndroidXImplPlugin.BUILD_TEST_APKS_TASK)
-
// NOTE: this task is used by the Github CI as well. If you make any changes here,
// please update the .github/workflows files as well, if necessary.
project.tasks.register(
@@ -150,6 +148,7 @@
it.entryCompression = ZipEntryCompression.STORED
// Archive is greater than 4Gb :O
it.isZip64 = true
+ it.isReproducibleFileOrder = true
}
project.tasks.register(
ZIP_CONSTRAINED_TEST_CONFIGS_WITH_APKS_TASK, Zip::class.java
@@ -161,6 +160,7 @@
it.entryCompression = ZipEntryCompression.STORED
// Archive is greater than 4Gb :O
it.isZip64 = true
+ it.isReproducibleFileOrder = true
}
AffectedModuleDetector.configure(gradle, this)
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/BuildOnServerTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/BuildOnServerTask.kt
index 006a4fc..5af1390 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/BuildOnServerTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/BuildOnServerTask.kt
@@ -16,15 +16,15 @@
package androidx.build
+import java.io.File
+import java.io.FileNotFoundException
import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
-import java.io.FileNotFoundException
-import org.gradle.api.tasks.CacheableTask
/**
* Task for building all of Androidx libraries and documentation
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/InspectionRelease.kt b/buildSrc/private/src/main/kotlin/androidx/build/InspectionRelease.kt
index dc38caa..0db92e6 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/InspectionRelease.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/InspectionRelease.kt
@@ -19,10 +19,10 @@
import androidx.inspection.gradle.InspectionPlugin
import androidx.inspection.gradle.createConsumeInspectionConfiguration
import androidx.inspection.gradle.createConsumeNonDexedInspectionConfiguration
+import java.io.File
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.Sync
-import java.io.File
/**
* Copies artifacts prepared by InspectionPlugin into $destDir/inspection
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/Ktlint.kt b/buildSrc/private/src/main/kotlin/androidx/build/Ktlint.kt
index 7ce68bb..d1319ad 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/Ktlint.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/Ktlint.kt
@@ -79,8 +79,6 @@
}
private val DisabledRules = listOf(
- // does not match IJ default ordering
- "import-ordering",
// not useful for our projects
"final-newline",
// TODO: reenable when https://github.com/pinterest/ktlint/issues/1221 is resolved
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
index e2d0e2a..6d9ff9c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
@@ -21,7 +21,6 @@
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.stream.JsonWriter
-import org.gradle.api.artifacts.Configuration
import groovy.util.Node
import java.io.File
import java.io.StringReader
@@ -37,6 +36,7 @@
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.XmlProvider
+import org.gradle.api.artifacts.Configuration
import org.gradle.api.component.ComponentWithVariants
import org.gradle.api.component.SoftwareComponent
import org.gradle.api.component.SoftwareComponentFactory
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt b/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt
new file mode 100644
index 0000000..bbe7f2a
--- /dev/null
+++ b/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.build
+
+import java.io.File
+import org.gradle.api.GradleException
+import org.gradle.api.Project
+
+// Translate common phrases and marketing names into Maven name component equivalents.
+private val mavenNameMap = mapOf(
+ "android for cars" to "car",
+ "android wear" to "wear",
+ "internationalization" to "i18n",
+ "kotlin extensions" to "ktx",
+ "lint checks" to "lint",
+ "material components" to "material",
+ "material3 components" to "material3",
+ "workmanager" to "work",
+ "windowmanager" to "window",
+)
+
+// Allow a small set of common Maven name components that don't need to appear in the project name.
+private val mavenNameAllowlist = setOf(
+ "extension",
+ "extensions",
+ "for",
+ "integration",
+ "with",
+)
+
+/**
+ * Validates the project's Maven name against Jetpack guidelines.
+ */
+fun Project.validateProjectMavenName(mavenName: String?, groupId: String) {
+ if (mavenName == null) return
+
+ // Tokenize the Maven name into components. This is *very* permissive regarding separators, and
+ // we may want to revisit that policy in the future.
+ val nameComponents = mavenName.lowercase().let { name ->
+ mavenNameMap.entries.fold(name) { newName, entry ->
+ newName.replace(entry.key, entry.value)
+ }
+ }.split(" ", ",", ":", "-").toMutableList() - mavenNameAllowlist
+
+ // Remaining components *must* appear in the Maven coordinate. Shortening long (>10 char) words
+ // to five letters or more is allowed, as is changing the pluralization of words.
+ nameComponents.find { nameComponent ->
+ !name.contains(nameComponent) && !groupId.contains(nameComponent) &&
+ !(nameComponent.length > 10 && name.contains(nameComponent.substring(0, 5))) &&
+ !(nameComponent.endsWith("s") && name.contains(nameComponent.dropLast(1)))
+ }?.let { missingComponent ->
+ throw GradleException(
+ "Invalid Maven name! Found \"$missingComponent\" in Maven name for $displayName, but " +
+ "not project name.\n\nConsider removing \"$missingComponent\" from \"$mavenName\"."
+ )
+ }
+}
+
+private const val GROUP_PREFIX = "androidx."
+
+/**
+ * Validates the project structure against Jetpack guidelines.
+ */
+fun Project.validateProjectStructure(groupId: String) {
+ if (!project.isValidateProjectStructureEnabled()) {
+ return
+ }
+
+ val shortGroupId = if (groupId.startsWith(GROUP_PREFIX)) {
+ groupId.substring(GROUP_PREFIX.length)
+ } else {
+ groupId
+ }
+
+ // Fully-qualified Gradle project name should match the Maven coordinate.
+ val expectName = ":${shortGroupId.replace(".",":")}:${project.name}"
+ val actualName = project.path
+ if (expectName != actualName) {
+ throw GradleException(
+ "Invalid project structure! Expected $expectName as project name, found $actualName"
+ )
+ }
+
+ // Project directory should match the Maven coordinate.
+ val expectDir = shortGroupId.replace(".", File.separator) +
+ "${File.separator}${project.name}"
+ // Canonical projectDir is needed because sometimes, at least in tests, on OSX, supportRoot
+ // starts with /var, and projectDir starts with /private/var (which are the same thing)
+ val canonicalProjectDir = project.projectDir.canonicalFile
+ val actualDir =
+ canonicalProjectDir.toRelativeString(project.getSupportRootFolder().canonicalFile)
+ if (expectDir != actualDir) {
+ throw GradleException(
+ "Invalid project structure! Expected $expectDir as project directory, found $actualDir"
+ )
+ }
+}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ProjectExt.kt b/buildSrc/private/src/main/kotlin/androidx/build/ProjectExt.kt
index 8dcfd8d..5c6a88c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/ProjectExt.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/ProjectExt.kt
@@ -15,12 +15,12 @@
*/
package androidx.build
-import org.gradle.api.Project
-import org.gradle.api.Task
-import org.gradle.api.tasks.TaskProvider
import java.util.Collections
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
+import org.gradle.api.Project
+import org.gradle.api.Task
+import org.gradle.api.tasks.TaskProvider
/**
* Holder class used for lazily registering tasks using the new Lazy task execution API.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ProjectParser.kt b/buildSrc/private/src/main/kotlin/androidx/build/ProjectParser.kt
index f12cbd1..9bf82ea 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/ProjectParser.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/ProjectParser.kt
@@ -16,13 +16,12 @@
package androidx.build
+import java.io.File
import java.util.concurrent.ConcurrentHashMap
import org.gradle.api.Project
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
-import java.io.File
-
abstract class ProjectParser : BuildService<BuildServiceParameters.None> {
@Transient
val cache: MutableMap<File, ParsedProject> = ConcurrentHashMap()
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/Release.kt b/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
index ea56dcb..d6e9baf 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
@@ -17,6 +17,9 @@
import androidx.build.uptodatedness.cacheEvenIfNoOutputs
import com.android.build.gradle.LibraryExtension
+import java.io.File
+import java.io.FileNotFoundException
+import java.util.Locale
import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
@@ -30,9 +33,6 @@
import org.gradle.api.tasks.bundling.Zip
import org.gradle.plugin.devel.GradlePluginDevelopmentExtension
import org.gradle.work.DisableCachingByDefault
-import java.io.File
-import java.io.FileNotFoundException
-import java.util.Locale
/**
* Simple description for an artifact that is released from this project.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/SourceJarTaskHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/SourceJarTaskHelper.kt
index 35ea471..45894a5 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/SourceJarTaskHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/SourceJarTaskHelper.kt
@@ -17,9 +17,13 @@
package androidx.build
import androidx.build.dokka.kmpDocs.DokkaAnalysisPlatform
+import androidx.build.dokka.kmpDocs.docsPlatform
import com.android.build.gradle.LibraryExtension
import com.google.gson.GsonBuilder
import java.io.File
+import java.util.Locale
+import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.attributes.Bundling
@@ -29,22 +33,18 @@
import org.gradle.api.component.AdhocComponentWithVariants
import org.gradle.api.file.DuplicatesStrategy
import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.named
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
-import java.util.Locale
-import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
-import androidx.build.dokka.kmpDocs.docsPlatform
-import org.gradle.api.DefaultTask
-import org.gradle.api.GradleException
-import org.gradle.api.tasks.CacheableTask
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.OutputFile
-import org.gradle.api.tasks.TaskAction
+import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
/**
* Sets up a source jar task for an Android library project.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
index 3cb172a..fcbd5cb 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VerifyDependencyVersionsTask.kt
@@ -24,11 +24,11 @@
import org.gradle.api.artifacts.Dependency
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
+import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.setProperty
-import org.gradle.api.tasks.CacheableTask
/**
* Task for verifying the androidx dependency-stability-suffix rule
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
index 14eacb9..da12c90 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VerifyVersionFilesTask.kt
@@ -16,16 +16,16 @@
package androidx.build
-import org.gradle.api.DefaultTask
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.PathSensitive
-import org.gradle.api.tasks.PathSensitivity
-import org.gradle.api.tasks.TaskAction
import java.io.File
import java.io.FileInputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
+import org.gradle.api.DefaultTask
import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.PathSensitive
+import org.gradle.api.tasks.PathSensitivity
+import org.gradle.api.tasks.TaskAction
/**
* Task for verifying version files in Androidx artifacts
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
index 328350a..ba29911 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/VersionFileWriterTask.kt
@@ -17,6 +17,8 @@
package androidx.build
import com.android.build.gradle.LibraryExtension
+import java.io.File
+import java.io.PrintWriter
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
@@ -25,8 +27,6 @@
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
-import java.io.PrintWriter
/**
* Task that allows to write a version to a given output file.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
index 0f22c64..535e820 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/ApiLocation.kt
@@ -16,12 +16,11 @@
package androidx.build.checkapi
-import java.io.File
-
import androidx.build.Version
import androidx.build.version
-import org.gradle.api.Project
+import java.io.File
import java.io.Serializable
+import org.gradle.api.Project
/**
* Contains information about the files used to record a library's API surfaces. This class may
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
index 9fec2fd..fdec904 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/checkapi/CheckApi.kt
@@ -19,12 +19,12 @@
import androidx.build.Version
import androidx.build.checkapi.ApiLocation.Companion.isResourceApiFilename
import androidx.build.version
-import org.gradle.api.GradleException
-import org.gradle.api.Project
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.name
+import org.gradle.api.GradleException
+import org.gradle.api.Project
enum class ApiType {
CLASSAPI,
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/BuildPropParser.kt b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/BuildPropParser.kt
index 5bd14ff1..f851099 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/BuildPropParser.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/BuildPropParser.kt
@@ -16,8 +16,8 @@
package androidx.build.dependencyTracker
-import org.gradle.api.logging.Logger
import java.io.File
+import org.gradle.api.logging.Logger
/**
* Utility class that can parse build.prop files and extract the sha's for frameworks/support.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/FileLogger.kt b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/FileLogger.kt
index 6bc5a7c..6bd3a1c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/FileLogger.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/FileLogger.kt
@@ -16,14 +16,13 @@
package androidx.build.dependencyTracker
+import java.io.File
+import java.io.Serializable
import org.gradle.api.logging.LogLevel
import org.gradle.internal.logging.slf4j.OutputEventListenerBackedLogger
import org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext
import org.gradle.internal.time.Clock
-import java.io.File
-import java.io.Serializable
-
/**
* Gradle logger that logs to a file
*/
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/ProjectGraph.kt b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/ProjectGraph.kt
index bdb408c..8472eeb 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/ProjectGraph.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/ProjectGraph.kt
@@ -17,10 +17,9 @@
package androidx.build.dependencyTracker
import androidx.build.getSupportRootFolder
-import org.gradle.api.Project
import java.io.File
-
import java.io.Serializable
+import org.gradle.api.Project
import org.gradle.api.logging.Logger
/**
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
index 25452de..21b7fdd 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/docs/AndroidXDocsImplPlugin.kt
@@ -18,7 +18,6 @@
import androidx.build.PROJECT_STRUCTURE_METADATA_FILENAME
import androidx.build.SupportConfig
-import androidx.build.multiplatformUsage
import androidx.build.dackka.DackkaTask
import androidx.build.dackka.GenerateMetadataTask
import androidx.build.dependencies.KOTLIN_VERSION
@@ -29,6 +28,7 @@
import androidx.build.getDistributionDirectory
import androidx.build.getKeystore
import androidx.build.getLibraryByName
+import androidx.build.multiplatformUsage
import com.android.build.api.attributes.BuildTypeAttr
import com.android.build.gradle.LibraryExtension
import com.android.build.gradle.LibraryPlugin
@@ -61,10 +61,10 @@
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Classpath
-import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.InputFiles
-import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.OutputDirectory
+import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.Sync
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitClient.kt b/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitClient.kt
index 4cdaa21..9b1ecee 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitClient.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitClient.kt
@@ -21,8 +21,8 @@
import java.io.File
import org.gradle.api.GradleException
import org.gradle.api.Project
-import org.gradle.api.provider.Provider
import org.gradle.api.logging.Logger
+import org.gradle.api.provider.Provider
interface GitClient {
fun findChangedFilesSince(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitRunnerGitClient.kt b/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitRunnerGitClient.kt
index 2be38e2..2057187 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitRunnerGitClient.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/gitclient/GitRunnerGitClient.kt
@@ -16,9 +16,9 @@
package androidx.build.gitclient
-import org.gradle.api.logging.Logger
import java.io.File
import java.util.concurrent.TimeUnit
+import org.gradle.api.logging.Logger
/**
* A simple git client that uses system process commands to communicate with the git setup in the
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiCompatibilityTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiCompatibilityTask.kt
index c176f11..15b77b7 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiCompatibilityTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiCompatibilityTask.kt
@@ -18,6 +18,9 @@
import androidx.build.OperatingSystem
import androidx.build.getOperatingSystem
+import java.io.ByteArrayOutputStream
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -34,9 +37,6 @@
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutionException
import org.gradle.workers.WorkerExecutor
-import java.io.ByteArrayOutputStream
-import java.io.File
-import javax.inject.Inject
/**
* Task which depends on [GenerateNativeApiTask] and compares the current native API from the build
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiEquivalenceTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiEquivalenceTask.kt
index 6ca2b8d..d6e5964 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiEquivalenceTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/CheckNativeApiEquivalenceTask.kt
@@ -17,6 +17,7 @@
package androidx.build.libabigail
import androidx.build.metalava.checkEqual
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -27,7 +28,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
/**
* Checks that the native API files in the build folder are exactly the same as the checked in
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/GenerateNativeApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/GenerateNativeApiTask.kt
index 41194e3..ad4c23f 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/GenerateNativeApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/GenerateNativeApiTask.kt
@@ -18,6 +18,8 @@
import androidx.build.OperatingSystem
import androidx.build.getOperatingSystem
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.provider.ListProperty
@@ -33,8 +35,6 @@
import org.gradle.workers.WorkAction
import org.gradle.workers.WorkParameters
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
private const val ARCH_PREFIX = "android."
internal val architectures = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/NativeApiTasks.kt b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/NativeApiTasks.kt
index 43f03ba..9101dc7 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/NativeApiTasks.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/NativeApiTasks.kt
@@ -21,8 +21,8 @@
import androidx.build.checkapi.getRequiredCompatibilityApiLocation
import androidx.build.uptodatedness.cacheEvenIfNoOutputs
import com.android.build.gradle.LibraryExtension
-import org.gradle.api.Project
import java.io.File
+import org.gradle.api.Project
/**
* Adds native API generation / updating / checking tasks to a project.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/UpdateNativeApi.kt b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/UpdateNativeApi.kt
index 4e46a2d..b430e48 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/libabigail/UpdateNativeApi.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/libabigail/UpdateNativeApi.kt
@@ -18,6 +18,7 @@
import androidx.build.OperatingSystem
import androidx.build.getOperatingSystem
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -28,7 +29,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
/**
* Task which depends on `[GenerateNativeApiTask] and takes the generated native API files from the
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
index c376ead..0b4c852 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiCompatibilityTask.kt
@@ -20,6 +20,8 @@
import androidx.build.checkapi.ApiLocation
import androidx.build.logging.TERMINAL_RED
import androidx.build.logging.TERMINAL_RESET
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.InputFiles
@@ -28,8 +30,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
/**
* This task validates that the API described in one signature txt file is compatible with the API
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
index d827a8d..58b826c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/CheckApiEquivalenceTask.kt
@@ -17,6 +17,8 @@
package androidx.build.metalava
import androidx.build.checkapi.ApiLocation
+import java.io.File
+import java.util.concurrent.TimeUnit
import org.apache.commons.io.FileUtils
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
@@ -28,8 +30,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
-import java.util.concurrent.TimeUnit
/** Compares two API txt files against each other. */
@DisableCachingByDefault(because = "Doesn't benefit from caching")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
index 659d191..0c68fc9 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiStubClassesTask.kt
@@ -16,13 +16,13 @@
package androidx.build.metalava
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
@CacheableTask
abstract class GenerateApiStubClassesTask @Inject constructor(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
index f087b00..1a1ccea 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/GenerateApiTask.kt
@@ -19,6 +19,8 @@
import androidx.build.checkapi.ApiBaselinesLocation
import androidx.build.checkapi.ApiLocation
import androidx.build.java.JavaCompileInputs
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
@@ -30,8 +32,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
/** Generate an API signature text file from a set of source files. */
@CacheableTask
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
index 3b87d7e..0083bed 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaTask.kt
@@ -16,12 +16,15 @@
package androidx.build.metalava
+import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Classpath
+import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
@@ -29,9 +32,6 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.workers.WorkerExecutor
-import javax.inject.Inject
-import org.gradle.api.provider.Property
-import org.gradle.api.tasks.Input
/** Base class for invoking Metalava. */
@CacheableTask
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
index 139541e..c802617 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/RegenerateOldApisTask.kt
@@ -23,6 +23,8 @@
import androidx.build.getAndroidJar
import androidx.build.getCheckoutRoot
import androidx.build.java.JavaCompileInputs
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
@@ -32,8 +34,6 @@
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.util.PatternFilterable
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
/** Generate API signature text files using previously built .jar/.aar artifacts. */
@CacheableTask
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
index 43dbc6e..59ad911 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/UpdateBaselineTasks.kt
@@ -18,6 +18,8 @@
import androidx.build.checkapi.ApiBaselinesLocation
import androidx.build.checkapi.ApiLocation
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.file.FileCollection
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
@@ -29,8 +31,6 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.workers.WorkerExecutor
-import java.io.File
-import javax.inject.Inject
@CacheableTask
abstract class UpdateApiLintBaselineTask @Inject constructor(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt
index 8137fdd..892e691 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/paparazzi/AndroidXPaparazziImplPlugin.kt
@@ -35,8 +35,8 @@
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.get
-import org.gradle.kotlin.dsl.the
import org.gradle.kotlin.dsl.register
+import org.gradle.kotlin.dsl.the
import org.gradle.kotlin.dsl.withType
import org.gradle.process.JavaForkOptions
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiReleaseTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiReleaseTask.kt
index 8091f1a..df32518 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiReleaseTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiReleaseTask.kt
@@ -17,6 +17,7 @@
package androidx.build.resources
import androidx.build.checkapi.ApiLocation
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.provider.Property
@@ -27,7 +28,6 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
/**
* Task for verifying changes in the public Android resource surface, e.g. `public.xml`.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiTask.kt
index 7320d3b..2b2a1b0 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/CheckResourceApiTask.kt
@@ -17,6 +17,7 @@
package androidx.build.resources
import androidx.build.checkapi.ApiLocation
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -24,10 +25,9 @@
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
-import java.io.File
+import org.gradle.api.tasks.TaskAction
/**
* Task for detecting changes in the public Android resource surface, e.g. `public.xml`.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/GenerateResourceApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/GenerateResourceApiTask.kt
index dffa723..a94bc4c 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/GenerateResourceApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/GenerateResourceApiTask.kt
@@ -17,6 +17,7 @@
package androidx.build.resources
import androidx.build.checkapi.ApiLocation
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.RegularFileProperty
@@ -28,7 +29,6 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
/**
* Generates a resource API file for consumption by other API tasks.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/PublicResourcesStubHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/PublicResourcesStubHelper.kt
index 528c6bb..baae1c5 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/PublicResourcesStubHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/PublicResourcesStubHelper.kt
@@ -18,9 +18,9 @@
import androidx.build.getSupportRootFolder
import com.android.build.gradle.LibraryExtension
+import java.io.File
import org.gradle.api.Project
import org.gradle.api.tasks.Copy
-import java.io.File
fun Project.configurePublicResourcesStub(extension: LibraryExtension) {
val targetResFolder = File(project.buildDir, "generated/res/public-stub")
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/ResourceTasks.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/ResourceTasks.kt
index 3e7187d..e889831 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/ResourceTasks.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/ResourceTasks.kt
@@ -23,8 +23,8 @@
import androidx.build.checkapi.getRequiredCompatibilityApiLocation
import androidx.build.metalava.UpdateApiTask
import androidx.build.uptodatedness.cacheEvenIfNoOutputs
-import org.gradle.api.Project
import java.util.Locale
+import org.gradle.api.Project
object ResourceTasks {
private const val GENERATE_RESOURCE_API_TASK = "generateResourceApi"
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/resources/UpdateResourceApiTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/resources/UpdateResourceApiTask.kt
index fa66eef..bec59cc0 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/resources/UpdateResourceApiTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/resources/UpdateResourceApiTask.kt
@@ -17,6 +17,7 @@
package androidx.build.resources
import androidx.build.checkapi.ApiLocation
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
@@ -28,7 +29,6 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
/**
* Task for updating the public Android resource surface, e.g. `public.xml`.
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioPlatformUtilities.kt b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioPlatformUtilities.kt
index 61b3bf7..587f0a9 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioPlatformUtilities.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioPlatformUtilities.kt
@@ -16,9 +16,9 @@
package androidx.build.studio
-import org.gradle.process.ExecSpec
import java.io.File
import java.util.Locale
+import org.gradle.process.ExecSpec
/**
* Utility class containing helper functions and values that change between Linux and OSX
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateMediaTestConfigurationTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateMediaTestConfigurationTask.kt
index 36ba7f9..57de24e 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateMediaTestConfigurationTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateMediaTestConfigurationTask.kt
@@ -17,8 +17,6 @@
package androidx.build.testConfiguration
import androidx.build.dependencyTracker.ProjectSubset
-import androidx.build.renameApkForTesting
-import com.android.build.api.variant.BuiltArtifact
import com.android.build.api.variant.BuiltArtifacts
import com.android.build.api.variant.BuiltArtifactsLoader
import java.io.File
@@ -79,18 +77,6 @@
abstract val affectedModuleDetectorSubset: Property<ProjectSubset>
@get:Input
- abstract val clientToTPath: Property<String>
-
- @get:Input
- abstract val clientPreviousPath: Property<String>
-
- @get:Input
- abstract val serviceToTPath: Property<String>
-
- @get:Input
- abstract val servicePreviousPath: Property<String>
-
- @get:Input
abstract val minSdk: Property<Int>
@get:Input
@@ -117,39 +103,60 @@
@get:OutputFile
abstract val jsonClientToTServiceToTServiceTests: RegularFileProperty
+ @get:OutputFile
+ abstract val previousClientApk: RegularFileProperty
+
+ @get:OutputFile
+ abstract val totClientApk: RegularFileProperty
+
+ @get:OutputFile
+ abstract val previousServiceApk: RegularFileProperty
+
+ @get:OutputFile
+ abstract val totServiceApk: RegularFileProperty
+
@TaskAction
fun generateAndroidTestZip() {
- val clientToTApk = resolveApk(clientToTFolder, clientToTLoader)
- val clientPreviousApk = resolveApk(clientPreviousFolder, clientPreviousLoader)
- val serviceToTApk = resolveApk(serviceToTFolder, serviceToTLoader)
- val servicePreviousApk = resolveApk(
- servicePreviousFolder, servicePreviousLoader
+ val clientToTApk = totClientApk.get().asFile
+ val clientToTSha256 = copyApkAndGetSha256(clientToTFolder, clientToTLoader, clientToTApk)
+ val clientPreviousApk = previousClientApk.get().asFile
+ val clientPreviousSha256 = copyApkAndGetSha256(
+ clientPreviousFolder, clientPreviousLoader, clientPreviousApk
)
+ val serviceToTApk = totServiceApk.get().asFile
+ val serviceToTSha256 = copyApkAndGetSha256(
+ serviceToTFolder, serviceToTLoader, serviceToTApk
+ )
+ val servicePreviousApk = previousServiceApk.get().asFile
+ val servicePreviousSha256 = copyApkAndGetSha256(
+ servicePreviousFolder, servicePreviousLoader, servicePreviousApk
+ )
+
writeConfigFileContent(
- clientApk = clientToTApk,
- serviceApk = serviceToTApk,
- clientPath = clientToTPath.get(),
- servicePath = serviceToTPath.get(),
+ clientApkName = clientToTApk.name,
+ serviceApkName = serviceToTApk.name,
+ clientApkSha256 = clientToTSha256,
+ serviceApkSha256 = serviceToTSha256,
jsonClientOutputFile = jsonClientToTServiceToTClientTests,
jsonServiceOutputFile = jsonClientToTServiceToTServiceTests,
isClientPrevious = false,
isServicePrevious = false
)
writeConfigFileContent(
- clientApk = clientToTApk,
- serviceApk = servicePreviousApk,
- clientPath = clientToTPath.get(),
- servicePath = servicePreviousPath.get(),
+ clientApkName = clientToTApk.name,
+ serviceApkName = servicePreviousApk.name,
+ clientApkSha256 = clientToTSha256,
+ serviceApkSha256 = servicePreviousSha256,
jsonClientOutputFile = jsonClientToTServicePreviousClientTests,
jsonServiceOutputFile = jsonClientToTServicePreviousServiceTests,
isClientPrevious = false,
isServicePrevious = true
)
writeConfigFileContent(
- clientApk = clientPreviousApk,
- serviceApk = serviceToTApk,
- clientPath = clientPreviousPath.get(),
- servicePath = serviceToTPath.get(),
+ clientApkName = clientPreviousApk.name,
+ serviceApkName = serviceToTApk.name,
+ clientApkSha256 = clientPreviousSha256,
+ serviceApkSha256 = serviceToTSha256,
jsonClientOutputFile = jsonClientPreviousServiceToTClientTests,
jsonServiceOutputFile = jsonClientPreviousServiceToTServiceTests,
isClientPrevious = true,
@@ -165,26 +172,27 @@
?: throw RuntimeException("Cannot load required APK for task: $name")
}
- private fun BuiltArtifact.resolveName(path: String): String {
- return outputFile.substringAfterLast("/").renameApkForTesting(path)
+ private fun copyApkAndGetSha256(
+ apkFolder: DirectoryProperty,
+ apkLoader: Property<BuiltArtifactsLoader>,
+ destination: File
+ ): String {
+ val artifacts = apkLoader.get().load(apkFolder.get())
+ ?: throw RuntimeException("Cannot load required APK for task: $name")
+ File(artifacts.elements.single().outputFile).copyTo(destination, overwrite = true)
+ return sha256(destination)
}
private fun writeConfigFileContent(
- clientApk: BuiltArtifacts,
- serviceApk: BuiltArtifacts,
- clientPath: String,
- servicePath: String,
+ clientApkName: String,
+ serviceApkName: String,
+ clientApkSha256: String,
+ serviceApkSha256: String,
jsonClientOutputFile: RegularFileProperty,
jsonServiceOutputFile: RegularFileProperty,
isClientPrevious: Boolean,
isServicePrevious: Boolean,
) {
- val clientBuiltArtifact = clientApk.elements.single()
- val serviceBuiltArtifact = serviceApk.elements.single()
- val clientApkName = clientBuiltArtifact.resolveName(clientPath)
- val clientApkSha256 = sha256(File(clientBuiltArtifact.outputFile))
- val serviceApkName = serviceBuiltArtifact.resolveName(servicePath)
- val serviceApkSha256 = sha256(File(serviceBuiltArtifact.outputFile))
createOrFail(jsonClientOutputFile).writeText(
buildMediaJson(
configName = jsonClientOutputFile.asFile.get().name,
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
index 64ce692..3f8005e 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/GenerateTestConfigurationTask.kt
@@ -17,15 +17,17 @@
package androidx.build.testConfiguration
import androidx.build.dependencyTracker.ProjectSubset
-import androidx.build.renameApkForTesting
import com.android.build.api.variant.BuiltArtifactsLoader
import java.io.File
+import javax.inject.Inject
import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
-import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
@@ -34,6 +36,7 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
+import org.gradle.work.DisableCachingByDefault
/**
* Writes a configuration file in
@@ -41,21 +44,23 @@
* format that gets zipped alongside the APKs to be tested.
* This config gets ingested by Tradefed.
*/
-@CacheableTask
-abstract class GenerateTestConfigurationTask : DefaultTask() {
+@DisableCachingByDefault(because = "Doesn't benefit from caching")
+abstract class GenerateTestConfigurationTask @Inject constructor(
+ private val objects: ObjectFactory
+) : DefaultTask() {
@get:InputFiles
@get:Optional
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val appFolder: DirectoryProperty
+ @get:InputFiles
+ @get:PathSensitive(PathSensitivity.RELATIVE)
+ abstract val appFileCollection: ConfigurableFileCollection
+
@get:Internal
abstract val appLoader: Property<BuiltArtifactsLoader>
- @get:Input
- @get:Optional
- abstract val appProjectPath: Property<String>
-
@get:InputFiles
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val testFolder: DirectoryProperty
@@ -96,6 +101,18 @@
@get:OutputFile
abstract val constrainedOutputXml: RegularFileProperty
+ @get:OutputFile
+ abstract val outputTestApk: RegularFileProperty
+
+ @get:OutputFile
+ abstract val constrainedOutputTestApk: RegularFileProperty
+
+ @get:[OutputFile Optional]
+ abstract val outputAppApk: RegularFileProperty
+
+ @get:[OutputFile Optional]
+ abstract val constrainedOutputAppApk: RegularFileProperty
+
@TaskAction
fun generateAndroidTestZip() {
writeConfigFileContent(
@@ -121,13 +138,30 @@
val configBuilder = ConfigBuilder()
configBuilder.configName = outputFile.asFile.get().name
if (appLoader.isPresent) {
- val appApk = appLoader.get().load(appFolder.get())
+
+ // Decides where to load the app apk from, depending on whether appFolder or
+ // appFileCollection has been set.
+ val appDir = if (appFolder.isPresent && appFileCollection.files.isEmpty()) {
+ appFolder.get()
+ } else if (!appFolder.isPresent && appFileCollection.files.size == 1) {
+ objects.directoryProperty().also { it.set(appFileCollection.files.first()) }.get()
+ } else {
+ throw IllegalStateException("""
+ App apk not specified or both appFileCollection and appFolder specified.
+ """.trimIndent())
+ }
+
+ val appApk = appLoader.get().load(appDir)
?: throw RuntimeException("Cannot load required APK for task: $name")
// We don't need to check hasBenchmarkPlugin because benchmarks shouldn't have test apps
val appApkBuiltArtifact = appApk.elements.single()
- val appName = appApkBuiltArtifact.outputFile.substringAfterLast("/")
- .renameApkForTesting(appProjectPath.get())
- configBuilder.appApkName(appName)
+ val destinationApk = if (isConstrained) {
+ constrainedOutputAppApk.get().asFile
+ } else {
+ outputAppApk.get().asFile
+ }
+ File(appApkBuiltArtifact.outputFile).copyTo(destinationApk, overwrite = true)
+ configBuilder.appApkName(destinationApk.name)
.appApkSha256(sha256(File(appApkBuiltArtifact.outputFile)))
}
configBuilder.additionalApkKeys(additionalApkKeys.get())
@@ -181,16 +215,25 @@
val testApk = testLoader.get().load(testFolder.get())
?: throw RuntimeException("Cannot load required APK for task: $name")
val testApkBuiltArtifact = testApk.elements.single()
- val testName = testApkBuiltArtifact.outputFile
- .substringAfterLast("/")
- .renameApkForTesting(testProjectPath.get())
- configBuilder.testApkName(testName)
+ val destinationApk = if (isConstrained) {
+ constrainedOutputTestApk.get().asFile
+ } else {
+ outputTestApk.get().asFile
+ }
+ File(testApkBuiltArtifact.outputFile).copyTo(destinationApk, overwrite = true)
+ configBuilder.testApkName(destinationApk.name)
.applicationId(testApk.applicationId)
.minSdk(minSdk.get().toString())
.testRunner(testRunner.get())
.testApkSha256(sha256(File(testApkBuiltArtifact.outputFile)))
createOrFail(outputFile).writeText(configBuilder.buildXml())
if (!isConstrained) {
+ if (!outputJson.asFile.get().name.startsWith("_")) {
+ // Prefixing json file names with _ allows us to collocate these files
+ // inside of the androidTest.zip to make fetching them less expensive.
+ throw GradleException("json output file names are expected to use _ prefix to, " +
+ "currently set to ${outputJson.asFile.get().name}")
+ }
createOrFail(outputJson).writeText(configBuilder.buildJson())
}
}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
index e75e8a9..d49701d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/OwnersService.kt
@@ -18,6 +18,7 @@
import androidx.build.getDistributionDirectory
import com.google.gson.GsonBuilder
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.RegularFileProperty
@@ -27,7 +28,6 @@
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.bundling.Zip
-import java.io.File
@CacheableTask
abstract class ModuleInfoGenerator : DefaultTask() {
@@ -52,7 +52,7 @@
}
/**
- * Register two tasks need to generate information for Android test owners service.
+ * Register two tasks needed to generate information for Android test owners service.
* One task zips all the OWNERS files in frameworks/support, and second task creates a
* module-info.json that links test modules to paths.
*/
@@ -62,6 +62,7 @@
task.destinationDirectory.set(getDistributionDirectory())
task.from(layout.projectDirectory)
task.include("**/OWNERS")
+ task.exclude("buildSrc/.gradle/**")
task.includeEmptyDirs = false
}
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
index 1c9a5e5..3d4d026 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/testConfiguration/TestSuiteConfiguration.kt
@@ -30,39 +30,39 @@
import androidx.build.hasAndroidTestSourceCode
import androidx.build.hasBenchmarkPlugin
import androidx.build.isPresubmitBuild
-import androidx.build.renameApkForTesting
import com.android.build.api.artifact.Artifacts
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.api.variant.HasAndroidTest
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import com.android.build.api.variant.TestAndroidComponentsExtension
+import com.android.build.api.variant.Variant
import com.android.build.gradle.BaseExtension
-import com.android.build.gradle.tasks.PackageAndroidArtifact
+import com.android.build.gradle.TestExtension
+import com.android.build.gradle.internal.attributes.VariantAttr
+import com.android.build.gradle.internal.publishing.AndroidArtifacts
+import com.android.build.gradle.internal.publishing.AndroidArtifacts.ArtifactType
import java.io.File
import org.gradle.api.Project
-import org.gradle.api.UnknownTaskException
-import org.gradle.api.file.DuplicatesStrategy
+import org.gradle.api.attributes.Usage
import org.gradle.api.tasks.TaskProvider
-import org.gradle.api.tasks.bundling.Zip
import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.named
/**
* Creates and configures the test config generation task for a project. Configuration includes
* populating the task with relevant data from the first 4 params, and setting whether the task
* is enabled.
- *
- * @param overrideProject Allows the config task for one project to get registered to an
- * alternative project. Default is for the project to register the new config task to itself
*/
fun Project.createTestConfigurationGenerationTask(
variantName: String,
artifacts: Artifacts,
minSdk: Int,
testRunner: String,
- overrideProject: Project = this
) {
val xmlName = "${path.asFilenamePrefix()}$variantName.xml"
- val jsonName = "${path.asFilenamePrefix()}$variantName.json"
+ val jsonName = "_${path.asFilenamePrefix()}$variantName.json"
rootProject.tasks.named("createModuleInfo").configure {
it as ModuleInfoGenerator
it.testModules.add(
@@ -72,7 +72,7 @@
)
)
}
- val generateTestConfigurationTask = overrideProject.tasks.register(
+ val generateTestConfigurationTask = tasks.register(
"${AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK}$variantName",
GenerateTestConfigurationTask::class.java
) { task ->
@@ -80,6 +80,15 @@
task.testFolder.set(artifacts.get(SingleArtifact.APK))
task.testLoader.set(artifacts.getBuiltArtifactsLoader())
+ task.outputTestApk.set(
+ File(getTestConfigDirectory(), "${path.asFilenamePrefix()}-$variantName.apk")
+ )
+ task.constrainedOutputTestApk.set(
+ File(
+ getConstrainedTestConfigDirectory(),
+ "${path.asFilenamePrefix()}-$variantName.apk"
+ )
+ )
task.additionalApkKeys.set(androidXExtension.additionalDeviceTestApkKeys)
task.additionalTags.set(androidXExtension.additionalDeviceTestTags)
task.outputXml.fileValue(File(getTestConfigDirectory(), xmlName))
@@ -109,7 +118,7 @@
afterEvaluate {
val androidXExtension = extensions.getByType<AndroidXExtension>()
generateTestConfigurationTask.configure {
- it.enabled = hasAndroidTestSourceCode() && !androidXExtension.disableDeviceTests
+ it.enabled = androidXExtension.deviceTests.enabled && hasAndroidTestSourceCode()
}
}
this.rootProject.tasks.findByName(ZIP_TEST_CONFIGS_WITH_APKS_TASK)!!
@@ -123,76 +132,146 @@
* there is a test app in addition to the instrumentation app, and the only thing it configures is
* the location of the testapp.
*/
-fun Project.addAppApkToTestConfigGeneration() {
- if (isMacrobenchmarkTarget()) {
- extensions.getByType<ApplicationAndroidComponentsExtension>().apply {
- onVariants(selector().withBuildType("release")) { appVariant ->
- getOrCreateMacrobenchmarkConfigTask().configure { configTask ->
- configTask.appFolder.set(appVariant.artifacts.get(SingleArtifact.APK))
- configTask.appLoader.set(appVariant.artifacts.getBuiltArtifactsLoader())
- configTask.appProjectPath.set(path)
- }
- if (path == ":benchmark:integration-tests:macrobenchmark-target") {
- // Ugly workaround for b/188699825 where we hardcode that
- // :benchmark:integration-tests:macrobenchmark-target needs to be installed
- // for :benchmark:benchmark-macro tests to work.
- project(":benchmark:benchmark-macro").tasks.withType(
- GenerateTestConfigurationTask::class.java
- ).named(
- "${AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK}debugAndroidTest"
- ).configure { configTask ->
- configTask.appFolder.set(appVariant.artifacts.get(SingleArtifact.APK))
- configTask.appLoader.set(appVariant.artifacts.getBuiltArtifactsLoader())
- configTask.appProjectPath.set(path)
- }
- }
- }
+fun Project.addAppApkToTestConfigGeneration(androidXExtension: AndroidXExtension) {
+
+ fun outputAppApkFile(
+ variant: Variant,
+ appProjectPath: String,
+ instrumentationProjectPath: String?
+ ): File {
+ var filename = appProjectPath.asFilenamePrefix()
+ if (instrumentationProjectPath != null) {
+ filename += "_for_${instrumentationProjectPath.asFilenamePrefix()}"
}
- return
+ filename += "-${variant.name}.apk"
+ return File(getTestConfigDirectory(), filename)
+ }
+ fun constrainedOutputAppApkFile(
+ variant: Variant,
+ path: String,
+ instrumentationPath: String?
+ ): File {
+ var filename = path.asFilenamePrefix()
+ if (instrumentationPath != null) {
+ filename += "-for-${instrumentationPath.asFilenamePrefix()}"
+ }
+ filename += "-${variant.name}.apk"
+ return File(getConstrainedTestConfigDirectory(), filename)
}
- extensions.getByType<ApplicationAndroidComponentsExtension>().apply {
- onVariants(selector().withBuildType("debug")) { appVariant ->
+ // For application modules, the instrumentation apk is generated in the module itself
+ extensions.findByType(ApplicationAndroidComponentsExtension::class.java)?.apply {
+ onVariants(selector().withBuildType("debug")) { variant ->
tasks.named(
- AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK +
- "${appVariant.name}AndroidTest"
- ) { configTask ->
- configTask as GenerateTestConfigurationTask
- configTask.appFolder.set(appVariant.artifacts.get(SingleArtifact.APK))
- configTask.appLoader.set(appVariant.artifacts.getBuiltArtifactsLoader())
- configTask.appProjectPath.set(path)
- }
- }
- }
-}
+ "${AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK}${variant.name}AndroidTest",
+ GenerateTestConfigurationTask::class.java
+ ) { task ->
+ task.appFolder.set(variant.artifacts.get(SingleArtifact.APK))
+ task.appLoader.set(variant.artifacts.getBuiltArtifactsLoader())
-/**
- * Configures the test zip task to include the project's apk
- */
-fun addToTestZips(project: Project, packageTask: PackageAndroidArtifact) {
- project.rootProject.tasks.named(ZIP_TEST_CONFIGS_WITH_APKS_TASK) { task ->
- task as Zip
- val projectPath = project.path
- task.from(packageTask.outputDirectory) {
- it.include("*.apk")
- it.duplicatesStrategy = DuplicatesStrategy.FAIL
- it.rename { fileName ->
- fileName.renameApkForTesting(projectPath)
+ // The target project is the same being evaluated
+ task.outputAppApk.set(outputAppApkFile(variant, path, null))
+ task.constrainedOutputAppApk.set(constrainedOutputAppApkFile(variant, path, null))
}
}
- task.dependsOn(packageTask)
}
- project.rootProject.tasks.named(ZIP_CONSTRAINED_TEST_CONFIGS_WITH_APKS_TASK) { task ->
- task as Zip
- val projectPath = project.path
- task.from(packageTask.outputDirectory) {
- it.include("*.apk")
- it.duplicatesStrategy = DuplicatesStrategy.FAIL
- it.rename { fileName ->
- fileName.renameApkForTesting(projectPath)
+
+ // For tests modules, the instrumentation apk is pulled from the <variant>TestedApks
+ // configuration. Note that also the associated test configuration task name is different
+ // from the application one.
+ extensions.findByType(TestAndroidComponentsExtension::class.java)?.apply {
+ onVariants(selector().all()) { variant ->
+ tasks.named(
+ "${AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK}${variant.name}",
+ GenerateTestConfigurationTask::class.java
+ ) { task ->
+ task.appLoader.set(
+ variant.artifacts.getBuiltArtifactsLoader()
+ )
+
+ // The target app path is defined in the targetProjectPath field in the android
+ // extension of the test module
+ val targetProjectPath = project
+ .extensions
+ .getByType(TestExtension::class.java)
+ .targetProjectPath
+ ?: throw IllegalStateException("""
+ Module `$path` does not have a targetProjectPath defined.
+ """.trimIndent())
+ task.outputAppApk.set(
+ outputAppApkFile(variant, targetProjectPath, path)
+ )
+ task.constrainedOutputAppApk.set(
+ constrainedOutputAppApkFile(variant, targetProjectPath, path)
+ )
+
+ task.appFileCollection.from(
+ configurations
+ .named("${variant.name}TestedApks")
+ .get()
+ .incoming
+ .artifactView {
+ it.attributes { container ->
+ container.attribute(
+ AndroidArtifacts.ARTIFACT_TYPE,
+ ArtifactType.APK.type
+ )
+ }
+ }
+ .files
+ )
}
}
- task.dependsOn(packageTask)
+ }
+
+ // For library modules we only look at the build type debug. The target app project can be
+ // specified through the androidX extension, through: targetAppProjectForInstrumentationTest
+ // and targetAppProjectVariantForInstrumentationTest.
+ extensions.findByType(LibraryAndroidComponentsExtension::class.java)?.apply {
+ onVariants(selector().withBuildType("debug")) { variant ->
+
+ val targetAppProject =
+ androidXExtension.deviceTests.targetAppProject ?: return@onVariants
+ val targetAppProjectVariant =
+ androidXExtension.deviceTests.targetAppVariant
+
+ // Recreate the same configuration existing for test modules to pull the artifact
+ // from the application module specified in the deviceTests extension.
+ val configuration = configurations.create("${variant.name}TestedApks") { config ->
+ config.isCanBeResolved = true
+ config.isCanBeConsumed = false
+ config.attributes {
+ it.attribute(VariantAttr.ATTRIBUTE, objects.named(targetAppProjectVariant))
+ it.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
+ }
+ config
+ .dependencies
+ .add(project.dependencyFactory.create(targetAppProject))
+ }
+
+ tasks.named(
+ "${AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK}${variant.name}AndroidTest",
+ GenerateTestConfigurationTask::class.java
+ ) { task ->
+ task.appLoader.set(variant.artifacts.getBuiltArtifactsLoader())
+
+ // The target app path is defined in the androidx extension
+ task.outputAppApk.set(
+ outputAppApkFile(variant, targetAppProject.path, path)
+ )
+ task.constrainedOutputAppApk.set(
+ constrainedOutputAppApkFile(variant, targetAppProject.path, path)
+ )
+
+ task.appFileCollection.from(
+ configuration.incoming.artifactView { view ->
+ view.attributes {
+ it.attribute(AndroidArtifacts.ARTIFACT_TYPE, ArtifactType.APK.type)
+ }
+ }.files
+ )
+ }
+ }
}
}
@@ -253,59 +332,67 @@
if (this.name.contains("previous")) {
it.clientPreviousFolder.set(artifacts.get(SingleArtifact.APK))
it.clientPreviousLoader.set(artifacts.getBuiltArtifactsLoader())
- it.clientPreviousPath.set(this.path)
} else {
it.clientToTFolder.set(artifacts.get(SingleArtifact.APK))
it.clientToTLoader.set(artifacts.getBuiltArtifactsLoader())
- it.clientToTPath.set(this.path)
}
} else {
if (this.name.contains("previous")) {
it.servicePreviousFolder.set(artifacts.get(SingleArtifact.APK))
it.servicePreviousLoader.set(artifacts.getBuiltArtifactsLoader())
- it.servicePreviousPath.set(this.path)
} else {
it.serviceToTFolder.set(artifacts.get(SingleArtifact.APK))
it.serviceToTLoader.set(artifacts.getBuiltArtifactsLoader())
- it.serviceToTPath.set(this.path)
}
}
it.jsonClientPreviousServiceToTClientTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientPreviousServiceToTClientTests$variantName.json"
+ "_${mediaPrefix}ClientPreviousServiceToTClientTests$variantName.json"
)
)
it.jsonClientPreviousServiceToTServiceTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientPreviousServiceToTServiceTests$variantName.json"
+ "_${mediaPrefix}ClientPreviousServiceToTServiceTests$variantName.json"
)
)
it.jsonClientToTServicePreviousClientTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientToTServicePreviousClientTests$variantName.json"
+ "_${mediaPrefix}ClientToTServicePreviousClientTests$variantName.json"
)
)
it.jsonClientToTServicePreviousServiceTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientToTServicePreviousServiceTests$variantName.json"
+ "_${mediaPrefix}ClientToTServicePreviousServiceTests$variantName.json"
)
)
it.jsonClientToTServiceToTClientTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientToTServiceToTClientTests$variantName.json"
+ "_${mediaPrefix}ClientToTServiceToTClientTests$variantName.json"
)
)
it.jsonClientToTServiceToTServiceTests.fileValue(
File(
this.getTestConfigDirectory(),
- "${mediaPrefix}ClientToTServiceToTServiceTests$variantName.json"
+ "_${mediaPrefix}ClientToTServiceToTServiceTests$variantName.json"
)
)
+ it.totClientApk.fileValue(
+ File(getTestConfigDirectory(), "${mediaPrefix}ClientToT$variantName.apk")
+ )
+ it.previousClientApk.fileValue(
+ File(getTestConfigDirectory(), "${mediaPrefix}ClientPrevious$variantName.apk")
+ )
+ it.totServiceApk.fileValue(
+ File(getTestConfigDirectory(), "${mediaPrefix}ServiceToT$variantName.apk")
+ )
+ it.previousServiceApk.fileValue(
+ File(getTestConfigDirectory(), "${mediaPrefix}ServicePrevious$variantName.apk")
+ )
it.minSdk.set(minSdk)
it.testRunner.set(testRunner)
it.presubmit.set(isPresubmitBuild())
@@ -313,85 +400,7 @@
}
}
-private fun Project.getOrCreateMacrobenchmarkConfigTask():
- TaskProvider<GenerateTestConfigurationTask> {
- val parentProject = this.parent!!
- return try {
- parentProject.tasks.withType(GenerateTestConfigurationTask::class.java)
- .named(AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK)
- } catch (e: UnknownTaskException) {
- parentProject.tasks.register(
- AndroidXImplPlugin.GENERATE_TEST_CONFIGURATION_TASK,
- GenerateTestConfigurationTask::class.java
- )
- }
-}
-
-private fun Project.configureMacrobenchmarkConfigTask(
- variantName: String,
- artifacts: Artifacts,
- minSdk: Int,
- testRunner: String
-) {
- val configTask = getOrCreateMacrobenchmarkConfigTask()
- configTask.configure { task ->
- val androidXExtension = extensions.getByType<AndroidXExtension>()
- val fileNamePrefix = path.asFilenamePrefix()
- task.testFolder.set(artifacts.get(SingleArtifact.APK))
- task.testLoader.set(artifacts.getBuiltArtifactsLoader())
- task.additionalApkKeys.set(androidXExtension.additionalDeviceTestApkKeys)
- task.additionalTags.set(androidXExtension.additionalDeviceTestTags)
- task.outputXml.fileValue(
- File(getTestConfigDirectory(), "$fileNamePrefix$variantName.xml")
- )
- task.outputJson.fileValue(
- File(getTestConfigDirectory(), "$fileNamePrefix$variantName.json")
- )
- task.constrainedOutputXml.fileValue(
- File(
- getTestConfigDirectory(),
- "${path.asFilenamePrefix()}$variantName.xml"
- )
- )
- task.minSdk.set(minSdk)
- task.hasBenchmarkPlugin.set(hasBenchmarkPlugin())
- task.testRunner.set(testRunner)
- task.testProjectPath.set(path)
- task.presubmit.set(isPresubmitBuild())
- val detector = AffectedModuleDetector.getInstance(project)
- task.affectedModuleDetectorSubset.set(
- project.provider {
- detector.getSubset(task)
- }
- )
-
- AffectedModuleDetector.configureTaskGuard(task)
- }
- // Disable xml generation for projects that have no test sources
- afterEvaluate {
- val androidXExtension = extensions.getByType<AndroidXExtension>()
- configTask.configure {
- it.enabled = hasAndroidTestSourceCode() && !androidXExtension.disableDeviceTests
- }
- }
- rootProject.tasks.findByName(ZIP_TEST_CONFIGS_WITH_APKS_TASK)!!
- .dependsOn(configTask)
- rootProject.tasks.findByName(ZIP_CONSTRAINED_TEST_CONFIGS_WITH_APKS_TASK)!!
- .dependsOn(configTask)
-}
-
-/**
- * Tells whether this project is the macrobenchmark-target project
- */
-fun Project.isMacrobenchmarkTarget(): Boolean {
- return path.endsWith("macrobenchmark-target")
-}
-
fun Project.configureTestConfigGeneration(baseExtension: BaseExtension) {
- if (isMacrobenchmarkTarget()) {
- // macrobenchmark target projects use special setup. See addAppApkToTestConfigGeneration
- return
- }
extensions.getByType(AndroidComponentsExtension::class.java).apply {
onVariants { variant ->
var name: String? = null
@@ -428,14 +437,6 @@
isMedia2 = false
)
}
- path.endsWith("macrobenchmark") -> {
- configureMacrobenchmarkConfigTask(
- name,
- artifacts,
- baseExtension.defaultConfig.minSdk!!,
- baseExtension.defaultConfig.testInstrumentationRunner!!
- )
- }
else -> {
createTestConfigurationGenerationTask(
name,
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/BundleInsideHelper.kt b/buildSrc/public/src/main/kotlin/androidx/build/BundleInsideHelper.kt
index d67eaca..502f2b5 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/BundleInsideHelper.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/BundleInsideHelper.kt
@@ -17,12 +17,12 @@
package androidx.build
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
+import java.io.File
import org.gradle.api.Project
+import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
-import java.io.File
-import org.gradle.api.Task
import org.gradle.kotlin.dsl.findByType
import org.gradle.kotlin.dsl.get
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/OperatingSystem.kt b/buildSrc/public/src/main/kotlin/androidx/build/OperatingSystem.kt
index 867ade5..c73ff70 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/OperatingSystem.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/OperatingSystem.kt
@@ -16,8 +16,8 @@
package androidx.build
-import org.gradle.api.GradleException
import java.util.Locale
+import org.gradle.api.GradleException
enum class OperatingSystem {
LINUX,
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/SingleFileCopy.kt b/buildSrc/public/src/main/kotlin/androidx/build/SingleFileCopy.kt
index 74d81b7..6064dd2 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/SingleFileCopy.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/SingleFileCopy.kt
@@ -17,16 +17,15 @@
package androidx.build
import com.google.common.io.Files
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
-import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
+import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
-
@DisableCachingByDefault(because = "Doesn't benefit from cache")
open class SingleFileCopy : DefaultTask() {
@InputFile @PathSensitive(PathSensitivity.ABSOLUTE)
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
index de3d495..aa3cf1e 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/SupportConfig.kt
@@ -17,15 +17,15 @@
package androidx.build
import androidx.build.SupportConfig.COMPILE_SDK_VERSION
+import java.io.File
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
-import java.io.File
object SupportConfig {
const val DEFAULT_MIN_SDK_VERSION = 14
const val INSTRUMENTATION_RUNNER = "androidx.test.runner.AndroidJUnitRunner"
private const val INTERNAL_BUILD_TOOLS_VERSION = "34.0.0-rc3"
- private const val PUBLIC_BUILD_TOOLS_VERSION = "33.0.1"
+ private const val PUBLIC_BUILD_TOOLS_VERSION = "34.0.0-rc3"
const val NDK_VERSION = "23.1.7779620"
/**
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/Version.kt b/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
index d385d9b..fbee578 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/Version.kt
@@ -16,11 +16,11 @@
package androidx.build
-import org.gradle.api.Project
import java.io.File
import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern
+import org.gradle.api.Project
/**
* Utility class which represents a version
diff --git a/buildSrc/repos.gradle b/buildSrc/repos.gradle
index 9b5077d..4ae93fa 100644
--- a/buildSrc/repos.gradle
+++ b/buildSrc/repos.gradle
@@ -65,6 +65,13 @@
url("https://maven.pkg.jetbrains.space/public/p/compose/dev")
}
handler.mavenLocal()
+ // TODO(b/280646217): Remove after official release to gmaven.
+ handler.maven {
+ url("https://storage.googleapis.com/r8-releases/raw")
+ content {
+ includeModule("com.android.tools", "r8")
+ }
+ }
}
// Ordering appears to be important: b/229733266
def androidPluginRepoOverride = System.getenv("GRADLE_PLUGIN_REPO")
diff --git a/busytown/androidx_host_tests.sh b/busytown/androidx_host_tests.sh
index bba9e74..67d8d37 100755
--- a/busytown/androidx_host_tests.sh
+++ b/busytown/androidx_host_tests.sh
@@ -5,7 +5,7 @@
cd "$(dirname $0)"
-impl/build.sh test \
+impl/build.sh test zipOwnersFiles \
-Pandroidx.ignoreTestFailures \
-Pandroidx.displayTestOutput=false \
"$@"
diff --git a/busytown/androidx_host_tests_max_dep_versions.sh b/busytown/androidx_host_tests_max_dep_versions.sh
index ef49669..4442f42 100755
--- a/busytown/androidx_host_tests_max_dep_versions.sh
+++ b/busytown/androidx_host_tests_max_dep_versions.sh
@@ -5,7 +5,7 @@
cd "$(dirname $0)"
-impl/build.sh test \
+impl/build.sh test zipOwnersFiles \
-Pandroidx.useMaxDepVersions \
-Pandroidx.displayTestOutput=false \
-Pandroidx.ignoreTestFailures "$@"
diff --git a/camera/camera-camera2-pipe-integration/build.gradle b/camera/camera-camera2-pipe-integration/build.gradle
index 5ba8cb5..3a1f95e 100644
--- a/camera/camera-camera2-pipe-integration/build.gradle
+++ b/camera/camera-camera2-pipe-integration/build.gradle
@@ -115,11 +115,11 @@
}
androidx {
- name = "Jetpack Camera Camera Pipe Integration Library"
+ name = "Camera2 Pipe Integration"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CAMERA_PIPE
inceptionYear = "2020"
- description = "A CameraPipe implementation of CameraX, a library providing a consistent and " +
- "reliable camera foundation that enables great camera driven experiences across all " +
- "of Android."
+ description = "A Camera2 Pipe implementation of CameraX, a library providing a consistent " +
+ "and reliable camera foundation that enables great camera driven experiences across " +
+ "all of Android."
}
diff --git a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
index 1c65179..f88ee43 100644
--- a/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
+++ b/camera/camera-camera2-pipe-integration/src/androidTest/java/androidx/camera/camera2/pipe/testing/VerifyResultListener.kt
@@ -22,11 +22,11 @@
import androidx.camera.camera2.pipe.FrameNumber
import androidx.camera.camera2.pipe.Request
import androidx.camera.camera2.pipe.RequestMetadata
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.withTimeout
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.TimeoutException
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class VerifyResultListener(capturesCount: Int) : Request.Listener {
diff --git a/camera/camera-camera2-pipe-integration/src/main/AndroidManifest.xml b/camera/camera-camera2-pipe-integration/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/camera/camera-camera2-pipe-integration/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
index 2b1d488..f920bed 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraSurfaceAdapter.kt
@@ -19,6 +19,7 @@
package androidx.camera.camera2.pipe.integration.adapter
import android.content.Context
+import android.util.Pair
import android.util.Size
import androidx.annotation.RequiresApi
import androidx.camera.camera2.pipe.CameraId
@@ -132,7 +133,7 @@
cameraId: String,
existingSurfaces: List<AttachedSurfaceInfo>,
newUseCaseConfigsSupportedSizeMap: Map<UseCaseConfig<*>, List<Size>>
- ): Map<UseCaseConfig<*>, StreamSpec> {
+ ): Pair<Map<UseCaseConfig<*>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>> {
if (!checkIfSupportedCombinationExist(cameraId)) {
throw IllegalArgumentException(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
index b98730d..a84d164 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombination.kt
@@ -28,6 +28,7 @@
import android.media.CamcorderProfile
import android.media.MediaRecorder
import android.os.Build
+import android.util.Pair
import android.util.Rational
import android.util.Size
import android.view.Display
@@ -197,7 +198,7 @@
cameraMode: Int,
existingSurfaces: List<AttachedSurfaceInfo>,
newUseCaseConfigsSupportedSizeMap: Map<UseCaseConfig<*>, List<Size>>
- ): Map<UseCaseConfig<*>, StreamSpec> {
+ ): Pair<Map<UseCaseConfig<*>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>> {
refreshPreviewSize()
val surfaceConfigs: MutableList<SurfaceConfig> = ArrayList()
for (scc in existingSurfaces) {
@@ -293,7 +294,7 @@
" New configs: " + newUseCaseConfigs
)
}
- return suggestedStreamSpecMap
+ return Pair.create(suggestedStreamSpecMap, mapOf<AttachedSurfaceInfo, StreamSpec>())
}
/**
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
index 33adefc..4143198 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/Camera2CameraControlCompat.kt
@@ -38,10 +38,10 @@
import androidx.camera.core.impl.annotation.ExecutedBy
import dagger.Binds
import dagger.Module
+import javax.inject.Inject
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.launch
-import javax.inject.Inject
private const val TAG_KEY = "Camera2CameraControl.tag"
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ConfigureSurfaceToSecondarySessionFailQuirk.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ConfigureSurfaceToSecondarySessionFailQuirk.kt
index 98507ce..969985f 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ConfigureSurfaceToSecondarySessionFailQuirk.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/compat/quirk/ConfigureSurfaceToSecondarySessionFailQuirk.kt
@@ -16,12 +16,12 @@
package androidx.camera.camera2.pipe.integration.compat.quirk
import android.annotation.SuppressLint
+import android.hardware.camera2.CameraCaptureSession
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
import androidx.annotation.RequiresApi
import androidx.camera.camera2.pipe.CameraMetadata
import androidx.camera.core.impl.Quirk
-import android.hardware.camera2.CameraCaptureSession
/**
* A quirk to denote the surface can only be used to configure to only one
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
index 9da5b32..d854d2b 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/CapturePipeline.kt
@@ -47,9 +47,9 @@
import androidx.camera.camera2.pipe.RequestMetadata
import androidx.camera.camera2.pipe.Result3A
import androidx.camera.camera2.pipe.core.Log
+import androidx.camera.camera2.pipe.integration.compat.workaround.UseTorchAsFlash
import androidx.camera.camera2.pipe.integration.compat.workaround.isFlashAvailable
import androidx.camera.camera2.pipe.integration.compat.workaround.shouldStopRepeatingBeforeCapture
-import androidx.camera.camera2.pipe.integration.compat.workaround.UseTorchAsFlash
import androidx.camera.camera2.pipe.integration.config.UseCaseCameraScope
import androidx.camera.camera2.pipe.integration.config.UseCaseGraphConfig
import androidx.camera.core.ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
index 2bba010..f53608f 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/EvCompControl.kt
@@ -26,9 +26,9 @@
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoSet
+import javax.inject.Inject
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
-import javax.inject.Inject
private const val DEFAULT_EXPOSURE_COMPENSATION = 0
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
index e0a02ad..a289f28 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManager.kt
@@ -31,9 +31,11 @@
import androidx.camera.camera2.pipe.integration.interop.Camera2CameraControl
import androidx.camera.camera2.pipe.integration.interop.ExperimentalCamera2Interop
import androidx.camera.core.UseCase
+import androidx.camera.core.impl.CameraInternal
import androidx.camera.core.impl.DeferrableSurface
import androidx.camera.core.impl.SessionConfig.ValidatingBuilder
import javax.inject.Inject
+import javax.inject.Provider
import kotlinx.coroutines.Job
import kotlinx.coroutines.joinAll
@@ -75,6 +77,7 @@
private val cameraStateAdapter: CameraStateAdapter,
private val cameraQuirks: CameraQuirks,
private val cameraGraphFlags: CameraGraph.Flags,
+ private val cameraInternal: Provider<CameraInternal>,
cameraProperties: CameraProperties,
displayInfoManager: DisplayInfoManager,
) {
@@ -318,6 +321,7 @@
@GuardedBy("lock")
private fun addRepeatingUseCase() {
+ meteringRepeating.bindToCamera(cameraInternal.get(), null, null)
meteringRepeating.setupSession()
attach(listOf(meteringRepeating))
activate(meteringRepeating)
@@ -338,7 +342,7 @@
private fun removeRepeatingUseCase() {
deactivate(meteringRepeating)
detach(listOf(meteringRepeating))
- meteringRepeating.onUnbind()
+ meteringRepeating.unbindFromCamera(cameraInternal.get())
}
private fun Collection<UseCase>.onlyVideoCapture(): Boolean {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseThreads.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseThreads.kt
index 3233279..e2c7c5f 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseThreads.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/UseCaseThreads.kt
@@ -18,11 +18,11 @@
import androidx.annotation.RequiresApi
import androidx.camera.core.impl.utils.executor.CameraXExecutors
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher
-import java.util.concurrent.Executor
/**
* Collection of threads and scope(s) that have been configured and tuned.
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
index af3b4d6..c758dc4 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/adapter/SupportedSurfaceCombinationTest.kt
@@ -1572,7 +1572,7 @@
CameraMode.DEFAULT,
attachedSurfaceInfoList,
useCaseConfigToOutputSizesMap
- )
+ ).first
useCasesExpectedResultMap.keys.forEach {
val resultSize = suggestedStreamSpecs[useCaseConfigMap[it]]!!.resolution
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
index 28e3c559..236bd7d 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/CapturePipelineTest.kt
@@ -37,14 +37,14 @@
import androidx.camera.camera2.pipe.integration.adapter.CameraStateAdapter
import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
import androidx.camera.camera2.pipe.integration.adapter.asListenableFuture
-import androidx.camera.camera2.pipe.integration.compat.workaround.CapturePipelineTorchCorrection
import androidx.camera.camera2.pipe.integration.compat.StreamConfigurationMapCompat
import androidx.camera.camera2.pipe.integration.compat.quirk.CameraQuirks
import androidx.camera.camera2.pipe.integration.compat.workaround.AeFpsRange
+import androidx.camera.camera2.pipe.integration.compat.workaround.CapturePipelineTorchCorrection
import androidx.camera.camera2.pipe.integration.compat.workaround.NoOpAutoFlashAEModeDisabler
import androidx.camera.camera2.pipe.integration.compat.workaround.NotUseTorchAsFlash
-import androidx.camera.camera2.pipe.integration.compat.workaround.UseTorchAsFlashImpl
import androidx.camera.camera2.pipe.integration.compat.workaround.OutputSizesCorrector
+import androidx.camera.camera2.pipe.integration.compat.workaround.UseTorchAsFlashImpl
import androidx.camera.camera2.pipe.integration.config.UseCaseGraphConfig
import androidx.camera.camera2.pipe.integration.testing.FakeCameraGraph
import androidx.camera.camera2.pipe.integration.testing.FakeCameraGraphSession
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManagerTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManagerTest.kt
index 9248cf6..d4488e2 100644
--- a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManagerTest.kt
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/UseCaseManagerTest.kt
@@ -312,25 +312,29 @@
controls: Set<UseCaseCameraControl> = emptySet(),
useCaseCameraComponentBuilder: FakeUseCaseCameraComponentBuilder =
FakeUseCaseCameraComponentBuilder(),
- ) = UseCaseManager(
- cameraConfig = CameraConfig(CameraId("0")),
- builder = useCaseCameraComponentBuilder,
- controls = controls as java.util.Set<UseCaseCameraControl>,
- cameraProperties = FakeCameraProperties(),
- camera2CameraControl = Camera2CameraControl.create(
- FakeCamera2CameraControlCompat(),
- useCaseThreads,
- ComboRequestListener()
- ),
- cameraStateAdapter = CameraStateAdapter(),
- cameraGraphFlags = CameraGraph.Flags(),
- cameraQuirks = CameraQuirks(
- FakeCameraMetadata(),
- StreamConfigurationMapCompat(null, OutputSizesCorrector(FakeCameraMetadata(), null))
- ),
- displayInfoManager = DisplayInfoManager(ApplicationProvider.getApplicationContext()),
- ).also {
- useCaseManagerList.add(it)
+ ): UseCaseManager {
+ val fakeCamera = FakeCamera()
+ return UseCaseManager(
+ cameraConfig = CameraConfig(CameraId("0")),
+ builder = useCaseCameraComponentBuilder,
+ controls = controls as java.util.Set<UseCaseCameraControl>,
+ cameraProperties = FakeCameraProperties(),
+ camera2CameraControl = Camera2CameraControl.create(
+ FakeCamera2CameraControlCompat(),
+ useCaseThreads,
+ ComboRequestListener()
+ ),
+ cameraStateAdapter = CameraStateAdapter(),
+ cameraGraphFlags = CameraGraph.Flags(),
+ cameraInternal = { fakeCamera },
+ cameraQuirks = CameraQuirks(
+ FakeCameraMetadata(),
+ StreamConfigurationMapCompat(null, OutputSizesCorrector(FakeCameraMetadata(), null))
+ ),
+ displayInfoManager = DisplayInfoManager(ApplicationProvider.getApplicationContext()),
+ ).also {
+ useCaseManagerList.add(it)
+ }
}
private fun createImageCapture(): ImageCapture =
diff --git a/camera/camera-camera2-pipe-testing/build.gradle b/camera/camera-camera2-pipe-testing/build.gradle
index fcf6f79..1d31206 100644
--- a/camera/camera-camera2-pipe-testing/build.gradle
+++ b/camera/camera-camera2-pipe-testing/build.gradle
@@ -60,12 +60,12 @@
}
androidx {
- name = "Jetpack Camera Camera Pipe Testing Library"
+ name = "Camera2 Pipe Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CAMERA_PIPE
runApiTasks = new RunApiTasks.No("CameraPipe is an implementation detail of other libraries.")
inceptionYear = "2020"
- description = "Testing components for the Jetpack CameraPipe Library, a library providing a " +
+ description = "Testing components for the Camera2 Pipe Library, a library providing a " +
"consistent and reliable camera foundation that enables great camera driven " +
"experiences across all of Android."
}
diff --git a/camera/camera-camera2-pipe/build.gradle b/camera/camera-camera2-pipe/build.gradle
index f339499..e2a6054 100644
--- a/camera/camera-camera2-pipe/build.gradle
+++ b/camera/camera-camera2-pipe/build.gradle
@@ -71,7 +71,7 @@
}
androidx {
- name = "Jetpack Camera Pipe"
+ name = "Camera2 Pipe"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CAMERA_PIPE
runApiTasks = new RunApiTasks.No("CameraPipe is an implementation detail of other libraries.")
diff --git a/camera/camera-camera2-pipe/src/main/AndroidManifest.xml b/camera/camera-camera2-pipe/src/main/AndroidManifest.xml
deleted file mode 100644
index 9515a11..0000000
--- a/camera/camera-camera2-pipe/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- Copyright 2020 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 />
diff --git a/camera/camera-camera2/build.gradle b/camera/camera-camera2/build.gradle
index 8c0100e..b4ad3b0 100644
--- a/camera/camera-camera2/build.gradle
+++ b/camera/camera-camera2/build.gradle
@@ -88,7 +88,7 @@
}
androidx {
- name = "Jetpack Camera Library Camera2 Implementation/Extensions"
+ name = "Camera2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Camera2 implementation and extensions for the Jetpack Camera Library, a " +
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/workaround/ExtraSupportedSurfaceCombinationsContainerDeviceTest.kt b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/workaround/ExtraSupportedSurfaceCombinationsContainerDeviceTest.kt
index 053529d..cfded9e 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/workaround/ExtraSupportedSurfaceCombinationsContainerDeviceTest.kt
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/workaround/ExtraSupportedSurfaceCombinationsContainerDeviceTest.kt
@@ -174,6 +174,10 @@
val callback = FakeImageCaptureCallback()
imageCapture.takePicture(CameraXExecutors.directExecutor(), callback)
callback.awaitCapturesAndAssert()
+
+ withContext(Dispatchers.Main) {
+ cameraUseCaseAdapter.removeUseCases(cameraUseCaseAdapter.useCases)
+ }
}
@SdkSuppress(minSdkVersion = 28)
@@ -229,6 +233,10 @@
val callback = FakeImageCaptureCallback()
imageCapture.takePicture(CameraXExecutors.directExecutor(), callback)
callback.awaitCapturesAndAssert()
+
+ withContext(Dispatchers.Main) {
+ cameraUseCaseAdapter.removeUseCases(cameraUseCaseAdapter.useCases)
+ }
}
private fun enableSessionProcessor(
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
index a85be9d..7c1d95e 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.hardware.camera2.CameraDevice;
import android.media.CamcorderProfile;
+import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
@@ -60,7 +61,6 @@
/**
* Creates a new, initialized Camera2DeviceSurfaceManager.
- *
*/
@RestrictTo(Scope.LIBRARY)
public Camera2DeviceSurfaceManager(@NonNull Context context,
@@ -166,8 +166,10 @@
*/
@NonNull
@Override
- public Map<UseCaseConfig<?>, StreamSpec> getSuggestedStreamSpecs(
- @CameraMode.Mode int cameraMode, @NonNull String cameraId,
+ public Pair<Map<UseCaseConfig<?>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>>
+ getSuggestedStreamSpecs(
+ @CameraMode.Mode int cameraMode,
+ @NonNull String cameraId,
@NonNull List<AttachedSurfaceInfo> existingSurfaces,
@NonNull Map<UseCaseConfig<?>, List<Size>> newUseCaseConfigsSupportedSizeMap) {
Preconditions.checkArgument(!newUseCaseConfigsSupportedSizeMap.isEmpty(),
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2UseCaseConfigFactory.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2UseCaseConfigFactory.java
index 5481b76..1c8859f 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2UseCaseConfigFactory.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2UseCaseConfigFactory.java
@@ -26,12 +26,10 @@
import static androidx.camera.core.impl.UseCaseConfig.OPTION_ZSL_DISABLED;
import android.content.Context;
-import android.hardware.camera2.CameraDevice;
import android.util.Size;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
-import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCapture.CaptureMode;
import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.Config;
@@ -66,22 +64,8 @@
final MutableOptionsBundle mutableConfig = MutableOptionsBundle.create();
SessionConfig.Builder sessionBuilder = new SessionConfig.Builder();
- switch (captureType) {
- case IMAGE_CAPTURE:
- sessionBuilder.setTemplateType(
- captureMode == ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG
- ? CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG :
- CameraDevice.TEMPLATE_PREVIEW);
- break;
- case PREVIEW:
- case IMAGE_ANALYSIS:
- sessionBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
- break;
- case VIDEO_CAPTURE:
- case STREAM_SHARING:
- sessionBuilder.setTemplateType(CameraDevice.TEMPLATE_RECORD);
- break;
- }
+ sessionBuilder.setTemplateType(
+ TemplateTypeUtil.getSessionConfigTemplateType(captureType, captureMode));
mutableConfig.insertOption(OPTION_DEFAULT_SESSION_CONFIG, sessionBuilder.build());
@@ -89,23 +73,8 @@
Camera2SessionOptionUnpacker.INSTANCE);
CaptureConfig.Builder captureBuilder = new CaptureConfig.Builder();
-
- switch (captureType) {
- case IMAGE_CAPTURE:
- captureBuilder.setTemplateType(
- captureMode == ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG
- ? CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG :
- CameraDevice.TEMPLATE_STILL_CAPTURE);
- break;
- case PREVIEW:
- case IMAGE_ANALYSIS:
- captureBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
- break;
- case VIDEO_CAPTURE:
- case STREAM_SHARING:
- captureBuilder.setTemplateType(CameraDevice.TEMPLATE_RECORD);
- break;
- }
+ captureBuilder.setTemplateType(
+ TemplateTypeUtil.getCaptureConfigTemplateType(captureType, captureMode));
mutableConfig.insertOption(OPTION_DEFAULT_CAPTURE_CONFIG, captureBuilder.build());
// Only CAPTURE_TYPE_IMAGE_CAPTURE has its own ImageCaptureOptionUnpacker. Other
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/StreamUseCaseUtil.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/StreamUseCaseUtil.java
index 5d8196d..1f1efeb 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/StreamUseCaseUtil.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/StreamUseCaseUtil.java
@@ -16,8 +16,6 @@
package androidx.camera.camera2.internal;
-import static androidx.camera.camera2.impl.Camera2ImplConfig.STREAM_USE_CASE_OPTION;
-
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
@@ -28,27 +26,44 @@
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.annotation.RequiresApi;
+import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
+import androidx.camera.core.DynamicRange;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.Preview;
import androidx.camera.core.UseCase;
+import androidx.camera.core.impl.AttachedSurfaceInfo;
+import androidx.camera.core.impl.CameraMode;
+import androidx.camera.core.impl.Config;
import androidx.camera.core.impl.DeferrableSurface;
+import androidx.camera.core.impl.ImageCaptureConfig;
+import androidx.camera.core.impl.MutableOptionsBundle;
import androidx.camera.core.impl.SessionConfig;
+import androidx.camera.core.impl.StreamSpec;
+import androidx.camera.core.impl.UseCaseConfig;
+import androidx.camera.core.impl.UseCaseConfigFactory;
import androidx.camera.core.streamsharing.StreamSharing;
+import androidx.core.util.Preconditions;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A class that contains utility methods for stream use case.
*/
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class StreamUseCaseUtil {
+ public static final Config.Option<Long> STREAM_USE_CASE_STREAM_SPEC_OPTION =
+ Config.Option.create("camera2.streamSpec.streamUseCase", long.class);
+
private StreamUseCaseUtil() {
}
@@ -93,11 +108,12 @@
}
for (DeferrableSurface surface : sessionConfig.getSurfaces()) {
if (sessionConfig.getImplementationOptions().containsOption(
- STREAM_USE_CASE_OPTION) && putStreamUseCaseToMappingIfAvailable(
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION)
+ && putStreamUseCaseToMappingIfAvailable(
streamUseCaseMap,
surface,
sessionConfig.getImplementationOptions().retrieveOption(
- STREAM_USE_CASE_OPTION),
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION),
supportedStreamUseCases)) {
continue;
}
@@ -155,4 +171,272 @@
}
return sUseCaseToStreamUseCaseMapping;
}
+
+ /**
+ * Populate all implementation options needed to determine the StreamUseCase option in the
+ * StreamSpec for this UseCaseConfig
+ */
+ @OptIn(markerClass = ExperimentalCamera2Interop.class)
+ @NonNull
+ public static Camera2ImplConfig getStreamSpecImplementationOptions(
+ @NonNull UseCaseConfig<?> useCaseConfig
+ ) {
+ MutableOptionsBundle optionsBundle = MutableOptionsBundle.create();
+ if (useCaseConfig.containsOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION)) {
+ optionsBundle.insertOption(
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION,
+ useCaseConfig.retrieveOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION)
+ );
+ }
+ if (useCaseConfig.containsOption(UseCaseConfig.OPTION_ZSL_DISABLED)) {
+ optionsBundle.insertOption(
+ UseCaseConfig.OPTION_ZSL_DISABLED,
+ useCaseConfig.retrieveOption(UseCaseConfig.OPTION_ZSL_DISABLED)
+ );
+ }
+ if (useCaseConfig.containsOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE)) {
+ optionsBundle.insertOption(
+ ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE,
+ useCaseConfig
+ .retrieveOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE)
+ );
+ }
+ if (useCaseConfig.containsOption(UseCaseConfig.OPTION_INPUT_FORMAT)) {
+ optionsBundle.insertOption(
+ UseCaseConfig.OPTION_INPUT_FORMAT,
+ useCaseConfig
+ .retrieveOption(UseCaseConfig.OPTION_INPUT_FORMAT)
+ );
+ }
+ return new Camera2ImplConfig(optionsBundle);
+ }
+
+ /**
+ * Populate the {@link STREAM_USE_CASE_STREAM_SPEC_OPTION} option in StreamSpecs for both
+ * existing UseCases and new UseCases to be attached. This option will be written into the
+ * session configurations of the UseCases. When creating a new capture session during
+ * downstream, it will be used to set the StreamUseCase flag via
+ * {@link android.hardware.camera2.params.OutputConfiguration#setStreamUseCase(long)}
+ *
+ * @param characteristicsCompat the camera characteristics of the device
+ * @param featureSettings the feature settings of this capture
+ * @param attachedSurfaces surface info of the already attached use cases
+ * @param suggestedStreamSpecMap the UseCaseConfig-to-StreamSpec map for new use cases
+ * @param attachedSurfaceStreamSpecMap the SurfaceInfo-to-StreamSpec map for attached use cases
+ * whose StreamSpecs needs to be updated
+ */
+ @OptIn(markerClass = ExperimentalCamera2Interop.class)
+ public static void populateStreamUseCaseStreamSpecOption(
+ @NonNull CameraCharacteristicsCompat characteristicsCompat,
+ @NonNull SupportedSurfaceCombination.FeatureSettings featureSettings,
+ @NonNull List<AttachedSurfaceInfo> attachedSurfaces,
+ @NonNull Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap,
+ @NonNull Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap) {
+ if (Build.VERSION.SDK_INT < 33) {
+ return;
+ }
+ long[] availableStreamUseCases = characteristicsCompat.get(
+ CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES);
+ if (availableStreamUseCases == null || availableStreamUseCases.length == 0) {
+ return;
+ }
+ if (featureSettings.getCameraMode() != CameraMode.DEFAULT
+ || featureSettings.getRequiredMaxBitDepth() != DynamicRange.BIT_DEPTH_8_BIT) {
+ return;
+ }
+ List<UseCaseConfig<?>> newUseCaseConfigs = new ArrayList<>(suggestedStreamSpecMap.keySet());
+ // All AttachedSurfaceInfo should have implementation options
+ for (AttachedSurfaceInfo attachedSurfaceInfo : attachedSurfaces) {
+ Preconditions.checkNotNull(attachedSurfaceInfo.getImplementationOptions());
+ }
+ // All StreamSpecs in the map should have implementation options
+ for (UseCaseConfig<?> useCaseConfig : newUseCaseConfigs) {
+ Preconditions.checkNotNull(Preconditions.checkNotNull(
+ suggestedStreamSpecMap.get(useCaseConfig)).getImplementationOptions());
+ }
+ if (containsZslUseCase(attachedSurfaces, newUseCaseConfigs)) {
+ return;
+ }
+ Set<Long> availableStreamUseCaseSet = new HashSet<>();
+ for (Long availableStreamUseCase : availableStreamUseCases) {
+ availableStreamUseCaseSet.add(availableStreamUseCase);
+ }
+ if (isValidCamera2InteropOverride(attachedSurfaces, newUseCaseConfigs,
+ availableStreamUseCaseSet)) {
+ for (AttachedSurfaceInfo attachedSurfaceInfo : attachedSurfaces) {
+ Config oldImplementationOptions = attachedSurfaceInfo.getImplementationOptions();
+ Config newImplementationOptions =
+ getUpdatedImplementationOptionsWithUseCaseStreamSpecOption(
+ oldImplementationOptions,
+ oldImplementationOptions.retrieveOption(
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION));
+ if (newImplementationOptions != null) {
+ StreamSpec.Builder newStreamSpecBuilder =
+ StreamSpec.builder(attachedSurfaceInfo.getSize())
+ .setDynamicRange(attachedSurfaceInfo.getDynamicRange())
+ .setImplementationOptions(newImplementationOptions);
+ if (attachedSurfaceInfo.getTargetFrameRate() != null) {
+ newStreamSpecBuilder.setExpectedFrameRateRange(
+ attachedSurfaceInfo.getTargetFrameRate());
+ }
+ attachedSurfaceStreamSpecMap.put(attachedSurfaceInfo,
+ newStreamSpecBuilder.build());
+ }
+ }
+ for (UseCaseConfig<?> newUseCaseConfig : newUseCaseConfigs) {
+ StreamSpec oldStreamSpec = suggestedStreamSpecMap.get(newUseCaseConfig);
+ Config oldImplementationOptions = oldStreamSpec.getImplementationOptions();
+ Config newImplementationOptions =
+ getUpdatedImplementationOptionsWithUseCaseStreamSpecOption(
+ oldImplementationOptions, oldImplementationOptions.retrieveOption(
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION));
+ if (newImplementationOptions != null) {
+ StreamSpec newStreamSpec =
+ oldStreamSpec.toBuilder().setImplementationOptions(
+ newImplementationOptions).build();
+ suggestedStreamSpecMap.put(newUseCaseConfig, newStreamSpec);
+ }
+ }
+ }
+ }
+
+ /**
+ * Given an old options, return a new option with stream use case stream spec option inserted
+ */
+ @Nullable
+ @OptIn(markerClass = ExperimentalCamera2Interop.class)
+ private static Config getUpdatedImplementationOptionsWithUseCaseStreamSpecOption(
+ Config oldImplementationOptions,
+ long streamUseCase
+ ) {
+ if (oldImplementationOptions.containsOption(STREAM_USE_CASE_STREAM_SPEC_OPTION)
+ && oldImplementationOptions.retrieveOption(STREAM_USE_CASE_STREAM_SPEC_OPTION)
+ == streamUseCase) {
+ // The old options already has the same stream use case. No need to update
+ return null;
+ }
+ MutableOptionsBundle optionsBundle =
+ MutableOptionsBundle.from(oldImplementationOptions);
+ optionsBundle.insertOption(STREAM_USE_CASE_STREAM_SPEC_OPTION, streamUseCase);
+ return new Camera2ImplConfig(optionsBundle);
+ }
+
+ /**
+ * Return true if any one of the existing or new UseCases is ZSL.
+ */
+ private static boolean containsZslUseCase(
+ List<AttachedSurfaceInfo> attachedSurfaces,
+ List<UseCaseConfig<?>> newUseCaseConfigs) {
+ for (AttachedSurfaceInfo attachedSurfaceInfo : attachedSurfaces) {
+ List<UseCaseConfigFactory.CaptureType> captureTypes =
+ attachedSurfaceInfo.getCaptureTypes();
+ UseCaseConfigFactory.CaptureType captureType = captureTypes.get(0);
+ if (isZslUseCase(
+ attachedSurfaceInfo.getImplementationOptions(),
+ captureType)) {
+ return true;
+ }
+ }
+ for (UseCaseConfig<?> useCaseConfig : newUseCaseConfigs) {
+ if (isZslUseCase(useCaseConfig, useCaseConfig.getCaptureType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check whether a UseCase is ZSL.
+ */
+ private static boolean isZslUseCase(Config config,
+ UseCaseConfigFactory.CaptureType captureType) {
+ if (config.retrieveOption(UseCaseConfig.OPTION_ZSL_DISABLED, false)) {
+ return false;
+ }
+ // Skip if capture mode doesn't exist in the options
+ if (!config.containsOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE)) {
+ return false;
+ }
+
+ @ImageCapture.CaptureMode int captureMode =
+ config.retrieveOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE);
+ return TemplateTypeUtil.getSessionConfigTemplateType(captureType, captureMode)
+ == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG;
+ }
+
+ /**
+ * Check whether the given StreamUseCases are available to the device.
+ */
+ private static boolean areStreamUseCasesAvailable(Set<Long> availableStreamUseCasesSet,
+ Set<Long> streamUseCases) {
+ for (Long streamUseCase : streamUseCases) {
+ if (!availableStreamUseCasesSet.contains(streamUseCase)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static void throwInvalidCamera2InteropOverrideException() {
+ throw new IllegalArgumentException("Either all use cases must have non-default stream use "
+ + "case assigned or none should have it");
+ }
+
+ /**
+ * Return true if all existing UseCases and new UseCases have Camera2Interop override and
+ * these StreamUseCases are all available to the device.
+ */
+ @OptIn(markerClass = ExperimentalCamera2Interop.class)
+ private static boolean isValidCamera2InteropOverride(
+ List<AttachedSurfaceInfo> attachedSurfaces,
+ List<UseCaseConfig<?>> newUseCaseConfigs,
+ Set<Long> availableStreamUseCases) {
+ Set<Long> streamUseCases = new HashSet<>();
+ boolean hasNonDefaultStreamUseCase = false;
+ boolean hasDefaultOrNullStreamUseCase = false;
+ for (AttachedSurfaceInfo attachedSurfaceInfo : attachedSurfaces) {
+ if (!attachedSurfaceInfo.getImplementationOptions().containsOption(
+ Camera2ImplConfig.STREAM_USE_CASE_OPTION)) {
+ hasDefaultOrNullStreamUseCase = true;
+ break;
+ }
+ long streamUseCaseOverride =
+ attachedSurfaceInfo.getImplementationOptions()
+ .retrieveOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION);
+ if (streamUseCaseOverride
+ == CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ hasDefaultOrNullStreamUseCase = true;
+ break;
+ }
+ hasNonDefaultStreamUseCase = true;
+ break;
+ }
+ for (UseCaseConfig<?> useCaseConfig : newUseCaseConfigs) {
+ if (!useCaseConfig.containsOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION)) {
+ hasDefaultOrNullStreamUseCase = true;
+ if (hasNonDefaultStreamUseCase) {
+ throwInvalidCamera2InteropOverrideException();
+ }
+ } else {
+ long streamUseCaseOverride =
+ useCaseConfig.retrieveOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION);
+ if (streamUseCaseOverride
+ == CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT) {
+ hasDefaultOrNullStreamUseCase = true;
+ if (hasNonDefaultStreamUseCase) {
+ throwInvalidCamera2InteropOverrideException();
+ }
+ } else {
+ hasNonDefaultStreamUseCase = true;
+ if (hasDefaultOrNullStreamUseCase) {
+ throwInvalidCamera2InteropOverrideException();
+ }
+ streamUseCases.add(streamUseCaseOverride);
+ }
+ }
+
+ }
+ return !hasDefaultOrNullStreamUseCase && areStreamUseCasesAvailable(availableStreamUseCases,
+ streamUseCases);
+ }
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/SupportedSurfaceCombination.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/SupportedSurfaceCombination.java
index 59fee41..b9a91cf 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/SupportedSurfaceCombination.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/SupportedSurfaceCombination.java
@@ -33,6 +33,7 @@
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
+import android.util.Pair;
import android.util.Range;
import android.util.Rational;
import android.util.Size;
@@ -40,6 +41,7 @@
import androidx.annotation.DoNotInline;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
+import androidx.annotation.OptIn;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.camera.camera2.internal.compat.CameraAccessExceptionCompat;
@@ -49,6 +51,7 @@
import androidx.camera.camera2.internal.compat.workaround.ExtraSupportedSurfaceCombinationsContainer;
import androidx.camera.camera2.internal.compat.workaround.ResolutionCorrector;
import androidx.camera.camera2.internal.compat.workaround.TargetAspectRatio;
+import androidx.camera.camera2.interop.ExperimentalCamera2Interop;
import androidx.camera.core.CameraUnavailableException;
import androidx.camera.core.DynamicRange;
import androidx.camera.core.impl.AttachedSurfaceInfo;
@@ -490,16 +493,20 @@
* @param attachedSurfaces the existing surfaces.
* @param newUseCaseConfigsSupportedSizeMap newly added UseCaseConfig to supported output
* sizes map.
- * @return the suggested stream specifications, which is a mapping from UseCaseConfig to the
- * suggested stream specification.
+ * @return the suggested stream specifications, which is a pair of mappings. The first
+ * mapping is from UseCaseConfig to the suggested stream specification representing new
+ * UseCases. The second mapping is from attachedSurfaceInfo to the suggested stream
+ * specifications representing existing UseCases.
* @throws IllegalArgumentException if the suggested solution for newUseCaseConfigs cannot be
* found. This may be due to no available output size, no
* available surface combination, unsupported combinations
* of {@link DynamicRange}, or requiring an
* unsupported combination of camera features.
*/
+ @OptIn(markerClass = ExperimentalCamera2Interop.class)
@NonNull
- Map<UseCaseConfig<?>, StreamSpec> getSuggestedStreamSpecifications(
+ Pair<Map<UseCaseConfig<?>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>>
+ getSuggestedStreamSpecifications(
@CameraMode.Mode int cameraMode,
@NonNull List<AttachedSurfaceInfo> attachedSurfaces,
@NonNull Map<UseCaseConfig<?>, List<Size>> newUseCaseConfigsSupportedSizeMap) {
@@ -669,7 +676,10 @@
useCasesPriorityOrder.indexOf(newUseCaseConfigs.indexOf(useCaseConfig)));
StreamSpec.Builder streamSpecBuilder = StreamSpec.builder(resolutionForUseCase)
.setDynamicRange(Preconditions.checkNotNull(
- resolvedDynamicRanges.get(useCaseConfig)));
+ resolvedDynamicRanges.get(useCaseConfig)))
+ .setImplementationOptions(
+ StreamUseCaseUtil.getStreamSpecImplementationOptions(useCaseConfig)
+ );
if (targetFramerateForDevice != null) {
streamSpecBuilder.setExpectedFrameRateRange(targetFramerateForDevice);
}
@@ -683,7 +693,9 @@
+ " Existing surfaces: " + attachedSurfaces
+ " New configs: " + newUseCaseConfigs);
}
- return suggestedStreamSpecMap;
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ // TODO(b/266879290): Invoke StreamUSeCaseUtil.populateStreamUseCaseStreamSpecOption()
+ return new Pair<>(suggestedStreamSpecMap, attachedSurfaceStreamSpecMap);
}
/**
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/TemplateTypeUtil.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/TemplateTypeUtil.java
new file mode 100644
index 0000000..905e01f
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/TemplateTypeUtil.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.camera.camera2.internal;
+
+import android.hardware.camera2.CameraDevice;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.OptIn;
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.ExperimentalZeroShutterLag;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.impl.UseCaseConfigFactory;
+
+/**
+ * A class that contains utility methods for template type.
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class TemplateTypeUtil {
+
+ private TemplateTypeUtil() {
+
+ }
+
+ /**
+ * Returns the appropriate template type for a session configuration.
+ */
+ @OptIn(markerClass = ExperimentalZeroShutterLag.class)
+ public static int getSessionConfigTemplateType(
+ @NonNull UseCaseConfigFactory.CaptureType captureType,
+ @ImageCapture.CaptureMode int captureMode
+ ) {
+ switch (captureType) {
+ case IMAGE_CAPTURE:
+ return captureMode == ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG
+ ? CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG :
+ CameraDevice.TEMPLATE_PREVIEW;
+ case VIDEO_CAPTURE:
+ case STREAM_SHARING:
+ return CameraDevice.TEMPLATE_RECORD;
+ case PREVIEW:
+ case IMAGE_ANALYSIS:
+ default:
+ return CameraDevice.TEMPLATE_PREVIEW;
+ }
+ }
+
+ /**
+ * Returns the appropriate template type for a capture configuration.
+ */
+ @OptIn(markerClass = ExperimentalZeroShutterLag.class)
+ public static int getCaptureConfigTemplateType(
+ @NonNull UseCaseConfigFactory.CaptureType captureType,
+ @ImageCapture.CaptureMode int captureMode
+ ) {
+ switch (captureType) {
+ case IMAGE_CAPTURE:
+ return captureMode == ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG
+ ? CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG :
+ CameraDevice.TEMPLATE_STILL_CAPTURE;
+ case VIDEO_CAPTURE:
+ case STREAM_SHARING:
+ return CameraDevice.TEMPLATE_RECORD;
+ case PREVIEW:
+ case IMAGE_ANALYSIS:
+ default:
+ return CameraDevice.TEMPLATE_PREVIEW;
+ }
+ }
+}
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/StreamUseCaseTest.java b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/StreamUseCaseTest.java
index 3c1f547..3919413 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/StreamUseCaseTest.java
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/StreamUseCaseTest.java
@@ -18,8 +18,14 @@
import static android.os.Build.VERSION.SDK_INT;
+import static androidx.camera.camera2.internal.StreamUseCaseUtil.STREAM_USE_CASE_STREAM_SPEC_OPTION;
+import static androidx.camera.core.ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY;
+import static androidx.camera.core.ImageCapture.CAPTURE_MODE_ZERO_SHUTTER_LAG;
+
+import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
+import android.graphics.ImageFormat;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraMetadata;
@@ -30,14 +36,25 @@
import androidx.annotation.NonNull;
import androidx.camera.camera2.impl.Camera2ImplConfig;
import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
+import androidx.camera.core.DynamicRange;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.Preview;
+import androidx.camera.core.impl.AttachedSurfaceInfo;
+import androidx.camera.core.impl.CameraMode;
import androidx.camera.core.impl.DeferrableSurface;
+import androidx.camera.core.impl.ImageCaptureConfig;
+import androidx.camera.core.impl.MutableConfig;
import androidx.camera.core.impl.MutableOptionsBundle;
import androidx.camera.core.impl.SessionConfig;
+import androidx.camera.core.impl.StreamSpec;
+import androidx.camera.core.impl.SurfaceConfig;
+import androidx.camera.core.impl.UseCaseConfig;
+import androidx.camera.core.impl.UseCaseConfigFactory;
+import androidx.camera.core.internal.utils.SizeUtil;
import androidx.camera.core.streamsharing.StreamSharing;
import androidx.camera.testing.fakes.FakeUseCase;
+import androidx.camera.testing.fakes.FakeUseCaseConfig;
import androidx.concurrent.futures.ResolvableFuture;
import androidx.test.filters.SdkSuppress;
@@ -54,6 +71,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
@@ -62,6 +80,10 @@
private CameraCharacteristics mCameraCharacteristics;
private static final String CAMERA_ID_0 = "0";
+ private static final Long TEST_STREAM_USE_CASE_OPTION_VALUE = Long.valueOf(
+ CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW);
+ private static final @ImageCapture.CaptureMode int TEST_OPTION_IMAGE_CAPTURE_MODE_VALUE =
+ CAPTURE_MODE_MAXIMIZE_QUALITY;
DeferrableSurface mMockSurface = new DeferrableSurface() {
private final ListenableFuture<Surface> mSurfaceFuture = ResolvableFuture.create();
@@ -283,9 +305,272 @@
== CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW);
}
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void getStreamSpecImplementationOptions() {
+ Camera2ImplConfig result =
+ StreamUseCaseUtil.getStreamSpecImplementationOptions(
+ getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE));
+ assertTrue(result.retrieveOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION)
+ == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ assertFalse(result.retrieveOption(UseCaseConfig.OPTION_ZSL_DISABLED));
+ assertTrue(result.retrieveOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE)
+ == TEST_OPTION_IMAGE_CAPTURE_MODE_VALUE);
+ assertTrue(result.retrieveOption(UseCaseConfig.OPTION_INPUT_FORMAT)
+ == ImageFormat.PRIVATE);
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_streamUseCaseNotAvailable() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(
+ getCameraCharacteristicsCompat(true),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertFalse(suggestedStreamSpecMap.get(useCaseConfig)
+ .getImplementationOptions().containsOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION));
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_cameraModeNotSupported() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(
+ getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.CONCURRENT_CAMERA,
+ DynamicRange.BIT_DEPTH_8_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertFalse(suggestedStreamSpecMap.get(useCaseConfig)
+ .getImplementationOptions().containsOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION));
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_bitDepthNotSupported() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(
+ getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_10_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertFalse(suggestedStreamSpecMap.get(useCaseConfig)
+ .getImplementationOptions().containsOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION));
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_isZslUseCase() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, true,
+ UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE, ImageFormat.JPEG);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertFalse(suggestedStreamSpecMap.get(useCaseConfig)
+ .getImplementationOptions().containsOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION));
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_isZslUseCase_ZslDisabled() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, true, true,
+ UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE, ImageFormat.JPEG);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertTrue(suggestedStreamSpecMap.get(
+ useCaseConfig).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_isZslSurface() {
+ List<AttachedSurfaceInfo> attachedSurfaces = new ArrayList<>();
+ attachedSurfaces.add(getFakeAttachedSurfaceInfo(true, false, true,
+ UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE, ImageFormat.JPEG));
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), attachedSurfaces, new HashMap<>(),
+ attachedSurfaceStreamSpecMap
+ );
+ assertFalse(attachedSurfaceStreamSpecMap.containsKey(attachedSurfaces.get(0)));
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_isZslSurface_ZslDisabled() {
+ List<AttachedSurfaceInfo> attachedSurfaces = new ArrayList<>();
+ attachedSurfaces.add(getFakeAttachedSurfaceInfo(true, true, true,
+ UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE, ImageFormat.JPEG));
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), attachedSurfaces, new HashMap<>(),
+ attachedSurfaceStreamSpecMap
+ );
+ assertTrue(attachedSurfaceStreamSpecMap.get(
+ attachedSurfaces.get(0)).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_camera2InteropOverride_singleNewUseCase() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), new ArrayList<>(), suggestedStreamSpecMap,
+ new HashMap<>());
+ assertTrue(suggestedStreamSpecMap.get(
+ useCaseConfig).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_camera2InteropOverride_singleSurface() {
+ List<AttachedSurfaceInfo> attachedSurfaces = new ArrayList<>();
+ attachedSurfaces.add(getFakeAttachedSurfaceInfo(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE));
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), attachedSurfaces, new HashMap<>(),
+ attachedSurfaceStreamSpecMap
+ );
+ assertTrue(attachedSurfaceStreamSpecMap.get(
+ attachedSurfaces.get(0)).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+
+ @SdkSuppress(minSdkVersion = 33)
+ @Test
+ public void populateStreamUseCaseStreamSpecOption_camera2InteropOverride_useCaseAndSurface() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ List<AttachedSurfaceInfo> attachedSurfaces = new ArrayList<>();
+ attachedSurfaces.add(getFakeAttachedSurfaceInfo(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE));
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), attachedSurfaces, suggestedStreamSpecMap,
+ attachedSurfaceStreamSpecMap
+ );
+ assertTrue(suggestedStreamSpecMap.get(
+ useCaseConfig).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ assertTrue(attachedSurfaceStreamSpecMap.get(
+ attachedSurfaces.get(0)).getImplementationOptions().retrieveOption(
+ STREAM_USE_CASE_STREAM_SPEC_OPTION) == TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void populateStreamUseCaseStreamSpecOption_camera2InteropOverride_missingOverride() {
+ Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecMap = new HashMap<>();
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(false, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE);
+ suggestedStreamSpecMap.put(useCaseConfig,
+ getFakeStreamSpecFromFakeUseCaseConfig(useCaseConfig));
+ List<AttachedSurfaceInfo> attachedSurfaces = new ArrayList<>();
+ attachedSurfaces.add(getFakeAttachedSurfaceInfo(true, false, false,
+ UseCaseConfigFactory.CaptureType.PREVIEW, ImageFormat.PRIVATE));
+ Map<AttachedSurfaceInfo, StreamSpec> attachedSurfaceStreamSpecMap = new HashMap<>();
+ StreamUseCaseUtil.populateStreamUseCaseStreamSpecOption(getCameraCharacteristicsCompat(),
+ SupportedSurfaceCombination.FeatureSettings.of(CameraMode.DEFAULT,
+ DynamicRange.BIT_DEPTH_8_BIT), attachedSurfaces, suggestedStreamSpecMap,
+ attachedSurfaceStreamSpecMap
+ );
+ }
+
+ private UseCaseConfig<?> getFakeUseCaseConfigWithOptions(boolean camera2InteropOverride,
+ boolean isZslDisabled, boolean isZslCaptureMode,
+ UseCaseConfigFactory.CaptureType captureType, int imageFormat) {
+ FakeUseCaseConfig.Builder fakeUseCaseConfigBuilder = new FakeUseCaseConfig.Builder(
+ captureType);
+ MutableConfig fakeConfig = fakeUseCaseConfigBuilder.getMutableConfig();
+ if (camera2InteropOverride) {
+ fakeConfig.insertOption(Camera2ImplConfig.STREAM_USE_CASE_OPTION,
+ TEST_STREAM_USE_CASE_OPTION_VALUE);
+ }
+ fakeConfig.insertOption(UseCaseConfig.OPTION_ZSL_DISABLED, isZslDisabled);
+ fakeConfig.insertOption(ImageCaptureConfig.OPTION_IMAGE_CAPTURE_MODE,
+ isZslCaptureMode ? CAPTURE_MODE_ZERO_SHUTTER_LAG
+ : TEST_OPTION_IMAGE_CAPTURE_MODE_VALUE);
+ fakeConfig.insertOption(ImageCaptureConfig.OPTION_INPUT_FORMAT, imageFormat);
+ return fakeUseCaseConfigBuilder.getUseCaseConfig();
+ }
+
+ private AttachedSurfaceInfo getFakeAttachedSurfaceInfo(boolean camera2InteropOverride,
+ boolean isZslDisabled, boolean isZslCaptureMode,
+ UseCaseConfigFactory.CaptureType captureType, int imageFormat) {
+ UseCaseConfig<?> useCaseConfig = getFakeUseCaseConfigWithOptions(camera2InteropOverride,
+ isZslDisabled, isZslCaptureMode, captureType, imageFormat);
+ List<UseCaseConfigFactory.CaptureType> captureTypes = new ArrayList<>();
+ captureTypes.add(useCaseConfig.getCaptureType());
+ return AttachedSurfaceInfo.create(SurfaceConfig.create(
+ SurfaceConfig.ConfigType.PRIV,
+ SurfaceConfig.ConfigSize.PREVIEW
+ ),
+ useCaseConfig.getInputFormat(),
+ SizeUtil.RESOLUTION_720P,
+ DynamicRange.SDR,
+ captureTypes,
+ StreamUseCaseUtil.getStreamSpecImplementationOptions(useCaseConfig),
+ /*targetFrameRate=*/null);
+ }
+
+ private StreamSpec getFakeStreamSpecFromFakeUseCaseConfig(UseCaseConfig<?> fakeUseCaseConfig) {
+ return StreamSpec.builder(SizeUtil.RESOLUTION_720P)
+ .setDynamicRange(DynamicRange.UNSPECIFIED)
+ .setImplementationOptions(
+ StreamUseCaseUtil.getStreamSpecImplementationOptions(fakeUseCaseConfig)
+ ).build();
+ }
+
private CameraCharacteristicsCompat getCameraCharacteristicsCompat() {
+ return getCameraCharacteristicsCompat(false);
+ }
+
+ private CameraCharacteristicsCompat getCameraCharacteristicsCompat(
+ boolean noAvailableStreamUseCase) {
ShadowCameraCharacteristics shadowCharacteristics0 = Shadow.extract(mCameraCharacteristics);
- if (SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ if (SDK_INT >= Build.VERSION_CODES.TIRAMISU && !noAvailableStreamUseCase) {
long[] uc = new long[]{CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW,
CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL,
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
index b11b2a5a..d0ea2aa 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/SupportedSurfaceCombinationTest.kt
@@ -1558,7 +1558,7 @@
cameraMode,
attachedSurfaceInfoList,
useCaseConfigToOutputSizesMap
- )
+ ).first
useCasesExpectedSizeMap.keys.forEach {
val resultSize = suggestedStreamSpecs[useCaseConfigMap[it]]!!.resolution
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
index 5779b96..83defcab 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/compat/quirk/CamcorderProfileResolutionQuirkTest.kt
@@ -29,8 +29,8 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
diff --git a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
index c526cd1..5354bb1 100644
--- a/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
+++ b/camera/camera-camera2/src/test/java/androidx/camera/camera2/internal/concurrent/Camera2CameraCoordinatorTest.kt
@@ -46,7 +46,6 @@
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
import org.robolectric.shadow.api.Shadow
-
import org.robolectric.shadows.ShadowCameraCharacteristics
import org.robolectric.shadows.ShadowCameraManager
diff --git a/camera/camera-core/build.gradle b/camera/camera-core/build.gradle
index c789d6d..90360e1 100644
--- a/camera/camera-core/build.gradle
+++ b/camera/camera-core/build.gradle
@@ -111,7 +111,7 @@
}
androidx {
- name = "Jetpack Camera Core Library"
+ name = "Camera Core"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Core components for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/AndroidImageProxyTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/AndroidImageProxyTest.kt
index a8dc00c..eafedc5 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/AndroidImageProxyTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/AndroidImageProxyTest.kt
@@ -22,15 +22,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import java.nio.ByteBuffer
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
-import java.nio.ByteBuffer
-
-import com.google.common.truth.Truth.assertThat
+import org.mockito.Mockito.`when`
/**
* Unit tests for {@link AndroidImageProxy}.
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
index d39f3e1..dba781b 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
@@ -33,7 +33,6 @@
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Rect;
-import android.os.Build;
import android.provider.MediaStore;
import android.util.Rational;
import android.util.Size;
@@ -50,6 +49,7 @@
import androidx.camera.core.impl.UseCaseConfigFactory;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.core.internal.CameraUseCaseAdapter;
+import androidx.camera.testing.CoreAppTestUtil;
import androidx.camera.testing.fakes.FakeCamera;
import androidx.camera.testing.fakes.FakeCameraCaptureResult;
import androidx.camera.testing.fakes.FakeCameraControl;
@@ -101,9 +101,7 @@
@Before
public void setup() {
- assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes"
- + " the test failure.",
- Build.MODEL.equalsIgnoreCase("wembley") && Build.VERSION.SDK_INT <= 30);
+ CoreAppTestUtil.assumeCompatibleDevice();
FakeCamera fakeCamera = new FakeCamera("fakeCameraId");
FakeCameraDeviceSurfaceManager fakeCameraDeviceSurfaceManager =
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/JpegBytes2DiskDeviceTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/JpegBytes2DiskDeviceTest.kt
index d414a20..1a60fa7 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/JpegBytes2DiskDeviceTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/imagecapture/JpegBytes2DiskDeviceTest.kt
@@ -19,22 +19,20 @@
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Matrix
-import androidx.camera.core.imagecapture.Utils.CAMERA_CAPTURE_RESULT
-import androidx.camera.core.imagecapture.Utils.HEIGHT
-import androidx.camera.core.imagecapture.Utils.ROTATION_DEGREES
-import androidx.camera.core.imagecapture.Utils.WIDTH
-import androidx.camera.core.imagecapture.Utils.TEMP_FILE
-
import android.graphics.Rect
import android.util.Size
import androidx.camera.core.ImageCapture
+import androidx.camera.core.imagecapture.Utils.CAMERA_CAPTURE_RESULT
+import androidx.camera.core.imagecapture.Utils.HEIGHT
+import androidx.camera.core.imagecapture.Utils.ROTATION_DEGREES
+import androidx.camera.core.imagecapture.Utils.TEMP_FILE
+import androidx.camera.core.imagecapture.Utils.WIDTH
import androidx.camera.core.impl.utils.Exif
import androidx.camera.core.processing.Packet
import androidx.camera.testing.ExifUtil
+import androidx.camera.testing.TestImageUtil.createBitmap
import androidx.camera.testing.TestImageUtil.createJpegBytes
import androidx.camera.testing.TestImageUtil.getAverageDiff
-import androidx.camera.testing.TestImageUtil.createBitmap
-
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java
index 28e1e0f..a38bb27 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/CaptureConfigTest.java
@@ -23,6 +23,7 @@
import static org.mockito.Mockito.mock;
import android.hardware.camera2.CameraDevice;
+import android.util.Range;
import android.view.Surface;
import androidx.annotation.NonNull;
@@ -276,6 +277,50 @@
configuration.getCameraCaptureCallbacks().add(mock(CameraCaptureCallback.class));
}
+ @Test
+ public void builderChange_doNotChangeEarlierBuiltInstance() {
+ // 1. Arrange
+ CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class);
+ CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class);
+ DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class);
+ DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class);
+ Range<Integer> fpsRange1 = new Range<>(30, 30);
+ Range<Integer> fpsRange2 = new Range<>(15, 30);
+ int optionValue1 = 1;
+ int optionValue2 = 2;
+ int tagValue1 = 1;
+ int tagValue2 = 2;
+ int template1 = CameraDevice.TEMPLATE_PREVIEW;
+ int template2 = CameraDevice.TEMPLATE_RECORD;
+
+ CaptureConfig.Builder builder = new CaptureConfig.Builder();
+ builder.addSurface(deferrableSurface1);
+ builder.setExpectedFrameRateRange(fpsRange1);
+ builder.addCameraCaptureCallback(callback1);
+ builder.setTemplateType(template1);
+ builder.addTag("KEY", tagValue1);
+ builder.addImplementationOption(OPTION, optionValue1);
+ CaptureConfig captureConfig = builder.build();
+
+ // 2. Act
+ // builder change should not affect the instance built earlier.
+ builder.addSurface(deferrableSurface2);
+ builder.setExpectedFrameRateRange(fpsRange2);
+ builder.addCameraCaptureCallback(callback2);
+ builder.setTemplateType(template2);
+ builder.addTag("KEY", tagValue2);
+ builder.addImplementationOption(OPTION, optionValue2);
+
+ // 3. Verify
+ assertThat(captureConfig.getSurfaces()).containsExactly(deferrableSurface1);
+ assertThat(captureConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1);
+ assertThat(captureConfig.getCameraCaptureCallbacks()).containsExactly(callback1);
+ assertThat(captureConfig.getTemplateType()).isEqualTo(template1);
+ assertThat(captureConfig.getTagBundle().getTag("KEY")).isEqualTo(tagValue1);
+ assertThat(captureConfig.getImplementationOptions().retrieveOption(OPTION))
+ .isEqualTo(optionValue1);
+ }
+
/**
* A fake {@link MultiValueSet}.
*/
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java
index e82f563..e326787 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/SessionConfigTest.java
@@ -840,6 +840,134 @@
assertThat(tag.getTag("TEST01")).isEqualTo("String");
}
+ @Test
+ public void builderChange_doNotChangeEarlierBuiltInstance() {
+ // 1. Arrange
+ CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class);
+ CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class);
+ DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class);
+ DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class);
+ CameraDevice.StateCallback deviceStateCallback1 = mock(CameraDevice.StateCallback.class);
+ CameraDevice.StateCallback deviceStateCallback2 = mock(CameraDevice.StateCallback.class);
+ CameraCaptureSession.StateCallback sessionCallback1 =
+ mock(CameraCaptureSession.StateCallback.class);
+ CameraCaptureSession.StateCallback sessionCallback2 =
+ mock(CameraCaptureSession.StateCallback.class);
+ SessionConfig.ErrorListener errorListener1 = mock(SessionConfig.ErrorListener.class);
+ SessionConfig.ErrorListener errorListener2 = mock(SessionConfig.ErrorListener.class);
+ Range<Integer> fpsRange1 = new Range<>(30, 30);
+ Range<Integer> fpsRange2 = new Range<>(15, 30);
+ MutableOptionsBundle optionsBundle1 = MutableOptionsBundle.create();
+ optionsBundle1.insertOption(OPTION, 1);
+ MutableOptionsBundle optionsBundle2 = MutableOptionsBundle.create();
+ optionsBundle2.insertOption(OPTION, 2);
+ int template1 = CameraDevice.TEMPLATE_PREVIEW;
+ int template2 = CameraDevice.TEMPLATE_RECORD;
+
+ SessionConfig.Builder builder = new SessionConfig.Builder();
+ builder.addSurface(deferrableSurface1);
+ builder.setExpectedFrameRateRange(fpsRange1);
+ builder.addCameraCaptureCallback(callback1);
+ builder.addRepeatingCameraCaptureCallback(callback1);
+ builder.addDeviceStateCallback(deviceStateCallback1);
+ builder.addSessionStateCallback(sessionCallback1);
+ builder.setTemplateType(template1);
+ builder.addImplementationOptions(optionsBundle1);
+ builder.addErrorListener(errorListener1);
+ SessionConfig sessionConfig = builder.build();
+
+ // 2. Act
+ // builder change should not affect the instance built earlier.
+ builder.addSurface(deferrableSurface2);
+ builder.setExpectedFrameRateRange(fpsRange2);
+ builder.addCameraCaptureCallback(callback2);
+ builder.addRepeatingCameraCaptureCallback(callback2);
+ builder.addDeviceStateCallback(deviceStateCallback2);
+ builder.addSessionStateCallback(sessionCallback2);
+ builder.setTemplateType(template2);
+ builder.addImplementationOptions(optionsBundle2);
+ builder.addErrorListener(errorListener2);
+
+ // 3. Verify
+ assertThat(sessionConfig.getSurfaces()).containsExactly(deferrableSurface1);
+ assertThat(sessionConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1);
+ assertThat(sessionConfig.getSingleCameraCaptureCallbacks()).containsExactly(callback1);
+ assertThat(sessionConfig.getRepeatingCaptureConfig().getCameraCaptureCallbacks())
+ .containsExactly(callback1);
+ assertThat(sessionConfig.getDeviceStateCallbacks()).containsExactly(deviceStateCallback1);
+ assertThat(sessionConfig.getSessionStateCallbacks()).containsExactly(sessionCallback1);
+ assertThat(sessionConfig.getTemplateType()).isEqualTo(template1);
+ assertThat(sessionConfig.getImplementationOptions().retrieveOption(OPTION)).isEqualTo(1);
+ assertThat(sessionConfig.getErrorListeners()).containsExactly(errorListener1);
+ }
+
+ @Test
+ public void validatingBuilderChange_doNotChangeEarlierBuiltInstance() {
+ // 1. Arrange
+ CameraCaptureCallback callback1 = mock(CameraCaptureCallback.class);
+ CameraCaptureCallback callback2 = mock(CameraCaptureCallback.class);
+ DeferrableSurface deferrableSurface1 = mock(DeferrableSurface.class);
+ DeferrableSurface deferrableSurface2 = mock(DeferrableSurface.class);
+ CameraDevice.StateCallback deviceStateCallback1 = mock(CameraDevice.StateCallback.class);
+ CameraDevice.StateCallback deviceStateCallback2 = mock(CameraDevice.StateCallback.class);
+ CameraCaptureSession.StateCallback sessionCallback1 =
+ mock(CameraCaptureSession.StateCallback.class);
+ CameraCaptureSession.StateCallback sessionCallback2 =
+ mock(CameraCaptureSession.StateCallback.class);
+ SessionConfig.ErrorListener errorListener1 = mock(SessionConfig.ErrorListener.class);
+ SessionConfig.ErrorListener errorListener2 = mock(SessionConfig.ErrorListener.class);
+ Range<Integer> fpsRange1 = new Range<>(30, 30);
+ Range<Integer> fpsRange2 = new Range<>(15, 30);
+ MutableOptionsBundle optionsBundle1 = MutableOptionsBundle.create();
+ optionsBundle1.insertOption(OPTION, 1);
+ MutableOptionsBundle optionsBundle2 = MutableOptionsBundle.create();
+ optionsBundle2.insertOption(OPTION, 2);
+ int template1 = CameraDevice.TEMPLATE_PREVIEW;
+ int template2 = CameraDevice.TEMPLATE_RECORD;
+
+ SessionConfig.Builder builder = new SessionConfig.Builder();
+ builder.addSurface(deferrableSurface1);
+ builder.setExpectedFrameRateRange(fpsRange1);
+ builder.addCameraCaptureCallback(callback1);
+ builder.addRepeatingCameraCaptureCallback(callback1);
+ builder.addDeviceStateCallback(deviceStateCallback1);
+ builder.addSessionStateCallback(sessionCallback1);
+ builder.setTemplateType(template1);
+ builder.addImplementationOptions(optionsBundle1);
+ builder.addErrorListener(errorListener1);
+
+ SessionConfig.ValidatingBuilder validatingBuilder = new SessionConfig.ValidatingBuilder();
+ validatingBuilder.add(builder.build());
+ SessionConfig sessionConfig = validatingBuilder.build();
+
+ // 2. Act
+ // add another SessionConfig to ValidatingBuilder. This should not affect the
+ // instance built earlier.
+ SessionConfig.Builder builder2 = new SessionConfig.Builder();
+ builder2.addSurface(deferrableSurface2);
+ builder2.setExpectedFrameRateRange(fpsRange2);
+ builder2.addCameraCaptureCallback(callback2);
+ builder2.addRepeatingCameraCaptureCallback(callback2);
+ builder2.addDeviceStateCallback(deviceStateCallback2);
+ builder2.addSessionStateCallback(sessionCallback2);
+ builder2.setTemplateType(template2);
+ builder2.addImplementationOptions(optionsBundle2);
+ builder2.addErrorListener(errorListener2);
+ validatingBuilder.add(builder2.build());
+
+ // 3. Verify
+ assertThat(sessionConfig.getSurfaces()).containsExactly(deferrableSurface1);
+ assertThat(sessionConfig.getExpectedFrameRateRange()).isEqualTo(fpsRange1);
+ assertThat(sessionConfig.getSingleCameraCaptureCallbacks()).containsExactly(callback1);
+ assertThat(sessionConfig.getRepeatingCaptureConfig().getCameraCaptureCallbacks())
+ .containsExactly(callback1);
+ assertThat(sessionConfig.getDeviceStateCallbacks()).containsExactly(deviceStateCallback1);
+ assertThat(sessionConfig.getSessionStateCallbacks()).containsExactly(sessionCallback1);
+ assertThat(sessionConfig.getTemplateType()).isEqualTo(template1);
+ assertThat(sessionConfig.getImplementationOptions().retrieveOption(OPTION)).isEqualTo(1);
+ assertThat(sessionConfig.getErrorListeners()).containsExactly(errorListener1);
+ }
+
private SessionConfig createSessionConfigWithTag(String key, Object tagValue) {
SessionConfig.Builder builder1 = new SessionConfig.Builder();
builder1.addSurface(mMockSurface1);
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/utils/ExifOutputStreamTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/utils/ExifOutputStreamTest.kt
index c6386b0..5945f0a 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/utils/ExifOutputStreamTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/impl/utils/ExifOutputStreamTest.kt
@@ -23,8 +23,8 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.io.File
+import org.junit.Test
@LargeTest
@SdkSuppress(minSdkVersion = 21)
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/utils/ZslRingBufferTest.kt b/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/utils/ZslRingBufferTest.kt
index 76d4471..63fcf61 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/utils/ZslRingBufferTest.kt
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/utils/ZslRingBufferTest.kt
@@ -31,11 +31,11 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
@RunWith(JUnit4::class)
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
index b7268b0..8c70299 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageAnalysis.java
@@ -22,6 +22,7 @@
import static androidx.camera.core.impl.ImageAnalysisConfig.OPTION_ONE_PIXEL_SHIFT_ENABLED;
import static androidx.camera.core.impl.ImageAnalysisConfig.OPTION_OUTPUT_IMAGE_FORMAT;
import static androidx.camera.core.impl.ImageAnalysisConfig.OPTION_OUTPUT_IMAGE_ROTATION_ENABLED;
+import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_DYNAMIC_RANGE;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_CUSTOM_ORDERED_RESOLUTIONS;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_DEFAULT_RESOLUTION;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_MAX_RESOLUTION;
@@ -70,6 +71,7 @@
import androidx.camera.core.impl.ConfigProvider;
import androidx.camera.core.impl.DeferrableSurface;
import androidx.camera.core.impl.ImageAnalysisConfig;
+import androidx.camera.core.impl.ImageInputConfig;
import androidx.camera.core.impl.ImageOutputConfig;
import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
import androidx.camera.core.impl.ImmediateSurface;
@@ -95,6 +97,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
+import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.Executor;
@@ -217,6 +220,9 @@
// [UseCase attached dynamic] - Can change but is only available when the UseCase is attached.
////////////////////////////////////////////////////////////////////////////////////////////
+ @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+ SessionConfig.Builder mSessionConfigBuilder;
+
@Nullable
private DeferrableSurface mDeferrableSurface;
@@ -370,6 +376,9 @@
SessionConfig.Builder sessionConfigBuilder = SessionConfig.Builder.createFrom(config,
streamSpec.getResolution());
+ if (streamSpec.getImplementationOptions() != null) {
+ sessionConfigBuilder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
if (mDeferrableSurface != null) {
mDeferrableSurface.close();
@@ -387,8 +396,7 @@
sessionConfigBuilder.setExpectedFrameRateRange(streamSpec.getExpectedFrameRateRange());
- sessionConfigBuilder.addSurface(mDeferrableSurface);
-
+ sessionConfigBuilder.addSurface(mDeferrableSurface, streamSpec.getDynamicRange());
sessionConfigBuilder.addErrorListener((sessionConfig, error) -> {
clearPipeline();
@@ -814,14 +822,26 @@
protected StreamSpec onSuggestedStreamSpecUpdated(@NonNull StreamSpec suggestedStreamSpec) {
final ImageAnalysisConfig config = (ImageAnalysisConfig) getCurrentConfig();
- SessionConfig.Builder sessionConfigBuilder = createPipeline(getCameraId(), config,
+ mSessionConfigBuilder = createPipeline(getCameraId(), config,
suggestedStreamSpec);
- updateSessionConfig(sessionConfigBuilder.build());
+ updateSessionConfig(mSessionConfigBuilder.build());
return suggestedStreamSpec;
}
/**
+ * {@inheritDoc}
+ */
+ @NonNull
+ @Override
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ mSessionConfigBuilder.addImplementationOptions(config);
+ updateSessionConfig(mSessionConfigBuilder.build());
+ return getAttachedStreamSpec().toBuilder().setImplementationOptions(config).build();
+ }
+
+ /**
* Updates relative rotation if attached to a camera. No-op otherwise.
*/
private void tryUpdateRelativeRotation() {
@@ -1009,6 +1029,15 @@
private static final int DEFAULT_SURFACE_OCCUPANCY_PRIORITY = 1;
private static final int DEFAULT_ASPECT_RATIO = AspectRatio.RATIO_4_3;
+ /**
+ * Explicitly setting the default dynamic range to SDR (rather than UNSPECIFIED) means
+ * ImageAnalysis won't inherit dynamic ranges from other use cases.
+ */
+ // TODO(b/258099919): ImageAnalysis currently can't support HDR, so we don't expose the
+ // dynamic range setter and require SDR. We may want to get rid of this default once we
+ // can support tone-mapping from HDR -> SDR
+ private static final DynamicRange DEFAULT_DYNAMIC_RANGE = DynamicRange.SDR;
+
private static final ResolutionSelector DEFAULT_RESOLUTION_SELECTOR =
new ResolutionSelector.Builder().setAspectRatioStrategy(
AspectRatioStrategy.RATIO_4_3_FALLBACK_AUTO_STRATEGY).setResolutionStrategy(
@@ -1024,7 +1053,8 @@
.setSurfaceOccupancyPriority(DEFAULT_SURFACE_OCCUPANCY_PRIORITY)
.setTargetAspectRatio(DEFAULT_ASPECT_RATIO)
.setResolutionSelector(DEFAULT_RESOLUTION_SELECTOR)
- .setCaptureType(UseCaseConfigFactory.CaptureType.IMAGE_ANALYSIS);
+ .setCaptureType(UseCaseConfigFactory.CaptureType.IMAGE_ANALYSIS)
+ .setDynamicRange(DEFAULT_DYNAMIC_RANGE);
DEFAULT_CONFIG = builder.getUseCaseConfig();
}
@@ -1041,7 +1071,8 @@
public static final class Builder
implements ImageOutputConfig.Builder<Builder>,
ThreadConfig.Builder<Builder>,
- UseCaseConfig.Builder<ImageAnalysis, ImageAnalysisConfig, Builder> {
+ UseCaseConfig.Builder<ImageAnalysis, ImageAnalysisConfig, Builder>,
+ ImageInputConfig.Builder<Builder> {
private final MutableOptionsBundle mMutableConfig;
@@ -1610,5 +1641,29 @@
getMutableConfig().insertOption(OPTION_CAPTURE_TYPE, captureType);
return this;
}
+
+ // Implementations of ImageInputConfig.Builder default methods
+
+ /**
+ * Sets the {@link DynamicRange}.
+ *
+ * <p>This is currently only exposed to internally set the dynamic range to SDR.
+ * @return The current Builder.
+ * @see DynamicRange
+ */
+ @RestrictTo(Scope.LIBRARY)
+ @NonNull
+ @Override
+ public Builder setDynamicRange(@NonNull DynamicRange dynamicRange) {
+ // TODO(b/258099919): ImageAnalysis currently can't support HDR, so we require SDR.
+ // It's possible to support other DynamicRanges through tone-mapping or by exposing
+ // other ImageReader formats, such as YCBCR_P010.
+ if (!Objects.equals(DynamicRange.SDR, dynamicRange)) {
+ throw new UnsupportedOperationException(
+ "ImageAnalysis currently only supports SDR");
+ }
+ getMutableConfig().insertOption(OPTION_INPUT_DYNAMIC_RANGE, dynamicRange);
+ return this;
+ }
}
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
index b547104..c4e9fd5 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/ImageCapture.java
@@ -38,6 +38,7 @@
import static androidx.camera.core.impl.ImageCaptureConfig.OPTION_TARGET_ROTATION;
import static androidx.camera.core.impl.ImageCaptureConfig.OPTION_USE_CASE_EVENT_CALLBACK;
import static androidx.camera.core.impl.ImageCaptureConfig.OPTION_USE_SOFTWARE_JPEG_ENCODER;
+import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_DYNAMIC_RANGE;
import static androidx.camera.core.impl.ImageInputConfig.OPTION_INPUT_FORMAT;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_CUSTOM_ORDERED_RESOLUTIONS;
import static androidx.camera.core.impl.ImageOutputConfig.OPTION_RESOLUTION_SELECTOR;
@@ -86,24 +87,21 @@
import androidx.annotation.RestrictTo.Scope;
import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
-import androidx.camera.core.ForwardingImageProxy.OnImageCloseListener;
import androidx.camera.core.imagecapture.ImageCaptureControl;
import androidx.camera.core.imagecapture.ImagePipeline;
import androidx.camera.core.imagecapture.TakePictureManager;
import androidx.camera.core.imagecapture.TakePictureRequest;
-import androidx.camera.core.impl.CameraCaptureCallback;
import androidx.camera.core.impl.CameraConfig;
import androidx.camera.core.impl.CameraInfoInternal;
import androidx.camera.core.impl.CameraInternal;
import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.Config;
import androidx.camera.core.impl.ConfigProvider;
-import androidx.camera.core.impl.DeferrableSurface;
import androidx.camera.core.impl.ImageCaptureConfig;
+import androidx.camera.core.impl.ImageInputConfig;
import androidx.camera.core.impl.ImageOutputConfig;
import androidx.camera.core.impl.ImageOutputConfig.RotationValue;
import androidx.camera.core.impl.ImageReaderProxy;
-import androidx.camera.core.impl.ImmediateSurface;
import androidx.camera.core.impl.MutableConfig;
import androidx.camera.core.impl.MutableOptionsBundle;
import androidx.camera.core.impl.OptionsBundle;
@@ -114,7 +112,6 @@
import androidx.camera.core.impl.utils.CameraOrientationUtil;
import androidx.camera.core.impl.utils.Exif;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
-import androidx.camera.core.impl.utils.futures.FutureCallback;
import androidx.camera.core.impl.utils.futures.Futures;
import androidx.camera.core.internal.IoConfig;
import androidx.camera.core.internal.TargetConfig;
@@ -124,7 +121,6 @@
import androidx.camera.core.resolutionselector.AspectRatioStrategy;
import androidx.camera.core.resolutionselector.ResolutionSelector;
import androidx.camera.core.resolutionselector.ResolutionStrategy;
-import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.core.util.Preconditions;
import androidx.lifecycle.LifecycleOwner;
@@ -137,17 +133,11 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Deque;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
+import java.util.Objects;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -274,8 +264,6 @@
@FlashMode
private static final int DEFAULT_FLASH_MODE = FLASH_MODE_OFF;
- boolean mUseProcessingPipeline = true;
-
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
static final ExifRotationAvailability EXIF_ROTATION_AVAILABILITY =
new ExifRotationAvailability();
@@ -288,9 +276,6 @@
}
};
- @NonNull
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- final Executor mIoExecutor;
@CaptureMode
private final int mCaptureMode;
@@ -312,35 +297,16 @@
private Rational mCropAspectRatio = null;
////////////////////////////////////////////////////////////////////////////////////////////
- // [UseCase attached constant] - Is only valid when the UseCase is attached to a camera.
- ////////////////////////////////////////////////////////////////////////////////////////////
- private CaptureConfig mCaptureConfig;
-
- /**
- * Whether the software JPEG pipeline will be used.
- */
- private boolean mUseSoftwareJpeg = false;
-
- ////////////////////////////////////////////////////////////////////////////////////////////
// [UseCase attached dynamic] - Can change but is only available when the UseCase is attached.
////////////////////////////////////////////////////////////////////////////////////////////
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
SessionConfig.Builder mSessionConfigBuilder;
- /** synthetic accessor */
- @SuppressWarnings("WeakerAccess")
- SafeCloseImageReaderProxy mImageReader;
-
- /** Callback used to match the {@link ImageProxy} with the {@link ImageInfo}. */
- private CameraCaptureCallback mMetadataMatchingCaptureCallback;
-
- private DeferrableSurface mDeferrableSurface;
-
- private ImageCaptureRequestProcessor mImageCaptureRequestProcessor;
- // Synthetic access
- @SuppressWarnings("WeakerAccess")
- final Executor mSequentialIoExecutor;
+ @Nullable
+ private ImagePipeline mImagePipeline;
+ @Nullable
+ private TakePictureManager mTakePictureManager;
/**
* Creates a new image capture use case from the given configuration.
@@ -360,115 +326,6 @@
}
mFlashType = useCaseConfig.getFlashType(FLASH_TYPE_ONE_SHOT_FLASH);
-
- mIoExecutor = checkNotNull(
- useCaseConfig.getIoExecutor(CameraXExecutors.ioExecutor()));
- mSequentialIoExecutor = CameraXExecutors.newSequentialExecutor(mIoExecutor);
-
- }
-
- @UiThread
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- SessionConfig.Builder createPipeline(@NonNull String cameraId,
- @NonNull ImageCaptureConfig config, @NonNull StreamSpec streamSpec) {
- checkMainThread();
- if (isNodeEnabled()) {
- return createPipelineWithNode(cameraId, config, streamSpec);
- }
- SessionConfig.Builder sessionConfigBuilder = SessionConfig.Builder.createFrom(config,
- streamSpec.getResolution());
-
- if (Build.VERSION.SDK_INT >= 23 && getCaptureMode() == CAPTURE_MODE_ZERO_SHUTTER_LAG) {
- getCameraControl().addZslConfig(sessionConfigBuilder);
- }
-
- // Setup the ImageReader to do processing
- Size resolution = streamSpec.getResolution();
- if (config.getImageReaderProxyProvider() != null) {
- mImageReader =
- new SafeCloseImageReaderProxy(
- config.getImageReaderProxyProvider().newInstance(resolution.getWidth(),
- resolution.getHeight(), getImageFormat(), MAX_IMAGES, 0));
- mMetadataMatchingCaptureCallback = new CameraCaptureCallback() {
- };
- } else if (isSessionProcessorEnabledInCurrentCamera()) {
- // TODO: remove this section and the rest of the code where it needs the
- // isSessionProcessorEnabledInCurrentCamera check.
- ImageReaderProxy imageReader;
- // SessionProcessor only outputs JPEG format.
- if (getImageFormat() == ImageFormat.JPEG) {
- // SessionProcessor can't guarantee that image and capture result have the same
- // time stamp. Thus we can't use MetadataImageReader
- imageReader = ImageReaderProxys.createIsolatedReader(resolution.getWidth(),
- resolution.getHeight(), ImageFormat.JPEG, MAX_IMAGES);
- mMetadataMatchingCaptureCallback = new CameraCaptureCallback() {
- };
- } else {
- throw new IllegalArgumentException("Unsupported image format:" + getImageFormat());
- }
- mImageReader = new SafeCloseImageReaderProxy(imageReader);
- } else {
- MetadataImageReader metadataImageReader = new MetadataImageReader(resolution.getWidth(),
- resolution.getHeight(), getImageFormat(), MAX_IMAGES);
- mMetadataMatchingCaptureCallback = metadataImageReader.getCameraCaptureCallback();
- mImageReader = new SafeCloseImageReaderProxy(metadataImageReader);
- }
-
- if (mImageCaptureRequestProcessor != null) {
- mImageCaptureRequestProcessor.cancelRequests(
- new CancellationException("Request is canceled."));
- }
-
- mImageCaptureRequestProcessor = new ImageCaptureRequestProcessor(MAX_IMAGES,
- this::takePictureInternal);
-
- // By default close images that come from the listener.
- mImageReader.setOnImageAvailableListener(mClosingListener,
- CameraXExecutors.mainThreadExecutor());
-
- if (mDeferrableSurface != null) {
- mDeferrableSurface.close();
- }
-
- mDeferrableSurface = new ImmediateSurface(
- requireNonNull(mImageReader.getSurface()),
- new Size(mImageReader.getWidth(),
- mImageReader.getHeight()),
- /* get the surface image format using getImageFormat */
- getImageFormat());
-
- mDeferrableSurface.getTerminationFuture().addListener(mImageReader::safeClose,
- CameraXExecutors.mainThreadExecutor());
-
- sessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface);
-
- sessionConfigBuilder.addErrorListener((sessionConfig, error) -> {
- // Get the unfinished requests before re-create the pipeline
- List<ImageCaptureRequest> pendingRequests = (mImageCaptureRequestProcessor != null)
- ? mImageCaptureRequestProcessor.pullOutUnfinishedRequests()
- : Collections.emptyList();
-
- clearPipeline();
- // Ensure the attached camera has not changed before resetting.
- // TODO(b/143915543): Ensure this never gets called by a camera that is not attached
- // to this use case so we don't need to do this check.
- if (isCurrentCamera(cameraId)) {
- // Only reset the pipeline when the bound camera is the same.
- mSessionConfigBuilder = createPipeline(cameraId, config, streamSpec);
-
- if (mImageCaptureRequestProcessor != null) {
- // Restore the unfinished requests to the created pipeline
- for (ImageCaptureRequest request : pendingRequests) {
- mImageCaptureRequestProcessor.sendRequest(request);
- }
- }
-
- updateSessionConfig(mSessionConfigBuilder.build());
- notifyReset();
- }
- });
-
- return sessionConfigBuilder;
}
private boolean isSessionProcessorEnabledInCurrentCamera() {
@@ -481,31 +338,6 @@
}
/**
- * Clear the internal pipeline so that the pipeline can be set up again.
- */
- @UiThread
- @SuppressWarnings("WeakerAccess")
- void clearPipeline() {
- checkMainThread();
- if (isNodeEnabled()) {
- clearPipelineWithNode();
- return;
- }
- if (mImageCaptureRequestProcessor != null) {
- mImageCaptureRequestProcessor.cancelRequests(
- new CancellationException("Request is canceled."));
- mImageCaptureRequestProcessor = null;
- }
- DeferrableSurface deferrableSurface = mDeferrableSurface;
- mDeferrableSurface = null;
- mImageReader = null;
-
- if (deferrableSurface != null) {
- deferrableSurface.close();
- }
- }
-
- /**
* {@inheritDoc}
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@@ -960,13 +792,8 @@
return;
}
- if (isNodeEnabled()) {
- takePictureWithNode(executor, callback, /*onDiskCallback=*/null,
- /*outputFileOptions=*/null);
- return;
- }
-
- sendImageCaptureRequest(executor, callback, /*saveImage=*/false);
+ takePictureInternal(executor, callback, /*onDiskCallback=*/null,
+ /*outputFileOptions=*/null);
}
/**
@@ -992,83 +819,8 @@
() -> takePicture(outputFileOptions, executor, imageSavedCallback));
return;
}
- if (isNodeEnabled()) {
- takePictureWithNode(executor, /*inMemoryCallback=*/null, imageSavedCallback,
- outputFileOptions);
- return;
- }
-
- /*
- * We need to chain the following callbacks to save the image to disk:
- *
- * +-----------------------+
- * | |
- * |ImageCapture. |
- * |OnImageCapturedCallback|
- * | |
- * +-----------+-----------+
- * |
- * |
- * +-----------v-----------+ +----------------------+
- * | | | |
- * | ImageSaver. | | ImageCapture. |
- * | OnImageSavedCallback +------> OnImageSavedCallback |
- * | | | |
- * +-----------------------+ +----------------------+
- */
-
- // Convert the ImageSaver.OnImageSavedCallback to ImageCapture.OnImageSavedCallback
- final ImageSaver.OnImageSavedCallback imageSavedCallbackWrapper =
- new ImageSaver.OnImageSavedCallback() {
- @Override
- public void onImageSaved(@NonNull OutputFileResults outputFileResults) {
- imageSavedCallback.onImageSaved(outputFileResults);
- }
-
- @Override
- public void onError(@NonNull ImageSaver.SaveError error,
- @NonNull String message,
- @Nullable Throwable cause) {
- @ImageCaptureError int imageCaptureError = ERROR_UNKNOWN;
- // Keep the imageCaptureError as UNKNOWN_ERROR
- if (error == ImageSaver.SaveError.FILE_IO_FAILED) {
- imageCaptureError = ERROR_FILE_IO;
- }
-
- imageSavedCallback.onError(
- new ImageCaptureException(imageCaptureError, message, cause));
- }
- };
-
- int outputJpegQuality = getJpegQualityInternal();
-
- // Wrap the ImageCapture.OnImageSavedCallback with an OnImageCapturedCallback so it can
- // be put into the capture request queue
- OnImageCapturedCallback imageCaptureCallbackWrapper =
- new OnImageCapturedCallback() {
- @Override
- public void onCaptureSuccess(@NonNull ImageProxy image) {
- mIoExecutor.execute(
- new ImageSaver(
- image,
- outputFileOptions,
- image.getImageInfo().getRotationDegrees(),
- outputJpegQuality,
- executor,
- mSequentialIoExecutor,
- imageSavedCallbackWrapper));
- }
-
- @Override
- public void onError(@NonNull final ImageCaptureException exception) {
- imageSavedCallback.onError(exception);
- }
- };
-
- // Always use the mainThreadExecutor for the initial callback so we don't need to double
- // post to another thread
- sendImageCaptureRequest(CameraXExecutors.mainThreadExecutor(),
- imageCaptureCallbackWrapper, /*saveImage=*/true);
+ takePictureInternal(executor, /*inMemoryCallback=*/null, imageSavedCallback,
+ outputFileOptions);
}
@NonNull
@@ -1109,87 +861,9 @@
private void abortImageCaptureRequests() {
if (mTakePictureManager != null) {
mTakePictureManager.abortRequests();
- } else if (mImageCaptureRequestProcessor != null) {
- Throwable throwable = new CameraClosedException("Camera is closed.");
- mImageCaptureRequestProcessor.cancelRequests(throwable);
}
}
- @UiThread
- private void sendImageCaptureRequest(@NonNull Executor callbackExecutor,
- @NonNull OnImageCapturedCallback callback, boolean saveImage) {
-
- // TODO(b/143734846): From here on, the image capture request should be
- // self-contained and use this camera for everything. Currently the pre-capture
- // sequence does not follow this approach and could fail if this use case is unbound
- // or reattached to a different camera in the middle of pre-capture.
- CameraInternal attachedCamera = getCamera();
- if (attachedCamera == null) {
- // Not bound. Notify callback.
- callbackExecutor.execute(
- () -> callback.onError(new ImageCaptureException(ERROR_INVALID_CAMERA,
- "Not bound to a valid Camera [" + ImageCapture.this + "]", null)));
- return;
- }
-
- if (mImageCaptureRequestProcessor == null) {
- callbackExecutor.execute(
- () -> callback.onError(
- new ImageCaptureException(ERROR_UNKNOWN, "Request is canceled", null)));
- return;
- }
-
- mImageCaptureRequestProcessor.sendRequest(new ImageCaptureRequest(
- getRelativeRotation(attachedCamera),
- getJpegQualityForImageCaptureRequest(attachedCamera, saveImage),
- mCropAspectRatio,
- getViewPortCropRect(),
- getSensorToBufferTransformMatrix(),
- callbackExecutor,
- callback));
- }
-
- @UiThread
- private int getJpegQualityForImageCaptureRequest(@NonNull CameraInternal cameraInternal,
- boolean saveImage) {
- int jpegQuality;
- if (saveImage) {
- int rotationDegrees = getRelativeRotation(cameraInternal);
- Size dispatchResolution = requireNonNull(getAttachedSurfaceResolution());
- // At this point, we can't know whether HAL will rotate the captured image or not. No
- // matter HAL will rotate the image byte array or not, it won't affect whether the final
- // image needs cropping or not. Therefore, we can still use the attached surface
- // resolution and its relative rotation degrees against to the target rotation
- // setting to calculate the possible crop rectangle and then use it to determine
- // whether the final image will need cropping or not.
- Rect cropRect = computeDispatchCropRect(getViewPortCropRect(), mCropAspectRatio,
- rotationDegrees, dispatchResolution, rotationDegrees);
- boolean shouldCropImage = ImageUtil.shouldCropImage(dispatchResolution.getWidth(),
- dispatchResolution.getHeight(), cropRect.width(), cropRect.height());
- if (shouldCropImage) {
- // When cropping is required, jpeg compression will occur twice:
- // 1. Jpeg quality set to camera HAL by camera capture request.
- // 2. Bitmap compression during cropping process in ImageSaver.
- // Here we need to define the first compression value and be careful to lose too
- // much quality due to double compression.
- // Setting 100 for the first compression can minimize quality loss, but will result
- // in poor performance during cropping than setting 95 (see b/206348741 for more
- // detail). As a trade-off, max quality mode is set to 100, and the others are set
- // to 95.
- jpegQuality = mCaptureMode == CAPTURE_MODE_MAXIMIZE_QUALITY ? 100 : 95;
- } else {
- jpegQuality = getJpegQualityInternal();
- }
- } else {
- // The captured image will be directly provided to the app via the
- // OnImageCapturedCallback callback. It won't be uncompressed and compressed again
- // after the image is captured. The JPEG quality setting will be directly provided to
- // the HAL to compress the output JPEG image.
- jpegQuality = getJpegQualityInternal();
- }
- return jpegQuality;
- }
-
void lockFlashMode() {
synchronized (mLockedFlashMode) {
if (mLockedFlashMode.get() != null) {
@@ -1250,267 +924,6 @@
}
}
- /**
- * The take picture flow.
- *
- * <p>There are three steps to take a picture.
- *
- * <p>(1) Pre-take picture, which will trigger af/ae scan or open torch if necessary. Then check
- * 3A converged if necessary.
- *
- * <p>(2) Issue take picture single request.
- *
- * <p>(3) Post-take picture, which will cancel af/ae scan or close torch if necessary.
- */
- @NonNull
- private ListenableFuture<ImageProxy> takePictureInternal(
- @NonNull ImageCaptureRequest imageCaptureRequest) {
- return CallbackToFutureAdapter.getFuture(
- completer -> {
- mImageReader.setOnImageAvailableListener(
- (imageReader) -> {
- try {
- ImageProxy image = imageReader.acquireLatestImage();
- if (image != null) {
- if (!completer.set(image)) {
- // If the future is already complete (probably be
- // cancelled), then close the image.
- image.close();
- }
- } else {
- completer.setException(new IllegalStateException(
- "Unable to acquire image"));
- }
- } catch (IllegalStateException e) {
- completer.setException(e);
- }
- },
- CameraXExecutors.mainThreadExecutor());
-
- lockFlashMode();
- ListenableFuture<Void> future = issueTakePicture(imageCaptureRequest);
-
- Futures.addCallback(future,
- new FutureCallback<Void>() {
- @Override
- public void onSuccess(Void result) {
- unlockFlashMode();
- }
-
- @Override
- public void onFailure(@NonNull Throwable throwable) {
- unlockFlashMode();
-
- completer.setException(throwable);
- }
- },
- CameraXExecutors.mainThreadExecutor());
-
- completer.addCancellationListener(() -> future.cancel(true),
- CameraXExecutors.directExecutor());
- return "takePictureInternal";
- });
- }
-
- /**
- * A processor that manages and issues the pending {@link ImageCaptureRequest}s.
- *
- * <p>It ensures that only one single {@link ImageCaptureRequest} is in progress at a time
- * and is able to process next request only when there is not over the maximum number of
- * dispatched image.
- */
- @VisibleForTesting
- static class ImageCaptureRequestProcessor implements OnImageCloseListener {
- @GuardedBy("mLock")
- private final Deque<ImageCaptureRequest> mPendingRequests = new ArrayDeque<>();
-
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- @GuardedBy("mLock")
- ImageCaptureRequest mCurrentRequest = null;
-
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- @GuardedBy("mLock")
- ListenableFuture<ImageProxy> mCurrentRequestFuture = null;
-
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- @GuardedBy("mLock")
- int mOutstandingImages = 0;
-
- @GuardedBy("mLock")
- private final ImageCaptor mImageCaptor;
- private final int mMaxImages;
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- final Object mLock = new Object();
-
- ImageCaptureRequestProcessor(int maxImages, @NonNull ImageCaptor imageCaptor) {
- mMaxImages = maxImages;
- mImageCaptor = imageCaptor;
- }
-
- /**
- * Sends an {@link ImageCaptureRequest} to queue.
- *
- * @param imageCaptureRequest the image request
- */
- public void sendRequest(@NonNull ImageCaptureRequest imageCaptureRequest) {
- synchronized (mLock) {
- mPendingRequests.offer(imageCaptureRequest);
- Logger.d(TAG, String.format(Locale.US,
- "Send image capture request [current, pending] = [%d, %d]",
- mCurrentRequest != null ? 1 : 0, mPendingRequests.size()));
- processNextRequest();
- }
- }
-
- /** Cancels current processing and pending requests. */
- public void cancelRequests(@NonNull Throwable throwable) {
- ImageCaptureRequest currentRequest;
- ListenableFuture<ImageProxy> currentRequestFuture;
- List<ImageCaptureRequest> pendingRequests;
- synchronized (mLock) {
- currentRequest = mCurrentRequest;
- mCurrentRequest = null;
- currentRequestFuture = mCurrentRequestFuture;
- mCurrentRequestFuture = null;
- pendingRequests = new ArrayList<>(mPendingRequests);
- mPendingRequests.clear();
- }
- if (currentRequest != null && currentRequestFuture != null) {
- currentRequest.notifyCallbackError(getError(throwable), throwable.getMessage(),
- throwable);
- currentRequestFuture.cancel(true);
- }
- for (ImageCaptureRequest request : pendingRequests) {
- request.notifyCallbackError(getError(throwable), throwable.getMessage(), throwable);
- }
- }
-
- /**
- * Removes and returns all unfinished requests.
- *
- * <p>The unfinished requests include:
- * <ul>
- * <li>Current running request if it is not complete yet.</li>
- * <li>All pending requests.</li>
- * </ul>
- *
- * @return list of the remaining requests
- */
- @NonNull
- public List<ImageCaptureRequest> pullOutUnfinishedRequests() {
- List<ImageCaptureRequest> remainingRequests;
- synchronized (mLock) {
- remainingRequests = new ArrayList<>(mPendingRequests);
- // Clear the pending requests before canceling the mCurrentRequestFuture.
- mPendingRequests.clear();
-
- ImageCaptureRequest currentRequest = mCurrentRequest;
- mCurrentRequest = null;
- if (currentRequest != null && mCurrentRequestFuture != null
- && mCurrentRequestFuture.cancel(true)) {
- remainingRequests.add(0, currentRequest);
- }
- }
-
- return remainingRequests;
- }
-
- @Override
- public void onImageClose(@NonNull ImageProxy image) {
- synchronized (mLock) {
- // TODO: mLock can be removed if all methods and callbacks in
- // ImageCaptureRequestProcessor are used in the main thread.
- // Side note: TakePictureManager already handles the requests in the main thread.
- mOutstandingImages--;
- CameraXExecutors.mainThreadExecutor().execute(this::processNextRequest);
- }
- }
-
- @SuppressWarnings("WeakerAccess") /* synthetic accessor */
- void processNextRequest() {
- synchronized (mLock) {
- // Unable to issue request if there is currently a request in flight
- if (mCurrentRequest != null) {
- return;
- }
-
- // Unable to issue request if the ImageReader has no available image buffer left.
- if (mOutstandingImages >= mMaxImages) {
- Logger.w(TAG,
- "Too many acquire images. Close image to be able to process next.");
- return;
- }
-
- ImageCaptureRequest imageCaptureRequest = mPendingRequests.poll();
- if (imageCaptureRequest == null) {
- return;
- }
-
- mCurrentRequest = imageCaptureRequest;
- mCurrentRequestFuture = mImageCaptor.capture(imageCaptureRequest);
- Futures.addCallback(mCurrentRequestFuture, new FutureCallback<ImageProxy>() {
- @Override
- public void onSuccess(@Nullable ImageProxy image) {
- synchronized (mLock) {
- checkNotNull(image);
- SingleCloseImageProxy wrappedImage = new SingleCloseImageProxy(image);
- wrappedImage.addOnImageCloseListener(ImageCaptureRequestProcessor.this);
- mOutstandingImages++;
- imageCaptureRequest.dispatchImage(wrappedImage);
-
- mCurrentRequest = null;
- mCurrentRequestFuture = null;
- processNextRequest();
- }
- }
-
- @Override
- public void onFailure(@NonNull Throwable t) {
- synchronized (mLock) {
- //noinspection StatementWithEmptyBody
- if (t instanceof CancellationException) {
- // Do not trigger callback which should be done in cancelRequests()
- // with a given throwable.
- } else {
- imageCaptureRequest.notifyCallbackError(getError(t),
- t != null ? t.getMessage() : "Unknown error", t);
- }
-
- mCurrentRequest = null;
- mCurrentRequestFuture = null;
- processNextRequest();
- }
- }
- }, CameraXExecutors.mainThreadExecutor());
- }
- }
-
- /** An interface of an {@link ImageProxy} captor. */
- interface ImageCaptor {
- /**
- * Captures an {@link ImageProxy} by giving a {@link ImageCaptureRequest}.
- *
- * @param imageCaptureRequest an {@link ImageCaptureRequest} contains required
- * parameters for this capture.
- * @return a {@link ListenableFuture represents the capture result. Cancellation to
- * the future should cancel the capture task.
- */
- @NonNull
- ListenableFuture<ImageProxy> capture(@NonNull ImageCaptureRequest imageCaptureRequest);
- }
-
- /**
- * An interface to provide callbacks when processing each capture request.
- */
- interface RequestProcessCallback {
- /**
- * This will be called before starting to process the
- * ImageCaptureRequest.
- */
- void onPreProcessRequest(@NonNull ImageCaptureRequest imageCaptureRequest);
- }
- }
-
@NonNull
@Override
public String toString() {
@@ -1569,7 +982,6 @@
public void onUnbind() {
abortImageCaptureRequests();
clearPipeline();
- mUseSoftwareJpeg = false;
}
/**
@@ -1578,15 +990,6 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
public void onBind() {
- ImageCaptureConfig useCaseConfig = (ImageCaptureConfig) getCurrentConfig();
-
- CaptureConfig.Builder captureBuilder = CaptureConfig.Builder.createFrom(useCaseConfig);
- mCaptureConfig = captureBuilder.build();
-
- // This will only be set to true if software JPEG was requested and
- // enforceSoftwareJpegConstraints() hasn't removed the request.
- mUseSoftwareJpeg = useCaseConfig.isSoftwareJpegEncoderRequested();
-
CameraInternal camera = getCamera();
checkNotNull(camera, "Attached camera cannot be null");
}
@@ -1610,59 +1013,18 @@
}
/**
- * Initiates a set of captures that will be used to create the output of
- * {@link #takePicture(OutputFileOptions, Executor, OnImageSavedCallback)} and its variants.
- *
- * <p> This returns a {@link ListenableFuture} whose completion indicates that the
- * captures are finished. Before the future is complete, any modification to the camera state
- * such as 3A could affect the result of the captures. After the future is complete, then it
- * is safe to reset or modify the 3A state.
+ * {@inheritDoc}
*/
- ListenableFuture<Void> issueTakePicture(@NonNull ImageCaptureRequest imageCaptureRequest) {
- Logger.d(TAG, "issueTakePicture");
-
- final CaptureConfig.Builder builder = new CaptureConfig.Builder();
- builder.setTemplateType(mCaptureConfig.getTemplateType());
-
- // Add the default implementation options of ImageCapture
- builder.addImplementationOptions(mCaptureConfig.getImplementationOptions());
- builder.addAllCameraCaptureCallbacks(
- mSessionConfigBuilder.getSingleCameraCaptureCallbacks());
-
- builder.addSurface(mDeferrableSurface);
-
- // Only sets the JPEG rotation and quality capture request options when capturing
- // images in JPEG format. Some devices do not handle these CaptureRequest key values
- // when capturing a non-JPEG image. Setting these capture requests and checking the
- // returned capture results for specific purpose might cause problems. See b/204375890.
- if (getImageFormat() == ImageFormat.JPEG) {
- // Add the dynamic implementation options of ImageCapture
- if (EXIF_ROTATION_AVAILABILITY.isRotationOptionSupported()) {
- builder.addImplementationOption(CaptureConfig.OPTION_ROTATION,
- imageCaptureRequest.mRotationDegrees);
- }
- builder.addImplementationOption(CaptureConfig.OPTION_JPEG_QUALITY,
- imageCaptureRequest.mJpegQuality);
- }
-
- builder.addCameraCaptureCallback(mMetadataMatchingCaptureCallback);
-
- return submitStillCaptureRequest(Arrays.asList(builder.build()));
+ @NonNull
+ @Override
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ mSessionConfigBuilder.addImplementationOptions(config);
+ updateSessionConfig(mSessionConfigBuilder.build());
+ return getAttachedStreamSpec().toBuilder().setImplementationOptions(config).build();
}
/**
- * ===== New architecture start =====
- *
- * TODO(b/229629844): unit test the interactions between {@link ImageCapture} and
- * {@link ImagePipeline}/{@link TakePictureManager}.
- */
-
- @Nullable
- private ImagePipeline mImagePipeline;
- @Nullable
- private TakePictureManager mTakePictureManager;
-
- /**
* An {@link ImageCaptureControl} implementation to control this {@link ImageCapture} instance.
*/
private final ImageCaptureControl mImageCaptureControl = new ImageCaptureControl() {
@@ -1689,31 +1051,14 @@
};
/**
- * Checks if the node is enabled given the current configuration.
- *
- * <p>This method checks if the new architecture can be enabled based on the current
- * configuration.
- *
- * <p>DO NOT turn on the new architecture until the 1.3 alpha branch is cut. We don't want
- * the quality of 1.2 beta to be affected by the refactoring.
- */
- @MainThread
- private boolean isNodeEnabled() {
- checkMainThread();
- return mUseProcessingPipeline;
- }
-
- /**
* Creates the pipeline for both capture request configuration and image post-processing.
- *
- * <p> This is the new {@link #createPipeline}.
*/
@OptIn(markerClass = ExperimentalZeroShutterLag.class)
@MainThread
- private SessionConfig.Builder createPipelineWithNode(@NonNull String cameraId,
+ private SessionConfig.Builder createPipeline(@NonNull String cameraId,
@NonNull ImageCaptureConfig config, @NonNull StreamSpec streamSpec) {
checkMainThread();
- Log.d(TAG, String.format("createPipelineWithNode(cameraId: %s, streamSpec: %s)",
+ Log.d(TAG, String.format("createPipeline(cameraId: %s, streamSpec: %s)",
cameraId, streamSpec));
Size resolution = streamSpec.getResolution();
@@ -1733,18 +1078,21 @@
if (Build.VERSION.SDK_INT >= 23 && getCaptureMode() == CAPTURE_MODE_ZERO_SHUTTER_LAG) {
getCameraControl().addZslConfig(sessionConfigBuilder);
}
+ if (streamSpec.getImplementationOptions() != null) {
+ sessionConfigBuilder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
sessionConfigBuilder.addErrorListener((sessionConfig, error) -> {
// TODO(b/143915543): Ensure this never gets called by a camera that is not attached
// to this use case so we don't need to do this check.
if (isCurrentCamera(cameraId)) {
mTakePictureManager.pause();
- clearPipelineWithNode(/*keepTakePictureManager=*/ true);
+ clearPipeline(/*keepTakePictureManager=*/ true);
mSessionConfigBuilder = createPipeline(cameraId, config, streamSpec);
updateSessionConfig(mSessionConfigBuilder.build());
notifyReset();
mTakePictureManager.resume();
} else {
- clearPipelineWithNode();
+ clearPipeline();
}
});
@@ -1755,18 +1103,18 @@
* Takes a picture with the new architecture.
*/
@MainThread
- private void takePictureWithNode(@NonNull Executor executor,
+ private void takePictureInternal(@NonNull Executor executor,
@Nullable OnImageCapturedCallback inMemoryCallback,
@Nullable ImageCapture.OnImageSavedCallback onDiskCallback,
@Nullable OutputFileOptions outputFileOptions) {
checkMainThread();
- Log.d(TAG, "takePictureWithNode");
+ Log.d(TAG, "takePictureInternal");
CameraInternal camera = getCamera();
if (camera == null) {
sendInvalidCameraError(executor, inMemoryCallback, onDiskCallback);
return;
}
- mTakePictureManager.offerRequest(TakePictureRequest.of(
+ requireNonNull(mTakePictureManager).offerRequest(TakePictureRequest.of(
executor,
inMemoryCallback,
onDiskCallback,
@@ -1819,19 +1167,16 @@
* Clears the pipeline without keeping the {@link TakePictureManager}.
*/
@MainThread
- private void clearPipelineWithNode() {
- clearPipelineWithNode(/*keepTakePictureManager=*/false);
+ private void clearPipeline() {
+ clearPipeline(/*keepTakePictureManager=*/false);
}
/**
* Clears the pipeline.
- *
- * <p>Similar to {@link #clearPipeline()}, this cancels unfinished requests and release
- * resources.
*/
@MainThread
- private void clearPipelineWithNode(boolean keepTakePictureManager) {
- Log.d(TAG, "clearPipelineWithNode");
+ private void clearPipeline(boolean keepTakePictureManager) {
+ Log.d(TAG, "clearPipeline");
checkMainThread();
if (mImagePipeline != null) {
mImagePipeline.close();
@@ -1874,8 +1219,6 @@
return requireNonNull(mTakePictureManager);
}
- // ===== New architecture end =====
-
/**
* @inheritDoc
*/
@@ -2020,13 +1363,17 @@
ResolutionStrategy.HIGHEST_AVAILABLE_STRATEGY).build();
private static final ImageCaptureConfig DEFAULT_CONFIG;
+ // ImageCapture does not yet support HDR so we must default to SDR. This ensures it won't
+ // choose an HDR format when other use cases have selected HDR.
+ private static final DynamicRange DEFAULT_DYNAMIC_RANGE = DynamicRange.SDR;
static {
Builder builder = new Builder()
.setSurfaceOccupancyPriority(DEFAULT_SURFACE_OCCUPANCY_PRIORITY)
.setTargetAspectRatio(DEFAULT_ASPECT_RATIO)
.setResolutionSelector(DEFAULT_RESOLUTION_SELECTOR)
- .setCaptureType(UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE);
+ .setCaptureType(UseCaseConfigFactory.CaptureType.IMAGE_CAPTURE)
+ .setDynamicRange(DEFAULT_DYNAMIC_RANGE);
DEFAULT_CONFIG = builder.getUseCaseConfig();
}
@@ -2512,7 +1859,8 @@
public static final class Builder implements
UseCaseConfig.Builder<ImageCapture, ImageCaptureConfig, Builder>,
ImageOutputConfig.Builder<Builder>,
- IoConfig.Builder<Builder> {
+ IoConfig.Builder<Builder>,
+ ImageInputConfig.Builder<Builder> {
private final MutableOptionsBundle mMutableConfig;
@@ -3090,5 +2438,26 @@
getMutableConfig().insertOption(OPTION_CAPTURE_TYPE, captureType);
return this;
}
+
+ // Implementations of ImageInputConfig.Builder default methods
+
+ /**
+ * Sets the {@link DynamicRange}.
+ *
+ * <p>This is currently only exposed to internally set the dynamic range to SDR.
+ * @return The current Builder.
+ * @see DynamicRange
+ */
+ @RestrictTo(Scope.LIBRARY)
+ @NonNull
+ @Override
+ public Builder setDynamicRange(@NonNull DynamicRange dynamicRange) {
+ // TODO(b/280893255): ImageCapture currently does not support HDR.
+ if (!Objects.equals(DynamicRange.SDR, dynamicRange)) {
+ throw new UnsupportedOperationException("ImageCapture currently only supports SDR");
+ }
+ getMutableConfig().insertOption(OPTION_INPUT_DYNAMIC_RANGE, dynamicRange);
+ return this;
+ }
}
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
index 153f731..e593232 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Preview.java
@@ -180,6 +180,9 @@
// [UseCase attached dynamic] - Can change but is only available when the UseCase is attached.
////////////////////////////////////////////////////////////////////////////////////////////
+ @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+ SessionConfig.Builder mSessionConfigBuilder;
+
// TODO(b/259308680): remove mSessionDeferrableSurface and rely on mCameraEdge to get the
// DeferrableSurface
private DeferrableSurface mSessionDeferrableSurface;
@@ -244,6 +247,9 @@
mSessionDeferrableSurface = surfaceRequest.getDeferrableSurface();
addCameraSurfaceAndErrorListener(sessionConfigBuilder, cameraId, config, streamSpec);
sessionConfigBuilder.setExpectedFrameRateRange(streamSpec.getExpectedFrameRateRange());
+ if (streamSpec.getImplementationOptions() != null) {
+ sessionConfigBuilder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
return sessionConfigBuilder;
}
@@ -298,6 +304,9 @@
// Send the camera Surface to the camera2.
SessionConfig.Builder sessionConfigBuilder = SessionConfig.Builder.createFrom(config,
streamSpec.getResolution());
+ if (streamSpec.getImplementationOptions() != null) {
+ sessionConfigBuilder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
addCameraSurfaceAndErrorListener(sessionConfigBuilder, cameraId, config, streamSpec);
return sessionConfigBuilder;
}
@@ -368,7 +377,8 @@
// SurfaceProcessorNode and CaptureProcessor cases, since no surface provider also means no
// output target for these two cases.
if (mSurfaceProvider != null) {
- sessionConfigBuilder.addSurface(mSessionDeferrableSurface);
+ sessionConfigBuilder.addSurface(mSessionDeferrableSurface,
+ streamSpec.getDynamicRange());
}
sessionConfigBuilder.addErrorListener((sessionConfig, error) -> {
@@ -516,7 +526,8 @@
private void updateConfigAndOutput(@NonNull String cameraId, @NonNull PreviewConfig config,
@NonNull StreamSpec streamSpec) {
- updateSessionConfig(createPipeline(cameraId, config, streamSpec).build());
+ mSessionConfigBuilder = createPipeline(cameraId, config, streamSpec);
+ updateSessionConfig(mSessionConfigBuilder.build());
}
/**
@@ -643,6 +654,19 @@
/**
* {@inheritDoc}
*/
+ @NonNull
+ @Override
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ mSessionConfigBuilder.addImplementationOptions(config);
+ updateSessionConfig(mSessionConfigBuilder.build());
+ return getAttachedStreamSpec().toBuilder().setImplementationOptions(config).build();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ */
@Override
@RestrictTo(Scope.LIBRARY)
public void setViewPortCropRect(@NonNull Rect viewPortCropRect) {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
index 5b381e7..acdce0c 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/UseCase.java
@@ -701,6 +701,32 @@
}
/**
+ * Update the implementation options of the stream specification for the UseCase.
+ *
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ public void updateSuggestedStreamSpecImplementationOptions(@NonNull Config config) {
+ mAttachedStreamSpec = onSuggestedStreamSpecImplementationOptionsUpdated(config);
+ }
+
+ /**
+ * Called when updating the stream specifications' implementation options of existing use cases
+ * via {@code CameraUseCaseAdapter#updateUseCases}.
+ *
+ * @param config The new implementationOptions for the stream specification.
+ */
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ @NonNull
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ if (mAttachedStreamSpec == null) {
+ throw new UnsupportedOperationException("Attempt to update the implementation options "
+ + "for a use case without attached stream specifications.");
+ }
+ return mAttachedStreamSpec.toBuilder().setImplementationOptions(config).build();
+ }
+
+
+ /**
* Called when CameraControlInternal is attached into the UseCase. UseCase may need to
* override this method to configure the CameraControlInternal here. Ex. Setting correct flash
* mode by CameraControlInternal.setFlashMode to enable correct AE mode and flash state.
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraDeviceSurfaceManager.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraDeviceSurfaceManager.java
index b0c0a2a..9abb314 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraDeviceSurfaceManager.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraDeviceSurfaceManager.java
@@ -17,6 +17,7 @@
package androidx.camera.core.impl;
import android.content.Context;
+import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
@@ -42,8 +43,8 @@
/**
* Creates a new, initialized instance of a CameraDeviceSurfaceManager.
*
- * @param context the android context
- * @param cameraManager the camera manager object used to query the camera information.
+ * @param context the android context
+ * @param cameraManager the camera manager object used to query the camera information.
* @param availableCameraIds current available camera ids.
* @return the factory instance
* @throws InitializationException if it fails to create the factory
@@ -90,7 +91,8 @@
* is not a valid id.
*/
@NonNull
- Map<UseCaseConfig<?>, StreamSpec> getSuggestedStreamSpecs(
+ Pair<Map<UseCaseConfig<?>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>>
+ getSuggestedStreamSpecs(
@CameraMode.Mode int cameraMode,
@NonNull String cameraId,
@NonNull List<AttachedSurfaceInfo> existingSurfaces,
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
index 1485065..6cf83bf 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
@@ -416,7 +416,7 @@
OptionsBundle.from(mImplementationOptions),
mTemplateType,
mExpectedFrameRateRange,
- mCameraCaptureCallbacks,
+ new ArrayList<>(mCameraCaptureCallbacks),
mUseRepeatingSurface,
TagBundle.from(mMutableTagBundle),
mCameraCaptureResult);
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/SessionConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/SessionConfig.java
index 91b520a..1ba7e29 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/SessionConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/SessionConfig.java
@@ -694,10 +694,10 @@
public SessionConfig build() {
return new SessionConfig(
new ArrayList<>(mOutputConfigs),
- mDeviceStateCallbacks,
- mSessionStateCallbacks,
- mSingleCameraCaptureCallbacks,
- mErrorListeners,
+ new ArrayList<>(mDeviceStateCallbacks),
+ new ArrayList<>(mSessionStateCallbacks),
+ new ArrayList<>(mSingleCameraCaptureCallbacks),
+ new ArrayList<>(mErrorListeners),
mCaptureConfigBuilder.build(),
mInputConfiguration);
}
@@ -847,10 +847,10 @@
return new SessionConfig(
outputConfigs,
- mDeviceStateCallbacks,
- mSessionStateCallbacks,
- mSingleCameraCaptureCallbacks,
- mErrorListeners,
+ new ArrayList<>(mDeviceStateCallbacks),
+ new ArrayList<>(mSessionStateCallbacks),
+ new ArrayList<>(mSingleCameraCaptureCallbacks),
+ new ArrayList<>(mErrorListeners),
mCaptureConfigBuilder.build(),
mInputConfiguration);
}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
index 2350fbc..7d284bd 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/CameraUseCaseAdapter.java
@@ -31,6 +31,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
+import android.util.Pair;
import android.util.Size;
import android.view.Surface;
@@ -62,6 +63,7 @@
import androidx.camera.core.impl.RestrictedCameraControl;
import androidx.camera.core.impl.RestrictedCameraControl.CameraOperation;
import androidx.camera.core.impl.RestrictedCameraInfo;
+import androidx.camera.core.impl.SessionConfig;
import androidx.camera.core.impl.SessionProcessor;
import androidx.camera.core.impl.StreamSpec;
import androidx.camera.core.impl.SurfaceConfig;
@@ -79,6 +81,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -334,6 +337,22 @@
}
mCameraInternal.detachUseCases(cameraUseCasesToDetach);
+ // Update StreamSpec for UseCases to keep.
+ if (!cameraUseCasesToDetach.isEmpty()) {
+ // Only do this if we are not removing UseCase, because updating SessionConfig
+ // when removing UseCases may lead to flickering.
+ for (UseCase useCase : cameraUseCasesToKeep) {
+ if (suggestedStreamSpecMap.containsKey(useCase)) {
+ StreamSpec newStreamSpec = suggestedStreamSpecMap.get(useCase);
+ Config config = newStreamSpec.getImplementationOptions();
+ if (config != null && hasImplementationOptionChanged(newStreamSpec,
+ useCase.getSessionConfig())) {
+ useCase.updateSuggestedStreamSpecImplementationOptions(config);
+ }
+ }
+ }
+ }
+
// Attach new UseCases.
for (UseCase useCase : cameraUseCasesToAttach) {
ConfigPair configPair = requireNonNull(configs.get(useCase));
@@ -361,6 +380,29 @@
}
}
+ /**
+ * Return true if the given StreamSpec has any option with a different value than that
+ * of the given sessionConfig.
+ */
+ private static boolean hasImplementationOptionChanged(
+ StreamSpec streamSpec,
+ SessionConfig sessionConfig) {
+ Config newStreamSpecOptions = streamSpec.getImplementationOptions();
+ Config sessionConfigOptions = sessionConfig.getImplementationOptions();
+ if (newStreamSpecOptions.listOptions().size()
+ != sessionConfig.getImplementationOptions().listOptions().size()) {
+ return true;
+ }
+ for (Config.Option<?> newOption : newStreamSpecOptions.listOptions()) {
+ if (!sessionConfigOptions.containsOption(newOption)
+ || !Objects.equals(sessionConfigOptions.retrieveOption(newOption),
+ newStreamSpecOptions.retrieveOption(newOption))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private @CameraMode.Mode int getCameraMode() {
synchronized (mLock) {
if (mCameraCoordinator.getCameraOperatingMode()
@@ -597,6 +639,7 @@
List<AttachedSurfaceInfo> existingSurfaces = new ArrayList<>();
String cameraId = cameraInfoInternal.getCameraId();
Map<UseCase, StreamSpec> suggestedStreamSpecs = new HashMap<>();
+ Map<AttachedSurfaceInfo, UseCase> surfaceInfoUseCaseMap = new HashMap<>();
// Get resolution for current use cases.
for (UseCase useCase : currentUseCases) {
@@ -606,12 +649,14 @@
cameraId,
useCase.getImageFormat(),
useCase.getAttachedSurfaceResolution());
- existingSurfaces.add(AttachedSurfaceInfo.create(surfaceConfig,
+ AttachedSurfaceInfo attachedSurfaceInfo = AttachedSurfaceInfo.create(surfaceConfig,
useCase.getImageFormat(), useCase.getAttachedSurfaceResolution(),
Preconditions.checkNotNull(useCase.getAttachedStreamSpec()).getDynamicRange(),
getCaptureTypes(useCase),
useCase.getAttachedStreamSpec().getImplementationOptions(),
- useCase.getCurrentConfig().getTargetFrameRate(null)));
+ useCase.getCurrentConfig().getTargetFrameRate(null));
+ existingSurfaces.add(attachedSurfaceInfo);
+ surfaceInfoUseCaseMap.put(attachedSurfaceInfo, useCase);
suggestedStreamSpecs.put(useCase, useCase.getAttachedStreamSpec());
}
@@ -643,7 +688,8 @@
}
// Get suggested stream specifications and update the use case session configuration
- Map<UseCaseConfig<?>, StreamSpec> useCaseConfigStreamSpecMap =
+ Pair<Map<UseCaseConfig<?>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>>
+ streamSpecMaps =
mCameraDeviceSurfaceManager.getSuggestedStreamSpecs(
cameraMode,
cameraId, existingSurfaces,
@@ -651,7 +697,14 @@
for (Map.Entry<UseCaseConfig<?>, UseCase> entry : configToUseCaseMap.entrySet()) {
suggestedStreamSpecs.put(entry.getValue(),
- useCaseConfigStreamSpecMap.get(entry.getKey()));
+ streamSpecMaps.first.get(entry.getKey()));
+ }
+ for (Map.Entry<AttachedSurfaceInfo, StreamSpec> entry :
+ streamSpecMaps.second.entrySet()) {
+ if (surfaceInfoUseCaseMap.containsKey(entry.getKey())) {
+ suggestedStreamSpecs.put(surfaceInfoUseCaseMap.get(entry.getKey()),
+ entry.getValue());
+ }
}
}
return suggestedStreamSpecs;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
index 93cd629..830387a 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/streamsharing/StreamSharing.java
@@ -36,6 +36,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
import androidx.annotation.VisibleForTesting;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.UseCase;
@@ -86,6 +87,9 @@
@Nullable
private SurfaceEdge mSharingInputEdge;
+ @SuppressWarnings("WeakerAccess") /* synthetic accessor */
+ SessionConfig.Builder mSessionConfigBuilder;
+
static {
MutableConfig mutableConfig = new StreamSharingBuilder().getMutableConfig();
mutableConfig.insertOption(OPTION_INPUT_FORMAT,
@@ -156,6 +160,18 @@
return streamSpec;
}
+ /**
+ * {@inheritDoc}
+ */
+ @NonNull
+ @Override
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ mSessionConfigBuilder.addImplementationOptions(config);
+ updateSessionConfig(mSessionConfigBuilder.build());
+ return getAttachedStreamSpec().toBuilder().setImplementationOptions(config).build();
+ }
+
@Override
public void onBind() {
super.onBind();
@@ -239,7 +255,11 @@
streamSpec.getResolution());
builder.addSurface(mCameraEdge.getDeferrableSurface());
builder.addRepeatingCameraCaptureCallback(mVirtualCamera.getParentMetadataCallback());
+ if (streamSpec.getImplementationOptions() != null) {
+ builder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
addCameraErrorListener(builder, cameraId, config, streamSpec);
+ mSessionConfigBuilder = builder;
return builder.build();
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
index 3195cae..dd4cd17 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageAnalysisTest.java
@@ -38,6 +38,7 @@
import androidx.camera.core.impl.CameraFactory;
import androidx.camera.core.impl.CameraInternal;
import androidx.camera.core.impl.ImageAnalysisConfig;
+import androidx.camera.core.impl.MutableOptionsBundle;
import androidx.camera.core.impl.TagBundle;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.core.internal.CameraUseCaseAdapter;
@@ -91,6 +92,8 @@
private static final long TIMESTAMP_1 = 1;
private static final long TIMESTAMP_2 = 2;
private static final long TIMESTAMP_3 = 3;
+ public static final androidx.camera.core.impl.Config.Option<Integer> TEST_OPTION =
+ androidx.camera.core.impl.Config.Option.create("test.testOption", int.class);
private Handler mCallbackHandler;
private Handler mBackgroundHandler;
@@ -438,6 +441,20 @@
assertCanReceiveAnalysisImage(mImageAnalysis);
}
+ @Test
+ public void sessionConfigHasStreamSpecImplementationOptions_whenUpdateStreamSpecImplOptions()
+ throws CameraUseCaseAdapter.CameraException {
+ setUpImageAnalysisWithStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
+ int newImplementationOptionValue = 6;
+ MutableOptionsBundle streamSpecOptions = MutableOptionsBundle.create();
+ streamSpecOptions.insertOption(TEST_OPTION, newImplementationOptionValue);
+ mImageAnalysis.updateSuggestedStreamSpecImplementationOptions(streamSpecOptions);
+ assertThat(
+ mImageAnalysis.getSessionConfig().getImplementationOptions().retrieveOption(
+ TEST_OPTION
+ )).isEqualTo(newImplementationOptionValue);
+ }
+
@SuppressWarnings("deprecation") // test for legacy resolution API
@Test
public void throwException_whenSetBothTargetResolutionAndAspectRatio() {
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
index ad923b7f1..2253979 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/ImageCaptureTest.kt
@@ -30,15 +30,13 @@
import androidx.camera.core.CameraEffect.IMAGE_CAPTURE
import androidx.camera.core.CameraEffect.PREVIEW
import androidx.camera.core.CameraEffect.VIDEO_CAPTURE
-import androidx.camera.core.ImageCapture.ImageCaptureRequest
-import androidx.camera.core.ImageCapture.ImageCaptureRequestProcessor
-import androidx.camera.core.ImageCapture.ImageCaptureRequestProcessor.ImageCaptor
import androidx.camera.core.MirrorMode.MIRROR_MODE_OFF
import androidx.camera.core.MirrorMode.MIRROR_MODE_ON_FRONT_ONLY
import androidx.camera.core.impl.CameraConfig
import androidx.camera.core.impl.CameraFactory
import androidx.camera.core.impl.CaptureConfig
import androidx.camera.core.impl.Identifier
+import androidx.camera.core.impl.MutableOptionsBundle
import androidx.camera.core.impl.OptionsBundle
import androidx.camera.core.impl.SessionConfig
import androidx.camera.core.impl.SessionProcessor
@@ -46,7 +44,6 @@
import androidx.camera.core.impl.UseCaseConfig
import androidx.camera.core.impl.utils.executor.CameraXExecutors
import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
-import androidx.camera.core.impl.utils.futures.Futures
import androidx.camera.core.internal.CameraUseCaseAdapter
import androidx.camera.core.internal.utils.SizeUtil
import androidx.camera.core.resolutionselector.ResolutionSelector
@@ -57,30 +54,20 @@
import androidx.camera.testing.fakes.FakeCameraControl
import androidx.camera.testing.fakes.FakeCameraFactory
import androidx.camera.testing.fakes.FakeCameraInfoInternal
-import androidx.camera.testing.fakes.FakeImageInfo
-import androidx.camera.testing.fakes.FakeImageProxy
import androidx.camera.testing.fakes.FakeImageReaderProxy
-import androidx.camera.testing.fakes.FakeSessionProcessor
-import androidx.concurrent.futures.ResolvableFuture
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import java.io.File
-import java.util.ArrayDeque
import java.util.Collections
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executor
-import java.util.concurrent.atomic.AtomicReference
import org.junit.After
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.eq
import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
@@ -89,8 +76,6 @@
import org.robolectric.shadow.api.Shadow
import org.robolectric.shadows.ShadowLooper
-private const val MAX_IMAGES = 3
-
/**
* Unit tests for [ImageCapture].
*/
@@ -116,6 +101,12 @@
override fun onError(exception: ImageCaptureException) {
}
}
+ private val testImplementationOption: androidx.camera.core.impl.Config.Option<Int> =
+ androidx.camera.core.impl.Config.Option.create(
+ "test.testOption",
+ Int::class.javaPrimitiveType!!
+ )
+ private val testImplementationOptionValue = 5
@Before
@Throws(ExecutionException::class, InterruptedException::class)
@@ -275,54 +266,11 @@
}
@Test
- fun processingPipelineOn_pipelineEnabled() {
- assertThat(
- bindImageCapture(
- useProcessingPipeline = true,
- bufferFormat = ImageFormat.JPEG,
- ).isProcessingPipelineEnabled
- ).isTrue()
- }
-
- @Test
fun detachWithoutAttach_doesNotCrash() {
ImageCapture.Builder().build().onUnbind()
}
@Test
- fun useImageReaderProvider_pipelineEnabled() {
- assertThat(
- bindImageCapture(
- useProcessingPipeline = true,
- bufferFormat = ImageFormat.JPEG,
- imageReaderProxyProvider = getImageReaderProxyProvider(),
- ).isProcessingPipelineEnabled
- ).isTrue()
- }
-
- @Test
- fun yuvFormat_pipelineEnabled() {
- assertThat(
- bindImageCapture(
- useProcessingPipeline = true,
- bufferFormat = ImageFormat.YUV_420_888,
- ).isProcessingPipelineEnabled
- ).isTrue()
- }
-
- @Config(minSdk = 28)
- @Test
- fun extensionIsOn_pipelineEnabled() {
- val imageCapture = bindImageCapture(
- useProcessingPipeline = true,
- bufferFormat = ImageFormat.JPEG,
- sessionProcessor = FakeSessionProcessor(null, null)
- )
- assertThat(imageCapture.isProcessingPipelineEnabled).isTrue()
- assertThat(imageCapture.imagePipeline!!.expectsMetadata()).isFalse()
- }
-
- @Test
fun captureImageWithViewPort_isSet() {
// Arrange
val imageCapture = bindImageCapture(
@@ -392,185 +340,6 @@
}
@Test
- fun imageCaptureRequestProcessor_canSendRequest() {
- // Arrange.
- val requestProcessor = ImageCaptureRequestProcessor(MAX_IMAGES, createSuccessImageCaptor())
- val request = createImageCaptureRequest()
-
- // Act.
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- verify(request).dispatchImage(any())
- }
-
- @Test
- fun imageCaptureRequestProcessor_canSendMultipleRequests() {
- // Arrange.
- val requestProcessor = ImageCaptureRequestProcessor(MAX_IMAGES, createSuccessImageCaptor())
- for (i in 0 until MAX_IMAGES) {
- val request = createImageCaptureRequest()
-
- // Act.
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- verify(request).dispatchImage(any())
- }
- }
-
- @Test
- fun imageCaptureRequestProcessor_onlyAllowOneRequestProcessing() {
- // Arrange.
- // Create an ImageCaptor that won't complete the future.
- val captorFutureRef = AtomicReference<ResolvableFuture<ImageProxy>?>()
- val imageCaptor = createHoldImageCaptor(captorFutureRef)
- val requestProcessor = ImageCaptureRequestProcessor(MAX_IMAGES, imageCaptor)
- val request0 = createImageCaptureRequest()
- val request1 = createImageCaptureRequest()
-
- // Act.
- requestProcessor.sendRequest(request0)
- requestProcessor.sendRequest(request1)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- // Has processing request but not complete.
- assertThat(captorFutureRef.get()).isNotNull()
- verify(request0, never()).dispatchImage(any())
- verify(request1, never()).dispatchImage(any())
-
- // Act.
- // Complete request0.
- captorFutureRef.getAndSet(null)!!.set(mock(ImageProxy::class.java))
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- // request0 is complete and request1 is in processing.
- verify(request0).dispatchImage(any())
- verify(request1, never()).dispatchImage(any())
- assertThat(captorFutureRef.get()).isNotNull()
-
- // Act.
- // Complete request1.
- captorFutureRef.getAndSet(null)!!.set(mock(ImageProxy::class.java))
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- verify(request1).dispatchImage(any())
- }
-
- @Test
- fun imageCaptureRequestProcessor_unableToProcessNextWhenOverMaxImages() {
- // Arrange.
- val requestProcessor = ImageCaptureRequestProcessor(MAX_IMAGES, createSuccessImageCaptor())
-
- // Exhaust outstanding image quota.
- val images = ArrayDeque<ImageProxy>()
- for (i in 0 until MAX_IMAGES) {
- val request = createImageCaptureRequest()
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Save the dispatched images.
- val captor = ArgumentCaptor.forClass(ImageProxy::class.java)
- verify(request).dispatchImage(captor.capture())
- images.offer(captor.value)
- }
- assertThat(images.size).isEqualTo(MAX_IMAGES)
-
- // Act.
- // Send one more request.
- val request = createImageCaptureRequest()
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- verify(request, never()).dispatchImage(any())
-
- // Act.
- // Close one image to trigger next processing.
- images.poll()!!.close()
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- // It should trigger next processing.
- verify(request).dispatchImage(any())
- }
-
- @Test
- fun imageCaptureRequestProcessor_canCancelRequests() {
- // Arrange.
- // Create an ImageCaptor that won't complete the future.
- val captorFutureRef = AtomicReference<ResolvableFuture<ImageProxy>?>()
- val imageCaptor = createHoldImageCaptor(captorFutureRef)
- val requestProcessor = ImageCaptureRequestProcessor(MAX_IMAGES, imageCaptor)
-
- // Send multiple requests and save these requests.
- val requestList = ArrayList<ImageCaptureRequest>()
- for (i in 0 until 5) {
- val request = createImageCaptureRequest()
- requestList.add(request)
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
- }
-
- // Act.
- val errorMsg = "Cancel request."
- val throwable = RuntimeException(errorMsg)
- requestProcessor.cancelRequests(throwable)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Assert.
- for (request in requestList) {
- verify(request).notifyCallbackError(anyInt(), eq(errorMsg), eq(throwable))
- }
- // Capture future is cancelled.
- assertThat(captorFutureRef.get()!!.isCancelled).isTrue()
- }
-
- @Test
- fun imageCaptureRequestProcessor_requestFail() {
- // Arrange.
- val errorMsg = "Capture failed."
- val throwable = RuntimeException(errorMsg)
- val requestProcessor =
- ImageCaptureRequestProcessor(MAX_IMAGES, createFailedImageCaptor(throwable))
- val request = createImageCaptureRequest()
-
- // Act.
- requestProcessor.sendRequest(request)
-
- // Ensure tasks are posted to the processing executor
- shadowOf(getMainLooper()).idle()
-
- // Verify.
- verify(request).notifyCallbackError(anyInt(), eq(errorMsg), eq(throwable))
- }
-
- @Test
fun sessionConfigSurfaceFormat_isInputFormat() {
// Act/arrange.
val imageCapture = bindImageCapture(bufferFormat = ImageFormat.YUV_420_888,
@@ -626,6 +395,22 @@
assertThat(cameraControl.isZslConfigAdded).isTrue()
}
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenUpdateStreamSpecImplOptions() {
+ val imageCapture = bindImageCapture(
+ bufferFormat = ImageFormat.JPEG,
+ )
+ val newImplementationOptionValue = 6
+ val streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, newImplementationOptionValue)
+ imageCapture.updateSuggestedStreamSpecImplementationOptions(streamSpecOptions)
+ assertThat(
+ imageCapture.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(newImplementationOptionValue)
+ }
+
@Suppress("DEPRECATION") // test for legacy resolution API
@Test
fun throwException_whenSetBothTargetResolutionAndAspectRatio() {
@@ -661,7 +446,6 @@
// Set non jpg format so it doesn't trigger the exif code path.
bufferFormat: Int = ImageFormat.YUV_420_888,
imageReaderProxyProvider: ImageReaderProxyProvider? = null,
- useProcessingPipeline: Boolean? = null,
sessionProcessor: SessionProcessor? = null
): ImageCapture {
// Arrange.
@@ -670,9 +454,6 @@
bufferFormat,
imageReaderProxyProvider,
)
- if (useProcessingPipeline != null) {
- imageCapture.mUseProcessingPipeline = useProcessingPipeline
- }
cameraUseCaseAdapter = CameraUtil.createCameraUseCaseAdapter(
ApplicationProvider.getApplicationContext(),
@@ -688,7 +469,7 @@
override fun getSessionProcessor(
valueIfMissing: SessionProcessor?
- ): SessionProcessor? {
+ ): SessionProcessor {
return sessionProcessor
}
@@ -741,30 +522,4 @@
private fun flushHandler(handler: Handler?) {
(Shadow.extract<Any>(handler!!.looper) as ShadowLooper).idle()
}
-
- private fun createImageCaptureRequest(): ImageCaptureRequest {
- return mock(ImageCaptureRequest::class.java)
- }
-
- private fun createSuccessImageCaptor(): ImageCaptor {
- return ImageCaptor {
- Futures.immediateFuture(FakeImageProxy(FakeImageInfo()))
- }
- }
-
- private fun createHoldImageCaptor(
- futureHolder: AtomicReference<ResolvableFuture<ImageProxy>?>
- ): ImageCaptor {
- return ImageCaptor {
- ResolvableFuture.create<ImageProxy>().apply {
- futureHolder.set(this)
- }
- }
- }
-
- private fun createFailedImageCaptor(throwable: Throwable): ImageCaptor {
- return ImageCaptor {
- Futures.immediateFailedFuture(throwable)
- }
- }
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
index 6f8fa37..3b09a2a 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/PreviewTest.kt
@@ -35,6 +35,7 @@
import androidx.camera.core.SurfaceRequest.TransformationInfo
import androidx.camera.core.impl.CameraFactory
import androidx.camera.core.impl.CameraThreadConfig
+import androidx.camera.core.impl.MutableOptionsBundle
import androidx.camera.core.impl.OptionsBundle
import androidx.camera.core.impl.PreviewConfig
import androidx.camera.core.impl.SessionConfig
@@ -80,6 +81,8 @@
@Config(
minSdk = Build.VERSION_CODES.LOLLIPOP
)
+// Option Declarations:
+// *********************************************************************************************
class PreviewTest {
private var cameraUseCaseAdapter: CameraUseCaseAdapter? = null
@@ -96,6 +99,13 @@
private val handlersToRelease = mutableListOf<Handler>()
+ private val testImplementationOption: androidx.camera.core.impl.Config.Option<Int> =
+ androidx.camera.core.impl.Config.Option.create(
+ "test.testOption",
+ Int::class.javaPrimitiveType!!
+ )
+ private val testImplementationOptionValue = 5
+
@Before
@Throws(ExecutionException::class, InterruptedException::class)
fun setUp() {
@@ -641,6 +651,30 @@
assertThat(receivedAfterAttach).isTrue()
}
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenCreatePipeline() {
+ val preview = createPreview(effect)
+ assertThat(
+ preview.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(testImplementationOptionValue)
+ }
+
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenUpdateStreamSpecImplOptions() {
+ val preview = createPreview(effect)
+ val newImplementationOptionValue = 6
+ val streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, newImplementationOptionValue)
+ preview.updateSuggestedStreamSpecImplementationOptions(streamSpecOptions)
+ assertThat(
+ preview.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(newImplementationOptionValue)
+ }
+
@Suppress("DEPRECATION") // test for legacy resolution API
@Test
fun throwException_whenSetBothTargetResolutionAndAspectRatio() {
@@ -734,8 +768,11 @@
)
previewToDetach.bindToCamera(camera, null, previewConfig)
- val streamSpec = StreamSpec.builder(Size(640, 480)).build()
- previewToDetach.onSuggestedStreamSpecUpdated(streamSpec)
+ val streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, testImplementationOptionValue)
+ val streamSpec = StreamSpec.builder(Size(640, 480))
+ .setImplementationOptions(streamSpecOptions).build()
+ previewToDetach.updateSuggestedStreamSpec(streamSpec)
return previewToDetach
}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInternalTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInternalTest.kt
index eb693ac..5299376 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInternalTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/CameraInternalTest.kt
@@ -20,12 +20,12 @@
import androidx.camera.core.CameraSelector
import androidx.camera.testing.fakes.FakeCamera
import androidx.camera.testing.fakes.FakeCameraInfoInternal
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
-import com.google.common.truth.Truth.assertThat
/**
* Unit tests for [CameraInternal].
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
index bc76e238..21dd66c 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/processing/SurfaceOutputImplTest.kt
@@ -23,8 +23,8 @@
import android.util.Size
import android.view.Surface
import androidx.camera.core.CameraEffect
-import androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
import androidx.camera.core.CameraSelector.LENS_FACING_FRONT
+import androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
import androidx.camera.core.impl.utils.TransformUtils.sizeToRect
import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor
import androidx.camera.testing.fakes.FakeCamera
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
index 969f695..82b2799 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/streamsharing/StreamSharingTest.kt
@@ -29,6 +29,7 @@
import androidx.camera.core.ImageProxy
import androidx.camera.core.impl.CameraCaptureCallback
import androidx.camera.core.impl.CameraCaptureResult
+import androidx.camera.core.impl.MutableOptionsBundle
import androidx.camera.core.impl.SessionConfig
import androidx.camera.core.impl.StreamSpec
import androidx.camera.core.impl.UseCaseConfig
@@ -80,6 +81,12 @@
private lateinit var effectProcessor: FakeSurfaceProcessorInternal
private lateinit var sharingProcessor: FakeSurfaceProcessorInternal
private lateinit var effect: CameraEffect
+ private val testImplementationOption: androidx.camera.core.impl.Config.Option<Int> =
+ androidx.camera.core.impl.Config.Option.create(
+ "test.testOption",
+ Int::class.javaPrimitiveType!!
+ )
+ private val testImplementationOptionValue = 5
@Before
fun setUp() {
@@ -183,6 +190,57 @@
assertThat(result2.getCompleted().tagBundle.getTag(key)).isEqualTo(value)
}
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenCreatePipeline() {
+ // Arrange: set up StreamSharing with ImageCapture as child
+ val imageCapture = ImageCapture.Builder().build()
+ streamSharing = StreamSharing(camera, setOf(child1, imageCapture), useCaseConfigFactory)
+ streamSharing.bindToCamera(camera, null, defaultConfig)
+
+ // Act: update stream specification.
+ val streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, testImplementationOptionValue)
+ streamSharing.onSuggestedStreamSpecUpdated(
+ StreamSpec.builder(size).setImplementationOptions(streamSpecOptions).build()
+ )
+
+ // Assert: the session config gets the correct implementation options from stream
+ // specification.
+ assertThat(
+ streamSharing.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(testImplementationOptionValue)
+ }
+
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenUpdateStreamSpecImplOptions() {
+ // Arrange: set up StreamSharing with ImageCapture as child with initial stream
+ // specification implementation options.
+ val imageCapture = ImageCapture.Builder().build()
+ streamSharing = StreamSharing(camera, setOf(child1, imageCapture), useCaseConfigFactory)
+ streamSharing.bindToCamera(camera, null, defaultConfig)
+ var streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, testImplementationOptionValue)
+ streamSharing.updateSuggestedStreamSpec(
+ StreamSpec.builder(size).setImplementationOptions(streamSpecOptions).build()
+ )
+
+ // Act: update stream specification implementation options.
+ val newImplementationOptionValue = 6
+ streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, newImplementationOptionValue)
+ streamSharing.updateSuggestedStreamSpecImplementationOptions(streamSpecOptions)
+
+ // Assert: the session config gets the correct implementation options from stream
+ // specification.
+ assertThat(
+ streamSharing.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(newImplementationOptionValue)
+ }
+
private fun FakeUseCase.setTagBundleOnSessionConfigAsync(
key: String,
value: String
diff --git a/camera/camera-effects-still-portrait/build.gradle b/camera/camera-effects-still-portrait/build.gradle
index e6d14aa..647567c 100644
--- a/camera/camera-effects-still-portrait/build.gradle
+++ b/camera/camera-effects-still-portrait/build.gradle
@@ -32,7 +32,7 @@
namespace "androidx.camera.effects.stillportrait"
}
androidx {
- name = "Jetpack Camera Portrait Still Effect Library"
+ name = "Camera Effects: Still Portrait"
publish = Publish.SNAPSHOT_ONLY
inceptionYear = "2022"
runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-effects/build.gradle b/camera/camera-effects/build.gradle
index d6fc08d..858866e 100644
--- a/camera/camera-effects/build.gradle
+++ b/camera/camera-effects/build.gradle
@@ -32,7 +32,7 @@
namespace "androidx.camera.effects"
}
androidx {
- name = "Jetpack Camera Effects Library"
+ name = "Camera Effects"
publish = Publish.NONE
inceptionYear = "2022"
runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-extensions-stub/build.gradle b/camera/camera-extensions-stub/build.gradle
index de2b943..efca9c0 100644
--- a/camera/camera-extensions-stub/build.gradle
+++ b/camera/camera-extensions-stub/build.gradle
@@ -25,7 +25,7 @@
}
androidx {
- name = "Jetpack Camera Library OEM Extensions Stub"
+ name = "Camera OEM Extensions Stub"
publish = Publish.NONE
inceptionYear = "2019"
diff --git a/camera/camera-extensions-stub/src/main/AndroidManifest.xml b/camera/camera-extensions-stub/src/main/AndroidManifest.xml
deleted file mode 100644
index 9517533..0000000
--- a/camera/camera-extensions-stub/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
\ No newline at end of file
diff --git a/camera/camera-extensions/build.gradle b/camera/camera-extensions/build.gradle
index 1627bec..4cb5a01 100644
--- a/camera/camera-extensions/build.gradle
+++ b/camera/camera-extensions/build.gradle
@@ -81,7 +81,7 @@
}
androidx {
- name = "Jetpack Camera Library OEM Extensions"
+ name = "Camera Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
diff --git a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
index 6aa7222..94f0466 100644
--- a/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
+++ b/camera/camera-extensions/src/androidTest/java/androidx/camera/extensions/ExtensionsManagerTest.kt
@@ -41,6 +41,7 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@@ -51,7 +52,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(Parameterized::class)
diff --git a/camera/camera-lifecycle/build.gradle b/camera/camera-lifecycle/build.gradle
index 7d0119c..4f7b607 100644
--- a/camera/camera-lifecycle/build.gradle
+++ b/camera/camera-lifecycle/build.gradle
@@ -61,7 +61,7 @@
}
androidx {
- name = "Jetpack Camera Lifecycle Library"
+ name = "Camera Lifecycle"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Lifecycle components for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-lifecycle/src/main/AndroidManifest.xml b/camera/camera-lifecycle/src/main/AndroidManifest.xml
deleted file mode 100644
index 39dd6cb..0000000
--- a/camera/camera-lifecycle/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
index 7909211..5d9db0e 100644
--- a/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
+++ b/camera/camera-lifecycle/src/main/java/androidx/camera/lifecycle/ProcessCameraProvider.java
@@ -285,8 +285,10 @@
@VisibleForTesting
@NonNull
public ListenableFuture<Void> shutdown() {
- runOnMainSync(this::unbindAll);
- mLifecycleCameraRepository.clear();
+ runOnMainSync(() -> {
+ unbindAll();
+ mLifecycleCameraRepository.clear();
+ });
ListenableFuture<Void> shutdownFuture = mCameraX != null ? mCameraX.shutdown() :
Futures.immediateFuture(null);
diff --git a/camera/camera-mlkit-vision/build.gradle b/camera/camera-mlkit-vision/build.gradle
index f0f3bad..e569d1f 100644
--- a/camera/camera-mlkit-vision/build.gradle
+++ b/camera/camera-mlkit-vision/build.gradle
@@ -58,7 +58,7 @@
}
androidx {
- name = "Jetpack Camera MLKit Vision Library"
+ name = "Camera MLKit Vision"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2022"
runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-testing/build.gradle b/camera/camera-testing/build.gradle
index 177e3db..3c9f0b7 100644
--- a/camera/camera-testing/build.gradle
+++ b/camera/camera-testing/build.gradle
@@ -91,7 +91,7 @@
}
androidx {
- name = "Jetpack Camera Testing Library"
+ name = "Camera Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
runApiTasks = new RunApiTasks.No("Internal testing library without any release plan yet.")
inceptionYear = "2019"
diff --git a/camera/camera-testing/src/androidTest/java/androidx/camera/testing/TestImageUtilDeviceTest.kt b/camera/camera-testing/src/androidTest/java/androidx/camera/testing/TestImageUtilDeviceTest.kt
index 1045e0b..7b69b03 100644
--- a/camera/camera-testing/src/androidTest/java/androidx/camera/testing/TestImageUtilDeviceTest.kt
+++ b/camera/camera-testing/src/androidTest/java/androidx/camera/testing/TestImageUtilDeviceTest.kt
@@ -24,9 +24,9 @@
import androidx.camera.testing.TestImageUtil.createJpegBytes
import androidx.camera.testing.TestImageUtil.createJpegFakeImageProxy
import androidx.camera.testing.TestImageUtil.getAverageDiff
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
-import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/CoreAppTestUtil.java b/camera/camera-testing/src/main/java/androidx/camera/testing/CoreAppTestUtil.java
index 089ee92..13b1112 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/CoreAppTestUtil.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/CoreAppTestUtil.java
@@ -16,6 +16,7 @@
package androidx.camera.testing;
+import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import android.annotation.SuppressLint;
@@ -72,6 +73,10 @@
&& Build.MODEL.contains("Nexus 5")) {
throw new AssumptionViolatedException("Known issue, b/134894604.");
}
+
+ assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes"
+ + " the test failure.",
+ Build.MODEL.equalsIgnoreCase("wembley") && Build.VERSION.SDK_INT <= 30);
}
/**
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/ObservableExtensions.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/ObservableExtensions.kt
index aec51e1..79b54b7 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/ObservableExtensions.kt
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/ObservableExtensions.kt
@@ -21,6 +21,7 @@
import androidx.annotation.RequiresApi
import androidx.camera.core.impl.Observable
+import kotlin.coroutines.ContinuationInterceptor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.asExecutor
@@ -28,7 +29,6 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.launch
-import kotlin.coroutines.ContinuationInterceptor
public fun <T> Observable<T>.asFlow(): Flow<T?> = callbackFlow {
val observer = object : Observable.Observer<T> {
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManager.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManager.java
index b3ff181..bf73e16 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManager.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManager.java
@@ -23,6 +23,7 @@
import static com.google.common.primitives.Ints.asList;
+import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
@@ -84,8 +85,10 @@
@NonNull
@Override
- public Map<UseCaseConfig<?>, StreamSpec> getSuggestedStreamSpecs(
- @CameraMode.Mode int cameraMode, @NonNull String cameraId,
+ public Pair<Map<UseCaseConfig<?>, StreamSpec>, Map<AttachedSurfaceInfo, StreamSpec>>
+ getSuggestedStreamSpecs(
+ @CameraMode.Mode int cameraMode,
+ @NonNull String cameraId,
@NonNull List<AttachedSurfaceInfo> existingSurfaces,
@NonNull Map<UseCaseConfig<?>, List<Size>> newUseCaseConfigsSupportedSizeMap) {
List<UseCaseConfig<?>> newUseCaseConfigs =
@@ -106,7 +109,7 @@
suggestedStreamSpecs.put(useCaseConfig, streamSpec);
}
- return suggestedStreamSpecs;
+ return new Pair<>(suggestedStreamSpecs, new HashMap<>());
}
/**
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
index 12a104a..8902d29 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeUseCaseConfig.java
@@ -45,9 +45,11 @@
public class FakeUseCaseConfig implements UseCaseConfig<FakeUseCase>, ImageOutputConfig {
private final Config mConfig;
+ private final CaptureType mCaptureType;
- FakeUseCaseConfig(Config config) {
+ FakeUseCaseConfig(Config config, CaptureType captureType) {
mConfig = config;
+ mCaptureType = captureType;
}
@NonNull
@@ -62,6 +64,12 @@
INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE);
}
+ @NonNull
+ @Override
+ public CaptureType getCaptureType() {
+ return mCaptureType;
+ }
+
/** Builder for an empty Config */
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public static final class Builder implements
@@ -103,7 +111,7 @@
@NonNull
@Override
public FakeUseCaseConfig getUseCaseConfig() {
- return new FakeUseCaseConfig(OptionsBundle.from(mOptionsBundle));
+ return new FakeUseCaseConfig(OptionsBundle.from(mOptionsBundle), mCaptureType);
}
@Override
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeVideoEncoderInfo.kt b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeVideoEncoderInfo.kt
index f1f27d5..ac8b164 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeVideoEncoderInfo.kt
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeVideoEncoderInfo.kt
@@ -22,41 +22,41 @@
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
class FakeVideoEncoderInfo(
- var _supportedWidths: Range<Int> = Range.create(0, Integer.MAX_VALUE),
- var _supportedHeights: Range<Int> = Range.create(0, Integer.MAX_VALUE),
- var _widthAlignment: Int = 2,
- var _heightAlignment: Int = 2,
- var _supportedBitrateRange: Range<Int> = Range(1, Int.MAX_VALUE)
+ @JvmField var supportedWidths: Range<Int> = Range.create(0, Integer.MAX_VALUE),
+ @JvmField var supportedHeights: Range<Int> = Range.create(0, Integer.MAX_VALUE),
+ @JvmField var widthAlignment: Int = 2,
+ @JvmField var heightAlignment: Int = 2,
+ @JvmField var supportedBitrateRange: Range<Int> = Range(1, Int.MAX_VALUE)
) : FakeEncoderInfo(), VideoEncoderInfo {
override fun isSizeSupported(width: Int, height: Int) =
- _supportedWidths.contains(width) && _supportedHeights.contains(height) &&
- width.mod(_widthAlignment) == 0 && height.mod(_heightAlignment) == 0
+ supportedWidths.contains(width) && supportedHeights.contains(height) &&
+ width.mod(widthAlignment) == 0 && height.mod(heightAlignment) == 0
override fun getSupportedWidths(): Range<Int> {
- return _supportedWidths
+ return supportedWidths
}
override fun getSupportedHeights(): Range<Int> {
- return _supportedHeights
+ return supportedHeights
}
override fun getSupportedWidthsFor(height: Int): Range<Int> {
- return _supportedWidths
+ return supportedWidths
}
override fun getSupportedHeightsFor(width: Int): Range<Int> {
- return _supportedHeights
+ return supportedHeights
}
override fun getWidthAlignment(): Int {
- return _widthAlignment
+ return widthAlignment
}
override fun getHeightAlignment(): Int {
- return _heightAlignment
+ return heightAlignment
}
override fun getSupportedBitrateRange(): Range<Int> {
- return _supportedBitrateRange
+ return supportedBitrateRange
}
}
\ No newline at end of file
diff --git a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java
index b5ba2a4..d60a5de 100644
--- a/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java
+++ b/camera/camera-testing/src/test/java/androidx/camera/testing/fakes/FakeCameraDeviceSurfaceManagerTest.java
@@ -132,12 +132,12 @@
mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs(
CameraMode.DEFAULT,
FAKE_CAMERA_ID0,
- Collections.emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig));
+ emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig)).first;
Map<UseCaseConfig<?>, StreamSpec> suggestedStreamSpecCamera1 =
mFakeCameraDeviceSurfaceManager.getSuggestedStreamSpecs(
CameraMode.DEFAULT,
FAKE_CAMERA_ID1,
- Collections.emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig));
+ emptyList(), createConfigOutputSizesMap(mFakeUseCaseConfig)).first;
assertThat(suggestedStreamSpecsCamera0.get(mFakeUseCaseConfig)).isEqualTo(
StreamSpec.builder(new Size(FAKE_WIDTH0, FAKE_HEIGHT0)).build());
diff --git a/camera/camera-testlib-extensions/build.gradle b/camera/camera-testlib-extensions/build.gradle
index 886b875..849e115 100644
--- a/camera/camera-testlib-extensions/build.gradle
+++ b/camera/camera-testlib-extensions/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "Jetpack Camera Extensions Example Library"
+ name = "Camera Extensions Example"
publish = Publish.NONE
inceptionYear = "2019"
description = "Example extension implementation for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-testlib-extensions/src/main/AndroidManifest.xml b/camera/camera-testlib-extensions/src/main/AndroidManifest.xml
deleted file mode 100644
index 9517533..0000000
--- a/camera/camera-testlib-extensions/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
\ No newline at end of file
diff --git a/camera/camera-video/build.gradle b/camera/camera-video/build.gradle
index ff70608..d62ee62 100644
--- a/camera/camera-video/build.gradle
+++ b/camera/camera-video/build.gradle
@@ -87,7 +87,7 @@
}
androidx {
- name = "Jetpack Camera Video Library"
+ name = "Camera Video"
publish = Publish.SNAPSHOT_AND_RELEASE
runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
inceptionYear = "2020"
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
index 8366234..afb86b0 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/RecorderTest.kt
@@ -16,7 +16,6 @@
package androidx.camera.video
-import androidx.camera.testing.mocks.helpers.ArgumentCaptor as ArgumentCaptorCameraX
import android.Manifest
import android.annotation.SuppressLint
import android.app.AppOpsManager
@@ -56,6 +55,7 @@
import androidx.camera.testing.SurfaceTextureProvider
import androidx.camera.testing.asFlow
import androidx.camera.testing.mocks.MockConsumer
+import androidx.camera.testing.mocks.helpers.ArgumentCaptor as ArgumentCaptorCameraX
import androidx.camera.testing.mocks.helpers.CallTimes
import androidx.camera.testing.mocks.helpers.CallTimesAtLeast
import androidx.camera.video.VideoOutput.SourceState.ACTIVE_NON_STREAMING
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoCaptureDeviceTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoCaptureDeviceTest.kt
index 5a9196e..3f32f37 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoCaptureDeviceTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoCaptureDeviceTest.kt
@@ -30,6 +30,7 @@
import androidx.camera.core.DynamicRange.BIT_DEPTH_10_BIT
import androidx.camera.core.DynamicRange.FORMAT_HLG
import androidx.camera.core.DynamicRange.HDR_UNSPECIFIED_10_BIT
+import androidx.camera.core.Preview
import androidx.camera.core.SurfaceRequest
import androidx.camera.core.impl.CameraInfoInternal
import androidx.camera.core.impl.MutableStateObservable
@@ -115,6 +116,8 @@
arrayOf(Camera2Config::class.simpleName, Camera2Config.defaultConfig()),
arrayOf(CameraPipeConfig::class.simpleName, CameraPipeConfig.defaultConfig())
)
+
+ private val DYNAMIC_RANGE_HLG10 = DynamicRange(FORMAT_HLG, BIT_DEPTH_10_BIT)
}
private val context: Context = ApplicationProvider.getApplicationContext()
@@ -390,18 +393,45 @@
@SdkSuppress(minSdkVersion = 33) // HLG10 only supported on API 33+
@Test
fun dynamicRangeHlg_selectsHlg(): Unit = runBlocking {
- val hlg10DynamicRange = DynamicRange(FORMAT_HLG, BIT_DEPTH_10_BIT)
assumeTrue(
"Device does not support HLG10",
- cameraInfo.supportedDynamicRanges.contains(hlg10DynamicRange)
+ cameraInfo.supportedDynamicRanges.contains(DYNAMIC_RANGE_HLG10)
)
testDynamicRangeSelection(
- requestedDynamicRange = hlg10DynamicRange
+ requestedDynamicRange = DYNAMIC_RANGE_HLG10
) { selectedDynamicRange ->
- assertThat(selectedDynamicRange).isEqualTo(hlg10DynamicRange)
+ assertThat(selectedDynamicRange).isEqualTo(DYNAMIC_RANGE_HLG10)
}
}
+ @SdkSuppress(minSdkVersion = 33) // HLG10 only supported on API 33+
+ @Test
+ fun dynamicRange_isSetInSessionConfig(): Unit = runBlocking {
+ // TODO(b/275632219): Disabled on camera-pipe until automatic dynamic range
+ // selection is supported
+ assumeTrue(implName != CameraPipeConfig::class.simpleName)
+ assumeTrue(
+ "Device does not support HLG10",
+ cameraInfo.supportedDynamicRanges.contains(DYNAMIC_RANGE_HLG10)
+ )
+
+ // Arrange.
+ val videoOutput = createTestVideoOutput()
+ val videoCapture = VideoCapture.Builder(videoOutput)
+ .setDynamicRange(DYNAMIC_RANGE_HLG10)
+ .build()
+
+ // Act.
+ withContext(Dispatchers.Main) {
+ cameraUseCaseAdapter.addUseCases(listOf(videoCapture))
+ }
+
+ // Assert.
+ // Wait for surface request to ensure session config was attached
+ videoOutput.nextSurfaceRequest(5, TimeUnit.SECONDS)
+ val outputConfig = videoCapture.sessionConfig.outputConfigs.first()
+ assertThat(outputConfig.dynamicRange).isEqualTo(DYNAMIC_RANGE_HLG10)
+ }
@SdkSuppress(minSdkVersion = 33) // 10-bit HDR only supported on API 33+
@Test
@@ -421,6 +451,46 @@
}
}
+ @SdkSuppress(minSdkVersion = 33) // 10-bit HDR only supported on API 33+
+ @Test
+ fun dynamicRangeHlg_selectsAndAppliesHlgForConcurrentPreview(): Unit = runBlocking {
+ // TODO(b/275632219): Disabled on camera-pipe until automatic dynamic range
+ // selection is supported
+ assumeTrue(implName != CameraPipeConfig::class.simpleName)
+ assumeTrue(
+ "Device does not support HLG10",
+ cameraInfo.supportedDynamicRanges.contains(DYNAMIC_RANGE_HLG10)
+ )
+
+ // Arrange.
+ val videoOutput = createTestVideoOutput()
+ val videoCapture = VideoCapture.Builder(videoOutput)
+ .setDynamicRange(DYNAMIC_RANGE_HLG10)
+ .build()
+ // Preview will derive dynamic range from VideoCapture since it uses
+ // DynamicRange.UNSPECIFIED by default.
+ val preview = Preview.Builder().build()
+
+ // Act.
+ val deferredSurfaceRequest = CompletableDeferred<SurfaceRequest>()
+ withContext(Dispatchers.Main) {
+ // SurfaceProvider will run on main thread
+ preview.setSurfaceProvider {
+ deferredSurfaceRequest.complete(it)
+ }
+ cameraUseCaseAdapter.addUseCases(listOf(videoCapture, preview))
+ }
+
+ // Assert.
+ val timeout = 5.seconds
+ val previewSurfaceRequest = withTimeoutOrNull(timeout) {
+ deferredSurfaceRequest.await()
+ } ?: fail("Timed out waiting for Preview SurfaceRequest. Waited $timeout.")
+ val previewOutputConfig = preview.sessionConfig.outputConfigs.first()
+ assertThat(previewSurfaceRequest.dynamicRange).isEqualTo(DYNAMIC_RANGE_HLG10)
+ assertThat(previewOutputConfig.dynamicRange).isEqualTo(DYNAMIC_RANGE_HLG10)
+ }
+
private suspend fun testDynamicRangeSelection(
requestedDynamicRange: DynamicRange? = null,
assertBlock: (selectedDynamicRange: DynamicRange) -> Unit
diff --git a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
index 7e62cf4..21b32bf 100644
--- a/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
+++ b/camera/camera-video/src/androidTest/java/androidx/camera/video/VideoRecordingTest.kt
@@ -16,11 +16,6 @@
package androidx.camera.video
-import androidx.camera.camera2.internal.compat.quirk.DeviceQuirks as Camera2DeviceQuirks
-import androidx.camera.camera2.internal.compat.quirk.ExtraCroppingQuirk as Camera2ExtraCroppingQuirk
-import androidx.camera.camera2.pipe.integration.compat.quirk.DeviceQuirks as PipeDeviceQuirks
-import androidx.camera.camera2.pipe.integration.compat.quirk.ExtraCroppingQuirk as PipeExtraCroppingQuirk
-import androidx.camera.testing.mocks.helpers.ArgumentCaptor as ArgumentCaptorCameraX
import android.Manifest
import android.content.Context
import android.graphics.Rect
@@ -34,7 +29,11 @@
import android.view.Surface
import androidx.annotation.RequiresApi
import androidx.camera.camera2.Camera2Config
+import androidx.camera.camera2.internal.compat.quirk.DeviceQuirks as Camera2DeviceQuirks
+import androidx.camera.camera2.internal.compat.quirk.ExtraCroppingQuirk as Camera2ExtraCroppingQuirk
import androidx.camera.camera2.pipe.integration.CameraPipeConfig
+import androidx.camera.camera2.pipe.integration.compat.quirk.DeviceQuirks as PipeDeviceQuirks
+import androidx.camera.camera2.pipe.integration.compat.quirk.ExtraCroppingQuirk as PipeExtraCroppingQuirk
import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera
import androidx.camera.core.CameraInfo
@@ -57,6 +56,7 @@
import androidx.camera.testing.SurfaceTextureProvider
import androidx.camera.testing.fakes.FakeLifecycleOwner
import androidx.camera.testing.mocks.MockConsumer
+import androidx.camera.testing.mocks.helpers.ArgumentCaptor as ArgumentCaptorCameraX
import androidx.camera.testing.mocks.helpers.CallTimesAtLeast
import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_NONE
import androidx.camera.video.VideoRecordEvent.Finalize.ERROR_SOURCE_INACTIVE
@@ -316,7 +316,7 @@
completeVideoRecording(videoCapture, file)
// Verify.
- verifyVideoResolution(getExpectedResolution(videoCapture), file)
+ verifyVideoResolution(getExpectedResolution(videoCapture, targetResolution), file)
// Cleanup.
instrumentation.runOnMainSync {
@@ -410,7 +410,10 @@
completeVideoRecording(videoCapture, file)
// Verify.
- verifyVideoResolution(getExpectedResolution(videoCapture), file)
+ verifyVideoResolution(
+ getExpectedResolution(videoCapture, rectToSize(videoCapture.cropRect!!)),
+ file
+ )
// Cleanup.
file.delete()
@@ -1024,11 +1027,10 @@
}
}
- private fun getExpectedResolution(videoCapture: VideoCapture<Recorder>): Size =
- rotateSize(
- rectToSize(videoCapture.cropRect!!),
- getExpectedRotation(videoCapture).contentRotation
- )
+ private fun getExpectedResolution(
+ videoCapture: VideoCapture<Recorder>,
+ resolution: Size
+ ): Size = rotateSize(resolution, getExpectedRotation(videoCapture).contentRotation)
private fun getExpectedAspectRatio(videoCapture: VideoCapture<Recorder>): Rational? {
val needRotate by lazy { is90or270(getExpectedRotation(videoCapture).contentRotation) }
diff --git a/camera/camera-video/src/main/AndroidManifest.xml b/camera/camera-video/src/main/AndroidManifest.xml
deleted file mode 100644
index 9a5f4d9..0000000
--- a/camera/camera-video/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- Copyright 2020 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 />
\ No newline at end of file
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
index 8d75923..0a0373e 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapture.java
@@ -463,11 +463,13 @@
+ "specification should be already updated and shouldn't be null.");
Preconditions.checkState(mSurfaceRequest == null, "The surface request should be null "
+ "when VideoCapture is attached.");
+ StreamSpec attachedStreamSpec = Preconditions.checkNotNull(getAttachedStreamSpec());
mStreamInfo = fetchObservableValue(getOutput().getStreamInfo(),
StreamInfo.STREAM_INFO_ANY_INACTIVE);
mSessionConfigBuilder = createPipeline(getCameraId(),
- (VideoCaptureConfig<T>) getCurrentConfig(), getAttachedStreamSpec());
- applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo);
+ (VideoCaptureConfig<T>) getCurrentConfig(), attachedStreamSpec);
+ applyStreamInfoAndStreamSpecToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo,
+ attachedStreamSpec);
updateSessionConfig(mSessionConfigBuilder.build());
// VideoCapture has to be active to apply SessionConfig's template type.
notifyActive();
@@ -508,6 +510,18 @@
clearPipeline();
}
+ /**
+ * {@inheritDoc}
+ */
+ @NonNull
+ @Override
+ @RestrictTo(Scope.LIBRARY_GROUP)
+ protected StreamSpec onSuggestedStreamSpecImplementationOptionsUpdated(@NonNull Config config) {
+ mSessionConfigBuilder.addImplementationOptions(config);
+ updateSessionConfig(mSessionConfigBuilder.build());
+ return getAttachedStreamSpec().toBuilder().setImplementationOptions(config).build();
+ }
+
@NonNull
@Override
public String toString() {
@@ -711,6 +725,9 @@
if (USE_TEMPLATE_PREVIEW_BY_QUIRK) {
sessionConfigBuilder.setTemplateType(CameraDevice.TEMPLATE_PREVIEW);
}
+ if (streamSpec.getImplementationOptions() != null) {
+ sessionConfigBuilder.addImplementationOptions(streamSpec.getImplementationOptions());
+ }
return sessionConfigBuilder;
}
@@ -762,7 +779,8 @@
if (isCurrentCamera(cameraId)) {
// Only reset the pipeline when the bound camera is the same.
mSessionConfigBuilder = createPipeline(cameraId, config, streamSpec);
- applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo);
+ applyStreamInfoAndStreamSpecToSessionConfigBuilder(mSessionConfigBuilder, mStreamInfo,
+ streamSpec);
updateSessionConfig(mSessionConfigBuilder.build());
notifyReset();
}
@@ -861,6 +879,7 @@
// Doing resetPipeline() includes notifyReset/notifyUpdated(). Doing NotifyReset()
// includes notifyUpdated(). So we just take actions on higher order item for
// optimization.
+ StreamSpec attachedStreamSpec = Preconditions.checkNotNull(getAttachedStreamSpec());
if (!StreamInfo.NON_SURFACE_STREAM_ID.contains(currentStreamInfo.getId())
&& !StreamInfo.NON_SURFACE_STREAM_ID.contains(streamInfo.getId())
&& currentStreamInfo.getId() != streamInfo.getId()) {
@@ -874,11 +893,15 @@
&& streamInfo.getId() != STREAM_ID_ERROR)) {
// If id switch to STREAM_ID_ERROR, it means VideoOutput is failed to setup video
// stream. The surface should be removed from camera. Vice versa.
- applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, streamInfo);
+ applyStreamInfoAndStreamSpecToSessionConfigBuilder(mSessionConfigBuilder,
+ streamInfo,
+ attachedStreamSpec);
updateSessionConfig(mSessionConfigBuilder.build());
notifyReset();
} else if (currentStreamInfo.getStreamState() != streamInfo.getStreamState()) {
- applyStreamInfoToSessionConfigBuilder(mSessionConfigBuilder, streamInfo);
+ applyStreamInfoAndStreamSpecToSessionConfigBuilder(mSessionConfigBuilder,
+ streamInfo,
+ attachedStreamSpec);
updateSessionConfig(mSessionConfigBuilder.build());
notifyUpdated();
}
@@ -892,8 +915,9 @@
@MainThread
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
- void applyStreamInfoToSessionConfigBuilder(@NonNull SessionConfig.Builder sessionConfigBuilder,
- @NonNull StreamInfo streamInfo) {
+ void applyStreamInfoAndStreamSpecToSessionConfigBuilder(
+ @NonNull SessionConfig.Builder sessionConfigBuilder,
+ @NonNull StreamInfo streamInfo, @NonNull StreamSpec streamSpec) {
final boolean isStreamError = streamInfo.getId() == StreamInfo.STREAM_ID_ERROR;
final boolean isStreamActive = streamInfo.getStreamState() == StreamState.ACTIVE;
if (isStreamError && isStreamActive) {
@@ -902,11 +926,12 @@
}
sessionConfigBuilder.clearSurfaces();
+ DynamicRange dynamicRange = streamSpec.getDynamicRange();
if (!isStreamError) {
if (isStreamActive) {
- sessionConfigBuilder.addSurface(mDeferrableSurface);
+ sessionConfigBuilder.addSurface(mDeferrableSurface, dynamicRange);
} else {
- sessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface);
+ sessionConfigBuilder.addNonRepeatingSurface(mDeferrableSurface, dynamicRange);
}
} // Don't attach surface when stream is invalid.
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/MediaCodecInfoReportIncorrectInfoQuirk.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/MediaCodecInfoReportIncorrectInfoQuirk.java
index 557a2a7..735a24e 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/MediaCodecInfoReportIncorrectInfoQuirk.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/MediaCodecInfoReportIncorrectInfoQuirk.java
@@ -24,6 +24,7 @@
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.os.Build;
+import android.util.Size;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -31,8 +32,10 @@
import androidx.camera.core.impl.Quirk;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.Set;
/**
* <p>QuirkSummary
@@ -126,6 +129,18 @@
return false;
}
+ /**
+ * Returns the extra supported sizes for the problematic devices if any, otherwise returns an
+ * empty set.
+ */
+ @NonNull
+ public static Set<Size> getExtraSupportedSizes() {
+ if (isFHDProblematicDevice()) {
+ return Collections.singleton(new Size(1920, 1080));
+ }
+ return Collections.emptySet();
+ }
+
private static boolean isFHDProblematicDevice() {
return INCORRECT_FHD_PROFILE_MODEL_LIST.contains(Build.MODEL.toLowerCase(Locale.US));
}
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapper.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapper.java
index 5b5778b..9f3448a 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapper.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapper.java
@@ -29,6 +29,9 @@
import androidx.camera.video.internal.encoder.VideoEncoderInfo;
import androidx.core.util.Preconditions;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Workaround to wrap the VideoEncoderInfo in order to fix the wrong information provided by
* {@link MediaCodecInfo}.
@@ -48,6 +51,10 @@
private final VideoEncoderInfo mVideoEncoderInfo;
private final Range<Integer> mSupportedWidths;
private final Range<Integer> mSupportedHeights;
+ // Extra supported sizes is used to put resolutions that are actually supported on the device
+ // but the MediaCodecInfo indicates the resolution is invalid. The most common one is
+ // 1920x1080. For resolutions in this set, #isSizeSupported(w, h) should return true.
+ private final Set<Size> mExtraSupportedSizes = new HashSet<>();
/**
* Check and wrap an input VideoEncoderInfo
@@ -89,10 +96,11 @@
} else {
toWrap = false;
}
- return toWrap ? new VideoEncoderInfoWrapper(videoEncoderInfo) : videoEncoderInfo;
+ return toWrap ? new VideoEncoderInfoWrapper(videoEncoderInfo, validSizeToCheck)
+ : videoEncoderInfo;
}
- VideoEncoderInfoWrapper(@NonNull VideoEncoderInfo videoEncoderInfo) {
+ VideoEncoderInfoWrapper(@NonNull VideoEncoderInfo videoEncoderInfo, @Nullable Size validSize) {
mVideoEncoderInfo = videoEncoderInfo;
// Ideally we should find out supported widths/heights for each problematic device.
@@ -104,6 +112,12 @@
int heightAlignment = videoEncoderInfo.getHeightAlignment();
int maxHeight = (int) Math.ceil((double) HEIGHT_4KDCI / heightAlignment) * heightAlignment;
mSupportedHeights = Range.create(heightAlignment, maxHeight);
+
+ if (validSize != null) {
+ mExtraSupportedSizes.add(validSize);
+ }
+ mExtraSupportedSizes.addAll(
+ MediaCodecInfoReportIncorrectInfoQuirk.getExtraSupportedSizes());
}
@NonNull
@@ -114,6 +128,10 @@
@Override
public boolean isSizeSupported(int width, int height) {
+ if (!mExtraSupportedSizes.isEmpty() && mExtraSupportedSizes.contains(
+ new Size(width, height))) {
+ return true;
+ }
return mSupportedWidths.contains(width)
&& mSupportedHeights.contains(height)
&& width % mVideoEncoderInfo.getWidthAlignment() == 0
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
index 02ef374..ccc85b0 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/VideoCaptureTest.kt
@@ -57,6 +57,7 @@
import androidx.camera.core.impl.EncoderProfilesProxy
import androidx.camera.core.impl.ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
import androidx.camera.core.impl.ImageOutputConfig
+import androidx.camera.core.impl.MutableOptionsBundle
import androidx.camera.core.impl.MutableStateObservable
import androidx.camera.core.impl.Observable
import androidx.camera.core.impl.StreamSpec
@@ -141,6 +142,12 @@
private lateinit var camera: FakeCamera
private var surfaceRequestsToRelease = mutableListOf<SurfaceRequest>()
private val handlersToRelease = mutableListOf<Handler>()
+ private val testImplementationOption: androidx.camera.core.impl.Config.Option<Int> =
+ androidx.camera.core.impl.Config.Option.create(
+ "test.testOption",
+ Int::class.javaPrimitiveType!!
+ )
+ private val testImplementationOptionValue = 5
@Before
fun setup() {
@@ -1276,6 +1283,28 @@
)
}
+ @Test
+ fun sessionConfigHasStreamSpecImplementationOptions_whenUpdateStreamSpecImplOptions() {
+ // Arrange.
+ setupCamera()
+ createCameraUseCaseAdapter()
+ cameraUseCaseAdapter.setEffects(listOf(createFakeEffect()))
+ val videoCapture = createVideoCapture(createVideoOutput())
+ // Act.
+ addAndAttachUseCases(videoCapture)
+ val newImplementationOptionValue = 6
+ val streamSpecOptions = MutableOptionsBundle.create()
+ streamSpecOptions.insertOption(testImplementationOption, newImplementationOptionValue)
+ videoCapture.updateSuggestedStreamSpecImplementationOptions(streamSpecOptions)
+ addAndAttachUseCases(videoCapture)
+ // Assert.
+ assertThat(
+ videoCapture.sessionConfig.implementationOptions.retrieveOption(
+ testImplementationOption
+ )
+ ).isEqualTo(newImplementationOptionValue)
+ }
+
private fun testSurfaceRequestContainsExpected(
quality: Quality = HD, // HD maps to 1280x720 (4:3)
videoEncoderInfo: VideoEncoderInfo = createVideoEncoderInfo(),
@@ -1347,10 +1376,10 @@
supportedHeights: Range<Int> = Range.create(1, Integer.MAX_VALUE),
): VideoEncoderInfo {
return FakeVideoEncoderInfo(
- _widthAlignment = widthAlignment,
- _heightAlignment = heightAlignment,
- _supportedWidths = supportedWidths,
- _supportedHeights = supportedHeights,
+ widthAlignment = widthAlignment,
+ heightAlignment = heightAlignment,
+ supportedWidths = supportedWidths,
+ supportedHeights = supportedHeights,
)
}
diff --git a/camera/camera-video/src/test/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapperTest.kt b/camera/camera-video/src/test/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapperTest.kt
index e03e90e..aa15d2a 100644
--- a/camera/camera-video/src/test/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapperTest.kt
+++ b/camera/camera-video/src/test/java/androidx/camera/video/internal/workaround/VideoEncoderInfoWrapperTest.kt
@@ -43,7 +43,7 @@
private val SUPPORTED_WIDTHS = Range.create(WIDTH_ALIGNMENT, 640)
private val SUPPORTED_HEIGHTS = Range.create(HEIGHT_ALIGNMENT, 480)
private val VALID_SIZE = Size(320, 240)
- private val INVALID_SIZE = Size(1920, 1080)
+ private val SIZE_SHOULD_BE_VALID = Size(1920, 1080)
private const val WIDTH_4KDCI = 4096
private const val HEIGHT_4KDCI = 2160
@@ -52,10 +52,10 @@
private val baseVideoEncoderInfo by lazy {
FakeVideoEncoderInfo(
- _supportedWidths = SUPPORTED_WIDTHS,
- _supportedHeights = SUPPORTED_HEIGHTS,
- _widthAlignment = WIDTH_ALIGNMENT,
- _heightAlignment = HEIGHT_ALIGNMENT,
+ supportedWidths = SUPPORTED_WIDTHS,
+ supportedHeights = SUPPORTED_HEIGHTS,
+ widthAlignment = WIDTH_ALIGNMENT,
+ heightAlignment = HEIGHT_ALIGNMENT,
)
}
@@ -86,7 +86,7 @@
arrayOf(
NONE_QUIRK_BRAND,
NONE_QUIRK_MODEL,
- INVALID_SIZE,
+ SIZE_SHOULD_BE_VALID,
true,
),
arrayOf(
@@ -125,41 +125,37 @@
@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
class WrappingMethodTest {
- private lateinit var videoEncoderInfo: VideoEncoderInfo
-
- @Before
- fun setup() {
- // Set an invalid size to enable wrapping
- videoEncoderInfo = VideoEncoderInfoWrapper.from(baseVideoEncoderInfo, INVALID_SIZE)
- assertThat(videoEncoderInfo is VideoEncoderInfoWrapper).isTrue()
- }
-
@Test
fun willNotWrapAWrapper() {
- val videoEncoderInfo2 = VideoEncoderInfoWrapper.from(videoEncoderInfo, INVALID_SIZE)
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
+ val videoEncoderInfo2 = createFakeVideoEncoderInfoWrapper(videoEncoderInfo)
assertThat(videoEncoderInfo2).isSameInstanceAs(videoEncoderInfo)
}
@Test
fun getSupportedWidths() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThat(videoEncoderInfo.supportedWidths).isEqualTo(OVERRIDDEN_SUPPORTED_WIDTHS)
assertThat(videoEncoderInfo.supportedHeights).isEqualTo(OVERRIDDEN_SUPPORTED_HEIGHTS)
}
@Test
fun getSupportedHeight() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThat(videoEncoderInfo.supportedWidths).isEqualTo(OVERRIDDEN_SUPPORTED_WIDTHS)
assertThat(videoEncoderInfo.supportedHeights).isEqualTo(OVERRIDDEN_SUPPORTED_HEIGHTS)
}
@Test
fun getSupportedHeightsFor() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThat(videoEncoderInfo.getSupportedHeightsFor(640))
.isEqualTo(OVERRIDDEN_SUPPORTED_HEIGHTS)
}
@Test
fun getSupportedHeightFor_invalidWidth() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThrows(IllegalArgumentException::class.java) {
// Too large
assertThat(videoEncoderInfo.getSupportedHeightsFor(5000))
@@ -172,12 +168,14 @@
@Test
fun getSupportedWidthsFor() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThat(videoEncoderInfo.getSupportedWidthsFor(480))
.isEqualTo(OVERRIDDEN_SUPPORTED_WIDTHS)
}
@Test
fun getSupportedWidthFor_invalidHeight() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThrows(IllegalArgumentException::class.java) {
// Too large
assertThat(videoEncoderInfo.getSupportedWidthsFor(5000))
@@ -190,15 +188,62 @@
@Test
fun isSizeSupported() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
assertThat(videoEncoderInfo.isSizeSupported(640, 480)).isTrue()
}
@Test
fun isSizeSupported_invalidSize() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper()
// Too large
assertThat(videoEncoderInfo.isSizeSupported(5000, 5000)).isFalse()
// Non alignment
assertThat(videoEncoderInfo.isSizeSupported(333, 333)).isFalse()
}
+
+ @Test
+ fun isSizeSupported_validSizeIsSupported() {
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper(
+ createFakeVideoEncoderInfo(
+ supportedWidths = Range(16, 640),
+ supportedHeights = Range(16, 480),
+ widthAlignment = 16,
+ heightAlignment = 16,
+ ), validSizeToCheck = Size(1920, 1080) // 1080 not align to 16
+ )
+ assertThat(videoEncoderInfo.isSizeSupported(1920, 1080)).isTrue()
+ }
+
+ @Test
+ fun isSizeSupported_supportFhdForFhdProblematicDevices() {
+ ReflectionHelpers.setStaticField(Build::class.java, "MODEL", "sm-a032f")
+
+ val videoEncoderInfo = createFakeVideoEncoderInfoWrapper(
+ createFakeVideoEncoderInfo(
+ supportedWidths = Range(16, 640),
+ supportedHeights = Range(16, 480),
+ widthAlignment = 16,
+ heightAlignment = 16,
+ ), null
+ )
+ assertThat(videoEncoderInfo.isSizeSupported(1920, 1080)).isTrue()
+ }
+
+ private fun createFakeVideoEncoderInfoWrapper(
+ videoEncoderInfo: VideoEncoderInfo = createFakeVideoEncoderInfo(),
+ validSizeToCheck: Size? = SIZE_SHOULD_BE_VALID,
+ ) = VideoEncoderInfoWrapper.from(videoEncoderInfo, validSizeToCheck)
+
+ private fun createFakeVideoEncoderInfo(
+ supportedWidths: Range<Int> = SUPPORTED_WIDTHS,
+ supportedHeights: Range<Int> = SUPPORTED_HEIGHTS,
+ widthAlignment: Int = WIDTH_ALIGNMENT,
+ heightAlignment: Int = HEIGHT_ALIGNMENT,
+ ) = FakeVideoEncoderInfo(
+ supportedWidths = supportedWidths,
+ supportedHeights = supportedHeights,
+ widthAlignment = widthAlignment,
+ heightAlignment = heightAlignment,
+ )
}
}
diff --git a/camera/camera-view/build.gradle b/camera/camera-view/build.gradle
index fe34a08..2476a37 100644
--- a/camera/camera-view/build.gradle
+++ b/camera/camera-view/build.gradle
@@ -80,7 +80,7 @@
namespace "androidx.camera.view"
}
androidx {
- name = "Jetpack Camera View Library"
+ name = "Camera View"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/SurfaceViewImplementationTest.kt b/camera/camera-view/src/androidTest/java/androidx/camera/view/SurfaceViewImplementationTest.kt
index a3f1971..f5fdfb6 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/SurfaceViewImplementationTest.kt
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/SurfaceViewImplementationTest.kt
@@ -32,12 +32,12 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewImplementationTest.kt b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewImplementationTest.kt
index 20d9291..25e1814 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewImplementationTest.kt
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/TextureViewImplementationTest.kt
@@ -15,14 +15,14 @@
*/
package androidx.camera.view
-import android.widget.FrameLayout
import android.graphics.SurfaceTexture
import android.os.Build
import android.util.Size
-import androidx.camera.view.PreviewViewImplementation.OnSurfaceNotInUseListener
import android.view.TextureView
+import android.widget.FrameLayout
import androidx.camera.core.SurfaceRequest
import androidx.camera.testing.fakes.FakeCamera
+import androidx.camera.view.PreviewViewImplementation.OnSurfaceNotInUseListener
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
@@ -30,14 +30,14 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
import java.lang.Exception
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/camera/camera-view/src/main/AndroidManifest.xml b/camera/camera-view/src/main/AndroidManifest.xml
deleted file mode 100644
index 39dd6cb..0000000
--- a/camera/camera-view/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/camera/camera-viewfinder-compose/api/current.txt b/camera/camera-viewfinder-compose/api/current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-viewfinder-compose/api/public_plus_experimental_current.txt b/camera/camera-viewfinder-compose/api/public_plus_experimental_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/public_plus_experimental_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-viewfinder-compose/api/res-current.txt b/camera/camera-viewfinder-compose/api/res-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/res-current.txt
diff --git a/camera/camera-viewfinder-compose/api/restricted_current.txt b/camera/camera-viewfinder-compose/api/restricted_current.txt
new file mode 100644
index 0000000..e6f50d0
--- /dev/null
+++ b/camera/camera-viewfinder-compose/api/restricted_current.txt
@@ -0,0 +1 @@
+// Signature format: 4.0
diff --git a/camera/camera-viewfinder-compose/build.gradle b/camera/camera-viewfinder-compose/build.gradle
new file mode 100644
index 0000000..3476e5e
--- /dev/null
+++ b/camera/camera-viewfinder-compose/build.gradle
@@ -0,0 +1,42 @@
+/*
+ * 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 androidx.build.LibraryType
+import androidx.build.Publish
+
+plugins {
+ id("AndroidXPlugin")
+ id("AndroidXComposePlugin")
+ id("com.android.library")
+ id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+ api(libs.kotlinStdlib)
+ // Add dependencies here
+}
+
+android {
+ namespace "androidx.camera.viewfinder.compose"
+}
+
+androidx {
+ name = "androidx.camera:camera-viewfinder-compose"
+ type = LibraryType.PUBLISHED_LIBRARY
+ publish = Publish.SNAPSHOT_AND_RELEASE
+ inceptionYear = "2023"
+ description = "Composable ViewFinder implementation for CameraX"
+}
diff --git a/camera/camera-viewfinder-compose/src/main/java/androidx/camera/androidx-camera-camera-viewfinder-compose-documentation.md b/camera/camera-viewfinder-compose/src/main/java/androidx/camera/androidx-camera-camera-viewfinder-compose-documentation.md
new file mode 100644
index 0000000..10d4659
--- /dev/null
+++ b/camera/camera-viewfinder-compose/src/main/java/androidx/camera/androidx-camera-camera-viewfinder-compose-documentation.md
@@ -0,0 +1,7 @@
+# Module root
+
+CameraX ViewFinder Compose
+
+# Package androidx.camera.viewfinder.compose
+
+Library providing a composable ViewFinder
diff --git a/camera/camera-viewfinder-core/build.gradle b/camera/camera-viewfinder-core/build.gradle
index f2a2a9e..840c124 100644
--- a/camera/camera-viewfinder-core/build.gradle
+++ b/camera/camera-viewfinder-core/build.gradle
@@ -33,9 +33,9 @@
}
androidx {
- name = "androidx.camera:camera-viewfinder-core"
+ name = "Camera ViewFinder Core"
type = LibraryType.PUBLISHED_LIBRARY
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2023"
- description = "core dependencies for viewfinder"
+ description = "Core dependencies for ViewFinder"
}
diff --git a/camera/camera-viewfinder/build.gradle b/camera/camera-viewfinder/build.gradle
index 39c752c..e77d559 100644
--- a/camera/camera-viewfinder/build.gradle
+++ b/camera/camera-viewfinder/build.gradle
@@ -80,7 +80,7 @@
}
androidx {
- name = "androidx.camera:camera-viewfinder"
+ name = "Camera ViewFinder"
publish = Publish.SNAPSHOT_AND_RELEASE
runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
inceptionYear = "2022"
diff --git a/camera/camera-viewfinder/src/test/java/androidx/camera/viewfinder/ViewfinderTransformationTest.kt b/camera/camera-viewfinder/src/test/java/androidx/camera/viewfinder/ViewfinderTransformationTest.kt
index c8e7ac1..f24e5cd 100644
--- a/camera/camera-viewfinder/src/test/java/androidx/camera/viewfinder/ViewfinderTransformationTest.kt
+++ b/camera/camera-viewfinder/src/test/java/androidx/camera/viewfinder/ViewfinderTransformationTest.kt
@@ -23,9 +23,9 @@
import android.view.Surface
import android.view.View
import androidx.camera.viewfinder.CameraViewfinder.ScaleType
-import androidx.camera.viewfinder.internal.utils.TransformUtils.sizeToVertices
import androidx.camera.viewfinder.internal.transform.Rotation.RotationValue
import androidx.camera.viewfinder.internal.transform.TransformationInfo
+import androidx.camera.viewfinder.internal.utils.TransformUtils.sizeToVertices
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import kotlin.math.roundToInt
diff --git a/camera/integration-tests/avsynctestapp/src/androidTest/java/androidx/camera/integration/avsync/model/AudioGeneratorDeviceTest.kt b/camera/integration-tests/avsynctestapp/src/androidTest/java/androidx/camera/integration/avsync/model/AudioGeneratorDeviceTest.kt
index e42853e..75e45364 100644
--- a/camera/integration-tests/avsynctestapp/src/androidTest/java/androidx/camera/integration/avsync/model/AudioGeneratorDeviceTest.kt
+++ b/camera/integration-tests/avsynctestapp/src/androidTest/java/androidx/camera/integration/avsync/model/AudioGeneratorDeviceTest.kt
@@ -19,8 +19,8 @@
import android.content.Context
import android.media.AudioTrack
import androidx.test.core.app.ApplicationProvider
-import androidx.test.filters.LargeTest
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
diff --git a/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/model/AudioGenerator.kt b/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/model/AudioGenerator.kt
index ab9edeb..76a8be0 100644
--- a/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/model/AudioGenerator.kt
+++ b/camera/integration-tests/avsynctestapp/src/main/java/androidx/camera/integration/avsync/model/AudioGenerator.kt
@@ -25,10 +25,10 @@
import androidx.camera.core.Logger
import androidx.core.util.Preconditions.checkArgument
import androidx.core.util.Preconditions.checkArgumentNonnegative
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
import kotlin.math.pow
import kotlin.math.sin
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
private const val TAG = "AudioGenerator"
private const val DEFAULT_SAMPLE_RATE: Int = 44100
diff --git a/camera/integration-tests/camerapipetestapp/src/test/java/androidx/camera/integration/camera2/pipe/GraphDataHolderValueImplTest.kt b/camera/integration-tests/camerapipetestapp/src/test/java/androidx/camera/integration/camera2/pipe/GraphDataHolderValueImplTest.kt
index 91278a7..9b2b13e 100644
--- a/camera/integration-tests/camerapipetestapp/src/test/java/androidx/camera/integration/camera2/pipe/GraphDataHolderValueImplTest.kt
+++ b/camera/integration-tests/camerapipetestapp/src/test/java/androidx/camera/integration/camera2/pipe/GraphDataHolderValueImplTest.kt
@@ -18,8 +18,8 @@
import androidx.camera.integration.camera2.pipe.dataholders.GraphDataHolderValueImpl
import androidx.camera.integration.camera2.pipe.dataholders.GraphDataSortedRingBuffer
-import org.junit.Test
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
class GraphDataHolderValueImplTest {
@Test(expected = IllegalArgumentException::class)
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BasicUITest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BasicUITest.kt
index 2fb1a60..5efe358 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BasicUITest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/BasicUITest.kt
@@ -19,7 +19,6 @@
import android.Manifest
import android.content.Context
import android.content.Intent
-import android.os.Build
import androidx.camera.camera2.Camera2Config
import androidx.camera.camera2.pipe.integration.CameraPipeConfig
import androidx.camera.lifecycle.ProcessCameraProvider
@@ -39,7 +38,6 @@
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
import org.junit.After
-import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
@@ -96,11 +94,6 @@
@Before
fun setUp() {
assumeTrue(CameraUtil.deviceHasCamera())
- assumeFalse(
- "See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30
- )
CoreAppTestUtil.assumeCompatibleDevice()
// Use the natural orientation throughout these tests to ensure the activity isn't
// recreated unexpectedly. This will also freeze the sensors until
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraXInitTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraXInitTest.kt
index d8b0f40..082a3dd 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraXInitTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/CameraXInitTest.kt
@@ -29,6 +29,7 @@
import androidx.test.filters.LargeTest
import androidx.test.rule.GrantPermissionRule
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import org.junit.After
@@ -38,7 +39,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit
@LargeTest
@RunWith(Parameterized::class)
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ExistingActivityLifecycleTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ExistingActivityLifecycleTest.kt
index 912d748..0c9a82a 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ExistingActivityLifecycleTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ExistingActivityLifecycleTest.kt
@@ -100,9 +100,6 @@
"Ignore Cuttlefish",
Build.MODEL.contains("Cuttlefish")
)
- Assume.assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30)
Assume.assumeTrue(CameraUtil.deviceHasCamera())
CoreAppTestUtil.assumeCompatibleDevice()
// Clear the device UI and check if there is no dialog or lock screen on the top of the
diff --git a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
index 5402bfe..1208c6a 100644
--- a/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
+++ b/camera/integration-tests/coretestapp/src/androidTest/java/androidx/camera/integration/core/ImageCaptureTest.kt
@@ -68,6 +68,7 @@
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.testing.CameraPipeConfigTestRule
import androidx.camera.testing.CameraUtil
+import androidx.camera.testing.CoreAppTestUtil
import androidx.camera.testing.SurfaceTextureProvider
import androidx.camera.testing.fakes.FakeLifecycleOwner
import androidx.camera.testing.fakes.FakeSessionProcessor
@@ -98,7 +99,6 @@
import org.junit.Assume.assumeNotNull
import org.junit.Assume.assumeTrue
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
@@ -150,9 +150,7 @@
@Before
fun setUp(): Unit = runBlocking {
- assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30)
+ CoreAppTestUtil.assumeCompatibleDevice()
assumeTrue(CameraUtil.hasCameraWithLensFacing(BACK_LENS_FACING))
createDefaultPictureFolderIfNotExist()
ProcessCameraProvider.configureInstance(cameraXConfig)
@@ -1580,8 +1578,13 @@
}
@Test
- @Ignore("b/280379397")
fun unbindVideoCaptureWithoutStartingRecorder_imageCapturingShouldSuccess() = runBlocking {
+ assumeTrue("b/280379397", implName != Camera2Config::class.simpleName)
+ assumeTrue(
+ "b/280560222: takePicture request is discarded if UseCaseCamera is recreated",
+ implName != CameraPipeConfig::class.simpleName
+ )
+
// Arrange.
val imageCapture = ImageCapture.Builder().build()
val videoStreamReceived = CompletableDeferred<Boolean>()
diff --git a/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/ImageCaptureTask.kt b/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/ImageCaptureTask.kt
index c7f3812..b032578 100644
--- a/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/ImageCaptureTask.kt
+++ b/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/ImageCaptureTask.kt
@@ -25,12 +25,12 @@
import androidx.camera.view.CameraController.IMAGE_CAPTURE
import androidx.camera.view.LifecycleCameraController
import androidx.core.content.ContextCompat
-import kotlinx.coroutines.withContext
import java.io.File
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
/**
* Diagnosis task that utilizes ImageCapture use case
diff --git a/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/MainActivity.kt b/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/MainActivity.kt
index 6eec96a..4327c6d 100644
--- a/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/MainActivity.kt
+++ b/camera/integration-tests/diagnosetestapp/src/main/java/androidx/camera/integration/diagnose/MainActivity.kt
@@ -32,10 +32,12 @@
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
+import androidx.camera.mlkit.vision.MlKitAnalyzer
import androidx.camera.video.MediaStoreOutputOptions
import androidx.camera.video.Recording
import androidx.camera.video.VideoRecordEvent
import androidx.camera.view.CameraController
+import androidx.camera.view.CameraController.IMAGE_ANALYSIS
import androidx.camera.view.CameraController.IMAGE_CAPTURE
import androidx.camera.view.CameraController.VIDEO_CAPTURE
import androidx.camera.view.LifecycleCameraController
@@ -44,18 +46,16 @@
import androidx.camera.view.video.ExperimentalVideo
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
-import java.text.SimpleDateFormat
-import java.util.Locale
-import java.util.concurrent.ExecutorService
-import androidx.camera.mlkit.vision.MlKitAnalyzer
-import androidx.camera.view.CameraController.IMAGE_ANALYSIS
import androidx.core.util.Preconditions
import androidx.lifecycle.lifecycleScope
import com.google.android.material.tabs.TabLayout
import com.google.mlkit.vision.barcode.BarcodeScanner
import com.google.mlkit.vision.barcode.BarcodeScanning
import java.io.IOException
+import java.text.SimpleDateFormat
+import java.util.Locale
import java.util.concurrent.Executor
+import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.asCoroutineDispatcher
diff --git a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DataStoreTest.kt b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DataStoreTest.kt
index 870902d..b2ca7af 100644
--- a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DataStoreTest.kt
+++ b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DataStoreTest.kt
@@ -22,6 +22,7 @@
import android.graphics.Color
import android.os.Build
import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
@@ -30,7 +31,6 @@
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
-import com.google.common.truth.Truth.assertThat
@RunWith(RobolectricTestRunner::class)
@Config(minSdk = Build.VERSION_CODES.M, maxSdk = 32)
diff --git a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DiagnosisTest.kt b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DiagnosisTest.kt
index 81d17de..e6af322 100644
--- a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DiagnosisTest.kt
+++ b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/DiagnosisTest.kt
@@ -23,6 +23,7 @@
import androidx.camera.testing.fakes.FakeLifecycleOwner
import androidx.camera.view.LifecycleCameraController
import androidx.test.core.app.ApplicationProvider
+import com.google.common.truth.Truth.assertThat
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
@@ -31,7 +32,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
diff --git a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/FakeTextAndImageSavingTask.kt b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/FakeTextAndImageSavingTask.kt
index aec614a..f5837dc 100644
--- a/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/FakeTextAndImageSavingTask.kt
+++ b/camera/integration-tests/diagnosetestapp/src/test/java/androidx/camera/integration/diagnose/FakeTextAndImageSavingTask.kt
@@ -19,7 +19,6 @@
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color.BLUE
-
import androidx.camera.view.LifecycleCameraController
class FakeTextAndImageSavingTask : DiagnosisTask("FakeTextAndImageSavingTask") {
diff --git a/camera/integration-tests/timingtestapp/src/androidTest/java/androidx/camera/integration/antelope/AntelopeInstrumentedTests.kt b/camera/integration-tests/timingtestapp/src/androidTest/java/androidx/camera/integration/antelope/AntelopeInstrumentedTests.kt
index 72e1b67..0b87c9a 100644
--- a/camera/integration-tests/timingtestapp/src/androidTest/java/androidx/camera/integration/antelope/AntelopeInstrumentedTests.kt
+++ b/camera/integration-tests/timingtestapp/src/androidTest/java/androidx/camera/integration/antelope/AntelopeInstrumentedTests.kt
@@ -23,35 +23,35 @@
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.hardware.camera2.CameraMetadata
-import android.preference.PreferenceManager
-import androidx.test.espresso.Espresso.onView
-import androidx.test.espresso.matcher.ViewMatchers.withId
-import androidx.test.espresso.IdlingRegistry
-import org.junit.Rule
-import androidx.test.rule.ActivityTestRule
-import androidx.test.rule.GrantPermissionRule
-import org.junit.Assert
-import org.junit.Test
-import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
-import org.junit.Before
import android.os.Environment
+import android.preference.PreferenceManager
import androidx.appcompat.app.AppCompatActivity
-import androidx.test.espresso.IdlingPolicies
-import androidx.test.espresso.assertion.ViewAssertions.matches
-import java.io.File
-import androidx.test.espresso.matcher.ViewMatchers.withSubstring
-import androidx.test.filters.MediumTest
-import androidx.test.filters.LargeTest
-import org.junit.Assume.assumeTrue
-import org.junit.FixMethodOrder
-import org.junit.runners.MethodSorters
-import java.util.concurrent.TimeUnit
import androidx.camera.integration.antelope.MainActivity.Companion.antelopeIdlingResource
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.IdlingPolicies
+import androidx.test.espresso.IdlingRegistry
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.espresso.matcher.ViewMatchers.withSubstring
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
-import org.junit.After
-import org.junit.runner.RunWith
+import androidx.test.filters.LargeTest
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.rule.ActivityTestRule
+import androidx.test.rule.GrantPermissionRule
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.util.concurrent.TimeUnit
+import org.junit.After
+import org.junit.Assert
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
const val PREVIEW_BUFFER = "1500"
diff --git a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/CustomLifecycle.kt b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/CustomLifecycle.kt
index 10efb75..a68e4f2 100644
--- a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/CustomLifecycle.kt
+++ b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/CustomLifecycle.kt
@@ -18,10 +18,10 @@
import android.os.Handler
import android.os.Looper
+import androidx.camera.integration.antelope.MainActivity.Companion.logd
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
-import androidx.camera.integration.antelope.MainActivity.Companion.logd
/**
* Camera X normally handles lifecycle events itself. Optimizations in the API make it difficult
diff --git a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/TestUtils.kt b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/TestUtils.kt
index bc16441..e327e0e 100644
--- a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/TestUtils.kt
+++ b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/TestUtils.kt
@@ -17,11 +17,11 @@
package androidx.camera.integration.antelope
import androidx.camera.integration.antelope.MainActivity.Companion.antelopeIdlingResource
-import com.google.common.math.Stats
import androidx.camera.integration.antelope.MainActivity.Companion.cameraParams
import androidx.camera.integration.antelope.MainActivity.Companion.isSingleTestRunning
import androidx.camera.integration.antelope.MainActivity.Companion.logd
import androidx.camera.integration.antelope.MainActivity.Companion.testsRemaining
+import com.google.common.math.Stats
import java.text.SimpleDateFormat
import java.util.Calendar
import kotlin.collections.ArrayList
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureLockedOrientationTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureLockedOrientationTest.kt
index b8d8429..f7078e5 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureLockedOrientationTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureLockedOrientationTest.kt
@@ -16,11 +16,10 @@
package androidx.camera.integration.uiwidgets.rotations
-import android.os.Build
+import androidx.camera.testing.CoreAppTestUtil
import androidx.test.core.app.ActivityScenario
import androidx.test.filters.LargeTest
import org.junit.After
-import org.junit.Assume
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -56,11 +55,7 @@
@Before
fun before() {
- Assume.assumeFalse(
- "See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30
- )
+ CoreAppTestUtil.assumeCompatibleDevice()
setUp(lensFacing)
}
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureOrientationConfigChangesTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureOrientationConfigChangesTest.kt
index 1ff8e45..782127b 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureOrientationConfigChangesTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureOrientationConfigChangesTest.kt
@@ -19,6 +19,7 @@
import android.os.Build
import android.view.Surface
import android.view.View
+import androidx.camera.testing.CoreAppTestUtil
import androidx.test.core.app.ActivityScenario
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
@@ -76,10 +77,7 @@
"redmi note 8"
).contains(Build.MODEL.lowercase(Locale.US)) && rotation == Surface.ROTATION_180
)
- Assume.assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30)
-
+ CoreAppTestUtil.assumeCompatibleDevice()
setUp(lensFacing)
}
diff --git a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureUnlockedOrientationTest.kt b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureUnlockedOrientationTest.kt
index aaedb05..94d4e55 100644
--- a/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureUnlockedOrientationTest.kt
+++ b/camera/integration-tests/uiwidgetstestapp/src/androidTest/java/androidx/camera/integration/uiwidgets/rotations/ImageCaptureUnlockedOrientationTest.kt
@@ -17,16 +17,15 @@
package androidx.camera.integration.uiwidgets.rotations
import android.app.Instrumentation
-import android.os.Build
import androidx.camera.core.CameraSelector
import androidx.camera.integration.uiwidgets.rotations.CameraActivity.Companion.IMAGE_CAPTURE_MODE_FILE
import androidx.camera.integration.uiwidgets.rotations.CameraActivity.Companion.IMAGE_CAPTURE_MODE_IN_MEMORY
import androidx.camera.integration.uiwidgets.rotations.CameraActivity.Companion.IMAGE_CAPTURE_MODE_MEDIA_STORE
import androidx.camera.integration.uiwidgets.rotations.CameraActivity.Companion.IMAGE_CAPTURE_MODE_OUTPUT_STREAM
+import androidx.camera.testing.CoreAppTestUtil
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.After
-import org.junit.Assume.assumeFalse
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -89,9 +88,7 @@
@Before
fun before() {
- assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30)
+ CoreAppTestUtil.assumeCompatibleDevice()
setUp(lensFacing)
}
diff --git a/camera/integration-tests/viewtestapp/src/androidTest/java/androidx/camera/integration/view/CameraControllerFragmentTest.kt b/camera/integration-tests/viewtestapp/src/androidTest/java/androidx/camera/integration/view/CameraControllerFragmentTest.kt
index b7d5960..17631cd 100644
--- a/camera/integration-tests/viewtestapp/src/androidTest/java/androidx/camera/integration/view/CameraControllerFragmentTest.kt
+++ b/camera/integration-tests/viewtestapp/src/androidTest/java/androidx/camera/integration/view/CameraControllerFragmentTest.kt
@@ -115,9 +115,7 @@
@Before
fun setup() {
- assumeFalse("See b/152082918, Wembley Api30 has a libjpeg issue which causes" +
- " the test failure.",
- Build.MODEL.equals("wembley", ignoreCase = true) && Build.VERSION.SDK_INT <= 30)
+ CoreAppTestUtil.assumeCompatibleDevice()
// Clear the device UI and check if there is no dialog or lock screen on the top of the
// window before start the test.
CoreAppTestUtil.prepareDeviceUI(instrumentation)
diff --git a/car/app/app-automotive/build.gradle b/car/app/app-automotive/build.gradle
index a496e2d..7361f0e 100644
--- a/car/app/app-automotive/build.gradle
+++ b/car/app/app-automotive/build.gradle
@@ -72,7 +72,7 @@
}
androidx {
- name = "Android for Cars App Library Automotive Extension"
+ name = "Android for Cars App Automotive Extension"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Automotive OS specific functionality to build navigation, parking, and charging apps for cars"
diff --git a/car/app/app-automotive/src/main/res/values-ky/strings.xml b/car/app/app-automotive/src/main/res/values-ky/strings.xml
index 90f8f6b2..db88152 100644
--- a/car/app/app-automotive/src/main/res/values-ky/strings.xml
+++ b/car/app/app-automotive/src/main/res/values-ky/strings.xml
@@ -21,8 +21,8 @@
<string name="error_action_update_host" msgid="4802951804749609593">"Жаңыртууларды карап көрүү"</string>
<string name="error_action_retry" msgid="985347670495166517">"Кайталоо"</string>
<string name="error_message_client_side_error" msgid="3323186720368387787">"Колдонмодо ката кетти. Бул катаны колдонмонун иштеп чыгуучусуна кабарлаңыз"</string>
- <string name="error_message_host_error" msgid="5484419926049675696">"Тутум катасы"</string>
- <string name="error_message_host_connection_lost" msgid="5723205987837759151">"Тутум убактылуу жеткиликсиз"</string>
+ <string name="error_message_host_error" msgid="5484419926049675696">"Система катасы"</string>
+ <string name="error_message_host_connection_lost" msgid="5723205987837759151">"Система убактылуу жеткиликсиз"</string>
<string name="error_message_host_not_found" msgid="3241065067065670113">"Системаны жаңыртуу керек"</string>
<string name="error_message_host_incompatible" msgid="160406216155183851">"Системаны жаңыртуу керек"</string>
<string name="error_message_multiple_hosts" msgid="2591031904206928207">"Шайкеш келбеген тутум"</string>
diff --git a/car/app/app-projected/build.gradle b/car/app/app-projected/build.gradle
index 5754a49..454cbec 100644
--- a/car/app/app-projected/build.gradle
+++ b/car/app/app-projected/build.gradle
@@ -60,7 +60,7 @@
}
androidx {
- name = "Android for Cars App Library Projected Extension"
+ name = "Android for Cars App Projected Extension"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Android Auto Projected specific funationaltiy to build navigation, parking, and charging apps for cars"
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ky/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ky/strings.xml
index 2452cc4..e753de6 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ky/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ky/strings.xml
@@ -123,7 +123,7 @@
<string name="pop_to_prefix" msgid="4288884615669751608">"Кыска убакытка токтотуу"</string>
<string name="pop_to_title" msgid="3924696281273379455">"Кыска убакытка токтотуу демосу"</string>
<string name="package_not_found_error_msg" msgid="7525619456883627939">"Топтом табылган жок."</string>
- <string name="permissions_granted_msg" msgid="2348556088141992714">"Бардык уруксаттар берилди. Уруксаттарга мүмкүнчүлүктү Жөндөөлөрдөн жабыңыз."</string>
+ <string name="permissions_granted_msg" msgid="2348556088141992714">"Бардык уруксаттар берилди. Уруксаттарга мүмкүнчүлүктү Параметрлерден жабыңыз."</string>
<string name="needs_access_msg_prefix" msgid="2204136858798832382">"Колдонмого төмөнкү уруксаттар керек:\n"</string>
<string name="phone_screen_permission_msg" msgid="3599815596923367256">"Телефондун экранындагы Уруксат берүү"</string>
<string name="enable_location_permission_on_device_msg" msgid="472752487966156897">"Түзмөктө Жайгашкан жер уруксаттарын иштетүү"</string>
diff --git a/car/app/app/build.gradle b/car/app/app/build.gradle
index 43d2789..e31bbf1 100644
--- a/car/app/app/build.gradle
+++ b/car/app/app/build.gradle
@@ -100,7 +100,7 @@
}
androidx {
- name = "Android for Cars App Library"
+ name = "Android for Cars App"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
description = "Build navigation, parking, and charging apps for Android Auto"
diff --git a/cardview/cardview/build.gradle b/cardview/cardview/build.gradle
index 239abf1..13cc235 100644
--- a/cardview/cardview/build.gradle
+++ b/cardview/cardview/build.gradle
@@ -11,7 +11,7 @@
}
androidx {
- name = "Android Support CardView"
+ name = "CardView"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2011"
description = "Android Support CardView"
diff --git a/cardview/cardview/src/main/AndroidManifest.xml b/cardview/cardview/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/cardview/cardview/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/collection/collection-benchmark/build.gradle b/collection/collection-benchmark/build.gradle
index dc0cf11..931098c 100644
--- a/collection/collection-benchmark/build.gradle
+++ b/collection/collection-benchmark/build.gradle
@@ -105,7 +105,7 @@
}
androidx {
- name = "AndroidX Collections Benchmarks (Android / iOS)"
+ name = "Collections Benchmarks (Android / iOS)"
inceptionYear = "2022"
description = "AndroidX Collections Benchmarks (Android / iOS)"
}
diff --git a/collection/collection-benchmark/src/androidMain/AndroidManifest.xml b/collection/collection-benchmark/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/collection/collection-benchmark/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/collection/collection/api/current.ignore b/collection/collection/api/current.ignore
index 7be6378..3ee4c0b 100644
--- a/collection/collection/api/current.ignore
+++ b/collection/collection/api/current.ignore
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+ChangedAbstract: androidx.collection.ArraySet#size():
+ Method androidx.collection.ArraySet.size has changed 'abstract' qualifier
+
+
ChangedType: androidx.collection.ArraySet#iterator():
Method androidx.collection.ArraySet.iterator has changed return type from java.util.Iterator<E!> to java.util.Iterator<E>
ChangedType: androidx.collection.LongSparseArray#clone():
@@ -25,9 +29,5 @@
Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
Removed constructor androidx.collection.ArraySet(java.util.Collection<E>)
-RemovedMethod: androidx.collection.ArraySet#size():
- Removed method androidx.collection.ArraySet.size()
-RemovedMethod: androidx.collection.LruCache#toString():
- Removed method androidx.collection.LruCache.toString()
RemovedMethod: androidx.collection.SimpleArrayMap#SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>):
Removed constructor androidx.collection.SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>)
diff --git a/collection/collection/api/restricted_current.ignore b/collection/collection/api/restricted_current.ignore
index 7be6378..3ee4c0b 100644
--- a/collection/collection/api/restricted_current.ignore
+++ b/collection/collection/api/restricted_current.ignore
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+ChangedAbstract: androidx.collection.ArraySet#size():
+ Method androidx.collection.ArraySet.size has changed 'abstract' qualifier
+
+
ChangedType: androidx.collection.ArraySet#iterator():
Method androidx.collection.ArraySet.iterator has changed return type from java.util.Iterator<E!> to java.util.Iterator<E>
ChangedType: androidx.collection.LongSparseArray#clone():
@@ -25,9 +29,5 @@
Removed constructor androidx.collection.ArraySet(androidx.collection.ArraySet<E>)
RemovedMethod: androidx.collection.ArraySet#ArraySet(java.util.Collection<E>):
Removed constructor androidx.collection.ArraySet(java.util.Collection<E>)
-RemovedMethod: androidx.collection.ArraySet#size():
- Removed method androidx.collection.ArraySet.size()
-RemovedMethod: androidx.collection.LruCache#toString():
- Removed method androidx.collection.LruCache.toString()
RemovedMethod: androidx.collection.SimpleArrayMap#SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>):
Removed constructor androidx.collection.SimpleArrayMap(androidx.collection.SimpleArrayMap<K,V>)
diff --git a/collection/collection/build.gradle b/collection/collection/build.gradle
index 0ac4f14..47b1d5e 100644
--- a/collection/collection/build.gradle
+++ b/collection/collection/build.gradle
@@ -136,7 +136,7 @@
}
androidx {
- name = "Android Support Library collections"
+ name = "collections"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2018"
description = "Standalone efficient collections."
diff --git a/collection/integration-tests/testapp/build.gradle b/collection/integration-tests/testapp/build.gradle
index a8d529f..67a0ce6 100644
--- a/collection/integration-tests/testapp/build.gradle
+++ b/collection/integration-tests/testapp/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "AndroidX Collection Integration Tests"
+ name = "Collection Integration Tests"
publish = Publish.NONE
inceptionYear = "2021"
description = "AndroidX Collection Integration Tests"
diff --git a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/TransitionDetector.kt b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/TransitionDetector.kt
index d15d058..656461a 100644
--- a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/TransitionDetector.kt
+++ b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/TransitionDetector.kt
@@ -32,9 +32,9 @@
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiPrimitiveType
import com.intellij.psi.impl.source.PsiClassReferenceType
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.ULambdaExpression
-import java.util.EnumSet
/**
* [Detector] that checks `Transition` usages for correctness.
diff --git a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetector.kt b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetector.kt
index adcf925..16dfcd4 100644
--- a/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetector.kt
+++ b/compose/animation/animation-core-lint/src/main/java/androidx/compose/animation/core/lint/UnrememberedAnimatableDetector.kt
@@ -32,9 +32,9 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.impl.source.PsiClassReferenceType
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.util.isConstructorCall
-import java.util.EnumSet
/**
* [Detector] that checks `Animatable` calls to make sure that if they are called inside a
diff --git a/compose/animation/animation-core/benchmark/src/androidTest/java/androidx/compose/animation/core/benchmark/SpringEstimationBenchmark.kt b/compose/animation/animation-core/benchmark/src/androidTest/java/androidx/compose/animation/core/benchmark/SpringEstimationBenchmark.kt
index 7c72011..0c15e61 100644
--- a/compose/animation/animation-core/benchmark/src/androidTest/java/androidx/compose/animation/core/benchmark/SpringEstimationBenchmark.kt
+++ b/compose/animation/animation-core/benchmark/src/androidTest/java/androidx/compose/animation/core/benchmark/SpringEstimationBenchmark.kt
@@ -21,10 +21,10 @@
import androidx.compose.animation.core.estimateAnimationDurationMillis
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import kotlin.math.sqrt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.sqrt
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/animation/animation-core/build.gradle b/compose/animation/animation-core/build.gradle
index 2482074..4777d20 100644
--- a/compose/animation/animation-core/build.gradle
+++ b/compose/animation/animation-core/build.gradle
@@ -15,9 +15,8 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,65 +24,15 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
- if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.annotation:annotation:1.1.0")
-
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation("androidx.compose.ui:ui:1.2.1")
- implementation("androidx.compose.ui:ui-unit:1.2.1")
- implementation("androidx.compose.ui:ui-util:1.2.1")
- implementation(libs.kotlinStdlib)
- api(libs.kotlinCoroutinesCore)
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.kotlinCoroutinesCore)
-
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.junit)
- androidTestImplementation(project(":compose:animation:animation"))
- androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.2.1")
- androidTestImplementation(project(":compose:test-utils"))
-
- lintPublish project(":compose:animation:animation-core-lint")
-
- samples(project(":compose:animation:animation-core:animation-core-samples"))
- }
-}
-
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
-
- jvmMain {
- dependencies {
- implementation(libs.kotlinStdlib)
- api(libs.kotlinCoroutinesCore)
- }
- }
-
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(project(":compose:runtime:runtime"))
implementation(project(":compose:ui:ui"))
implementation(project(":compose:ui:ui-unit"))
@@ -91,45 +40,86 @@
implementation(libs.kotlinStdlibCommon)
api(libs.kotlinCoroutinesCore)
}
+ }
- androidMain {
- dependencies {
- api("androidx.annotation:annotation:1.1.0")
- implementation(libs.kotlinStdlib)
- }
+ commonTest {
+ dependencies {
}
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ api(libs.kotlinCoroutinesCore)
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ implementation(libs.kotlinStdlib)
+ }
+ }
+
+ if (desktopEnabled) {
desktopMain {
+ dependsOn(jvmMain)
dependencies {
implementation(libs.kotlinStdlib)
+ implementation(project(":compose:runtime:runtime"))
+ implementation(project(":compose:ui:ui"))
+ implementation(project(":compose:ui:ui-unit"))
+ implementation(project(":compose:ui:ui-util"))
}
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.testCore)
+ implementation(libs.junit)
+ implementation(project(":compose:animation:animation"))
+ implementation("androidx.compose.ui:ui-test-junit4:1.2.1")
+ implementation(project(":compose:test-utils"))
+ }
+ }
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.junit)
implementation(libs.truth)
implementation(libs.kotlinCoroutinesCore)
}
+ }
- androidAndroidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.testCore)
- implementation(libs.junit)
- implementation(project(":compose:animation:animation"))
- implementation(project(":compose:ui:ui-test-junit4"))
- implementation(project(":compose:test-utils"))
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
}
}
}
- dependencies {
- samples(project(":compose:animation:animation-core:animation-core-samples"))
- }
+}
+
+dependencies {
+ lintPublish project(":compose:animation:animation-core-lint")
}
androidx {
diff --git a/compose/animation/animation-core/samples/build.gradle b/compose/animation/animation-core/samples/build.gradle
index 160f365..735da8e 100644
--- a/compose/animation/animation-core/samples/build.gradle
+++ b/compose/animation/animation-core/samples/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Compose UI Animation Library Core Classes Samples"
+ name = "Compose UI Animation Core Classes Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Animation Core Classes"
diff --git a/compose/animation/animation-core/samples/src/main/AndroidManifest.xml b/compose/animation/animation-core/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index dc2f180..0000000
--- a/compose/animation/animation-core/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
index 0ca9c61..160a753 100644
--- a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
+++ b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatableSamples.kt
@@ -43,17 +43,17 @@
import androidx.compose.ui.composed
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
+import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
-import kotlin.math.roundToInt
@Sampled
@Composable
diff --git a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatedValueSamples.kt b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatedValueSamples.kt
index 9a76f58..110f0c6 100644
--- a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatedValueSamples.kt
+++ b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimatedValueSamples.kt
@@ -19,11 +19,11 @@
import androidx.annotation.Sampled
import androidx.compose.animation.core.AnimationVector2D
import androidx.compose.animation.core.TwoWayConverter
-import androidx.compose.animation.core.animateValueAsState
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateIntOffsetAsState
import androidx.compose.animation.core.animateOffsetAsState
+import androidx.compose.animation.core.animateValueAsState
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
diff --git a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimationSpecSamples.kt b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimationSpecSamples.kt
index 272a82d..96ce4ce 100644
--- a/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimationSpecSamples.kt
+++ b/compose/animation/animation-core/samples/src/main/java/androidx/compose/animation/core/samples/AnimationSpecSamples.kt
@@ -27,8 +27,8 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
diff --git a/compose/animation/animation-core/src/androidAndroidTest/AndroidManifest.xml b/compose/animation/animation-core/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 127ad73..0000000
--- a/compose/animation/animation-core/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright 2020 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 />
diff --git a/compose/animation/animation-core/src/androidAndroidTest/kotlin/androidx/compose/animation/core/InfiniteTransitionTest.kt b/compose/animation/animation-core/src/androidAndroidTest/kotlin/androidx/compose/animation/core/InfiniteTransitionTest.kt
index 379163f..acc232c 100644
--- a/compose/animation/animation-core/src/androidAndroidTest/kotlin/androidx/compose/animation/core/InfiniteTransitionTest.kt
+++ b/compose/animation/animation-core/src/androidAndroidTest/kotlin/androidx/compose/animation/core/InfiniteTransitionTest.kt
@@ -19,8 +19,8 @@
import androidx.compose.animation.VectorConverter
import androidx.compose.animation.animateColor
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.withFrameNanos
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/compose/animation/animation-core/src/androidMain/AndroidManifest.xml b/compose/animation/animation-core/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 34d825b..0000000
--- a/compose/animation/animation-core/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2019 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 />
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt
index a2c7d99..23f1cce 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt
@@ -19,7 +19,6 @@
import androidx.compose.ui.util.packFloats
import androidx.compose.ui.util.unpackFloat1
import androidx.compose.ui.util.unpackFloat2
-
import kotlin.math.cos
import kotlin.math.exp
import kotlin.math.sin
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
index 21c13c8..7ae4fe0 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/Transition.kt
@@ -18,6 +18,7 @@
package androidx.compose.animation.core
+import androidx.compose.animation.core.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -26,6 +27,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -37,9 +39,8 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
-import kotlin.math.max
-import androidx.compose.animation.core.internal.JvmDefaultWithCompatibility
import kotlin.jvm.JvmName
+import kotlin.math.max
/**
* This sets up a [Transition], and updates it with the target provided by [targetState]. When
@@ -231,8 +232,8 @@
* @suppress
*/
@InternalAnimationApi
- var playTimeNanos by mutableStateOf(0L)
- private var startTimeNanos by mutableStateOf(AnimationConstants.UnspecifiedTime)
+ var playTimeNanos by mutableLongStateOf(0L)
+ private var startTimeNanos by mutableLongStateOf(AnimationConstants.UnspecifiedTime)
// This gets calculated every time child is updated/added
internal var updateChildrenNeeded: Boolean by mutableStateOf(true)
@@ -495,7 +496,7 @@
private set
internal var isFinished: Boolean by mutableStateOf(true)
- private var offsetTimeNanos by mutableStateOf(0L)
+ private var offsetTimeNanos by mutableLongStateOf(0L)
private var needsReset by mutableStateOf(false)
// Changed during animation, no concerns of rolling back
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
index 39415bc..e3354a9 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorConverters.kt
@@ -20,9 +20,9 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt
index 83c39ce..bc21855 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VectorizedAnimationSpec.kt
@@ -17,8 +17,8 @@
package androidx.compose.animation.core
import androidx.compose.animation.core.AnimationConstants.DefaultDurationMillis
-import kotlin.math.min
import androidx.compose.animation.core.internal.JvmDefaultWithCompatibility
+import kotlin.math.min
/**
* [VectorizedAnimationSpec]s are stateless vector based animation specifications. They do
diff --git a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VisibilityThresholds.kt b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VisibilityThresholds.kt
index 5b27b547..7293a1b 100644
--- a/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VisibilityThresholds.kt
+++ b/compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/VisibilityThresholds.kt
@@ -20,9 +20,9 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
private const val DpVisibilityThreshold = 0.1f
diff --git a/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/AnimationTest.kt b/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/AnimationTest.kt
index c932fe1..a632f65 100644
--- a/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/AnimationTest.kt
+++ b/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/AnimationTest.kt
@@ -16,11 +16,11 @@
package androidx.compose.animation.core
+import java.lang.Long.max
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.lang.Long.max
@RunWith(JUnit4::class)
class AnimationTest {
diff --git a/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/SpringEstimationTest.kt b/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/SpringEstimationTest.kt
index 7396ca5..9b0281d 100644
--- a/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/SpringEstimationTest.kt
+++ b/compose/animation/animation-core/src/test/java/androidx/compose/animation/core/SpringEstimationTest.kt
@@ -19,12 +19,12 @@
import android.os.Build
import androidx.test.filters.SdkSuppress
import junit.framework.TestCase.assertTrue
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.sqrt
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class SpringEstimationTest(private val m: Double, private val k: Double) {
diff --git a/compose/animation/animation-graphics/build.gradle b/compose/animation/animation-graphics/build.gradle
index c6597a7..bb4c4c1 100644
--- a/compose/animation/animation-graphics/build.gradle
+++ b/compose/animation/animation-graphics/build.gradle
@@ -15,7 +15,7 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@@ -25,55 +25,15 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.annotation:annotation:1.1.0")
- api(project(":compose:animation:animation"))
- api("androidx.compose.foundation:foundation-layout:1.2.1")
- api("androidx.compose.runtime:runtime:1.2.1")
- api("androidx.compose.ui:ui:1.2.1")
- api("androidx.compose.ui:ui-geometry:1.2.1")
-
- implementation("androidx.compose.ui:ui-util:1.2.1")
- implementation(libs.kotlinStdlibCommon)
- implementation("androidx.core:core-ktx:1.5.0")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
-
- androidTestImplementation("androidx.compose.foundation:foundation:1.2.1")
- androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.2.1")
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
-
- samples(project(":compose:animation:animation-graphics:animation-graphics-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:animation:animation"))
@@ -84,39 +44,84 @@
implementation(project(":compose:ui:ui-util"))
}
+ }
+ androidMain.dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ implementation("androidx.core:core-ktx:1.5.0")
+ }
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.1.0")
- implementation("androidx.core:core-ktx:1.5.0")
+ commonTest {
+ dependencies {
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ api(project(":compose:foundation:foundation-layout"))
+ api(project(":compose:runtime:runtime"))
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-geometry"))
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.junit)
implementation(libs.truth)
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:ui:ui-test-junit4"))
+ implementation("androidx.compose.foundation:foundation:1.2.1")
+ implementation("androidx.compose.ui:ui-test-junit4:1.2.1")
implementation(project(":compose:test-utils"))
}
}
- }
- dependencies {
- samples(project(":compose:animation:animation-graphics:animation-graphics-samples"))
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
+ }
+ }
}
}
diff --git a/compose/animation/animation-graphics/samples/build.gradle b/compose/animation/animation-graphics/samples/build.gradle
index 2b0e793..c317288 100644
--- a/compose/animation/animation-graphics/samples/build.gradle
+++ b/compose/animation/animation-graphics/samples/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "AndroidX Compose UI Animation Graphics Library Samples"
+ name = "Compose UI Animation Graphics Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the Androidx Compose UI Animation Graphics Library"
diff --git a/compose/animation/animation-graphics/samples/src/main/AndroidManifest.xml b/compose/animation/animation-graphics/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 3063116..0000000
--- a/compose/animation/animation-graphics/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
--->
-<manifest />
diff --git a/compose/animation/animation-graphics/src/androidAndroidTest/AndroidManifest.xml b/compose/animation/animation-graphics/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/compose/animation/animation-graphics/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/compose/animation/animation-graphics/src/androidAndroidTest/kotlin/androidx/compose/animation/graphics/vector/compat/XmlAnimatorParserTest.kt b/compose/animation/animation-graphics/src/androidAndroidTest/kotlin/androidx/compose/animation/graphics/vector/compat/XmlAnimatorParserTest.kt
index 6906bf6..e4cbe31 100644
--- a/compose/animation/animation-graphics/src/androidAndroidTest/kotlin/androidx/compose/animation/graphics/vector/compat/XmlAnimatorParserTest.kt
+++ b/compose/animation/animation-graphics/src/androidAndroidTest/kotlin/androidx/compose/animation/graphics/vector/compat/XmlAnimatorParserTest.kt
@@ -18,7 +18,10 @@
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.RepeatMode
-import androidx.compose.ui.graphics.Color
+import androidx.compose.animation.graphics.res.AccelerateEasing
+import androidx.compose.animation.graphics.res.DecelerateEasing
+import androidx.compose.animation.graphics.res.loadAnimatorResource
+import androidx.compose.animation.graphics.test.R
import androidx.compose.animation.graphics.vector.AnimatorSet
import androidx.compose.animation.graphics.vector.ObjectAnimator
import androidx.compose.animation.graphics.vector.Ordering
@@ -27,11 +30,8 @@
import androidx.compose.animation.graphics.vector.PropertyValuesHolderFloat
import androidx.compose.animation.graphics.vector.PropertyValuesHolderInt
import androidx.compose.animation.graphics.vector.PropertyValuesHolderPath
-import androidx.compose.animation.graphics.res.AccelerateEasing
-import androidx.compose.animation.graphics.res.DecelerateEasing
-import androidx.compose.animation.graphics.res.loadAnimatorResource
-import androidx.compose.animation.graphics.test.R
import androidx.compose.animation.graphics.vector.RepeatCountInfinite
+import androidx.compose.ui.graphics.Color
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
diff --git a/compose/animation/animation-graphics/src/androidMain/AndroidManifest.xml b/compose/animation/animation-graphics/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 3063116..0000000
--- a/compose/animation/animation-graphics/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
--->
-<manifest />
diff --git a/compose/animation/animation-graphics/src/androidMain/kotlin/androidx/compose/animation/graphics/res/AnimatorResources.android.kt b/compose/animation/animation-graphics/src/androidMain/kotlin/androidx/compose/animation/graphics/res/AnimatorResources.android.kt
index ed925eb..7c51152 100644
--- a/compose/animation/animation-graphics/src/androidMain/kotlin/androidx/compose/animation/graphics/res/AnimatorResources.android.kt
+++ b/compose/animation/animation-graphics/src/androidMain/kotlin/androidx/compose/animation/graphics/res/AnimatorResources.android.kt
@@ -26,19 +26,19 @@
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.LinearOutSlowInEasing
-import androidx.compose.animation.graphics.vector.compat.AndroidVectorResources
import androidx.compose.animation.graphics.vector.Animator
+import androidx.compose.animation.graphics.vector.compat.AndroidVectorResources
import androidx.compose.animation.graphics.vector.compat.TagObjectAnimator
import androidx.compose.animation.graphics.vector.compat.TagSet
-import androidx.compose.animation.graphics.vector.compat.seekToStartTag
import androidx.compose.animation.graphics.vector.compat.parseAnimatorSet
import androidx.compose.animation.graphics.vector.compat.parseInterpolator
import androidx.compose.animation.graphics.vector.compat.parseObjectAnimator
-import org.xmlpull.v1.XmlPullParserException
+import androidx.compose.animation.graphics.vector.compat.seekToStartTag
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
+import org.xmlpull.v1.XmlPullParserException
/**
* Synchronously loads an [Animator] resource.
diff --git a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
index 9dcc564..fbef2b9 100644
--- a/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
+++ b/compose/animation/animation-lint/src/main/java/androidx/compose/animation/lint/CrossfadeDetector.kt
@@ -31,9 +31,9 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.ULambdaExpression
-import java.util.EnumSet
/**
* [Detector] that checks `Crossfade` usages for correctness.
diff --git a/compose/animation/animation/build.gradle b/compose/animation/animation/build.gradle
index 8d6b39f..f2b4f811 100644
--- a/compose/animation/animation/build.gradle
+++ b/compose/animation/animation/build.gradle
@@ -14,10 +14,8 @@
* limitations under the License.
*/
-
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,56 +23,15 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.annotation:annotation:1.1.0")
- api(project(":compose:animation:animation-core"))
- api("androidx.compose.foundation:foundation-layout:1.2.1")
- api("androidx.compose.runtime:runtime:1.2.1")
- api("androidx.compose.ui:ui:1.2.1")
- api("androidx.compose.ui:ui-geometry:1.2.1")
-
- implementation("androidx.compose.ui:ui-util:1.2.1")
- implementation(libs.kotlinStdlibCommon)
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
-
- androidTestImplementation("androidx.compose.foundation:foundation:1.2.1")
- androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.2.1")
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
-
- lintPublish project(":compose:animation:animation-lint")
-
- samples(project(":compose:animation:animation:animation-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:animation:animation-core"))
@@ -85,39 +42,84 @@
implementation(project(":compose:ui:ui-util"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+
+ api(project(":compose:foundation:foundation-layout"))
+ api(project(":compose:runtime:runtime"))
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-geometry"))
+
+ implementation(project(":compose:ui:ui-util"))
+ }
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
+ jvmTest {
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.junit)
implementation(libs.truth)
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:ui:ui-test-junit4"))
+ implementation("androidx.compose.foundation:foundation:1.2.1")
+ implementation("androidx.compose.ui:ui-test-junit4:1.2.1")
implementation(project(":compose:test-utils"))
}
}
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
- dependencies {
- samples(project(":compose:animation:animation:animation-samples"))
- }
+}
+
+dependencies {
+ lintPublish project(":compose:animation:animation-lint")
}
androidx {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/AndroidManifest.xml b/compose/animation/animation/integration-tests/animation-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index dc2f180..0000000
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/AnimatedClockDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/AnimatedClockDemo.kt
index f7b4e9ca..7bc053f 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/AnimatedClockDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/AnimatedClockDemo.kt
@@ -38,7 +38,8 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -50,8 +51,8 @@
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.isActive
import java.util.Calendar
+import kotlinx.coroutines.isActive
private class Time(hours: State<Int>, minutes: State<Int>, seconds: State<Int>) {
val hours by hours
@@ -63,9 +64,9 @@
@Composable
fun AnimatedClockDemo() {
val calendar = remember { Calendar.getInstance() }
- val seconds = remember { mutableStateOf(calendar[Calendar.SECOND]) }
- val minutes = remember { mutableStateOf(calendar[Calendar.MINUTE]) }
- val hours = remember { mutableStateOf(calendar[Calendar.HOUR_OF_DAY]) }
+ val seconds = remember { mutableIntStateOf(calendar[Calendar.SECOND]) }
+ val minutes = remember { mutableIntStateOf(calendar[Calendar.MINUTE]) }
+ val hours = remember { mutableIntStateOf(calendar[Calendar.HOUR_OF_DAY]) }
LaunchedEffect(key1 = Unit) {
// Start from 23:59:50 to give an impressive animation for all numbers
calendar.set(2020, 10, 10, 23, 59, 50)
@@ -74,9 +75,9 @@
while (isActive) {
withInfiniteAnimationFrameMillis {
calendar.timeInMillis = it - firstFrameTime + initialTime
- seconds.value = calendar[Calendar.SECOND]
- minutes.value = calendar[Calendar.MINUTE]
- hours.value = calendar[Calendar.HOUR_OF_DAY]
+ seconds.intValue = calendar[Calendar.SECOND]
+ minutes.intValue = calendar[Calendar.MINUTE]
+ hours.intValue = calendar[Calendar.HOUR_OF_DAY]
}
}
}
@@ -110,7 +111,7 @@
targetValue = ((9 - digit) * digitHeight).dp,
animationSpec = tween(moveDuration),
).value
- var circleOffset by remember { mutableStateOf(0f) }
+ var circleOffset by remember { mutableFloatStateOf(0f) }
LaunchedEffect(digit) {
if (digit == 0) return@LaunchedEffect // Don't animate for 0 as direction is reversed
animate(
@@ -124,7 +125,7 @@
animationSpec = spring(dampingRatio = 0.6f)
) { animationValue, _ -> circleOffset = animationValue }
}
- var circleStretch by remember { mutableStateOf(1f) }
+ var circleStretch by remember { mutableFloatStateOf(1f) }
LaunchedEffect(digit) {
if (digit == 0) return@LaunchedEffect // Don't animate for 0 as direction is reversed
animate(
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/ChatScreenDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/ChatScreenDemo.kt
index 565070f..8fe01ca 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/ChatScreenDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/fancy/ChatScreenDemo.kt
@@ -36,8 +36,8 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateListOf
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -113,13 +113,13 @@
@Composable
private fun animateCorner(hasSharpCorner: Boolean): MutableState<Float> {
- val state = remember { mutableStateOf(roundCornerSize) }
+ val state = remember { mutableFloatStateOf(roundCornerSize) }
LaunchedEffect(hasSharpCorner) {
animate(
- initialValue = state.value,
+ initialValue = state.floatValue,
targetValue = if (hasSharpCorner) 2f else roundCornerSize,
animationSpec = spring(stiffness = 50f, dampingRatio = 0.6f)
- ) { animationValue, _ -> state.value = animationValue }
+ ) { animationValue, _ -> state.floatValue = animationValue }
}
return state
}
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/FancyScrollingDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/FancyScrollingDemo.kt
index c1d1e00..86bc567 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/FancyScrollingDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/FancyScrollingDemo.kt
@@ -27,11 +27,11 @@
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
@@ -42,8 +42,8 @@
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import kotlinx.coroutines.launch
import kotlin.math.roundToInt
+import kotlinx.coroutines.launch
const val DEBUG = false
@@ -57,7 +57,7 @@
modifier = Modifier.padding(40.dp)
)
val animScroll = remember { Animatable(0f) }
- val itemWidth = remember { mutableStateOf(0f) }
+ val itemWidth = remember { mutableFloatStateOf(0f) }
val scope = rememberCoroutineScope()
val modifier = Modifier.draggable(
orientation = Orientation.Horizontal,
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SpringBackScrollingDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SpringBackScrollingDemo.kt
index b954194..4f02955 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SpringBackScrollingDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SpringBackScrollingDemo.kt
@@ -31,11 +31,12 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -50,9 +51,9 @@
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import kotlin.math.roundToInt
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
-import kotlin.math.roundToInt
@Preview
@Composable
@@ -64,8 +65,8 @@
fontSize = 20.sp
)
- var scrollPosition by remember { mutableStateOf(0f) }
- val itemWidth = remember { mutableStateOf(0f) }
+ var scrollPosition by remember { mutableFloatStateOf(0f) }
+ var itemWidth by remember { mutableFloatStateOf(0f) }
val mutatorMutex = remember { MutatorMutex() }
var animation by remember { mutableStateOf(AnimationState(scrollPosition)) }
@@ -96,7 +97,7 @@
val springBackTarget: Float = calculateSpringBackTarget(
target,
latestVelocityX,
- itemWidth.value
+ itemWidth
)
animation.animateDecay(exponentialDecay()) {
@@ -129,7 +130,7 @@
}
}
Canvas(gesture.fillMaxWidth().height(400.dp)) {
- itemWidth.value = size.width / 2f
+ itemWidth = size.width / 2f
if (DEBUG) {
println(
"Anim, Spring back scrolling, redrawing with new" +
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SwipeToDismissDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SwipeToDismissDemo.kt
index befd745..2f0db13 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SwipeToDismissDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/gesture/SwipeToDismissDemo.kt
@@ -25,16 +25,16 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -49,15 +49,15 @@
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import kotlin.math.roundToInt
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
-import kotlin.math.roundToInt
@Preview
@Composable
fun SwipeToDismissDemo() {
Column {
- var index by remember { mutableStateOf(0) }
+ var index by remember { mutableIntStateOf(0) }
Box(Modifier.requiredHeight(300.dp).fillMaxWidth()) {
Box(
Modifier.swipeToDismiss(index).align(Alignment.BottomCenter).requiredSize(150.dp)
@@ -82,7 +82,7 @@
private fun Modifier.swipeToDismiss(index: Int): Modifier = composed {
val animatedOffset = remember { Animatable(0f) }
- val height = remember { mutableStateOf(0) }
+ val height = remember { mutableIntStateOf(0) }
LaunchedEffect(index) {
animatedOffset.snapTo(0f)
}
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimateContentSizeDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimateContentSizeDemo.kt
index 7c036ad..15b8a2f 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimateContentSizeDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimateContentSizeDemo.kt
@@ -25,8 +25,8 @@
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSizeIn
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedContentWithContentKeyDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedContentWithContentKeyDemo.kt
index b8edc12..88ec8f8 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedContentWithContentKeyDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedContentWithContentKeyDemo.kt
@@ -31,6 +31,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
@@ -58,7 +59,7 @@
) {
if (it.type == MyScreen.Type.Count) {
holder.SaveableStateProvider(it.type) {
- var count by rememberSaveable { mutableStateOf(0) }
+ var count by rememberSaveable { mutableIntStateOf(0) }
Column(
Modifier.fillMaxSize(),
Arrangement.Center,
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedVisibilityDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedVisibilityDemo.kt
index 46e8603..0f679fd 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedVisibilityDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/layoutanimation/AnimatedVisibilityDemo.kt
@@ -49,6 +49,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -73,7 +74,7 @@
@Composable
fun AnimatedItems(animateContentSize: Boolean) {
- var itemNum by remember { mutableStateOf(0) }
+ var itemNum by remember { mutableIntStateOf(0) }
Column {
Row(
Modifier.fillMaxWidth().padding(20.dp),
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/AnimateBoundsModifierDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/AnimateBoundsModifierDemo.kt
index 789d3f4..8e60214 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/AnimateBoundsModifierDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/AnimateBoundsModifierDemo.kt
@@ -28,7 +28,8 @@
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -43,22 +44,22 @@
@Composable
fun AnimateBoundsModifierDemo() {
var height by remember {
- mutableStateOf(200)
+ mutableIntStateOf(200)
}
var left by remember {
- mutableStateOf(0)
+ mutableIntStateOf(0)
}
var top by remember {
- mutableStateOf(0)
+ mutableIntStateOf(0)
}
var right by remember {
- mutableStateOf(0)
+ mutableIntStateOf(0)
}
var bottom by remember {
- mutableStateOf(0)
+ mutableIntStateOf(0)
}
var weight by remember {
- mutableStateOf(2f)
+ mutableFloatStateOf(2f)
}
LookaheadScope {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt
index 4754294..dba31d2 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/CraneDemo.kt
@@ -39,6 +39,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.movableContentWithReceiverOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
@@ -172,7 +173,7 @@
class ProgressProviderImpl<T>(initialState: T) : ProgressProvider<T> {
override var initialState: T by mutableStateOf(initialState)
override var targetState: T by mutableStateOf(initialState)
- override var progress: Float by mutableStateOf(0f)
+ override var progress: Float by mutableFloatStateOf(0f)
}
interface ProgressProvider<T> {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithMovableContentDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithMovableContentDemo.kt
index 3100d36..f25cb8a 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithMovableContentDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithMovableContentDemo.kt
@@ -20,9 +20,9 @@
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.spring
+import androidx.compose.animation.demos.fancy.AnimatedDotsDemo
import androidx.compose.animation.demos.statetransition.InfiniteProgress
import androidx.compose.animation.demos.statetransition.InfinitePulsingHeart
-import androidx.compose.animation.demos.fancy.AnimatedDotsDemo
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithScaffold.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithScaffold.kt
index 4a0fad9..36d5ffd 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithScaffold.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithScaffold.kt
@@ -59,7 +59,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -98,7 +98,7 @@
if (hasPadding) Modifier.padding(bottom = 300.dp) else Modifier
)
) {
- var state by remember { mutableStateOf(0) }
+ var state by remember { mutableIntStateOf(0) }
val titles = listOf(
"SimpleScaffold", "W/Cutout", "SimpleSnackbar", "CustomSnackbar", "Backdrop"
)
@@ -256,7 +256,7 @@
Scaffold(
scaffoldState = scaffoldState,
floatingActionButton = {
- var clickCount by remember { mutableStateOf(0) }
+ var clickCount by remember { mutableIntStateOf(0) }
ExtendedFloatingActionButton(
text = { Text("Show snackbar") },
onClick = {
@@ -296,7 +296,7 @@
}
},
floatingActionButton = {
- var clickCount by remember { mutableStateOf(0) }
+ var clickCount by remember { mutableIntStateOf(0) }
ExtendedFloatingActionButton(
text = { Text("Show snackbar") },
onClick = {
@@ -323,7 +323,7 @@
@OptIn(ExperimentalMaterialApi::class)
fun BackdropScaffoldSample() {
val scope = rememberCoroutineScope()
- val selection = remember { mutableStateOf(1) }
+ var selection by remember { mutableIntStateOf(1) }
val scaffoldState = rememberBackdropScaffoldState(BackdropValue.Concealed)
LaunchedEffect(scaffoldState) {
scaffoldState.reveal()
@@ -345,7 +345,7 @@
}
},
actions = {
- var clickCount by remember { mutableStateOf(0) }
+ var clickCount by remember { mutableIntStateOf(0) }
IconButton(
onClick = {
// show snackbar as a suspend function
@@ -364,10 +364,10 @@
},
backLayerContent = {
LazyColumn {
- items(if (selection.value >= 3) 3 else 5) {
+ items(if (selection >= 3) 3 else 5) {
ListItem(
Modifier.clickable {
- selection.value = it
+ selection = it
scope.launch { scaffoldState.conceal() }
},
text = { Text("Select $it") }
@@ -376,7 +376,7 @@
}
},
frontLayerContent = {
- Text("Selection: ${selection.value}")
+ Text("Selection: $selection")
LazyColumn {
items(50) {
ListItem(
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithTabRowDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithTabRowDemo.kt
index 6ec1f2b..b49e42f 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithTabRowDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/lookahead/LookaheadWithTabRowDemo.kt
@@ -38,7 +38,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -79,7 +79,7 @@
@Composable
fun FancyTabs() {
- var state by remember { mutableStateOf(0) }
+ var state by remember { mutableIntStateOf(0) }
val titles = listOf("TAB 1", "TAB 2", "TAB 3")
Column {
TabRow(
@@ -124,7 +124,7 @@
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun ScrollingTextTabs() {
- var state by remember { mutableStateOf(0) }
+ var state by remember { mutableIntStateOf(0) }
val titles = listOf(
"Tab 1",
"Tab 2",
@@ -159,7 +159,7 @@
@Composable
fun ScrollingFancyIndicatorContainerTabs() {
- var state by remember { mutableStateOf(0) }
+ var state by remember { mutableIntStateOf(0) }
val titles = listOf(
"Tab 1",
"Tab 2",
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/CrossfadeDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/CrossfadeDemo.kt
index 1cf5b4a..2f77328 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/CrossfadeDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/CrossfadeDemo.kt
@@ -27,7 +27,7 @@
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.runtime.setValue
@@ -41,7 +41,7 @@
@Preview
@Composable
fun CrossfadeDemo() {
- var current by rememberSaveable { mutableStateOf(0) }
+ var current by rememberSaveable { mutableIntStateOf(0) }
Column {
Row {
tabs.forEachIndexed { index, tab ->
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/MultiDimensionalAnimationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/MultiDimensionalAnimationDemo.kt
index c3b4274..01ca017 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/MultiDimensionalAnimationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/MultiDimensionalAnimationDemo.kt
@@ -22,11 +22,12 @@
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -50,8 +51,8 @@
}
}
- var width by remember { mutableStateOf(0f) }
- var height by remember { mutableStateOf(0f) }
+ var width by remember { mutableFloatStateOf(0f) }
+ var height by remember { mutableFloatStateOf(0f) }
val transition = updateTransition(currentState)
val rect by transition.animateRect(transitionSpec = { spring(stiffness = 100f) }) {
when (it) {
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/RepeatedRotationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/RepeatedRotationDemo.kt
index ade287e..5e89ee7 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/RepeatedRotationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/statetransition/RepeatedRotationDemo.kt
@@ -20,8 +20,8 @@
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.repeatable
-import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/InfiniteAnimationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/InfiniteAnimationDemo.kt
index 9910030..b8e5bad 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/InfiniteAnimationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/InfiniteAnimationDemo.kt
@@ -27,8 +27,10 @@
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -38,7 +40,7 @@
@Preview
@Composable
fun InfiniteAnimationDemo() {
- val alpha = remember { mutableStateOf(1f) }
+ var alpha by remember { mutableFloatStateOf(1f) }
LaunchedEffect(Unit) {
animate(
initialValue = 1f,
@@ -48,7 +50,7 @@
repeatMode = RepeatMode.Reverse
)
) { value, _ ->
- alpha.value = value
+ alpha = value
}
}
Box(Modifier.fillMaxSize()) {
@@ -59,7 +61,7 @@
.graphicsLayer(
scaleX = 3.0f,
scaleY = 3.0f,
- alpha = alpha.value
+ alpha = alpha
),
tint = Color.Red
)
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/SuspendDoubleTapToLikeDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/SuspendDoubleTapToLikeDemo.kt
index 600de97..b3691cc 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/SuspendDoubleTapToLikeDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/suspendfun/SuspendDoubleTapToLikeDemo.kt
@@ -27,7 +27,7 @@
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@@ -43,8 +43,8 @@
@Preview
@Composable
fun SuspendDoubleTapToLikeDemo() {
- var alpha by remember { mutableStateOf(0f) }
- var scale by remember { mutableStateOf(0f) }
+ var alpha by remember { mutableFloatStateOf(0f) }
+ var scale by remember { mutableFloatStateOf(0f) }
val mutatorMutex = MutatorMutex()
val scope = rememberCoroutineScope()
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualaid/ColumnConfigurationDemo.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualaid/ColumnConfigurationDemo.kt
index 4b94c68..dfd5b8e 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualaid/ColumnConfigurationDemo.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualaid/ColumnConfigurationDemo.kt
@@ -27,11 +27,11 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/AnimatedContentWithInterruptions.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/AnimatedContentWithInterruptions.kt
index 4e58285..48187047 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/AnimatedContentWithInterruptions.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/AnimatedContentWithInterruptions.kt
@@ -35,7 +35,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -47,7 +47,7 @@
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun AnimatedContentWithInterruptions() {
- var count by remember { mutableStateOf(0) }
+ var count by remember { mutableIntStateOf(0) }
AnimatedContent(targetState = count, transitionSpec = {
if (targetState == 0) {
(slideInVertically { it } togetherWith fadeOut(targetAlpha = 0.88f))
diff --git a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/SeekingDebugging.kt b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/SeekingDebugging.kt
index 6b38572..21756cd 100644
--- a/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/SeekingDebugging.kt
+++ b/compose/animation/animation/integration-tests/animation-demos/src/main/java/androidx/compose/animation/demos/visualinspection/SeekingDebugging.kt
@@ -49,6 +49,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -69,7 +70,7 @@
val transition = updateTransition(true)
var entering by remember { mutableStateOf(true) }
- var progress by remember { mutableStateOf(0f) }
+ var progress by remember { mutableFloatStateOf(0f) }
Column(
Modifier.fillMaxSize().padding(10.dp),
verticalArrangement = Arrangement.spacedBy(20.dp)
diff --git a/compose/animation/animation/samples/build.gradle b/compose/animation/animation/samples/build.gradle
index d355cdf..9fd59da 100644
--- a/compose/animation/animation/samples/build.gradle
+++ b/compose/animation/animation/samples/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Compose UI Animation Library Samples"
+ name = "Compose UI Animation Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Animation Library"
diff --git a/compose/animation/animation/samples/src/main/AndroidManifest.xml b/compose/animation/animation/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index dc2f180..0000000
--- a/compose/animation/animation/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/animation/animation/src/androidAndroidTest/AndroidManifest.xml b/compose/animation/animation/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/animation/animation/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/AnimationModifierTest.kt b/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/AnimationModifierTest.kt
index fb17dc0..ae167df 100644
--- a/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/AnimationModifierTest.kt
+++ b/compose/animation/animation/src/androidAndroidTest/kotlin/androidx/compose/animation/AnimationModifierTest.kt
@@ -43,8 +43,8 @@
import junit.framework.TestCase.assertNull
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.nullValue
-import org.junit.After
import org.hamcrest.MatcherAssert.assertThat
+import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
diff --git a/compose/animation/animation/src/androidMain/AndroidManifest.xml b/compose/animation/animation/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 34d825b..0000000
--- a/compose/animation/animation/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2019 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 />
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
index 06a90b9..d1ac4ac 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedContent.kt
@@ -41,6 +41,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -196,7 +197,7 @@
* to 0f. Content with higher zIndex will be drawn over lower `zIndex`ed content. Among
* content with the same index, the target content will be placed on top.
*/
- var targetContentZIndex by mutableStateOf(targetContentZIndex)
+ var targetContentZIndex by mutableFloatStateOf(targetContentZIndex)
/**
* [sizeTransform] manages the expanding and shrinking of the container if there is any size
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
index 408246d..2e6a3b2 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimatedVisibility.kt
@@ -25,6 +25,7 @@
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.createChildTransition
import androidx.compose.animation.core.updateTransition
+import androidx.compose.animation.internal.JvmDefaultWithCompatibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
@@ -50,7 +51,6 @@
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMaxBy
import kotlinx.coroutines.flow.collect
-import androidx.compose.animation.internal.JvmDefaultWithCompatibility
/**
* [AnimatedVisibility] composable animates the appearance and disappearance of its content, as
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
index 2763366..4d49ae5 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/AnimationModifier.kt
@@ -23,10 +23,10 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.spring
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
index 2b1411e..b11c7c0 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/ColorVectorConverter.kt
@@ -21,7 +21,6 @@
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.colorspace.ColorSpace
import androidx.compose.ui.graphics.colorspace.ColorSpaces
-import kotlin.math.pow
/**
* A lambda that takes a [ColorSpace] and returns a converter that can both convert a [Color] to
@@ -32,34 +31,17 @@
{ colorSpace ->
TwoWayConverter(
convertToVector = { color ->
- // TODO: use Oklab when it is public API
- val colorXyz = color.convert(ColorSpaces.CieXyz)
- val x = colorXyz.red
- val y = colorXyz.green
- val z = colorXyz.blue
-
- val l = multiplyColumn(0, x, y, z, M1).pow(1f / 3f)
- val a = multiplyColumn(1, x, y, z, M1).pow(1f / 3f)
- val b = multiplyColumn(2, x, y, z, M1).pow(1f / 3f)
- AnimationVector4D(color.alpha, l, a, b)
+ val (l, a, b, alpha) = color.convert(ColorSpaces.Oklab)
+ AnimationVector4D(alpha, l, a, b)
},
- convertFromVector = {
- val l = it.v2.pow(3f)
- val a = it.v3.pow(3f)
- val b = it.v4.pow(3f)
-
- val x = multiplyColumn(0, l, a, b, InverseM1)
- val y = multiplyColumn(1, l, a, b, InverseM1)
- val z = multiplyColumn(2, l, a, b, InverseM1)
-
- val colorXyz = Color(
- alpha = it.v1.coerceIn(0f, 1f),
- red = x.coerceIn(-2f, 2f),
- green = y.coerceIn(-2f, 2f),
- blue = z.coerceIn(-2f, 2f),
- colorSpace = ColorSpaces.CieXyz // here we have the right color space
- )
- colorXyz.convert(colorSpace)
+ convertFromVector = { vector ->
+ Color(
+ vector.v2.coerceIn(0f, 1f), // L (red)
+ vector.v3.coerceIn(-0.5f, 0.5f), // a (blue)
+ vector.v4.coerceIn(-0.5f, 0.5f), // b (green)
+ vector.v1.coerceIn(0f, 1f), // alpha
+ ColorSpaces.Oklab
+ ).convert(colorSpace)
}
)
}
@@ -70,23 +52,5 @@
* [ColorSpace].
*/
val Color.Companion.VectorConverter:
- (colorSpace: ColorSpace) -> TwoWayConverter<Color, AnimationVector4D>
- get() = ColorToVector
-
-// These are utilities and constants to emulate converting to/from Oklab color space.
-// These can be removed when Oklab becomes public and we can use it directly in the conversion.
-private val M1 = floatArrayOf(
- 0.80405736f, 0.026893456f, 0.04586542f,
- 0.3188387f, 0.9319606f, 0.26299807f,
- -0.11419419f, 0.05105356f, 0.83999807f
-)
-
-private val InverseM1 = floatArrayOf(
- 1.2485008f, -0.032856926f, -0.057883114f,
- -0.48331892f, 1.1044513f, -0.3194066f,
- 0.19910365f, -0.07159331f, 1.202023f
-)
-
-private fun multiplyColumn(column: Int, x: Float, y: Float, z: Float, matrix: FloatArray): Float {
- return x * matrix[column] + y * matrix[3 + column] + z * matrix[6 + column]
-}
\ No newline at end of file
+ (colorSpace: ColorSpace) -> TwoWayConverter<Color, AnimationVector4D>
+ get() = ColorToVector
diff --git a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
index 93c840e..6c7d2fa 100644
--- a/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
+++ b/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/EnterExitTransition.kt
@@ -36,6 +36,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -938,7 +939,7 @@
convertFromVector = { TransformOrigin(it.v1, it.v2) }
)
-private val DefaultAlpha = mutableStateOf(1f)
+private val DefaultAlpha = mutableFloatStateOf(1f)
private val DefaultAlphaAndScaleSpring = spring<Float>(stiffness = Spring.StiffnessMediumLow)
private fun Modifier.slideInOut(
diff --git a/compose/animation/animation/src/test/kotlin/androidx/compose/animation/ConverterTest.kt b/compose/animation/animation/src/test/kotlin/androidx/compose/animation/ConverterTest.kt
index 1134f6c..ea4d100 100644
--- a/compose/animation/animation/src/test/kotlin/androidx/compose/animation/ConverterTest.kt
+++ b/compose/animation/animation/src/test/kotlin/androidx/compose/animation/ConverterTest.kt
@@ -27,10 +27,10 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import junit.framework.TestCase.assertEquals
+import kotlin.random.Random
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.random.Random
@RunWith(JUnit4::class)
class ConverterTest {
@@ -63,48 +63,46 @@
0f
)
- // all channels should clamp:
+ // all channels are clamped before conversion, the result of 3/3/3 in OkLab should be
+ // 1,0,0 in sRGB
+ val maxOkLab = Color(1.0f, 0.5f, 0.5f, 1.0f, ColorSpaces.Oklab).convert(ColorSpaces.Srgb)
assertEquals(
- 1f,
+ maxOkLab.red,
converter.convertFromVector(AnimationVector4D(1.0f, 3f, 3f, 3f)).red,
0f
)
assertEquals(
- 1f,
+ maxOkLab.green,
converter.convertFromVector(AnimationVector4D(1.0f, 3f, 3f, 3f)).green,
0f
)
assertEquals(
- 1f,
+ maxOkLab.blue,
converter.convertFromVector(AnimationVector4D(1.0f, 3f, 3f, 3f)).blue,
0f
)
- // All channel below 0.0f clamps to 0.0f and the result is black
+ // all channels are clamped before conversion, the result of -3/-3/-3 in OkLab should be
+ // 0,0,1 in sRGB
+ val minOkLab = Color(0.0f, -0.5f, -0.5f, 1.0f, ColorSpaces.Oklab).convert(ColorSpaces.Srgb)
assertEquals(
- 0f,
+ minOkLab.red,
converter.convertFromVector(AnimationVector4D(1.0f, -3f, -3f, -3f))
.red,
0f
)
assertEquals(
- 0f,
+ minOkLab.green,
converter.convertFromVector(AnimationVector4D(1.0f, -3f, -3f, -3f))
.green,
0f
)
assertEquals(
- 0f,
+ minOkLab.blue,
converter.convertFromVector(AnimationVector4D(1.0f, -3f, -3f, -3f))
.blue,
0f
)
-
- // Green channel above 1.0f clamps to 1.0f and the result is green
- assertEquals(
- converter.convertFromVector(AnimationVector4D(1.0f, 0.0f, 1.1f, 0f)),
- Color.Green
- )
}
@Test
diff --git a/compose/benchmark-utils/src/androidTest/AndroidManifest.xml b/compose/benchmark-utils/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e865f27..0000000
--- a/compose/benchmark-utils/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
- -->
-<manifest />
diff --git a/compose/benchmark-utils/src/main/java/androidx/compose/testutils/benchmark/BenchmarksExtensions.kt b/compose/benchmark-utils/src/main/java/androidx/compose/testutils/benchmark/BenchmarksExtensions.kt
index b0c29ab..b2247bd 100644
--- a/compose/benchmark-utils/src/main/java/androidx/compose/testutils/benchmark/BenchmarksExtensions.kt
+++ b/compose/benchmark-utils/src/main/java/androidx/compose/testutils/benchmark/BenchmarksExtensions.kt
@@ -20,12 +20,12 @@
import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.compose.testutils.ComposeTestCase
-import androidx.compose.ui.graphics.Canvas
import androidx.compose.testutils.ToggleableTestCase
import androidx.compose.testutils.assertNoPendingChanges
import androidx.compose.testutils.benchmark.android.AndroidTestCase
import androidx.compose.testutils.doFramesUntilNoChangesPending
import androidx.compose.testutils.recomposeAssertHadChanges
+import androidx.compose.ui.graphics.Canvas
/**
* Measures measure and layout performance of the given test case by toggling measure constraints.
diff --git a/compose/compiler/OWNERS b/compose/compiler/OWNERS
index e48b97d..51ec95d 100644
--- a/compose/compiler/OWNERS
+++ b/compose/compiler/OWNERS
@@ -3,4 +3,5 @@
chuckj@google.com
lelandr@google.com
anbailey@google.com
+ashikov@google.com
per-file settings.gradle = dustinlam@google.com, rahulrav@google.com
diff --git a/compose/compiler/compiler-daemon/integration-tests/build.gradle b/compose/compiler/compiler-daemon/integration-tests/build.gradle
index afda48a..5416516 100644
--- a/compose/compiler/compiler-daemon/integration-tests/build.gradle
+++ b/compose/compiler/compiler-daemon/integration-tests/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "AndroidX Compiler Daemon CLI Tests"
+ name = "Compiler Daemon CLI Tests"
type = LibraryType.COMPILER_DAEMON_TEST
inceptionYear = "2021"
description = "Contains test for the compose compiler daemon"
diff --git a/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/CompilerTest.kt b/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/CompilerTest.kt
index 15fa946..8b284f3 100644
--- a/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/CompilerTest.kt
+++ b/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/CompilerTest.kt
@@ -16,14 +16,14 @@
package androidx.compose.compiler.daemon
+import java.io.File
+import java.nio.file.Files
import org.jetbrains.kotlin.cli.common.ExitCode
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.io.File
-import java.nio.file.Files
@RunWith(Parameterized::class)
class CompilerTest(
diff --git a/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/DaemonProtocolTest.kt b/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/DaemonProtocolTest.kt
index a97752d..d993c1e 100644
--- a/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/DaemonProtocolTest.kt
+++ b/compose/compiler/compiler-daemon/integration-tests/src/test/kotlin/androidx/compose/compiler/daemon/DaemonProtocolTest.kt
@@ -16,9 +16,6 @@
package androidx.compose.compiler.daemon
-import org.jetbrains.kotlin.cli.common.ExitCode
-import org.junit.Assert.assertEquals
-import org.junit.Test
import java.io.ByteArrayOutputStream
import java.io.OutputStreamWriter
import java.io.PipedReader
@@ -26,6 +23,9 @@
import java.io.PrintWriter
import java.util.concurrent.CountDownLatch
import kotlin.concurrent.thread
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.junit.Assert.assertEquals
+import org.junit.Test
class DaemonProtocolTest {
diff --git a/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/Compiler.kt b/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/Compiler.kt
index 976bfa8..65757e6 100644
--- a/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/Compiler.kt
+++ b/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/Compiler.kt
@@ -16,8 +16,11 @@
package androidx.compose.compiler.daemon
+import java.io.File
+import java.nio.file.Files
import org.jetbrains.kotlin.build.DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS
import org.jetbrains.kotlin.build.report.BuildReporter
+import org.jetbrains.kotlin.build.report.DoNothingICReporter
import org.jetbrains.kotlin.build.report.metrics.DoNothingBuildMetricsReporter
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
@@ -26,13 +29,10 @@
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ClasspathChanges.ClasspathSnapshotEnabled
-import org.jetbrains.kotlin.build.report.DoNothingICReporter
+import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles
import org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner
import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory
import org.jetbrains.kotlin.incremental.withIC
-import java.io.File
-import java.nio.file.Files
-import org.jetbrains.kotlin.incremental.ClasspathSnapshotFiles
internal fun parseArgs(
args: Array<String>,
diff --git a/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/main.kt b/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/main.kt
index 20445ef..8e8f201 100644
--- a/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/main.kt
+++ b/compose/compiler/compiler-daemon/src/main/kotlin/androidx/compose/compiler/daemon/main.kt
@@ -17,11 +17,11 @@
package androidx.compose.compiler.daemon
import java.io.File
-import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
import java.io.PrintWriter
import java.lang.IllegalArgumentException
import java.net.URLDecoder
import java.nio.charset.Charset
+import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
private data class CliOptions(
val disableEmbeddedPlugin: Boolean = false,
diff --git a/compose/compiler/compiler-hosted/build.gradle b/compose/compiler/compiler-hosted/build.gradle
index fb76744..e4ce28e 100644
--- a/compose/compiler/compiler-hosted/build.gradle
+++ b/compose/compiler/compiler-hosted/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "AndroidX Compose Hosted Compiler Plugin"
+ name = "Compose Hosted Compiler Plugin"
// This is only published because that is required when exporting it to g3.
// Nobody should ever get this artifact from maven; just from studio or from source
type = LibraryType.COMPILER_PLUGIN
diff --git a/compose/compiler/compiler-hosted/integration-tests/build.gradle b/compose/compiler/compiler-hosted/integration-tests/build.gradle
index b874154..00a111c 100644
--- a/compose/compiler/compiler-hosted/integration-tests/build.gradle
+++ b/compose/compiler/compiler-hosted/integration-tests/build.gradle
@@ -82,7 +82,7 @@
}
androidx {
- name = "AndroidX Compiler CLI Tests"
+ name = "Compiler CLI Tests"
publish = Publish.NONE
inceptionYear = "2019"
description = "Contains test for the compose compiler plugin"
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractCodegenSignatureTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractCodegenSignatureTest.kt
index f0a2827..668afad 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractCodegenSignatureTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractCodegenSignatureTest.kt
@@ -20,11 +20,11 @@
import android.content.Context
import android.os.Bundle
import android.widget.LinearLayout
+import java.net.URLClassLoader
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.backend.common.output.OutputFile
-import org.robolectric.Robolectric
-import java.net.URLClassLoader
import org.junit.Assert.assertEquals
+import org.robolectric.Robolectric
fun printPublicApi(classDump: String, name: String): String {
return classDump
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractComposeDiagnosticsTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractComposeDiagnosticsTest.kt
index 2cf385c..9cc20bc 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractComposeDiagnosticsTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractComposeDiagnosticsTest.kt
@@ -16,103 +16,54 @@
package androidx.compose.compiler.plugins.kotlin
-import androidx.compose.compiler.plugins.kotlin.facade.AnalysisResult
import androidx.compose.compiler.plugins.kotlin.facade.SourceFile
import org.jetbrains.kotlin.checkers.DiagnosedRange
import org.jetbrains.kotlin.checkers.utils.CheckerTestUtil
-import org.junit.Assert
+import org.jetbrains.kotlin.utils.addToStdlib.flatGroupBy
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertThrows
abstract class AbstractComposeDiagnosticsTest : AbstractCompilerTest() {
- private class DiagnosticTestException(message: String) : Exception(message)
-
protected fun check(expectedText: String, ignoreParseErrors: Boolean = false) {
val diagnosedRanges: MutableList<DiagnosedRange> = ArrayList()
val clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges)
val errors = analyze(
listOf(SourceFile("test.kt", clearText, ignoreParseErrors))
- ).diagnostics.toMutableList()
+ ).diagnostics
- // Ensure all the expected messages are there
- val message = StringBuilder()
- val found = mutableSetOf<AnalysisResult.Diagnostic>()
- for (range in diagnosedRanges) {
- for (diagnostic in range.getDiagnostics()) {
- val reportedDiagnostics = errors.filter { it.factoryName == diagnostic.name }
- if (reportedDiagnostics.isNotEmpty()) {
- val reportedDiagnostic =
- reportedDiagnostics.find {
- it.textRanges.find {
- it.startOffset == range.start && it.endOffset == range.end
- } != null
- }
- if (reportedDiagnostic == null) {
- val firstRange = reportedDiagnostics.first().textRanges.first()
- message.append(
- " Error ${diagnostic.name} reported at ${
- firstRange.startOffset
- }-${firstRange.endOffset} but expected at ${range.start}-${range.end}\n"
- )
- message.append(
- sourceInfo(clearText, firstRange.startOffset, firstRange.endOffset)
- )
- } else {
- errors.remove(reportedDiagnostic)
- found.add(reportedDiagnostic)
- }
- } else {
- message.append(
- " Diagnostic ${diagnostic.name} not reported, expected at ${
- range.start
- }\n"
- )
- message.append(
- sourceInfo(clearText, range.start, range.end)
- )
+ val rangeToDiagnostics = errors.flatGroupBy { it.textRanges }.mapValues { entry ->
+ entry.value.map { it.factoryName }.toSet()
+ }
+ val startOffsetToGroups = rangeToDiagnostics.entries.groupBy(
+ keySelector = { it.key.startOffset },
+ valueTransform = { it.value }
+ )
+ val endOffsetsToGroups = rangeToDiagnostics.entries.groupBy(
+ keySelector = { it.key.endOffset },
+ valueTransform = { it.value }
+ )
+
+ val annotatedText = buildString {
+ for ((i, c) in clearText.withIndex()) {
+ endOffsetsToGroups[i]?.let { groups ->
+ repeat(groups.size) { append("<!>") }
}
+ startOffsetToGroups[i]?.let { groups ->
+ for (diagnostics in groups) {
+ append("<!${diagnostics.joinToString(",")}!>")
+ }
+ }
+ append(c)
}
}
- // Ensure only the expected errors are reported
- for (diagnostic in errors) {
- if (diagnostic !in found) {
- val range = diagnostic.textRanges.first()
- message.append(
- " Unexpected diagnostic ${diagnostic.factoryName} reported at ${
- range.startOffset
- }\n"
- )
- message.append(
- sourceInfo(clearText, range.startOffset, range.endOffset)
- )
- }
- }
-
- // Throw an error if anything was found that was not expected
- if (message.isNotEmpty()) throw DiagnosticTestException("Mismatched errors:\n$message")
+ assertEquals(expectedText, annotatedText)
}
protected fun checkFail(expectedText: String) {
- Assert.assertThrows(DiagnosticTestException::class.java) {
+ assertThrows(AssertionError::class.java) {
check(expectedText)
}
}
-
- private fun String.lineStart(offset: Int): Int {
- return this.lastIndexOf('\n', offset) + 1
- }
-
- private fun String.lineEnd(offset: Int): Int {
- val result = this.indexOf('\n', offset)
- return if (result < 0) this.length else result
- }
-
- // Return the source line that contains the given range with the range underlined with '~'s
- private fun sourceInfo(clearText: String, start: Int, end: Int): String {
- val lineStart = clearText.lineStart(start)
- val lineEnd = clearText.lineEnd(start)
- val displayEnd = if (end > lineEnd) lineEnd else end
- return " " + clearText.substring(lineStart, lineEnd) + "\n" +
- " ".repeat(2 + start - lineStart) + "~".repeat(displayEnd - start) + "\n"
- }
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractLoweringTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractLoweringTests.kt
index 11a509a..7ce1dbf 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractLoweringTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractLoweringTests.kt
@@ -18,9 +18,9 @@
import androidx.compose.runtime.Composer
import androidx.compose.runtime.snapshots.Snapshot
+import java.net.URLClassLoader
import org.intellij.lang.annotations.Language
import org.robolectric.RuntimeEnvironment
-import java.net.URLClassLoader
abstract class AbstractLoweringTests : AbstractCodegenTest() {
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractMultiPlatformIntegrationTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractMultiPlatformIntegrationTest.kt
index 6d470eb..e62740f 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractMultiPlatformIntegrationTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/AbstractMultiPlatformIntegrationTest.kt
@@ -17,6 +17,10 @@
package androidx.compose.compiler.plugins.kotlin
import com.intellij.openapi.util.io.FileUtil
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.PrintStream
+import java.io.PrintWriter
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLITool
@@ -24,10 +28,6 @@
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.util.TraceClassVisitor
-import java.io.ByteArrayOutputStream
-import java.io.File
-import java.io.PrintStream
-import java.io.PrintWriter
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.rules.TemporaryFolder
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
index e3ca786..611c856 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ComposerParamTransformTests.kt
@@ -697,6 +697,7 @@
}
class Bar {
+ @get:Composable
val foo by Foo()
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
index 48ceddc..096c0ac 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/ControlFlowTransformTests.kt
@@ -455,7 +455,7 @@
A(%composer, 0)
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@M3
}
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
@@ -504,7 +504,7 @@
if (isTraceInProgress()) {
traceEventEnd()
}
- return
+ return@composableLambdaInstance
}
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
@@ -575,7 +575,7 @@
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@M1
}
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
@@ -636,7 +636,7 @@
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
if (condition) {
%composer.endToMarker(tmp0_marker)
- return
+ return@M3
}
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
@@ -773,7 +773,7 @@
A(%composer, 0)
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@M3
}
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
@@ -783,7 +783,7 @@
A(%composer, 0)
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@M3
}
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
@@ -908,7 +908,7 @@
sourceInformationMarkerStart(%composer, <>, "C<A()>:Test.kt")
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@FakeBox
}
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
@@ -1081,7 +1081,7 @@
sourceInformationMarkerStart(%composer, <>, "C<A()>:Test.kt")
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@IW
}
A(%composer, 0)
sourceInformationMarkerEnd(%composer)
@@ -1242,7 +1242,7 @@
Identity {
if (condition) {
sourceInformationMarkerEnd(%composer)
- return
+ return@M1
}
}
sourceInformationMarkerEnd(%composer)
@@ -6175,7 +6175,7 @@
sourceInformationMarkerStart(%composer, <>, "C:Test.kt")
if (true) {
%composer.endToMarker(tmp0_marker)
- return
+ return@Inline1
}
sourceInformationMarkerEnd(%composer)
}, %composer, 0)
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FcsTypeResolutionTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FcsTypeResolutionTests.kt
index ad921b5..72f0c67 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FcsTypeResolutionTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/FcsTypeResolutionTests.kt
@@ -38,7 +38,7 @@
@Composable
fun Int.Foo(content: @Composable Int.(foo: String) -> Unit) {
- content<!NO_VALUE_FOR_PARAMETER, NO_VALUE_FOR_PARAMETER!>()<!>
+ content<!NO_VALUE_FOR_PARAMETER!>()<!>
}
@Composable
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
index 2cd3d0b..1ed753c 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RememberIntrinsicTransformTests.kt
@@ -1167,10 +1167,10 @@
if (isTraceInProgress()) {
traceEventStart(<>, %dirty, -1, <>)
}
- used(%composer.cache(%dirty and 0b1110 === 0b0100, {
+ used(%composer.cache(%dirty and 0b1110 === 0b0100) {
effect()
}
- ))
+ )
if (isTraceInProgress()) {
traceEventEnd()
}
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RunComposableTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RunComposableTests.kt
index 4aad0a8..2fc2e49 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RunComposableTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/RunComposableTests.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.Composition
import androidx.compose.runtime.MonotonicFrameClock
import androidx.compose.runtime.Recomposer
+import java.net.URLClassLoader
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
@@ -31,9 +32,8 @@
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.setupLanguageVersionSettings
import org.jetbrains.kotlin.config.CompilerConfiguration
-import org.junit.Test
-import java.net.URLClassLoader
import org.junit.Assert.assertEquals
+import org.junit.Test
class RunComposableTests : AbstractCodegenTest() {
override fun CompilerConfiguration.updateConfiguration() {
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
index 9211731..b198df57 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -1363,7 +1363,10 @@
}
class Bar {
- val foo by Foo()
+ val <!COMPOSABLE_EXPECTED!>foo<!> by Foo()
+
+ @get:Composable
+ val foo2 by Foo()
}
"""
)
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableDeclarationCheckerTests.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableDeclarationCheckerTests.kt
index 07aa897..2c611cf 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableDeclarationCheckerTests.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposableDeclarationCheckerTests.kt
@@ -128,7 +128,7 @@
acceptSuspend <!TYPE_MISMATCH!>@Composable {}<!>
acceptComposableSuspend @Composable {}
acceptComposableSuspend(composableLambda)
- acceptSuspend(<!COMPOSABLE_SUSPEND_FUN, TYPE_MISMATCH!>@Composable suspend fun() { }<!>)
+ acceptSuspend(<!COMPOSABLE_SUSPEND_FUN,TYPE_MISMATCH!>@Composable suspend fun() { }<!>)
}
"""
)
diff --git a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/debug/AbstractDebuggerTest.kt b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/debug/AbstractDebuggerTest.kt
index 51ed468..ec3ef15 100644
--- a/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/debug/AbstractDebuggerTest.kt
+++ b/compose/compiler/compiler-hosted/integration-tests/src/test/java/androidx/compose/compiler/plugins/kotlin/debug/AbstractDebuggerTest.kt
@@ -39,13 +39,13 @@
import com.sun.jdi.request.StepRequest
import com.sun.tools.jdi.SocketAttachingConnector
import java.io.File
+import java.net.URL
+import java.net.URLClassLoader
+import kotlin.properties.Delegates
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.codegen.GeneratedClassLoader
-import java.net.URL
-import java.net.URLClassLoader
-import kotlin.properties.Delegates
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
index 848bf03..25c7023 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableCallChecker.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,8 +50,6 @@
import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL
-import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
-import org.jetbrains.kotlin.resolve.calls.util.getValueArgumentForExpression
import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
@@ -60,6 +58,8 @@
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
+import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
+import org.jetbrains.kotlin.resolve.calls.util.getValueArgumentForExpression
import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinedArgument
import org.jetbrains.kotlin.resolve.sam.getSingleAbstractMethodOrNull
import org.jetbrains.kotlin.types.KotlinType
@@ -243,6 +243,10 @@
// setValue delegate is not allowed for now.
illegalComposableDelegate(context, reportOn)
}
+ if (descriptor is PropertyDescriptor &&
+ descriptor.getter?.hasComposableAnnotation() != true) {
+ composableExpected(context, node.nameIdentifier ?: node)
+ }
return
}
}
@@ -318,10 +322,17 @@
) {
context.trace.report(ComposeErrors.COMPOSABLE_INVOCATION.on(callEl))
if (functionEl != null) {
- context.trace.report(ComposeErrors.COMPOSABLE_EXPECTED.on(functionEl))
+ composableExpected(context, functionEl)
}
}
+ private fun composableExpected(
+ context: CallCheckerContext,
+ functionEl: PsiElement
+ ) {
+ context.trace.report(ComposeErrors.COMPOSABLE_EXPECTED.on(functionEl))
+ }
+
private fun illegalCallMustBeReadonly(
context: CallCheckerContext,
callEl: PsiElement
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableTargetChecker.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableTargetChecker.kt
index bd9e032..a6f50fa 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableTargetChecker.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposableTargetChecker.kt
@@ -17,9 +17,8 @@
package androidx.compose.compiler.plugins.kotlin
import androidx.compose.compiler.plugins.kotlin.analysis.ComposeWritableSlices
-import androidx.compose.compiler.plugins.kotlin.inference.ErrorReporter
-import androidx.compose.compiler.plugins.kotlin.inference.TypeAdapter
import androidx.compose.compiler.plugins.kotlin.inference.ApplierInferencer
+import androidx.compose.compiler.plugins.kotlin.inference.ErrorReporter
import androidx.compose.compiler.plugins.kotlin.inference.Item
import androidx.compose.compiler.plugins.kotlin.inference.LazyScheme
import androidx.compose.compiler.plugins.kotlin.inference.LazySchemeStorage
@@ -28,6 +27,7 @@
import androidx.compose.compiler.plugins.kotlin.inference.Open
import androidx.compose.compiler.plugins.kotlin.inference.Scheme
import androidx.compose.compiler.plugins.kotlin.inference.Token
+import androidx.compose.compiler.plugins.kotlin.inference.TypeAdapter
import androidx.compose.compiler.plugins.kotlin.inference.deserializeScheme
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.jvm.ir.psiElement
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposeFlags.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposeFlags.kt
deleted file mode 100644
index 99d7528..0000000
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ComposeFlags.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2019 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 androidx.compose.compiler.plugins.kotlin
-
-object ComposeFlags {
- var FRAMED_COMPONENTS = false
- var FRAMED_MODEL_CLASSES = true
-}
\ No newline at end of file
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ValidatedAssignment.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ValidatedAssignment.kt
deleted file mode 100644
index 9646462..0000000
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/ValidatedAssignment.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2019 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 androidx.compose.compiler.plugins.kotlin
-
-import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
-import org.jetbrains.kotlin.types.KotlinType
-
-class ValidatedAssignment(
- val validationType: ValidationType,
- val validationCall: ResolvedCall<*>?,
- val uncheckedValidationCall: ResolvedCall<*>?,
- val assignment: ResolvedCall<*>?,
- val assignmentLambda: FunctionDescriptor?, // needed?
- val type: KotlinType,
- val name: String,
- val descriptor: DeclarationDescriptor
-)
-
-enum class ValidationType {
- CHANGED,
- SET,
- UPDATE
-}
\ No newline at end of file
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposeWritableSlices.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposeWritableSlices.kt
index 9261e3e..550b80e 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposeWritableSlices.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/analysis/ComposeWritableSlices.kt
@@ -1,8 +1,8 @@
package androidx.compose.compiler.plugins.kotlin.analysis
-import androidx.compose.compiler.plugins.kotlin.lower.KeyInfo
import androidx.compose.compiler.plugins.kotlin.FunctionMetrics
import androidx.compose.compiler.plugins.kotlin.inference.LazyScheme
+import androidx.compose.compiler.plugins.kotlin.lower.KeyInfo
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer
import org.jetbrains.kotlin.ir.expressions.IrExpression
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTargetAnnotationsTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTargetAnnotationsTransformer.kt
index 2eb7e75..73ee72d 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTargetAnnotationsTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposableTargetAnnotationsTransformer.kt
@@ -23,7 +23,6 @@
import androidx.compose.compiler.plugins.kotlin.analysis.ComposeWritableSlices
import androidx.compose.compiler.plugins.kotlin.inference.ApplierInferencer
import androidx.compose.compiler.plugins.kotlin.inference.ErrorReporter
-import androidx.compose.compiler.plugins.kotlin.inference.TypeAdapter
import androidx.compose.compiler.plugins.kotlin.inference.Item
import androidx.compose.compiler.plugins.kotlin.inference.LazyScheme
import androidx.compose.compiler.plugins.kotlin.inference.LazySchemeStorage
@@ -32,6 +31,7 @@
import androidx.compose.compiler.plugins.kotlin.inference.Open
import androidx.compose.compiler.plugins.kotlin.inference.Scheme
import androidx.compose.compiler.plugins.kotlin.inference.Token
+import androidx.compose.compiler.plugins.kotlin.inference.TypeAdapter
import androidx.compose.compiler.plugins.kotlin.inference.deserializeScheme
import androidx.compose.compiler.plugins.kotlin.irTrace
import androidx.compose.compiler.plugins.kotlin.mergeWith
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
index 7bb80ae..fd4a4db 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/ComposerParamTransformer.kt
@@ -34,7 +34,6 @@
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrLocalDelegatedProperty
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
-import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.copyAttributes
@@ -174,18 +173,6 @@
return super.visitLocalDelegatedProperty(declaration)
}
- override fun visitProperty(declaration: IrProperty): IrStatement {
- if (declaration.getter?.isComposableDelegatedAccessor() == true) {
- declaration.getter!!.annotations += createComposableAnnotation()
- }
-
- if (declaration.setter?.isComposableDelegatedAccessor() == true) {
- declaration.setter!!.annotations += createComposableAnnotation()
- }
-
- return super.visitProperty(declaration)
- }
-
private fun createComposableAnnotation() =
IrConstructorCallImpl(
startOffset = SYNTHETIC_OFFSET,
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
index f3b721c..7870f61 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrInlineReferenceLocator.kt
@@ -61,7 +61,7 @@
val parent = declaration.parent as? IrFunction
if (parent?.isInlineFunctionCall(context) == true &&
declaration.isInlineParameter()) {
- declaration.defaultValue?.expression?.unwrapInlineLambda()?.let {
+ declaration.defaultValue?.expression?.unwrapLambda()?.let {
inlineLambdaToParameter[it] = declaration
}
}
@@ -74,7 +74,7 @@
for (parameter in function.valueParameters) {
if (parameter.isInlineParameter()) {
expression.getValueArgument(parameter.index)
- ?.unwrapInlineLambda()
+ ?.unwrapLambda()
?.let { inlineLambdaToParameter[it] = parameter }
}
}
@@ -96,8 +96,8 @@
it in context.irBuiltIns.primitiveArraysToPrimitiveTypes
}
-private fun IrExpression.unwrapInlineLambda(): IrFunctionSymbol? = when {
- this is IrBlock && origin.isInlinable ->
+fun IrExpression.unwrapLambda(): IrFunctionSymbol? = when {
+ this is IrBlock && origin.isLambdaBlockOrigin ->
(statements.lastOrNull() as? IrFunctionReference)?.symbol
this is IrFunctionExpression ->
@@ -107,6 +107,6 @@
null
}
-private val IrStatementOrigin?.isInlinable: Boolean
+private val IrStatementOrigin?.isLambdaBlockOrigin: Boolean
get() = isLambda || this == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE ||
this == IrStatementOrigin.SUSPEND_CONVERSION
diff --git a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
index 01fc0be..ccf22cf 100644
--- a/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
+++ b/compose/compiler/compiler-hosted/src/main/java/androidx/compose/compiler/plugins/kotlin/lower/IrSourcePrinter.kt
@@ -23,6 +23,7 @@
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
+import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -89,6 +90,7 @@
import org.jetbrains.kotlin.ir.expressions.IrWhen
import org.jetbrains.kotlin.ir.expressions.IrWhileLoop
import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl
+import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
import org.jetbrains.kotlin.ir.types.IrDynamicType
import org.jetbrains.kotlin.ir.types.IrErrorType
@@ -115,6 +117,7 @@
import org.jetbrains.kotlin.ir.util.statements
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
+import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.Printer
@@ -516,11 +519,16 @@
val arg = getValueArgument(i)
if (arg != null) {
val param = symbol.owner.valueParameters[i]
- val isTrailingLambda = i == symbol.owner.valueParameters.size - 1 &&
- (
- arg is IrFunctionExpression ||
- (arg is IrBlock && arg.origin == IrStatementOrigin.LAMBDA)
- )
+ val isLambda = arg is IrFunctionExpression ||
+ (arg is IrBlock &&
+ (arg.origin == IrStatementOrigin.LAMBDA ||
+ arg.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE))
+ if (isLambda) {
+ arg.unwrapLambda()?.let {
+ returnTargetToCall[it] = this
+ }
+ }
+ val isTrailingLambda = i == symbol.owner.valueParameters.size - 1 && isLambda
if (isTrailingLambda) {
trailingLambda = arg
} else {
@@ -801,33 +809,42 @@
println("}")
}
+ // Map local return targets to the corresponding function call.
+ // This is used to print qualified returns.
+ private val returnTargetToCall =
+ mutableMapOf<IrReturnTargetSymbol, IrFunctionAccessExpression>()
+
+ private val IrFunction.isLambda: Boolean
+ get() = name.asString() == SpecialNames.ANONYMOUS_STRING ||
+ origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE
+
+ private fun IrExpression.isLastStatementIn(statements: List<IrStatement>): Boolean {
+ val lastStatement = statements.lastOrNull()
+ return when {
+ lastStatement === this -> true
+ lastStatement is IrBlock -> isLastStatementIn(lastStatement.statements)
+ else -> false
+ }
+ }
+
+ private fun IrExpression.isLastStatementIn(function: IrFunction): Boolean =
+ function.body?.let { isLastStatementIn(it.statements) } ?: false
+
override fun visitReturn(expression: IrReturn) {
val value = expression.value
- // only print the return statement directly if it is not a lambda
+ // Only print the return statement directly if it is not the last statement in a lambda
val returnTarget = expression.returnTargetSymbol.owner
- if (returnTarget !is IrFunction ||
- returnTarget.origin != IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE) {
-
- val isLastStatementInLambda =
- returnTarget is IrFunction &&
- returnTarget.name.asString() == "<anonymous>" &&
- returnTarget.body?.statements?.last().let {
- it == expression || (it is IrBlock && it.statements.last() == expression)
- }
-
- if (!isLastStatementInLambda) {
- print("return ")
- }
+ if (returnTarget !is IrFunction || !returnTarget.isLambda ||
+ !expression.isLastStatementIn(returnTarget)) {
+ val suffix = returnTargetToCall[returnTarget.symbol]?.let {
+ "@${it.symbol.owner.name}"
+ } ?: ""
+ print("return$suffix ")
}
- if (expression.type.isUnit() || value.type.isUnit()) {
- if (value is IrGetObjectValue) {
- return
- } else {
- value.print()
- }
- } else {
- value.print()
+ if (value.type.isUnit() && value is IrGetObjectValue) {
+ return
}
+ value.print()
}
override fun visitBlock(expression: IrBlock) {
diff --git a/compose/compiler/compiler/integration-tests/src/test/kotlin/androidx/compose/compiler/test/CompilerPluginRuntimeVersionCheckTest.kt b/compose/compiler/compiler/integration-tests/src/test/kotlin/androidx/compose/compiler/test/CompilerPluginRuntimeVersionCheckTest.kt
index fd0bf61..9559f16 100644
--- a/compose/compiler/compiler/integration-tests/src/test/kotlin/androidx/compose/compiler/test/CompilerPluginRuntimeVersionCheckTest.kt
+++ b/compose/compiler/compiler/integration-tests/src/test/kotlin/androidx/compose/compiler/test/CompilerPluginRuntimeVersionCheckTest.kt
@@ -17,6 +17,10 @@
package androidx.compose.compiler.test
import androidx.testutils.gradle.ProjectSetupRule
+import java.io.File
+import javax.xml.parsers.DocumentBuilderFactory
+import javax.xml.xpath.XPathConstants
+import javax.xml.xpath.XPathFactory
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Assert.assertEquals
@@ -26,10 +30,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.File
-import javax.xml.parsers.DocumentBuilderFactory
-import javax.xml.xpath.XPathConstants
-import javax.xml.xpath.XPathFactory
@RunWith(JUnit4::class)
class CompilerPluginRuntimeVersionCheckTest {
diff --git a/compose/desktop/desktop/build.gradle b/compose/desktop/desktop/build.gradle
index 46e9c83..2ff1640 100644
--- a/compose/desktop/desktop/build.gradle
+++ b/compose/desktop/desktop/build.gradle
@@ -98,7 +98,7 @@
}
androidx {
- name = "Jetpack Compose desktop implementation"
+ name = "Compose Desktop"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
legacyDisableKotlinStrictApiMode = true
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
index 584efe8..8bf13c0 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/example1/Main.jvm.kt
@@ -24,7 +24,6 @@
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.VerticalScrollbar
-import androidx.compose.foundation.mouseClickable
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
@@ -42,6 +41,7 @@
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.foundation.mouseClickable
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.foundation.shape.CircleShape
@@ -75,29 +75,29 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.key.Key
-import androidx.compose.ui.input.pointer.isAltPressed
-import androidx.compose.ui.input.pointer.isCtrlPressed
-import androidx.compose.ui.input.pointer.isMetaPressed
-import androidx.compose.ui.input.pointer.isPrimaryPressed
-import androidx.compose.ui.input.pointer.isSecondaryPressed
-import androidx.compose.ui.input.pointer.isShiftPressed
-import androidx.compose.ui.input.pointer.isTertiaryPressed
import androidx.compose.ui.input.key.isMetaPressed
import androidx.compose.ui.input.key.isShiftPressed
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.PointerIcon
+import androidx.compose.ui.input.pointer.isAltPressed
import androidx.compose.ui.input.pointer.isBackPressed
+import androidx.compose.ui.input.pointer.isCtrlPressed
import androidx.compose.ui.input.pointer.isForwardPressed
+import androidx.compose.ui.input.pointer.isMetaPressed
+import androidx.compose.ui.input.pointer.isPrimaryPressed
+import androidx.compose.ui.input.pointer.isSecondaryPressed
+import androidx.compose.ui.input.pointer.isShiftPressed
+import androidx.compose.ui.input.pointer.isTertiaryPressed
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalUriHandler
@@ -118,15 +118,15 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
-import androidx.compose.ui.window.Window
import androidx.compose.ui.window.FrameWindowScope
+import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.launchApplication
import androidx.compose.ui.window.rememberWindowState
import androidx.compose.ui.window.singleWindowApplication
+import kotlin.random.Random
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
-import kotlin.random.Random
private const val title = "Desktop Compose Elements"
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
index 2b9d6c4..912f063 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/popupexample/AppContent.jvm.kt
@@ -17,9 +17,9 @@
package androidx.compose.desktop.examples.popupexample
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.background
import androidx.compose.foundation.TooltipArea
import androidx.compose.foundation.TooltipPlacement
+import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
index cb1aa60..06ddea7 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/swingexample/Main.jvm.kt
@@ -47,13 +47,11 @@
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.launchApplication
import androidx.compose.ui.window.rememberWindowState
-import kotlinx.coroutines.DelicateCoroutinesApi
-import kotlinx.coroutines.GlobalScope
import java.awt.BorderLayout
import java.awt.Color as awtColor
import java.awt.Component
-import java.awt.GridLayout
import java.awt.Dimension
+import java.awt.GridLayout
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import javax.swing.JButton
@@ -61,6 +59,8 @@
import javax.swing.JPanel
import javax.swing.SwingUtilities
import javax.swing.WindowConstants
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.GlobalScope
val northClicks = mutableStateOf(0)
val westClicks = mutableStateOf(0)
diff --git a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/windowapi/Examples.jvm.kt b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/windowapi/Examples.jvm.kt
index e360681..a74900c 100644
--- a/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/windowapi/Examples.jvm.kt
+++ b/compose/desktop/desktop/samples/src/jvmMain/kotlin/androidx/compose/desktop/examples/windowapi/Examples.jvm.kt
@@ -60,6 +60,12 @@
import androidx.compose.ui.window.launchApplication
import androidx.compose.ui.window.rememberNotification
import androidx.compose.ui.window.rememberWindowState
+import java.awt.Dimension
+import java.awt.FileDialog
+import java.awt.Frame
+import java.awt.event.WindowAdapter
+import java.awt.event.WindowEvent
+import javax.imageio.ImageIO
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
@@ -67,12 +73,6 @@
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
-import java.awt.Dimension
-import java.awt.FileDialog
-import java.awt.Frame
-import java.awt.event.WindowAdapter
-import java.awt.event.WindowEvent
-import javax.imageio.ImageIO
@OptIn(DelicateCoroutinesApi::class)
fun helloWorld() = GlobalScope.launchApplication {
diff --git a/compose/foundation/foundation-layout/benchmark/src/androidTest/java/androidx/compose/foundation/layout/benchmark/SpacingBenchmark.kt b/compose/foundation/foundation-layout/benchmark/src/androidTest/java/androidx/compose/foundation/layout/benchmark/SpacingBenchmark.kt
index 182d5b4..d0d5564 100644
--- a/compose/foundation/foundation-layout/benchmark/src/androidTest/java/androidx/compose/foundation/layout/benchmark/SpacingBenchmark.kt
+++ b/compose/foundation/foundation-layout/benchmark/src/androidTest/java/androidx/compose/foundation/layout/benchmark/SpacingBenchmark.kt
@@ -37,16 +37,16 @@
import androidx.compose.testutils.benchmark.toggleStateBenchmarkLayout
import androidx.compose.testutils.benchmark.toggleStateBenchmarkMeasure
import androidx.compose.testutils.benchmark.toggleStateBenchmarkRecompose
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.offset
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/build.gradle b/compose/foundation/foundation-layout/build.gradle
index a754486..872eef6 100644
--- a/compose/foundation/foundation-layout/build.gradle
+++ b/compose/foundation/foundation-layout/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,94 +23,66 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
-
- api("androidx.annotation:annotation:1.1.0")
- api(project(":compose:ui:ui"))
- api("androidx.compose.ui:ui-unit:1.2.1")
-
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation("androidx.compose.ui:ui-util:1.2.1")
- implementation("androidx.core:core:1.7.0")
- implementation("androidx.compose.animation:animation-core:1.2.1")
- implementation(libs.kotlinStdlibCommon)
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation("androidx.compose.ui:ui-test-junit4:1.2.1")
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation("androidx.activity:activity-compose:1.3.1")
- // old version of common-java8 conflicts with newer version, because both have
- // DefaultLifecycleEventObserver.
- // Outside of androidx this is resolved via constraint added to lifecycle-common,
- // but it doesn't work in androidx.
- // See aosp/1804059
- androidTestImplementation("androidx.lifecycle:lifecycle-common-java8:2.5.1")
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
-
- samples(project(":compose:foundation:foundation-layout:foundation-layout-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:ui:ui"))
implementation(project(":compose:runtime:runtime"))
implementation(project(":compose:ui:ui-util"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core:1.7.0")
implementation("androidx.compose.animation:animation-core:1.2.1")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+
+ implementation(project(":compose:runtime:runtime"))
+ implementation(project(":compose:ui:ui-util"))
+ }
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
+ jvmTest {
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:ui:ui-test-junit4"))
+ implementation("androidx.compose.ui:ui-test-junit4:1.2.1")
implementation(project(":compose:test-utils"))
implementation("androidx.activity:activity-compose:1.3.1")
@@ -121,9 +92,26 @@
implementation(libs.truth)
}
}
- }
- dependencies {
- samples(project(":compose:foundation:foundation-layout:foundation-layout-samples"))
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
}
diff --git a/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml b/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index d04f9bb..0000000
--- a/compose/foundation/foundation-layout/integration-tests/layout-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2016 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 />
\ No newline at end of file
diff --git a/compose/foundation/foundation-layout/samples/build.gradle b/compose/foundation/foundation-layout/samples/build.gradle
index dd396a9..3e07527 100644
--- a/compose/foundation/foundation-layout/samples/build.gradle
+++ b/compose/foundation/foundation-layout/samples/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "AndroidX Compose UI Core Layout Classes Samples"
+ name = "Compose UI Core Layout Classes Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Core Layout Classes"
diff --git a/compose/foundation/foundation-layout/samples/src/main/AndroidManifest.xml b/compose/foundation/foundation-layout/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index b962196..0000000
--- a/compose/foundation/foundation-layout/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
\ No newline at end of file
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/AspectRatioSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/AspectRatioSample.kt
index 9063cd8..7a7f5b5 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/AspectRatioSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/AspectRatioSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.layout.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/BoxWithConstraintsSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/BoxWithConstraintsSample.kt
index 8c17d20..0222c88 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/BoxWithConstraintsSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/BoxWithConstraintsSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.layout.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
index 66fd1c0..c4cfe09 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/ColumnSample.kt
@@ -17,18 +17,18 @@
package androidx.compose.foundation.layout.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.VerticalAlignmentLine
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.VerticalAlignmentLine
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlin.math.max
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/LayoutPaddingSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/LayoutPaddingSample.kt
index b34d40f..86e4ea6 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/LayoutPaddingSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/LayoutPaddingSample.kt
@@ -18,8 +18,8 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.absolutePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SizeModifierSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SizeModifierSample.kt
index 90a175c..ac4662d 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SizeModifierSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SizeModifierSample.kt
@@ -24,14 +24,14 @@
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.sizeIn
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.requiredSizeIn
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.sizeIn
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.layout.wrapContentWidth
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SpacerSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SpacerSample.kt
index fe7d2d5..ac36b09 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SpacerSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/SpacerSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.layout.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
diff --git a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/WindowInsetsPaddingSample.kt b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/WindowInsetsPaddingSample.kt
index ae72f5e..44ff60d 100644
--- a/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/WindowInsetsPaddingSample.kt
+++ b/compose/foundation/foundation-layout/samples/src/main/java/androidx/compose/foundation/layout/samples/WindowInsetsPaddingSample.kt
@@ -24,8 +24,8 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.MutableWindowInsets
-import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.captionBarPadding
import androidx.compose.foundation.layout.consumeWindowInsets
@@ -34,7 +34,6 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.ime
import androidx.compose.foundation.layout.imePadding
-import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.layout.mandatorySystemGesturesPadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding
@@ -51,6 +50,7 @@
import androidx.compose.foundation.layout.systemGesturesPadding
import androidx.compose.foundation.layout.union
import androidx.compose.foundation.layout.waterfallPadding
+import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
index 02d5c5c..c8d896e 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AlignmentLineTest.kt
@@ -39,14 +39,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.min
import org.junit.After
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.min
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AspectRatioTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AspectRatioTest.kt
index 71c17f1..460b85a 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AspectRatioTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/AspectRatioTest.kt
@@ -17,9 +17,9 @@
package androidx.compose.foundation.layout
import androidx.compose.runtime.Composable
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.node.Ref
import androidx.compose.ui.platform.InspectableValue
import androidx.compose.ui.platform.ValueElement
@@ -27,17 +27,17 @@
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
index 55c4cb4..913aff8 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxTest.kt
@@ -40,14 +40,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
index a4c46cf..d3cdacb 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/BoxWithConstraintsTest.kt
@@ -35,8 +35,8 @@
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.paint
import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.draw.paint
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.Layout
@@ -57,15 +57,15 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.test.rule.ActivityTestRule
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
index 0d96ae64..dcc13ab 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/IntrinsicTest.kt
@@ -17,33 +17,33 @@
package androidx.compose.foundation.layout
import androidx.compose.runtime.Composable
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.node.Ref
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.node.Ref
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
index 7b3e8ca..bfc6d1d 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/LayoutTest.kt
@@ -54,6 +54,9 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isFinite
import androidx.compose.ui.unit.offset
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.max
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
@@ -62,9 +65,6 @@
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Rule
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.max
open class LayoutTest {
@Suppress("DEPRECATION")
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/OffsetTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/OffsetTest.kt
index a20f98e..b784301 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/OffsetTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/OffsetTest.kt
@@ -40,6 +40,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertEquals
@@ -48,7 +49,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/PaddingTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/PaddingTest.kt
index cb1732a..d1af40b1 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/PaddingTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/PaddingTest.kt
@@ -19,12 +19,12 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.InspectableValue
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ValueElement
@@ -34,8 +34,12 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertEquals
@@ -43,10 +47,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
index 7356bd9..46f3307 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SizeTest.kt
@@ -22,20 +22,20 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.node.Ref
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.layout.positionInRoot
+import androidx.compose.ui.node.Ref
import androidx.compose.ui.platform.InspectableValue
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.ValueElement
@@ -48,20 +48,21 @@
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.constrain
import androidx.compose.ui.unit.dp
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
-import org.junit.Assert.assertNotEquals
+import com.google.common.truth.Truth.assertThat
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
@@ -1836,6 +1837,7 @@
)
}
+ @Ignore // b/281171119
@Test
fun testModifiers_doNotCauseUnnecessaryRemeasure() {
var first by mutableStateOf(true)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SpacerTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SpacerTest.kt
index cb7da5b..6d2bb4e 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SpacerTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/SpacerTest.kt
@@ -21,14 +21,14 @@
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
index fab47f7..9cabe4e 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsAnimationTest.kt
@@ -31,6 +31,7 @@
import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
@@ -57,6 +58,7 @@
@SdkSuppress(minSdkVersion = 22) // b/266742122
@OptIn(ExperimentalLayoutApi::class)
@Test
+ @Ignore("b/266742122")
fun imeAnimationWhenShowingIme() {
val imeAnimationSourceValues = mutableListOf<Int>()
val imeAnimationTargetValues = mutableListOf<Int>()
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsPaddingTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsPaddingTest.kt
index 4872573..ca4f233 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsPaddingTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsPaddingTest.kt
@@ -16,13 +16,13 @@
package androidx.compose.foundation.layout
+import android.content.Context
import android.graphics.Insets as FrameworkInsets
import android.graphics.Rect as AndroidRect
-import android.view.WindowInsets as AndroidWindowInsets
-import android.content.Context
import android.os.Build
import android.view.View
import android.view.ViewGroup
+import android.view.WindowInsets as AndroidWindowInsets
import android.view.WindowInsetsAnimation
import android.view.animation.LinearInterpolator
import android.widget.FrameLayout
diff --git a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsSizeTest.kt b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsSizeTest.kt
index 5615d51..f6d68db 100644
--- a/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsSizeTest.kt
+++ b/compose/foundation/foundation-layout/src/androidAndroidTest/kotlin/androidx/compose/foundation/layout/WindowInsetsSizeTest.kt
@@ -17,10 +17,10 @@
package androidx.compose.foundation.layout
import android.graphics.Rect as AndroidRect
-import android.view.WindowInsets as AndroidWindowInsets
import android.os.Build
import android.view.View
import android.view.ViewGroup
+import android.view.WindowInsets as AndroidWindowInsets
import androidx.activity.ComponentActivity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
diff --git a/compose/foundation/foundation-layout/src/androidMain/AndroidManifest.xml b/compose/foundation/foundation-layout/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index b47339d..0000000
--- a/compose/foundation/foundation-layout/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsets.android.kt b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsets.android.kt
index c77441a..44a21ed 100644
--- a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsets.android.kt
+++ b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsets.android.kt
@@ -16,7 +16,6 @@
package androidx.compose.foundation.layout
-import androidx.core.graphics.Insets as AndroidXInsets
import android.os.Build
import android.view.View
import android.view.View.OnAttachStateChangeListener
@@ -28,16 +27,17 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.ui.R
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.core.graphics.Insets as AndroidXInsets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import java.util.WeakHashMap
-import androidx.compose.ui.R
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.LayoutDirection
import org.jetbrains.annotations.TestOnly
internal fun AndroidXInsets.toInsetsValues(): InsetsValues =
diff --git a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
index e406da8..91d6cff 100644
--- a/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
+++ b/compose/foundation/foundation-layout/src/androidMain/kotlin/androidx/compose/foundation/layout/WindowInsetsConnection.android.kt
@@ -36,26 +36,26 @@
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.Velocity
-import kotlin.math.roundToInt
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.util.packFloats
import androidx.compose.ui.util.unpackFloat1
import androidx.compose.ui.util.unpackFloat2
import kotlin.math.abs
import kotlin.math.exp
import kotlin.math.ln
+import kotlin.math.roundToInt
import kotlin.math.sign
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
/**
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
index a408742..b7e385e 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Arrangement.kt
@@ -16,6 +16,7 @@
package androidx.compose.foundation.layout
+import androidx.compose.foundation.layout.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment
@@ -25,7 +26,6 @@
import androidx.compose.ui.unit.dp
import kotlin.math.min
import kotlin.math.roundToInt
-import androidx.compose.foundation.layout.internal.JvmDefaultWithCompatibility
/**
* Used to specify the arrangement of the layout's children in layouts like [Row] or [Column] in
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
index bd8c46e..03ba1e45 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/AspectRatio.kt
@@ -17,12 +17,12 @@
package androidx.compose.foundation.layout
import androidx.compose.runtime.Stable
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.InspectorInfo
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
index 4b382a7..d4b84a8 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Intrinsic.kt
@@ -17,13 +17,13 @@
package androidx.compose.foundation.layout
import androidx.compose.runtime.Stable
-import androidx.compose.ui.layout.LayoutModifier
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.LayoutModifier
+import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.constrain
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
index 78210e2..b0a80c7 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Size.kt
@@ -38,7 +38,6 @@
import androidx.compose.ui.unit.constrain
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
-import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt
/**
@@ -768,12 +767,12 @@
private val Density.targetConstraints: Constraints
get() {
val maxWidth = if (maxWidth != Dp.Unspecified) {
- maxWidth.coerceAtLeast(0.dp).roundToPx()
+ maxWidth.roundToPx().coerceAtLeast(0)
} else {
Constraints.Infinity
}
val maxHeight = if (maxHeight != Dp.Unspecified) {
- maxHeight.coerceAtLeast(0.dp).roundToPx()
+ maxHeight.roundToPx().coerceAtLeast(0)
} else {
Constraints.Infinity
}
diff --git a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Spacer.kt b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Spacer.kt
index 2dfc2c8..4ba62fe 100644
--- a/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Spacer.kt
+++ b/compose/foundation/foundation-layout/src/commonMain/kotlin/androidx/compose/foundation/layout/Spacer.kt
@@ -18,13 +18,13 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.NonRestartableComposable
+import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.Modifier
/**
* Component that represents an empty space layout, whose size can be defined using
diff --git a/compose/foundation/foundation/api/public_plus_experimental_current.txt b/compose/foundation/foundation/api/public_plus_experimental_current.txt
index c37d48d..260f499 100644
--- a/compose/foundation/foundation/api/public_plus_experimental_current.txt
+++ b/compose/foundation/foundation/api/public_plus_experimental_current.txt
@@ -777,6 +777,7 @@
method public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> getIntervals();
method public final int getItemCount();
method public final Object getKey(int index);
+ method public final inline <T> T withInterval(int globalIndex, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super Interval,? extends T> block);
property public abstract androidx.compose.foundation.lazy.layout.IntervalList<Interval> intervals;
property public final int itemCount;
}
@@ -788,12 +789,8 @@
property public default kotlin.jvm.functions.Function1<java.lang.Integer,java.lang.Object> type;
}
- public final class LazyLayoutIntervalContentKt {
- method @androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Composable public static <T extends androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent.Interval> void PinnableItem(androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent<T>, int index, androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList pinnedItemList, kotlin.jvm.functions.Function2<? super T,? super java.lang.Integer,kotlin.Unit> content);
- }
-
@androidx.compose.foundation.ExperimentalFoundationApi @androidx.compose.runtime.Stable public interface LazyLayoutItemProvider {
- method @androidx.compose.runtime.Composable public void Item(int index);
+ method @androidx.compose.runtime.Composable public void Item(int index, Object key);
method public default Object? getContentType(int index);
method public default int getIndex(Object key);
method public int getItemCount();
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/NestedScrollerTestCase.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/NestedScrollerTestCase.kt
index ff79ab3..96778f3 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/NestedScrollerTestCase.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/NestedScrollerTestCase.kt
@@ -37,8 +37,8 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
-import kotlinx.coroutines.runBlocking
import kotlin.random.Random
+import kotlinx.coroutines.runBlocking
/**
* Test case that puts many horizontal scrollers in a vertical scroller
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/TrailingLambdaBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/TrailingLambdaBenchmark.kt
index 73585f9..3cc15b9 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/TrailingLambdaBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/TrailingLambdaBenchmark.kt
@@ -30,11 +30,11 @@
import androidx.compose.testutils.benchmark.toggleStateBenchmarkRecompose
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyGridScrollingBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyGridScrollingBenchmark.kt
index d21da5c..2e190b3 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyGridScrollingBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/lazy/LazyGridScrollingBenchmark.kt
@@ -25,10 +25,10 @@
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
-import androidx.compose.foundation.lazy.grid.LazyGridState
-import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyGridState
+import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.shape.RoundedCornerShape
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextDelegateBenchmark.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextDelegateBenchmark.kt
index 9bb4429..101c12e 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextDelegateBenchmark.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextDelegateBenchmark.kt
@@ -35,12 +35,12 @@
import androidx.compose.ui.unit.sp
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
+import kotlin.math.roundToInt
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.roundToInt
@OptIn(InternalFoundationTextApi::class)
@LargeTest
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextFieldToggleTextTestCase.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextFieldToggleTextTestCase.kt
index 308b085..92c706c 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextFieldToggleTextTestCase.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/text/TextFieldToggleTextTestCase.kt
@@ -32,8 +32,8 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalTextInputService
-import androidx.compose.ui.text.benchmark.RandomTextGenerator
import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.benchmark.RandomTextGenerator
import androidx.compose.ui.text.input.EditCommand
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.ImeOptions
diff --git a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/view/AndroidNestedScrollViewTestCase.kt b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/view/AndroidNestedScrollViewTestCase.kt
index 7c7f2a5..eb41dcf 100644
--- a/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/view/AndroidNestedScrollViewTestCase.kt
+++ b/compose/foundation/foundation/benchmark/src/androidTest/java/androidx/compose/foundation/benchmark/view/AndroidNestedScrollViewTestCase.kt
@@ -20,11 +20,11 @@
import android.view.View
import android.view.ViewGroup
import android.widget.HorizontalScrollView
+import androidx.compose.foundation.benchmark.NestedScrollerTestCase
import androidx.compose.testutils.ToggleableTestCase
import androidx.compose.testutils.benchmark.android.AndroidTestCase
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
-import androidx.compose.foundation.benchmark.NestedScrollerTestCase
import kotlin.random.Random
/**
diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle
index e367382..a57dfef 100644
--- a/compose/foundation/foundation/build.gradle
+++ b/compose/foundation/foundation/build.gradle
@@ -15,9 +15,8 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -26,80 +25,15 @@
id("AndroidXPaparazziPlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- api("androidx.annotation:annotation:1.1.0")
- api("androidx.compose.animation:animation:1.2.1")
- api(project(":compose:runtime:runtime"))
- api(project(":compose:ui:ui"))
-
- implementation(libs.kotlinStdlibCommon)
- implementation(project(":compose:foundation:foundation-layout"))
- implementation(project(':emoji2:emoji2'))
- implementation(project(':core:core'))
- implementation("androidx.compose.ui:ui-graphics:1.2.1")
- implementation("androidx.compose.ui:ui-text:1.2.1")
- implementation("androidx.compose.ui:ui-util:1.2.1")
-
- testImplementation(project(":compose:test-utils"))
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.kotlinCoroutinesTest)
- testImplementation(libs.kotlinTest)
- testImplementation(libs.mockitoCore4)
- testImplementation(libs.kotlinReflect)
- testImplementation(libs.mockitoKotlin4)
-
- testImplementation(project(":constraintlayout:constraintlayout-compose"))
-
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":internal-testutils-fonts"))
- androidTestImplementation(project(":test:screenshot:screenshot"))
- androidTestImplementation(project(":internal-testutils-runtime"))
- androidTestImplementation(libs.testUiautomator)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testMonitor)
- androidTestImplementation "androidx.activity:activity-compose:1.3.1"
- androidTestImplementation "androidx.lifecycle:lifecycle-runtime:2.6.1"
- androidTestImplementation "androidx.savedstate:savedstate:1.2.1"
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.kotlinTest)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.mockitoKotlin)
-
- lintChecks(project(":compose:foundation:foundation-lint"))
- lintPublish(project(":compose:foundation:foundation-lint"))
-
- samples(project(":compose:foundation:foundation:foundation-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(':compose:animation:animation'))
api(project(':compose:runtime:runtime'))
@@ -108,36 +42,57 @@
implementation(project(":compose:ui:ui-util"))
implementation(project(':compose:foundation:foundation-layout'))
}
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.1.0")
- implementation(project(':emoji2:emoji2'))
- implementation(project(":core:core"))
- }
+ }
+ androidMain.dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ implementation(project(':emoji2:emoji2'))
+ implementation(project(":core:core"))
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
- }
-
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.mockitoCore4)
- implementation(libs.truth)
- implementation(libs.kotlinReflect)
- implementation(libs.mockitoKotlin4)
- }
-
- commonTest.dependencies {
+ commonTest {
+ dependencies {
implementation(libs.kotlinTest)
implementation(libs.kotlinCoroutinesTest)
}
+ }
- androidAndroidTest.dependencies {
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ implementation(project(':emoji2:emoji2'))
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ implementation(project(":compose:ui:ui-test"))
+ implementation(project(":compose:ui:ui-test-junit4"))
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:test-utils"))
implementation(project(":internal-testutils-fonts"))
implementation(project(":test:screenshot:screenshot"))
@@ -157,20 +112,43 @@
implementation(libs.mockitoCore)
implementation(libs.mockitoKotlin)
}
+ }
- desktopTest.dependencies {
- implementation(project(":compose:ui:ui-test-junit4"))
- implementation(libs.truth)
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
implementation(libs.junit)
- implementation(libs.skikoCurrentOs)
- implementation(libs.mockitoCore)
- implementation(libs.mockitoKotlin)
+ implementation(libs.truth)
+ implementation(libs.kotlinReflect)
+ implementation(project(":constraintlayout:constraintlayout-compose"))
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.skikoCurrentOs)
+ implementation(libs.mockitoCore)
+ implementation(libs.mockitoKotlin)
+ }
}
}
}
- dependencies {
- samples(project(":compose:foundation:foundation:foundation-samples"))
- }
+}
+
+dependencies {
+ lintChecks(project(":compose:foundation:foundation-lint"))
+ lintPublish(project(":compose:foundation:foundation-lint"))
}
// Screenshot tests related setup
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a69672..0000000
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/DrawModifiersDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/DrawModifiersDemo.kt
index 0698db6..ca3fffe 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/DrawModifiersDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/DrawModifiersDemo.kt
@@ -19,11 +19,12 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.samples.BorderSample
import androidx.compose.foundation.samples.BorderSampleWithBrush
import androidx.compose.foundation.samples.BorderSampleWithDataClass
+import androidx.compose.foundation.samples.BorderSampleWithDynamicData
import androidx.compose.foundation.samples.DrawBackgroundColor
import androidx.compose.foundation.samples.DrawBackgroundShapedBrush
import androidx.compose.runtime.Composable
@@ -41,6 +42,8 @@
BorderSampleWithBrush()
Spacer(Modifier.height(30.dp))
BorderSampleWithDataClass()
+ Spacer(Modifier.height(30.dp))
+ BorderSampleWithDynamicData()
}
Column(Modifier.weight(1f).padding(10.dp)) {
DrawBackgroundColor()
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
index 5993f24..303631a 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt
@@ -40,6 +40,8 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -117,8 +119,8 @@
internal val scrollChannel = Channel<Float>()
- private var draggingItemDraggedDelta by mutableStateOf(0f)
- private var draggingItemInitialOffset by mutableStateOf(0)
+ private var draggingItemDraggedDelta by mutableFloatStateOf(0f)
+ private var draggingItemInitialOffset by mutableIntStateOf(0)
internal val draggingItemOffset: Float
get() = draggingItemLayoutInfo?.let { item ->
draggingItemInitialOffset + draggingItemDraggedDelta - item.offset
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
index c7d9378..4634941 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ListDemos.kt
@@ -80,6 +80,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
@@ -158,8 +159,8 @@
@Preview
@Composable
private fun ListAddRemoveItemsDemo() {
- var numItems by remember { mutableStateOf(0) }
- var offset by remember { mutableStateOf(0) }
+ var numItems by remember { mutableIntStateOf(0) }
+ var offset by remember { mutableIntStateOf(0) }
Column {
Row {
val buttonModifier = Modifier.padding(8.dp)
@@ -406,8 +407,8 @@
@Composable
private fun LazyListArrangements() {
- var count by remember { mutableStateOf(3) }
- var arrangement by remember { mutableStateOf(6) }
+ var count by remember { mutableIntStateOf(3) }
+ var arrangement by remember { mutableIntStateOf(6) }
Column {
Row {
Button(onClick = { count-- }) {
@@ -480,7 +481,7 @@
Column {
val scrollState = rememberScrollState()
val lazyState = rememberLazyListState()
- var count by remember { mutableStateOf(10) }
+ var count by remember { mutableIntStateOf(10) }
var reverse by remember { mutableStateOf(false) }
var rtl by remember { mutableStateOf(false) }
var column by remember { mutableStateOf(true) }
@@ -634,7 +635,7 @@
.background(Color.LightGray),
contentAlignment = Alignment.Center
) {
- var state by rememberSaveable { mutableStateOf(0) }
+ var state by rememberSaveable { mutableIntStateOf(0) }
Button(onClick = { state++ }) {
Text("Index=$index State=$state")
}
@@ -660,7 +661,7 @@
GridCells.Fixed(3),
GridCells.Adaptive(minSize = 60.dp)
)
- var currentMode by remember { mutableStateOf(0) }
+ var currentMode by remember { mutableIntStateOf(0) }
Column {
Button(
modifier = Modifier.wrapContentSize(),
@@ -709,10 +710,10 @@
}
}
)
- var currentMode by remember { mutableStateOf(0) }
- var horizontalSpacing by remember { mutableStateOf(8) }
+ var currentMode by remember { mutableIntStateOf(0) }
+ var horizontalSpacing by remember { mutableIntStateOf(8) }
var horizontalSpacingExpanded by remember { mutableStateOf(false) }
- var verticalSpacing by remember { mutableStateOf(8) }
+ var verticalSpacing by remember { mutableIntStateOf(8) }
var verticalSpacingExpanded by remember { mutableStateOf(false) }
Column {
Row {
@@ -860,7 +861,7 @@
}
LazyColumn {
item {
- var counter by rememberSaveable { mutableStateOf(0) }
+ var counter by rememberSaveable { mutableIntStateOf(0) }
Button(onClick = { counter++ }) {
Text("Header has $counter")
}
@@ -869,7 +870,7 @@
items = names,
key = { it }
) {
- var counter by rememberSaveable { mutableStateOf(0) }
+ var counter by rememberSaveable { mutableIntStateOf(0) }
Button(onClick = { counter++ }, modifier = Modifier.animateItemPlacement()) {
Text("$it has $counter")
}
@@ -962,7 +963,7 @@
mutableStateOf(List(100) { it })
}
- var count by remember { mutableStateOf(10) }
+ var count by remember { mutableIntStateOf(10) }
var reverseLayout by remember { mutableStateOf(false) }
var rtl by remember { mutableStateOf(false) }
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/OverscrollDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/OverscrollDemo.kt
index df7592a..c375e4e 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/OverscrollDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/OverscrollDemo.kt
@@ -20,9 +20,9 @@
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.samples.OverscrollSample
import androidx.compose.foundation.samples.OverscrollWithDraggable_After
import androidx.compose.foundation.samples.OverscrollWithDraggable_Before
-import androidx.compose.foundation.samples.OverscrollSample
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/PointerIconDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/PointerIconDemo.kt
index 6a4a6cd..4c73cb5 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/PointerIconDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/PointerIconDemo.kt
@@ -26,8 +26,8 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.integration.demos.common.ComposableDemo
-import androidx.compose.runtime.Composable
import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
index 8ba6e1e..92d0c13 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/ScrollableFocusedChildDemo.kt
@@ -41,6 +41,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -153,8 +154,8 @@
}
private class ResizableState {
- var widthOverride by mutableStateOf(-1)
- var heightOverride by mutableStateOf(-1)
+ var widthOverride by mutableIntStateOf(-1)
+ var heightOverride by mutableIntStateOf(-1)
fun resetToMaxSize() {
widthOverride = -1
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
index 183a7d9..4a3744e 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/SuspendingGesturesDemo.kt
@@ -20,8 +20,8 @@
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
-import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.detectTransformGestures
@@ -33,16 +33,17 @@
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
-import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.size
import androidx.compose.integration.demos.common.ComposableDemo
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -109,12 +110,12 @@
*/
@Composable
fun CoroutineTapDemo() {
- var tapHue by remember { mutableStateOf(randomHue()) }
- var longPressHue by remember { mutableStateOf(randomHue()) }
- var doubleTapHue by remember { mutableStateOf(randomHue()) }
- var pressHue by remember { mutableStateOf(randomHue()) }
- var releaseHue by remember { mutableStateOf(randomHue()) }
- var cancelHue by remember { mutableStateOf(randomHue()) }
+ var tapHue by remember { mutableFloatStateOf(randomHue()) }
+ var longPressHue by remember { mutableFloatStateOf(randomHue()) }
+ var doubleTapHue by remember { mutableFloatStateOf(randomHue()) }
+ var pressHue by remember { mutableFloatStateOf(randomHue()) }
+ var releaseHue by remember { mutableFloatStateOf(randomHue()) }
+ var cancelHue by remember { mutableFloatStateOf(randomHue()) }
Column {
Text("The boxes change color when you tap the white box.")
@@ -214,7 +215,7 @@
@Composable
fun TouchSlopDragGestures() {
Column {
- var width by remember { mutableStateOf(0f) }
+ var width by remember { mutableFloatStateOf(0f) }
Box(
Modifier.fillMaxWidth()
.background(Color.Cyan)
@@ -241,7 +242,7 @@
}
Box(Modifier.weight(1f)) {
- var height by remember { mutableStateOf(0f) }
+ var height by remember { mutableFloatStateOf(0f) }
Box(
Modifier.fillMaxHeight()
.background(Color.Yellow)
@@ -328,23 +329,23 @@
@Composable
fun Drag2DGestures() {
var size by remember { mutableStateOf(IntSize.Zero) }
- val offsetX = remember { mutableStateOf(0f) }
- val offsetY = remember { mutableStateOf(0f) }
+ var offsetX by remember { mutableFloatStateOf(0f) }
+ var offsetY by remember { mutableFloatStateOf(0f) }
Box(
Modifier.onSizeChanged {
size = it
}.fillMaxSize()
) {
Box(
- Modifier.offset { IntOffset(offsetX.value.roundToInt(), offsetY.value.roundToInt()) }
+ Modifier.offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) }
.background(Color.Blue)
.requiredSize(50.dp)
.pointerInput(Unit) {
detectDragGestures { _, dragAmount ->
- offsetX.value = (offsetX.value + dragAmount.x)
+ offsetX = (offsetX + dragAmount.x)
.coerceIn(0f, size.width.toFloat() - 50.dp.toPx())
- offsetY.value = (offsetY.value + dragAmount.y)
+ offsetY = (offsetY + dragAmount.y)
.coerceIn(0f, size.height.toFloat() - 50.dp.toPx())
}
}
@@ -361,10 +362,10 @@
) -> Unit
) {
val matrix by remember { mutableStateOf(Matrix()) }
- var angle by remember { mutableStateOf(0f) }
- var zoom by remember { mutableStateOf(1f) }
- var offsetX by remember { mutableStateOf(0f) }
- var offsetY by remember { mutableStateOf(0f) }
+ var angle by remember { mutableFloatStateOf(0f) }
+ var zoom by remember { mutableFloatStateOf(1f) }
+ var offsetX by remember { mutableFloatStateOf(0f) }
+ var offsetY by remember { mutableFloatStateOf(0f) }
Box(
Modifier.fillMaxSize().pointerInput(Unit) {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/LazyGridSnappingDemos.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/LazyGridSnappingDemos.kt
index 7b7ec83..86151d9 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/LazyGridSnappingDemos.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/snapping/LazyGridSnappingDemos.kt
@@ -19,8 +19,8 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.FlingBehavior
-import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
+import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeFontPadding.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeFontPadding.kt
index 3e76a2e..d20cf1b 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeFontPadding.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeFontPadding.kt
@@ -43,10 +43,10 @@
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
+import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
-import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
index 085258f..a91e0d2 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeLineHeight.kt
@@ -36,6 +36,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -70,8 +71,8 @@
Modifier.verticalScroll(rememberScrollState())
.background(TextMetricColors.Default.background)
) {
- var lineHeightSp = remember { mutableStateOf(60f) }
- var lineHeightEm = remember { mutableStateOf(1f) }
+ var lineHeightSp = remember { mutableFloatStateOf(60f) }
+ var lineHeightEm = remember { mutableFloatStateOf(1f) }
var lineHeightEnabled = remember { mutableStateOf(false) }
val lineHeightStyleEnabled = remember { mutableStateOf(false) }
var lineHeightAlignment = remember {
@@ -97,8 +98,8 @@
Spacer(Modifier.padding(16.dp))
TextWithLineHeight(
lineHeightEnabled.value,
- lineHeightSp.value,
- lineHeightEm.value,
+ lineHeightSp.floatValue,
+ lineHeightEm.floatValue,
if (lineHeightStyleEnabled.value) {
LineHeightStyle(
alignment = lineHeightAlignment.value,
@@ -336,7 +337,7 @@
snap: Boolean = true,
enabled: Boolean = true
) {
- var lastValue by remember(value) { mutableStateOf(value) }
+ var lastValue by remember(value) { mutableFloatStateOf(value) }
val increment = valueRange.endInclusive / (steps + 1).toFloat()
val snapValue = round(value / increment / 2f) * increment
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeText.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeText.kt
index bf5e4dd..5a10e21 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeText.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeText.kt
@@ -44,8 +44,8 @@
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ListItem
-import androidx.compose.material.Slider
import androidx.compose.material.RadioButton
+import androidx.compose.material.Slider
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
@@ -54,6 +54,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -562,7 +563,7 @@
val textStyleHyphensOff = TextStyle(fontSize = fontSize8, color = Color.Blue,
hyphens = Hyphens.None)
Column {
- var width by remember { mutableStateOf(30f) }
+ var width by remember { mutableFloatStateOf(30f) }
Slider(
value = width,
onValueChange = { width = it },
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextAccessibility.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextAccessibility.kt
index 3f36fd9..f3ccb2e 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextAccessibility.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextAccessibility.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.demos.text
-import androidx.compose.material.Text
import androidx.compose.foundation.layout.Column
+import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.SpanStyle
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelection.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelection.kt
index d251f63..fcfec76 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelection.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelection.kt
@@ -24,12 +24,12 @@
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.text.selection.DisableSelection
+import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.foundation.text.selection.DisableSelection
-import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelectionSample.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelectionSample.kt
index 01670e0..9d63ed7 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelectionSample.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/ComposeTextSelectionSample.kt
@@ -24,15 +24,15 @@
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.withStyle
import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/FontFamilyDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/FontFamilyDemo.kt
index d7aae18..0b21ea8 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/FontFamilyDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/FontFamilyDemo.kt
@@ -28,6 +28,7 @@
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -64,7 +65,7 @@
@Composable
fun AsyncFontFamilyDemo() {
- var recreateFontFamily by remember { mutableStateOf(0) }
+ var recreateFontFamily by remember { mutableIntStateOf(0) }
var showW800 by remember {
mutableStateOf(false)
}
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
index b671f6b..57d039b 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/InteractiveText.kt
@@ -25,8 +25,11 @@
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
@@ -38,7 +41,7 @@
fun InteractiveTextDemo() {
val clickedOffset = remember { mutableStateOf<Int?>(null) }
val hoveredOffset = remember { mutableStateOf<Int?>(null) }
- val numOnHoverInvocations = remember { mutableStateOf(0) }
+ var numOnHoverInvocations by remember { mutableIntStateOf(0) }
Column(
modifier = Modifier.padding(horizontal = 10.dp)
) {
@@ -47,14 +50,14 @@
Text(text = "Click/Hover the lorem ipsum text below.")
Text(text = "Clicked offset: ${clickedOffset.value ?: "No click yet"}")
Text(text = "Hovered offset: ${hoveredOffset.value ?: "Not hovering"}")
- Text(text = "Number of onHover invocations: ${numOnHoverInvocations.value}")
+ Text(text = "Number of onHover invocations: $numOnHoverInvocations")
ClickableText(
text = AnnotatedString(loremIpsum(wordCount = 30)),
modifier = Modifier.border(Dp.Hairline, Color.Black),
style = MaterialTheme.typography.body1,
onHover = {
- numOnHoverInvocations.value = numOnHoverInvocations.value + 1
+ numOnHoverInvocations++
hoveredOffset.value = it
}
) { offset ->
@@ -65,7 +68,7 @@
onClick = {
clickedOffset.value = null
hoveredOffset.value = null
- numOnHoverInvocations.value = 0
+ numOnHoverInvocations = 0
}
) {
Text(text = "Reset Offsets/Counter")
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LetterSpacingDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LetterSpacingDemo.kt
index 654faea..045a0c1 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LetterSpacingDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LetterSpacingDemo.kt
@@ -26,6 +26,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -42,8 +43,8 @@
Column(
Modifier.padding(horizontal = 16.dp)
) {
- var letterSpacing: Float by remember { mutableStateOf(0.0f) }
- var fontSize: Float by remember { mutableStateOf(12f) }
+ var letterSpacing: Float by remember { mutableFloatStateOf(0.0f) }
+ var fontSize: Float by remember { mutableFloatStateOf(12f) }
Text("LetterSpacing: ${letterSpacing.toString().take(4)}.sp")
Slider(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LineBreakDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LineBreakDemo.kt
index 55ccf56..f571dc0 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LineBreakDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/LineBreakDemo.kt
@@ -26,8 +26,10 @@
import androidx.compose.material.Slider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.SpanStyle
@@ -55,13 +57,13 @@
@Composable
fun TextLineBreakDemo() {
- val selectedFontSize = remember { mutableStateOf(16f) }
+ var selectedFontSize by remember { mutableFloatStateOf(16f) }
Column(modifier = Modifier.fillMaxSize()) {
- Text("Font size: ${selectedFontSize.value}")
+ Text("Font size: $selectedFontSize")
Slider(
- value = selectedFontSize.value,
- onValueChange = { value -> selectedFontSize.value = value },
+ value = selectedFontSize,
+ onValueChange = { value -> selectedFontSize = value },
valueRange = 8f..48f
)
@@ -82,7 +84,7 @@
},
style = TextStyle(
lineBreak = preset,
- fontSize = selectedFontSize.value.sp
+ fontSize = selectedFontSize.sp
),
modifier = textModifier.weight(1f)
)
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt
index c3c5211..bc0cda0 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/StrokeDemo.kt
@@ -27,6 +27,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -45,7 +46,7 @@
@OptIn(ExperimentalTextApi::class)
@Composable
fun TextStrokeDemo() {
- var dashInterval by remember { mutableStateOf(2f) }
+ var dashInterval by remember { mutableFloatStateOf(2f) }
var stroke by remember {
mutableStateOf(
Stroke(
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldFocusKeyboardInteraction.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldFocusKeyboardInteraction.kt
index e57604b..0d01e6b 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldFocusKeyboardInteraction.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldFocusKeyboardInteraction.kt
@@ -16,11 +16,11 @@
package androidx.compose.foundation.demos.text
-import android.widget.Button as AndroidButton
import android.content.Context
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.inputmethod.EditorInfo
+import android.widget.Button as AndroidButton
import android.widget.EditText
import android.widget.LinearLayout
import androidx.compose.foundation.border
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
index bce2a5f..15f6d1e 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/TextFieldsInDialogDemo.kt
@@ -32,6 +32,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
@@ -106,7 +107,7 @@
@Composable
fun TextFieldsInDialogDemo() {
val listState = rememberLazyListState()
- val (currentDemoIndex, setDemoIndex) = rememberSaveable { mutableStateOf(-1) }
+ val (currentDemoIndex, setDemoIndex) = rememberSaveable { mutableIntStateOf(-1) }
if (currentDemoIndex == -1) {
LazyColumn(state = listState) {
diff --git a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
index ba89fe4..8e052ff 100644
--- a/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
+++ b/compose/foundation/foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/text/VariableFontsDemo.kt
@@ -25,7 +25,6 @@
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
-import androidx.testutils.fonts.R
import androidx.compose.foundation.demos.text.FontVariationSettingsCompot.compatSetFontVariationSettings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -37,6 +36,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@@ -53,6 +53,7 @@
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.testutils.fonts.R
import java.io.File
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@@ -65,7 +66,7 @@
Text("Variable fonts are only supported on API 26+")
}
- val (weight, setWeight) = remember { mutableStateOf(1000f) }
+ val (weight, setWeight) = remember { mutableFloatStateOf(1000f) }
val (italic, setItalic) = remember { mutableStateOf(false) }
LazyColumn {
this.stickyHeader {
diff --git a/compose/foundation/foundation/samples/build.gradle b/compose/foundation/foundation/samples/build.gradle
index 38d57ca..d6871de 100644
--- a/compose/foundation/foundation/samples/build.gradle
+++ b/compose/foundation/foundation/samples/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "AndroidX Compose UI Foundational Component Samples"
+ name = "Compose UI Foundational Component Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Foundational Components"
diff --git a/compose/foundation/foundation/samples/src/main/AndroidManifest.xml b/compose/foundation/foundation/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a69672..0000000
--- a/compose/foundation/foundation/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BorderSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BorderSamples.kt
index 304227b..e42bb65 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BorderSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/BorderSamples.kt
@@ -19,23 +19,35 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CutCornerShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Button
import androidx.compose.material.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.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
@Composable
@Sampled
fun BorderSample() {
Text(
"Text with square border",
- modifier = Modifier.border(4.dp, Color.Magenta).padding(10.dp)
+ modifier = Modifier
+ .border(4.dp, Color.Magenta)
+ .padding(10.dp)
)
}
@@ -50,7 +62,8 @@
)
Text(
"Text with gradient border",
- modifier = Modifier.border(width = 2.dp, brush = gradientBrush, shape = CircleShape)
+ modifier = Modifier
+ .border(width = 2.dp, brush = gradientBrush, shape = CircleShape)
.padding(10.dp)
)
}
@@ -60,9 +73,102 @@
fun BorderSampleWithDataClass() {
Text(
"Text with gradient border",
- modifier = Modifier.border(
- border = BorderStroke(2.dp, Color.Blue),
- shape = CutCornerShape(8.dp)
- ).padding(10.dp)
+ modifier = Modifier
+ .border(
+ border = BorderStroke(2.dp, Color.Blue),
+ shape = CutCornerShape(8.dp)
+ )
+ .padding(10.dp)
)
-}
\ No newline at end of file
+}
+
+@Composable
+@Sampled
+fun BorderSampleWithDynamicData() {
+ val widthRange = (1..10)
+ var width by remember { mutableStateOf((widthRange.random()).dp) }
+
+ val shapes = remember {
+ listOf(CutCornerShape(8.dp), CircleShape, RoundedCornerShape(20))
+ }
+ var selectedShape by remember { mutableStateOf(shapes.random()) }
+
+ val colors = listOf(
+ Color.Black,
+ Color.DarkGray,
+ Color.Gray,
+ Color.LightGray,
+ Color.White,
+ Color.Red,
+ Color.Blue,
+ Color.Green,
+ Color.Yellow,
+ Color.Cyan,
+ Color.Magenta
+ )
+ var gradientBrush by remember {
+ mutableStateOf(
+ Brush.horizontalGradient(
+ colors = listOf(colors.random(), colors.random(), colors.random()),
+ startX = 0.0f,
+ endX = 500.0f,
+ tileMode = TileMode.Repeated
+ )
+ )
+ }
+
+ Column(Modifier.padding(2.dp)) {
+ Text(text = "Update border with buttons")
+ Row {
+ Button(
+ modifier = Modifier.width(60.dp),
+ onClick = {
+
+ width = (widthRange.random()).dp
+ }
+ ) {
+ Text(
+ fontSize = 8.sp,
+ text = "width"
+ )
+ }
+ Button(
+ modifier = Modifier.width(60.dp),
+ onClick = {
+ gradientBrush = Brush.horizontalGradient(
+ colors = listOf(colors.random(), colors.random(), colors.random()),
+ startX = 0.0f,
+ endX = 500.0f,
+ tileMode = TileMode.Repeated
+ )
+ }
+ ) {
+ Text(
+ fontSize = 8.sp,
+ text = "brush"
+ )
+ }
+ Button(
+ modifier = Modifier.width(60.dp),
+ onClick = {
+ selectedShape = shapes.random()
+ }
+ ) {
+ Text(
+ fontSize = 8.sp,
+ text = "shape"
+ )
+ }
+ }
+ Text(
+ "Dynamic border",
+ modifier = Modifier
+ .border(
+ width = width,
+ brush = gradientBrush,
+ shape = selectedShape
+ )
+ .padding(10.dp)
+ )
+ }
+}
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
index 2cc6ff7..96b1a1e 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ClickableTextSample.kt
@@ -18,8 +18,8 @@
import android.util.Log
import androidx.annotation.Sampled
-import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/DragGestureDetectorSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/DragGestureDetectorSamples.kt
index ed0b6f4..d08b4cf 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/DragGestureDetectorSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/DragGestureDetectorSamples.kt
@@ -19,6 +19,7 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.awaitDragOrCancellation
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitHorizontalDragOrCancellation
import androidx.compose.foundation.gestures.awaitHorizontalTouchSlopOrCancellation
@@ -27,7 +28,6 @@
import androidx.compose.foundation.gestures.awaitVerticalTouchSlopOrCancellation
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.detectHorizontalDragGestures
import androidx.compose.foundation.gestures.detectVerticalDragGestures
import androidx.compose.foundation.gestures.drag
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
index e394ae4..c90595b 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/FocusableSample.kt
@@ -20,8 +20,8 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.border
import androidx.compose.foundation.focusGroup
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.focusable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt
index 4b8fb36..ffe33b6 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/InteractionSourceSample.kt
@@ -18,17 +18,17 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.interaction.DragInteraction
-import androidx.compose.foundation.interaction.Interaction
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.LocalIndication
-import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.indication
+import androidx.compose.foundation.interaction.DragInteraction
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.interaction.collectIsDraggedAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Box
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ScrollerSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ScrollerSamples.kt
index b0028b7..9a1430e 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ScrollerSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/ScrollerSamples.kt
@@ -17,17 +17,17 @@
package androidx.compose.foundation.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.gestures.scrollBy
-import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/SelectionSample.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/SelectionSample.kt
index 2d93ad6..38973fb 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/SelectionSample.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/SelectionSample.kt
@@ -18,10 +18,10 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.layout.Column
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
import androidx.compose.foundation.text.selection.DisableSelection
import androidx.compose.foundation.text.selection.SelectionContainer
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
@Sampled
@Composable
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TapGestureSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TapGestureSamples.kt
index 9255c67..b78ea5d 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TapGestureSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TapGestureSamples.kt
@@ -20,9 +20,9 @@
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitLongPressOrCancellation
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TransformGestureSamples.kt b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TransformGestureSamples.kt
index d4940a6..f0c3785 100644
--- a/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TransformGestureSamples.kt
+++ b/compose/foundation/foundation/samples/src/main/java/androidx/compose/foundation/samples/TransformGestureSamples.kt
@@ -18,14 +18,14 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.calculateCentroid
import androidx.compose.foundation.gestures.calculateCentroidSize
import androidx.compose.foundation.gestures.calculatePan
import androidx.compose.foundation.gestures.calculateRotation
import androidx.compose.foundation.gestures.calculateZoom
import androidx.compose.foundation.gestures.detectTransformGestures
-import androidx.compose.foundation.gestures.awaitFirstDown
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BackgroundTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BackgroundTest.kt
index 1bf2f65..7cc04da 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BackgroundTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BackgroundTest.kt
@@ -21,9 +21,12 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
import androidx.compose.testutils.assertShape
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -180,6 +183,42 @@
}
@Test
+ fun background_changeShape() {
+ var shape by mutableStateOf(RoundedCornerShape(10f))
+
+ rule.setContent {
+ SemanticParent {
+ Box(
+ Modifier.size(40f.toDp())
+ .background(Color.Magenta)
+ .background(color = Color.White, shape = shape)
+ )
+ }
+ }
+
+ val bitmap = rule.onNodeWithTag(contentTag).captureToImage()
+ bitmap.assertShape(
+ density = rule.density,
+ backgroundColor = Color.Magenta,
+ shape = RoundedCornerShape(10f),
+ shapeColor = Color.White,
+ shapeOverlapPixelCount = 2.0f
+ )
+
+ shape = CircleShape
+ rule.waitForIdle()
+
+ val bitmap2 = rule.onNodeWithTag(contentTag).captureToImage()
+ bitmap2.assertShape(
+ density = rule.density,
+ backgroundColor = Color.Magenta,
+ shape = CircleShape,
+ shapeColor = Color.White,
+ shapeOverlapPixelCount = 2.0f
+ )
+ }
+
+ @Test
fun background_rtl_initially() {
rule.setContent {
SemanticParent {
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BorderTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BorderTest.kt
index 599ccd0..1eb8626 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BorderTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/BorderTest.kt
@@ -19,8 +19,8 @@
import android.os.Build
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.GenericShape
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -54,13 +54,13 @@
import androidx.compose.ui.unit.dp
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import kotlin.math.floor
+import kotlin.math.roundToInt
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.floor
-import kotlin.math.roundToInt
@MediumTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ImageTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ImageTest.kt
index f852d45..364d71f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ImageTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ImageTest.kt
@@ -19,9 +19,9 @@
import android.os.Build
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.sizeIn
-import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.test.R
import androidx.compose.runtime.mutableStateOf
@@ -41,8 +41,8 @@
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
-import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.toPixelMap
import androidx.compose.ui.layout.ContentScale
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
index 64ba70c..6de2d3d 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/IndicationTest.kt
@@ -37,6 +37,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
@@ -45,8 +47,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SystemGestureExclusionTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SystemGestureExclusionTest.kt
index 17e0b89..8314fe4 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SystemGestureExclusionTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/SystemGestureExclusionTest.kt
@@ -16,6 +16,7 @@
package androidx.compose.foundation
+import android.graphics.Rect as AndroidRect
import android.os.Build
import android.view.View
import android.view.ViewGroup
@@ -41,7 +42,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import android.graphics.Rect as AndroidRect
/**
* Testing the support for Android Views in Compose UI.
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitEachGestureTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitEachGestureTest.kt
index 592c0df..2107d07 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitEachGestureTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitEachGestureTest.kt
@@ -34,14 +34,14 @@
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.cancel
import kotlinx.coroutines.coroutineScope
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitTouchEventTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitTouchEventTest.kt
index 591e968..851df06 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitTouchEventTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/AwaitTouchEventTest.kt
@@ -16,9 +16,9 @@
package androidx.compose.foundation.gesture
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitLongPressOrCancellation
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.Modifier
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt
index 5660223..59f9952 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/ForEachGestureTest.kt
@@ -31,10 +31,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Assert.assertTrue
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CancellationException
@@ -42,6 +38,10 @@
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
+import org.junit.Assert.assertTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
@Suppress("DEPRECATION")
@MediumTest
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
index 39f045c..af3679b 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
@@ -24,7 +24,10 @@
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion.CenterToCenter
import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
+import androidx.compose.foundation.gestures.snapping.offsetOnMainAxis
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.singleAxisViewportSize
+import androidx.compose.foundation.gestures.snapping.sizeOnMainAxis
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
@@ -469,11 +472,16 @@
var itemIndex = -1
if (state == null) return -1
var minDistance = Float.POSITIVE_INFINITY
+ val layoutInfo = state.layoutInfo
(state.layoutInfo.visibleItemsInfo).forEach {
val distance = calculateDistanceToDesiredSnapPosition(
- state.layoutInfo,
- it,
- CenterToCenter
+ mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = it.sizeOnMainAxis(orientation = layoutInfo.orientation),
+ itemOffset = it.offsetOnMainAxis(orientation = layoutInfo.orientation),
+ itemIndex = it.index,
+ snapPositionInLayout = CenterToCenter
)
if (abs(distance) < minDistance) {
minDistance = abs(distance)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
index 3153d92..603bbf7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
@@ -26,6 +26,7 @@
import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion.CenterToCenter
import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.singleAxisViewportSize
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
@@ -457,11 +458,16 @@
var itemIndex = -1
if (state == null) return -1
var minDistance = Float.POSITIVE_INFINITY
+ val layoutInfo = state.layoutInfo
(state.layoutInfo.visibleItemsInfo).forEach {
val distance = calculateDistanceToDesiredSnapPosition(
- state.layoutInfo,
- it,
- CenterToCenter
+ mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = it.size,
+ itemOffset = it.offset,
+ itemIndex = it.index,
+ snapPositionInLayout = CenterToCenter
)
if (abs(distance) < minDistance) {
minDistance = abs(distance)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyCustomKeysTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyCustomKeysTest.kt
index aa07638..76103d9 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyCustomKeysTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyCustomKeysTest.kt
@@ -422,6 +422,26 @@
}
}
+ @Test
+ fun keysLambdaIsCalledOnlyOnce() {
+ var keyCalls = 0
+
+ rule.setContent {
+ LazyVerticalGrid(GridCells.Fixed(1)) {
+ items(1, key = {
+ keyCalls++
+ 0
+ }) {
+ Item("item")
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(keyCalls).isEqualTo(1)
+ }
+ }
+
private fun testReordering(content: LazyGridScope.(List<MyClass>) -> Unit) {
var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
index 030e1d7..5885114 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
@@ -18,6 +18,8 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.scrollBy
@@ -28,6 +30,8 @@
import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.requiredWidthIn
+import androidx.compose.foundation.lazy.list.getValueAtFrame
+import androidx.compose.foundation.lazy.list.getVelocityAtFrame
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -2254,6 +2258,70 @@
}
}
+ @Test
+ fun interruptedSizeChange() {
+ var item0Size by mutableStateOf(itemSizeDp)
+ val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+ rule.setContent {
+ LazyGrid(cells = 1) {
+ items(2, key = { it }) {
+ Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = itemSize2Dp
+ }
+
+ rule.waitForIdle()
+ rule.mainClock.advanceTimeByFrame()
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, itemSize)
+ )
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterOneFrame =
+ animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, valueAfterOneFrame)
+ )
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = 0.dp
+ }
+
+ rule.waitForIdle()
+ val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+ val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, startValue)
+ )
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterThreeFrames = animSpec.getValueAtFrame(
+ 1,
+ from = startValue,
+ to = 0f,
+ initialVelocity = startVelocity
+ )
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, valueAfterThreeFrames)
+ )
+ }
+ }
+ }
+
private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
@@ -2337,9 +2405,11 @@
for (i in 0..duration step FrameDuration) {
val fraction = i / duration.toFloat()
onFrame(fraction)
- rule.mainClock.advanceTimeBy(FrameDuration)
- expectedTime += FrameDuration
- assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ if (i < duration) {
+ rule.mainClock.advanceTimeBy(FrameDuration)
+ expectedTime += FrameDuration
+ assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ }
}
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridsIndexedTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridsIndexedTest.kt
index d6b35bd..53934b3 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridsIndexedTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridsIndexedTest.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.lazy.grid
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyNestedScrollingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyNestedScrollingTest.kt
index eba984d..25502d0 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyNestedScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyNestedScrollingTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.foundation.lazy.grid
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.lazy.list.TestTouchSlop
import androidx.compose.foundation.lazy.list.scrollBy
import androidx.compose.foundation.lazy.list.setContentWithTestViewConfiguration
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
index c868e03..fc52c37 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyScrollTest.kt
@@ -24,8 +24,8 @@
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.test.filters.MediumTest
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutStateRestorationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutStateRestorationTest.kt
index e8dcc77..d05d1f1 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutStateRestorationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutStateRestorationTest.kt
@@ -305,7 +305,7 @@
override val itemCount: Int = itemCount()
@Composable
- override fun Item(index: Int) {
+ override fun Item(index: Int, key: Any) {
content(index)
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
index d0fc90e..c9c1a87 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutTest.kt
@@ -23,6 +23,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -94,7 +95,10 @@
@Test
fun measureAndPlaceTwoItems() {
val itemProvider = itemProvider({ 2 }) { index ->
- Box(Modifier.fillMaxSize().testTag("$index"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("$index"))
}
rule.setContent {
LazyLayout(itemProvider) {
@@ -118,8 +122,14 @@
@Test
fun measureAndPlaceMultipleLayoutsInOneItem() {
val itemProvider = itemProvider({ 1 }) { index ->
- Box(Modifier.fillMaxSize().testTag("${index}x0"))
- Box(Modifier.fillMaxSize().testTag("${index}x1"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("${index}x0"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("${index}x1"))
}
rule.setContent {
@@ -143,7 +153,10 @@
@Test
fun updatingitemProvider() {
var itemProvider by mutableStateOf(itemProvider({ 1 }) { index ->
- Box(Modifier.fillMaxSize().testTag("$index"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("$index"))
})
rule.setContent {
@@ -166,7 +179,10 @@
rule.runOnIdle {
itemProvider = itemProvider({ 2 }) { index ->
- Box(Modifier.fillMaxSize().testTag("$index"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("$index"))
}
}
@@ -178,7 +194,10 @@
fun stateBaseditemProvider() {
var itemCount by mutableStateOf(1)
val itemProvider = itemProvider({ itemCount }) { index ->
- Box(Modifier.fillMaxSize().testTag("$index"))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("$index"))
}
rule.setContent {
@@ -228,7 +247,11 @@
}
}
val itemProvider = itemProvider({ 1 }) { index ->
- Box(Modifier.fillMaxSize().testTag("$index").then(modifier))
+ Box(
+ Modifier
+ .fillMaxSize()
+ .testTag("$index")
+ .then(modifier))
}
var needToCompose by mutableStateOf(false)
val prefetchState = LazyLayoutPrefetchState()
@@ -335,13 +358,15 @@
fun nodeIsReusedWithoutExtraRemeasure() {
var indexToCompose by mutableStateOf<Int?>(0)
var remeasuresCount = 0
- val modifier = Modifier.layout { measurable, constraints ->
- val placeable = measurable.measure(constraints)
- remeasuresCount++
- layout(placeable.width, placeable.height) {
- placeable.place(0, 0)
+ val modifier = Modifier
+ .layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+ remeasuresCount++
+ layout(placeable.width, placeable.height) {
+ placeable.place(0, 0)
+ }
}
- }.fillMaxSize()
+ .fillMaxSize()
val itemProvider = itemProvider({ 2 }) {
Box(modifier)
}
@@ -376,6 +401,52 @@
}
@Test
+ fun nodeIsReusedWhenRemovedFirst() {
+ var itemCount by mutableStateOf(1)
+ var remeasuresCount = 0
+ val modifier = Modifier
+ .layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+ remeasuresCount++
+ layout(placeable.width, placeable.height) {
+ placeable.place(0, 0)
+ }
+ }
+ .fillMaxSize()
+ val itemProvider = itemProvider({ itemCount }) {
+ Box(modifier)
+ }
+
+ rule.setContent {
+ LazyLayout(itemProvider) { constraints ->
+ val node = if (itemCount == 1) {
+ measure(0, constraints).first()
+ } else {
+ null
+ }
+ layout(10, 10) {
+ node?.place(0, 0)
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(remeasuresCount).isEqualTo(1)
+ // node will be kept for reuse
+ itemCount = 0
+ }
+
+ rule.runOnIdle {
+ // node should be now reused
+ itemCount = 1
+ }
+
+ rule.runOnIdle {
+ assertThat(remeasuresCount).isEqualTo(1)
+ }
+ }
+
+ @Test
fun regularCompositionIsUsedInPrefetchTimeCalculation() {
val itemProvider = itemProvider({ 1 }) {
Box(Modifier.fillMaxSize())
@@ -397,13 +468,47 @@
}
}
+ @Test
+ fun skippingItemBlockWhenKeyIsObservableButDidntChange() {
+ val stateList = mutableStateListOf(0)
+ var itemCalls = 0
+ val itemProvider = object : LazyLayoutItemProvider {
+ @Composable
+ override fun Item(index: Int, key: Any) {
+ assertThat(index).isEqualTo(0)
+ assertThat(key).isEqualTo(index)
+ itemCalls++
+ }
+
+ override val itemCount: Int get() = stateList.size
+
+ override fun getKey(index: Int) = stateList[index]
+ }
+ rule.setContent {
+ LazyLayout(itemProvider) { constraint ->
+ measure(0, constraint)
+ layout(100, 100) {}
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(itemCalls).isEqualTo(1)
+
+ stateList += 1
+ }
+
+ rule.runOnIdle {
+ assertThat(itemCalls).isEqualTo(1)
+ }
+ }
+
private fun itemProvider(
itemCount: () -> Int,
itemContent: @Composable (Int) -> Unit
): LazyLayoutItemProvider {
return object : LazyLayoutItemProvider {
@Composable
- override fun Item(index: Int) {
+ override fun Item(index: Int, key: Any) {
itemContent(index)
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyCustomKeysTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyCustomKeysTest.kt
index fcb0408..9c97094 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyCustomKeysTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyCustomKeysTest.kt
@@ -429,6 +429,26 @@
}
}
+ @Test
+ fun keysLambdaIsCalledOnlyOnce() {
+ var keyCalls = 0
+
+ rule.setContent {
+ LazyColumn {
+ items(1, key = {
+ keyCalls++
+ 0
+ }) {
+ Item("item")
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(keyCalls).isEqualTo(1)
+ }
+ }
+
private fun testReordering(content: LazyListScope.(List<MyClass>) -> Unit) {
var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
index fa60831..2763637 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
@@ -18,6 +18,10 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.VectorConverter
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.scrollBy
@@ -65,14 +69,15 @@
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import kotlinx.coroutines.runBlocking
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.junit.runners.Parameterized
-import kotlin.math.roundToInt
import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@LargeTest
@RunWith(Parameterized::class)
@@ -1703,6 +1708,58 @@
}
}
+ @Test
+ fun interruptedSizeChange() {
+ var item0Size by mutableStateOf(itemSizeDp)
+ val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+ rule.setContent {
+ LazyList {
+ items(2, key = { it }) {
+ Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = itemSize2Dp
+ }
+
+ rule.waitForIdle()
+ rule.mainClock.advanceTimeByFrame()
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(0 to 0f, 1 to itemSize)
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterOneFrame =
+ animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+ assertPositions(0 to 0f, 1 to valueAfterOneFrame, fraction = fraction)
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = 0.dp
+ }
+
+ rule.waitForIdle()
+ val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+ val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(0 to 0f, 1 to startValue)
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterThreeFrames = animSpec.getValueAtFrame(
+ 1,
+ from = startValue,
+ to = 0f,
+ initialVelocity = startVelocity
+ )
+ assertPositions(0 to 0f, 1 to valueAfterThreeFrames)
+ }
+ }
+ }
+
private fun assertPositions(
vararg expected: Pair<Any, Float>,
crossAxis: List<Pair<Any, Float>>? = null,
@@ -1777,9 +1834,11 @@
for (i in 0..duration step FrameDuration) {
val fraction = i / duration.toFloat()
onFrame(fraction)
- rule.mainClock.advanceTimeBy(FrameDuration)
- expectedTime += FrameDuration
- assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ if (i < duration) {
+ rule.mainClock.advanceTimeBy(FrameDuration)
+ expectedTime += FrameDuration
+ assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ }
}
}
@@ -1923,3 +1982,51 @@
End,
Center
}
+
+internal fun SpringSpec<IntOffset>.getValueAtFrame(
+ frameCount: Int,
+ from: Float,
+ to: Float,
+ initialVelocity: IntOffset = IntOffset.Zero
+): Float {
+ val frameInNanos = TimeUnit.MILLISECONDS.toNanos(FrameDuration)
+ val vectorized = vectorize(converter = IntOffset.VectorConverter)
+ return IntOffset.VectorConverter.convertFromVector(
+ vectorized.getValueFromNanos(
+ playTimeNanos = frameInNanos * frameCount,
+ initialValue = IntOffset.VectorConverter.convertToVector(
+ IntOffset(0, from.toInt())
+ ),
+ targetValue = IntOffset.VectorConverter.convertToVector(
+ IntOffset(0, to.toInt())
+ ),
+ initialVelocity = IntOffset.VectorConverter.convertToVector(
+ initialVelocity
+ )
+ )
+ ).y.toFloat()
+}
+
+internal fun SpringSpec<IntOffset>.getVelocityAtFrame(
+ frameCount: Int,
+ from: Float,
+ to: Float,
+ initialVelocity: IntOffset = IntOffset.Zero
+): IntOffset {
+ val frameInNanos = TimeUnit.MILLISECONDS.toNanos(FrameDuration)
+ val vectorized = vectorize(converter = IntOffset.VectorConverter)
+ return IntOffset.VectorConverter.convertFromVector(
+ vectorized.getVelocityFromNanos(
+ playTimeNanos = frameInNanos * frameCount,
+ initialValue = IntOffset.VectorConverter.convertToVector(
+ IntOffset(0, from.toInt())
+ ),
+ targetValue = IntOffset.VectorConverter.convertToVector(
+ IntOffset(0, to.toInt())
+ ),
+ initialVelocity = IntOffset.VectorConverter.convertToVector(
+ initialVelocity
+ )
+ )
+ )
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListPinnableContainerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListPinnableContainerTest.kt
index a743ac3c..1b9ebac 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListPinnableContainerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListPinnableContainerTest.kt
@@ -18,9 +18,9 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListsIndexedTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListsIndexedTest.kt
index df2d615..41fc6d4 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListsIndexedTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListsIndexedTest.kt
@@ -21,10 +21,10 @@
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyList
import androidx.compose.foundation.lazy.LazyListScope
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyNestedScrollingTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyNestedScrollingTest.kt
index 78a5fdc..cac03bd 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyNestedScrollingTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyNestedScrollingTest.kt
@@ -16,17 +16,17 @@
package androidx.compose.foundation.lazy.list
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.requiredSize
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyScrollTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyScrollTest.kt
index bca1dc3..14fe3b1 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyScrollTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyScrollTest.kt
@@ -19,24 +19,26 @@
import androidx.compose.animation.core.FloatSpringSpec
import androidx.compose.foundation.AutoTestFrameClock
import androidx.compose.foundation.BaseLazyLayoutTestWithOrientation.Companion.FrameDuration
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -47,8 +49,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
@MediumTest
@RunWith(Parameterized::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
index 984c7d4..41f1c73f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
@@ -18,6 +18,8 @@
import androidx.compose.animation.core.FiniteAnimationSpec
import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.scrollBy
@@ -27,6 +29,8 @@
import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.requiredWidthIn
+import androidx.compose.foundation.lazy.list.getValueAtFrame
+import androidx.compose.foundation.lazy.list.getVelocityAtFrame
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -1992,6 +1996,70 @@
}
}
+ @Test
+ fun interruptedSizeChange() {
+ var item0Size by mutableStateOf(itemSizeDp)
+ val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+ rule.setContent {
+ LazyStaggeredGrid(cells = 1) {
+ items(2, key = { it }) {
+ Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+ }
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = itemSize2Dp
+ }
+
+ rule.waitForIdle()
+ rule.mainClock.advanceTimeByFrame()
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, itemSize)
+ )
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterOneFrame =
+ animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, valueAfterOneFrame)
+ )
+ }
+ }
+
+ rule.runOnUiThread {
+ item0Size = 0.dp
+ }
+
+ rule.waitForIdle()
+ val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+ val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+ onAnimationFrame(duration = FrameDuration) { fraction ->
+ if (fraction == 0f) {
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, startValue)
+ )
+ } else {
+ assertThat(fraction).isEqualTo(1f)
+ val valueAfterThreeFrames = animSpec.getValueAtFrame(
+ 1,
+ from = startValue,
+ to = 0f,
+ initialVelocity = startVelocity
+ )
+ assertPositions(
+ 0 to AxisOffset(0f, 0f),
+ 1 to AxisOffset(0f, valueAfterThreeFrames)
+ )
+ }
+ }
+ }
+
private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
@@ -2075,9 +2143,11 @@
for (i in 0..duration step FrameDuration) {
val fraction = i / duration.toFloat()
onFrame(fraction)
- rule.mainClock.advanceTimeBy(FrameDuration)
- expectedTime += FrameDuration
- assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ if (i < duration) {
+ rule.mainClock.advanceTimeBy(FrameDuration)
+ expectedTime += FrameDuration
+ assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+ }
}
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCustomKeysTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCustomKeysTest.kt
new file mode 100644
index 0000000..554a393
--- /dev/null
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridCustomKeysTest.kt
@@ -0,0 +1,508 @@
+/*
+ * Copyright 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.
+ */
+
+package androidx.compose.foundation.lazy.staggeredgrid
+
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.assertHeightIsEqualTo
+import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class LazyCustomKeysTest {
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ val itemSize = with(rule.density) {
+ 100.toDp()
+ }
+ val columns = 2
+
+ @Test
+ fun itemsWithKeysAreLaidOutCorrectly() {
+ val list = listOf(MyClass(0), MyClass(1), MyClass(2))
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item("${it.id}")
+ }
+ }
+ }
+
+ assertItems("0", "1", "2")
+ }
+
+ @Test
+ fun removing_statesAreMoved() {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(list[0], list[2])
+ }
+
+ assertItems("0", "2")
+ }
+
+ @Test
+ fun reordering_statesAreMoved_list() {
+ testReordering { grid ->
+ items(grid, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ @Test
+ fun reordering_statesAreMoved_list_indexed() {
+ testReordering { grid ->
+ itemsIndexed(grid, key = { _, item -> item.id }) { _, item ->
+ Item(remember { "${item.id}" })
+ }
+ }
+ }
+
+ @Test
+ fun reordering_statesAreMoved_array() {
+ testReordering { grid ->
+ val array = grid.toTypedArray()
+ items(array, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ @Test
+ fun reordering_statesAreMoved_array_indexed() {
+ testReordering { grid ->
+ val array = grid.toTypedArray()
+ itemsIndexed(array, key = { _, item -> item.id }) { _, item ->
+ Item(remember { "${item.id}" })
+ }
+ }
+ }
+
+ @Test
+ fun reordering_statesAreMoved_itemsWithCount() {
+ testReordering { grid ->
+ items(grid.size, key = { grid[it].id }) {
+ Item(remember { "${grid[it].id}" })
+ }
+ }
+ }
+
+ @Test
+ fun fullyReplacingTheList() {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+ var counter = 0
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item(remember { counter++ }.toString())
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(MyClass(3), MyClass(4), MyClass(5), MyClass(6))
+ }
+
+ assertItems("3", "4", "5", "6")
+ }
+
+ @Test
+ fun keepingOneItem() {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+ var counter = 0
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item(remember { counter++ }.toString())
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(MyClass(1))
+ }
+
+ assertItems("1")
+ }
+
+ @Test
+ fun keepingOneItemAndAddingMore() {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+ var counter = 0
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item(remember { counter++ }.toString())
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(MyClass(1), MyClass(3))
+ }
+
+ assertItems("1", "3")
+ }
+
+ @Test
+ fun mixingKeyedItemsAndNot() {
+ testReordering { list ->
+ item {
+ Item("${list.first().id}")
+ }
+ items(list.subList(fromIndex = 1, toIndex = list.size), key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ @Test
+ fun updatingTheDataSetIsCorrectlyApplied() {
+ val state = mutableStateOf(emptyList<Int>())
+
+ rule.setContent {
+ LaunchedEffect(Unit) {
+ state.value = listOf(4, 1, 3)
+ }
+
+ val list = state.value
+
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns), Modifier.fillMaxSize()) {
+ items(list, key = { it }) {
+ Item(it.toString())
+ }
+ }
+ }
+
+ assertItems("4", "1", "3")
+
+ rule.runOnIdle {
+ state.value = listOf(2, 4, 6, 1, 3, 5)
+ }
+
+ assertItems("2", "4", "6", "1", "3", "5")
+ }
+
+ @Test
+ fun reordering_usingMutableStateListOf() {
+ val list = mutableStateListOf(MyClass(0), MyClass(1), MyClass(2))
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ items(list, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list.add(list.removeAt(1))
+ }
+
+ assertItems("0", "2", "1")
+ }
+
+ @Test
+ fun keysInLazyListItemInfoAreCorrect() {
+ val list = listOf(MyClass(0), MyClass(1), MyClass(2))
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState()
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns), state = state) {
+ items(list, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(
+ state.visibleKeys
+ ).isEqualTo(listOf(0, 1, 2))
+ }
+ }
+
+ @Test
+ fun keysInLazyListItemInfoAreCorrectAfterReordering() {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState()
+ LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Fixed(columns), state = state) {
+ items(list, key = { it.id }) {
+ Item(remember { "${it.id}" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(list[0], list[2], list[1])
+ }
+
+ rule.runOnIdle {
+ assertThat(
+ state.visibleKeys
+ ).isEqualTo(listOf(0, 2, 1))
+ }
+ }
+
+ @Test
+ fun addingItemsBeforeWithoutKeysIsMaintainingTheIndex() {
+ var list by mutableStateOf((10..15).toList())
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState()
+ LazyVerticalStaggeredGrid(
+ StaggeredGridCells.Fixed(columns),
+ Modifier.size(itemSize * 2.5f),
+ state
+ ) {
+ items(list) {
+ Item(remember { "$it" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = (0..15).toList()
+ }
+
+ rule.runOnIdle {
+ assertThat(state.firstVisibleItemIndex).isEqualTo(0)
+ }
+ }
+
+ @Test
+ fun addingItemsBeforeKeepingThisItemFirst() {
+ var list by mutableStateOf((10..15).toList())
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState()
+ LazyVerticalStaggeredGrid(
+ StaggeredGridCells.Fixed(columns),
+ Modifier.size(itemSize * 2.5f),
+ state
+ ) {
+ items(list, key = { it }) {
+ Item(remember { "$it" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = (0..15).toList()
+ }
+
+ rule.runOnIdle {
+ assertThat(state.firstVisibleItemIndex).isEqualTo(10)
+ assertThat(
+ state.visibleKeys
+ ).isEqualTo(listOf(10, 11, 12, 13, 14, 15))
+ }
+ }
+
+ @Test
+ fun addingItemsRightAfterKeepingThisItemFirst() {
+ var list by mutableStateOf((0..5).toList() + (10..15).toList())
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState(5)
+ LazyVerticalStaggeredGrid(
+ StaggeredGridCells.Fixed(1),
+ Modifier.size(itemSize * 2.5f),
+ state
+ ) {
+ items(list, key = { it }) {
+ Item(remember { "$it" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = (0..15).toList()
+ }
+
+ rule.runOnIdle {
+ assertThat(state.firstVisibleItemIndex).isEqualTo(5)
+ assertThat(
+ state.visibleKeys
+ ).isEqualTo(listOf(5, 6, 7))
+ }
+ }
+
+ @Test
+ fun addingItemsBeforeWhileCurrentItemIsNotInTheBeginning() {
+ var list by mutableStateOf((10..30).toList())
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState(10) // key 20 is the first item
+ LazyVerticalStaggeredGrid(
+ StaggeredGridCells.Fixed(columns),
+ Modifier.size(itemSize * 2.5f),
+ state
+ ) {
+ items(list, key = { it }) {
+ Item(remember { "$it" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = (0..30).toList()
+ }
+
+ rule.runOnIdle {
+ assertThat(state.firstVisibleItemIndex).isEqualTo(20)
+ assertThat(
+ state.visibleKeys
+ ).isEqualTo(listOf(20, 21, 22, 23, 24, 25))
+ }
+ }
+
+ @Test
+ fun removingTheCurrentItemMaintainsTheIndex() {
+ var list by mutableStateOf((0..20).toList())
+ lateinit var state: LazyStaggeredGridState
+
+ rule.setContent {
+ state = rememberLazyStaggeredGridState(8)
+ LazyVerticalStaggeredGrid(
+ StaggeredGridCells.Fixed(columns),
+ Modifier.size(itemSize * 2.5f),
+ state
+ ) {
+ items(list, key = { it }) {
+ Item(remember { "$it" })
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ list = (0..20) - 8
+ }
+
+ rule.runOnIdle {
+ assertThat(state.firstVisibleItemIndex).isEqualTo(8)
+ assertThat(state.visibleKeys).isEqualTo(listOf(9, 10, 11, 12, 13, 14))
+ }
+ }
+
+ @Test
+ fun keysLambdaIsCalledOnlyOnce() {
+ var keyCalls = 0
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(1)) {
+ items(1, key = {
+ keyCalls++
+ 0
+ }) {
+ Item("item")
+ }
+ }
+ }
+
+ rule.runOnIdle {
+ assertThat(keyCalls).isEqualTo(1)
+ }
+ }
+
+ private fun testReordering(content: LazyStaggeredGridScope.(List<MyClass>) -> Unit) {
+ var list by mutableStateOf(listOf(MyClass(0), MyClass(1), MyClass(2)))
+
+ rule.setContent {
+ LazyVerticalStaggeredGrid(StaggeredGridCells.Fixed(columns)) {
+ content(list)
+ }
+ }
+
+ rule.runOnIdle {
+ list = listOf(list[0], list[2], list[1])
+ }
+
+ assertItems("0", "2", "1")
+ }
+
+ private fun assertItems(vararg tags: String) {
+ var currentTop = 0.dp
+ var column = 0
+ tags.forEach {
+ rule.onNodeWithTag(it)
+ .assertTopPositionInRootIsEqualTo(currentTop)
+ .assertHeightIsEqualTo(itemSize)
+ ++column
+ if (column == columns) {
+ currentTop += itemSize
+ column = 0
+ }
+ }
+ }
+
+ @Composable
+ private fun Item(tag: String) {
+ Spacer(
+ Modifier
+ .testTag(tag)
+ .size(itemSize)
+ )
+ }
+
+ private class MyClass(val id: Int)
+}
+
+val LazyStaggeredGridState.visibleKeys: List<Any> get() = layoutInfo.visibleItemsInfo.map { it.key }
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridReverseLayoutTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridReverseLayoutTest.kt
index 6af08de..344ebe3 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridReverseLayoutTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridReverseLayoutTest.kt
@@ -19,15 +19,15 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
-import androidx.compose.ui.Modifier
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
-import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridTest.kt
index 4dedd01..d5e13df 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridTest.kt
@@ -22,10 +22,12 @@
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.list.setContentWithTestViewConfiguration
import androidx.compose.foundation.text.BasicText
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
@@ -1934,4 +1936,60 @@
rule.onNodeWithTag("1")
.assertAxisBounds(DpOffset(itemSizeDp, itemSizeDp * 2), DpSize(itemSizeDp, itemSizeDp))
}
+
+ @Test
+ fun scrollDuringMeasure() {
+ rule.setContent {
+ BoxWithConstraints {
+ val state = rememberLazyStaggeredGridState()
+ LazyStaggeredGrid(
+ lanes = 1,
+ state = state,
+ modifier = Modifier.axisSize(
+ crossAxis = itemSizeDp * 2,
+ mainAxis = itemSizeDp * 5
+ ),
+ ) {
+ items(20) {
+ Spacer(
+ modifier = Modifier.mainAxisSize(itemSizeDp).testTag(it.toString())
+ )
+ }
+ }
+ LaunchedEffect(state) {
+ state.scrollToItem(10)
+ }
+ }
+ }
+
+ rule.onNodeWithTag("10")
+ .assertStartPositionInRootIsEqualTo(0.dp)
+ }
+
+ @Test
+ fun scrollInLaunchedEffect() {
+ rule.setContent {
+ val state = rememberLazyStaggeredGridState()
+ LazyStaggeredGrid(
+ lanes = 1,
+ state = state,
+ modifier = Modifier.axisSize(
+ crossAxis = itemSizeDp * 2,
+ mainAxis = itemSizeDp * 5
+ ),
+ ) {
+ items(20) {
+ Spacer(
+ modifier = Modifier.mainAxisSize(itemSizeDp).testTag(it.toString())
+ )
+ }
+ }
+ LaunchedEffect(state) {
+ state.scrollToItem(10)
+ }
+ }
+
+ rule.onNodeWithTag("10")
+ .assertStartPositionInRootIsEqualTo(0.dp)
+ }
}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCustomKeyTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCustomKeyTest.kt
new file mode 100644
index 0000000..5e3afed
--- /dev/null
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/pager/PagerCustomKeyTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.foundation.pager
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalFoundationApi::class)
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class PagerCustomKeyTest {
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ @Test
+ fun keysLambdaIsCalledOnlyOnce() {
+ var keyCalls = 0
+
+ rule.setContent {
+ HorizontalPager(
+ state = rememberPagerState { 1 },
+ key = {
+ keyCalls++
+ 0
+ }
+ ) {
+ Spacer(Modifier.fillMaxSize())
+ }
+ }
+
+ rule.runOnIdle {
+ Truth.assertThat(keyCalls).isEqualTo(1)
+ }
+ }
+}
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequesterViewIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequesterViewIntegrationTest.kt
index d3a38ce..37436c9 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequesterViewIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/relocation/BringIntoViewRequesterViewIntegrationTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.relocation
-import android.graphics.Rect as AndroidRect
import android.content.Context
+import android.graphics.Rect as AndroidRect
import android.view.View
import android.widget.FrameLayout
import androidx.compose.foundation.ExperimentalFoundationApi
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
index b23e468..d48e823 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/ClickableTextTest.kt
@@ -29,6 +29,9 @@
import androidx.compose.ui.text.AnnotatedString
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argWhere
import org.mockito.kotlin.inOrder
@@ -36,9 +39,6 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldSoftWrapTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldSoftWrapTest.kt
index bba26f4..e96325c 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldSoftWrapTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextFieldSoftWrapTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.text
-import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
index 0226267..3d76e18 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/CoreTextInlineContentTest.kt
@@ -43,11 +43,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextDelegateIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextDelegateIntegrationTest.kt
index 3120601..ecc70a7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextDelegateIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextDelegateIntegrationTest.kt
@@ -28,13 +28,13 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import kotlin.math.roundToInt
@OptIn(InternalFoundationTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
index dc5e79b..1970055 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextFieldInteractionsTest.kt
@@ -16,12 +16,12 @@
package androidx.compose.foundation.text
+import androidx.compose.foundation.focusable
import androidx.compose.foundation.interaction.DragInteraction
import androidx.compose.foundation.interaction.FocusInteraction
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
-import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutResultIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutResultIntegrationTest.kt
index b6a2ee9..2a3379c 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutResultIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/TextLayoutResultIntegrationTest.kt
@@ -28,13 +28,13 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import kotlin.math.floor
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import kotlin.math.floor
@OptIn(InternalFoundationTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/modifiers/TextLayoutResultIntegrationTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/modifiers/TextLayoutResultIntegrationTest.kt
index 1735715..e86416a 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/modifiers/TextLayoutResultIntegrationTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/modifiers/TextLayoutResultIntegrationTest.kt
@@ -29,14 +29,14 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.IntegerSubject
import com.google.common.truth.Truth.assertThat
+import kotlin.math.floor
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.google.common.truth.IntegerSubject
-import kotlin.math.floor
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
index 05fbc24..e601a24 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/MultiWidgetSelectionDelegateTest.kt
@@ -40,10 +40,10 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
index 4abc2b5..540a13b 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerFocusTest.kt
@@ -57,13 +57,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import java.util.concurrent.CountDownLatch
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
index 54927cb..7096695 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionContainerTest.kt
@@ -79,15 +79,15 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import java.util.concurrent.CountDownLatch
import kotlin.math.max
import kotlin.math.sign
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlePopupPositionTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlePopupPositionTest.kt
index 69c23d1..55b4d0e 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlePopupPositionTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlePopupPositionTest.kt
@@ -44,6 +44,8 @@
import androidx.test.espresso.matcher.BoundedMatcher
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
@@ -51,8 +53,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlesTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlesTest.kt
index d4c185a..8e8cdac 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlesTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/text/selection/SelectionHandlesTest.kt
@@ -37,14 +37,14 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldDefaultWidthTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldDefaultWidthTest.kt
index 6ff37fe..bc01efe 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldDefaultWidthTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldDefaultWidthTest.kt
@@ -36,11 +36,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.ceil
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.ceil
-import kotlin.math.roundToInt
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
index adda314..ed5ac51 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldOnValueChangeTextFieldValueTest.kt
@@ -41,6 +41,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.clearInvocations
@@ -48,10 +52,6 @@
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
index 990b749..31f5b9d 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldTest.kt
@@ -150,12 +150,6 @@
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import kotlin.test.assertFailsWith
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -163,6 +157,12 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
index 3ad3067..4d82c56 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/textfield/TextFieldUndoTest.kt
@@ -16,7 +16,6 @@
package androidx.compose.foundation.textfield
-import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent
import android.view.KeyEvent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.text.BasicTextField
@@ -27,6 +26,7 @@
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.key.Key
+import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent
import androidx.compose.ui.input.key.nativeKeyCode
import androidx.compose.ui.platform.LocalTextInputService
import androidx.compose.ui.test.hasSetTextAction
@@ -36,10 +36,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/foundation/foundation/src/androidMain/AndroidManifest.xml b/compose/foundation/foundation/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/compose/foundation/foundation/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.kt
index 0df1c34..48fccdc 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/AndroidOverscroll.kt
@@ -24,8 +24,8 @@
import androidx.compose.foundation.EdgeEffectCompat.onAbsorbCompat
import androidx.compose.foundation.EdgeEffectCompat.onPullDistanceCompat
import androidx.compose.foundation.EdgeEffectCompat.onReleaseWithOppositeDelta
-import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
diff --git a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/ContextMenu.android.kt b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/ContextMenu.android.kt
index e5d86d8..077a75f 100644
--- a/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/ContextMenu.android.kt
+++ b/compose/foundation/foundation/src/androidMain/kotlin/androidx/compose/foundation/text/ContextMenu.android.kt
@@ -20,8 +20,10 @@
import androidx.compose.foundation.text.selection.TextFieldSelectionManager
import androidx.compose.runtime.Composable
+// TODO (b/269341173) remove inline once these composables are non-trivial
+
@Composable
-internal actual fun ContextMenuArea(
+internal actual inline fun ContextMenuArea(
manager: TextFieldSelectionManager,
content: @Composable () -> Unit
) {
@@ -29,7 +31,7 @@
}
@Composable
-internal actual fun ContextMenuArea(
+internal actual inline fun ContextMenuArea(
manager: SelectionManager,
content: @Composable () -> Unit
) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
index 910e79f..83ed93c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt
@@ -16,7 +16,6 @@
package androidx.compose.foundation
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
@@ -25,6 +24,7 @@
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.InspectorInfo
@@ -89,7 +89,7 @@
)
private class BackgroundElement(
- private val color: Color? = null,
+ private val color: Color = Color.Unspecified,
private val brush: Brush? = null,
private val alpha: Float,
private val shape: Shape,
@@ -116,7 +116,7 @@
}
override fun hashCode(): Int {
- var result = color?.hashCode() ?: 0
+ var result = color.hashCode()
result = 31 * result + (brush?.hashCode() ?: 0)
result = 31 * result + alpha.hashCode()
result = 31 * result + shape.hashCode()
@@ -133,7 +133,7 @@
}
private class BackgroundNode(
- var color: Color?,
+ var color: Color,
var brush: Brush?,
var alpha: Float,
var shape: Shape,
@@ -143,6 +143,7 @@
private var lastSize: Size? = null
private var lastLayoutDirection: LayoutDirection? = null
private var lastOutline: Outline? = null
+ private var lastShape: Shape? = null
override fun ContentDrawScope.draw() {
if (shape === RectangleShape) {
@@ -155,21 +156,22 @@
}
private fun ContentDrawScope.drawRect() {
- color?.let { drawRect(color = it) }
+ if (color != Color.Unspecified) drawRect(color = color)
brush?.let { drawRect(brush = it, alpha = alpha) }
}
private fun ContentDrawScope.drawOutline() {
val outline =
- if (size == lastSize && layoutDirection == lastLayoutDirection) {
+ if (size == lastSize && layoutDirection == lastLayoutDirection && lastShape == shape) {
lastOutline!!
} else {
shape.createOutline(size, layoutDirection, this)
}
- color?.let { drawOutline(outline, color = it) }
+ if (color != Color.Unspecified) drawOutline(outline, color = color)
brush?.let { drawOutline(outline, brush = it, alpha = alpha) }
lastOutline = outline
lastSize = size
lastLayoutDirection = layoutDirection
+ lastShape = shape
}
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
index 61d3630..c96bdb3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/BasicMarquee.kt
@@ -32,6 +32,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
@@ -201,8 +202,8 @@
DrawModifierNode,
FocusEventModifierNode {
- private var contentWidth by mutableStateOf(0)
- private var containerWidth by mutableStateOf(0)
+ private var contentWidth by mutableIntStateOf(0)
+ private var containerWidth by mutableIntStateOf(0)
private var hasFocus by mutableStateOf(false)
var spacing: MarqueeSpacing by mutableStateOf(spacing)
var animationMode: MarqueeAnimationMode by mutableStateOf(animationMode)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Border.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Border.kt
index 0f0816b..c95216d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Border.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Border.kt
@@ -16,12 +16,10 @@
package androidx.compose.foundation
-import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
+import androidx.compose.ui.draw.CacheDrawModifierNode
import androidx.compose.ui.draw.CacheDrawScope
import androidx.compose.ui.draw.DrawResult
-import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.RoundRect
@@ -47,8 +45,9 @@
import androidx.compose.ui.graphics.drawscope.clipRect
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.drawscope.translate
-import androidx.compose.ui.node.Ref
-import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.node.DelegatingNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.toSize
@@ -85,68 +84,29 @@
* and clip it.
*
* @sample androidx.compose.foundation.samples.BorderSampleWithBrush()
+ * @sample androidx.compose.foundation.samples.BorderSampleWithDynamicData()
*
* @param width width of the border. Use [Dp.Hairline] for a hairline border.
* @param brush brush to paint the border with
* @param shape shape of the border
*/
-fun Modifier.border(width: Dp, brush: Brush, shape: Shape): Modifier = composed(
- factory = {
- // BorderCache object that is lazily allocated depending on the type of shape
- // This object is only used for generic shapes and rounded rectangles with different corner
- // radius sizes.
- val borderCacheRef = remember { Ref<BorderCache>() }
- this.then(
- Modifier.drawWithCache {
- val hasValidBorderParams = width.toPx() >= 0f && size.minDimension > 0f
- if (!hasValidBorderParams) {
- drawContentWithoutBorder()
- } else {
- val strokeWidthPx = min(
- if (width == Dp.Hairline) 1f else ceil(width.toPx()),
- ceil(size.minDimension / 2)
- )
- val halfStroke = strokeWidthPx / 2
- val topLeft = Offset(halfStroke, halfStroke)
- val borderSize = Size(
- size.width - strokeWidthPx,
- size.height - strokeWidthPx
- )
- // The stroke is larger than the drawing area so just draw a full shape instead
- val fillArea = (strokeWidthPx * 2) > size.minDimension
- when (val outline = shape.createOutline(size, layoutDirection, this)) {
- is Outline.Generic ->
- drawGenericBorder(
- borderCacheRef,
- brush,
- outline,
- fillArea,
- strokeWidthPx
- )
- is Outline.Rounded ->
- drawRoundRectBorder(
- borderCacheRef,
- brush,
- outline,
- topLeft,
- borderSize,
- fillArea,
- strokeWidthPx
- )
- is Outline.Rectangle ->
- drawRectBorder(
- brush,
- topLeft,
- borderSize,
- fillArea,
- strokeWidthPx
- )
- }
- }
- }
- )
- },
- inspectorInfo = debugInspectorInfo {
+fun Modifier.border(width: Dp, brush: Brush, shape: Shape) =
+ this then BorderModifierNodeElement(width, brush, shape)
+
+internal data class BorderModifierNodeElement(
+ val width: Dp,
+ val brush: Brush,
+ val shape: Shape
+) : ModifierNodeElement<BorderModifierNode>() {
+ override fun create() = BorderModifierNode(width, brush, shape)
+
+ override fun update(node: BorderModifierNode) {
+ node.width = width
+ node.brush = brush
+ node.shape = shape
+ }
+
+ override fun InspectorInfo.inspectableProperties() {
name = "border"
properties["width"] = width
if (brush is SolidColor) {
@@ -157,10 +117,241 @@
}
properties["shape"] = shape
}
-)
+}
-private fun Ref<BorderCache>.obtain(): BorderCache =
- this.value ?: BorderCache().also { value = it }
+internal class BorderModifierNode(
+ widthParameter: Dp,
+ brushParameter: Brush,
+ shapeParameter: Shape
+) : DelegatingNode() {
+
+ // BorderCache object that is lazily allocated depending on the type of shape
+ // This object is only used for generic shapes and rounded rectangles with different corner
+ // radius sizes.
+ // Note: Extension functions that use BorderCache are part of this class.
+ private var borderCache: BorderCache? = null
+
+ var width = widthParameter
+ set(value) {
+ field = value
+ drawWithCacheModifierNode.invalidateDrawCache()
+ }
+ var brush = brushParameter
+ var shape = shapeParameter
+ set(value) {
+ field = value
+ drawWithCacheModifierNode.invalidateDrawCache()
+ }
+
+ private val drawWithCacheModifierNode = delegate(
+ CacheDrawModifierNode {
+ val hasValidBorderParams = width.toPx() >= 0f && size.minDimension > 0f
+ if (!hasValidBorderParams) {
+ drawContentWithoutBorder()
+ } else {
+ val strokeWidthPx = min(
+ if (width == Dp.Hairline) 1f else ceil(width.toPx()),
+ ceil(size.minDimension / 2)
+ )
+ val halfStroke = strokeWidthPx / 2
+ val topLeft = Offset(halfStroke, halfStroke)
+ val borderSize = Size(
+ size.width - strokeWidthPx,
+ size.height - strokeWidthPx
+ )
+ // The stroke is larger than the drawing area so just draw a full shape instead
+ val fillArea = (strokeWidthPx * 2) > size.minDimension
+ when (val outline = shape.createOutline(size, layoutDirection, this)) {
+ is Outline.Generic ->
+ drawGenericBorder(
+ brush,
+ outline,
+ fillArea,
+ strokeWidthPx
+ )
+
+ is Outline.Rounded ->
+ drawRoundRectBorder(
+ brush,
+ outline,
+ topLeft,
+ borderSize,
+ fillArea,
+ strokeWidthPx
+ )
+
+ is Outline.Rectangle ->
+ drawRectBorder(
+ brush,
+ topLeft,
+ borderSize,
+ fillArea,
+ strokeWidthPx
+ )
+ }
+ }
+ }
+ )
+
+ /**
+ * Border implementation for generic paths. Note it is possible to be given paths
+ * that do not make sense in the context of a border (ex. a figure 8 path or a non-enclosed
+ * shape) We do not handle that here as we expect developers to give us enclosed,
+ * non-overlapping paths.
+ */
+ private fun CacheDrawScope.drawGenericBorder(
+ brush: Brush,
+ outline: Outline.Generic,
+ fillArea: Boolean,
+ strokeWidth: Float
+ ): DrawResult =
+ if (fillArea) {
+ onDrawWithContent {
+ drawContent()
+ drawPath(outline.path, brush = brush)
+ }
+ } else {
+ // Optimization, if we are only drawing a solid color border, we only need an alpha8
+ // mask as we can draw the mask with a tint.
+ // Otherwise we need to allocate a full ImageBitmap and draw it normally
+ val config: ImageBitmapConfig
+ val colorFilter: ColorFilter?
+ if (brush is SolidColor) {
+ config = ImageBitmapConfig.Alpha8
+ colorFilter = ColorFilter.tint(brush.value)
+ } else {
+ config = ImageBitmapConfig.Argb8888
+ colorFilter = null
+ }
+
+ val pathBounds = outline.path.getBounds()
+ // Create a mask path that includes a rectangle with the original path cut out of it.
+ // Note: borderCache is part of the class that defines this extension function.
+ if (borderCache == null) {
+ borderCache = BorderCache()
+ }
+ val maskPath = borderCache!!.obtainPath().apply {
+ reset()
+ addRect(pathBounds)
+ op(this, outline.path, PathOperation.Difference)
+ }
+
+ val cacheImageBitmap: ImageBitmap
+ val pathBoundsSize = IntSize(
+ ceil(pathBounds.width).toInt(),
+ ceil(pathBounds.height).toInt()
+ )
+ with(borderCache!!) {
+ // Draw into offscreen bitmap with the size of the path
+ // We need to draw into this intermediate bitmap to act as a layer
+ // and make sure that the clearing logic does not generate underdraw
+ // into the target we are rendering into
+ cacheImageBitmap = drawBorderCache(
+ pathBoundsSize,
+ config
+ ) {
+ // Paths can have offsets, so translate to keep the drawn path
+ // within the bounds of the mask bitmap
+ translate(-pathBounds.left, -pathBounds.top) {
+ // Draw the path with a stroke width twice the provided value.
+ // Because strokes are centered, this will draw both and inner and
+ // outer stroke with the desired stroke width
+ drawPath(
+ path = outline.path,
+ brush = brush,
+ style = Stroke(strokeWidth * 2)
+ )
+
+ // Scale the canvas slightly to cover the background that may be visible
+ // after clearing the outer stroke
+ scale(
+ (size.width + 1) / size.width,
+ (size.height + 1) / size.height
+ ) {
+ // Remove the outer stroke by clearing the inverted mask path
+ drawPath(path = maskPath, brush = brush, blendMode = BlendMode.Clear)
+ }
+ }
+ }
+ }
+
+ onDrawWithContent {
+ drawContent()
+ translate(pathBounds.left, pathBounds.top) {
+ drawImage(cacheImageBitmap, srcSize = pathBoundsSize, colorFilter = colorFilter)
+ }
+ }
+ }
+
+ /**
+ * Border implementation for simple rounded rects and those with different corner
+ * radii
+ */
+ private fun CacheDrawScope.drawRoundRectBorder(
+ brush: Brush,
+ outline: Outline.Rounded,
+ topLeft: Offset,
+ borderSize: Size,
+ fillArea: Boolean,
+ strokeWidth: Float
+ ): DrawResult {
+ return if (outline.roundRect.isSimple) {
+ val cornerRadius = outline.roundRect.topLeftCornerRadius
+ val halfStroke = strokeWidth / 2
+ val borderStroke = Stroke(strokeWidth)
+ onDrawWithContent {
+ drawContent()
+ when {
+ fillArea -> {
+ // If the drawing area is smaller than the stroke being drawn
+ // drawn all around it just draw a filled in rounded rect
+ drawRoundRect(brush, cornerRadius = cornerRadius)
+ }
+ cornerRadius.x < halfStroke -> {
+ // If the corner radius is smaller than half of the stroke width
+ // then the interior curvature of the stroke will be a sharp edge
+ // In this case just draw a normal filled in rounded rect with the
+ // desired corner radius but clipping out the interior rectangle
+ clipRect(
+ strokeWidth,
+ strokeWidth,
+ size.width - strokeWidth,
+ size.height - strokeWidth,
+ clipOp = ClipOp.Difference
+ ) {
+ drawRoundRect(brush, cornerRadius = cornerRadius)
+ }
+ }
+ else -> {
+ // Otherwise draw a stroked rounded rect with the corner radius
+ // shrunk by half of the stroke width. This will ensure that the
+ // outer curvature of the rounded rectangle will have the desired
+ // corner radius.
+ drawRoundRect(
+ brush = brush,
+ topLeft = topLeft,
+ size = borderSize,
+ cornerRadius = cornerRadius.shrink(halfStroke),
+ style = borderStroke
+ )
+ }
+ }
+ }
+ } else {
+ // Note: borderCache is part of the class that defines this extension function.
+ if (borderCache == null) {
+ borderCache = BorderCache()
+ }
+ val path = borderCache!!.obtainPath()
+ val roundedRectPath =
+ createRoundRectPath(path, outline.roundRect, strokeWidth, fillArea)
+ onDrawWithContent {
+ drawContent()
+ drawPath(roundedRectPath, brush = brush)
+ }
+ }
+ }
+}
/**
* Helper object that handles lazily allocating and re-using objects
@@ -202,7 +393,8 @@
}
}
- val targetDrawScope = canvasDrawScope ?: CanvasDrawScope().also { canvasDrawScope = it }
+ val targetDrawScope =
+ canvasDrawScope ?: CanvasDrawScope().also { canvasDrawScope = it }
val drawSize = borderSize.toSize()
targetDrawScope.draw(
this,
@@ -237,155 +429,6 @@
}
/**
- * Border implementation for generic paths. Note it is possible to be given paths
- * that do not make sense in the context of a border (ex. a figure 8 path or a non-enclosed
- * shape) We do not handle that here as we expect developers to give us enclosed, non-overlapping
- * paths
- */
-private fun CacheDrawScope.drawGenericBorder(
- borderCacheRef: Ref<BorderCache>,
- brush: Brush,
- outline: Outline.Generic,
- fillArea: Boolean,
- strokeWidth: Float
-): DrawResult =
- if (fillArea) {
- onDrawWithContent {
- drawContent()
- drawPath(outline.path, brush = brush)
- }
- } else {
- // Optimization, if we are only drawing a solid color border, we only need an alpha8 mask
- // as we can draw the mask with a tint.
- // Otherwise we need to allocate a full ImageBitmap and draw it normally
- val config: ImageBitmapConfig
- val colorFilter: ColorFilter?
- if (brush is SolidColor) {
- config = ImageBitmapConfig.Alpha8
- colorFilter = ColorFilter.tint(brush.value)
- } else {
- config = ImageBitmapConfig.Argb8888
- colorFilter = null
- }
-
- val pathBounds = outline.path.getBounds()
- val borderCache = borderCacheRef.obtain()
- // Create a mask path that includes a rectangle with the original path cut out of it
- val maskPath = borderCache.obtainPath().apply {
- reset()
- addRect(pathBounds)
- op(this, outline.path, PathOperation.Difference)
- }
-
- val cacheImageBitmap: ImageBitmap
- val pathBoundsSize = IntSize(
- ceil(pathBounds.width).toInt(),
- ceil(pathBounds.height).toInt()
- )
- with(borderCache) {
- // Draw into offscreen bitmap with the size of the path
- // We need to draw into this intermediate bitmap to act as a layer
- // and make sure that the clearing logic does not generate underdraw
- // into the target we are rendering into
- cacheImageBitmap = drawBorderCache(
- pathBoundsSize,
- config
- ) {
- // Paths can have offsets, so translate to keep the drawn path
- // within the bounds of the mask bitmap
- translate(-pathBounds.left, -pathBounds.top) {
- // Draw the path with a stroke width twice the provided value.
- // Because strokes are centered, this will draw both and inner and outer stroke
- // with the desired stroke width
- drawPath(path = outline.path, brush = brush, style = Stroke(strokeWidth * 2))
-
- // Scale the canvas slightly to cover the background that may be visible
- // after clearing the outer stroke
- scale(
- (size.width + 1) / size.width,
- (size.height + 1) / size.height
- ) {
- // Remove the outer stroke by clearing the inverted mask path
- drawPath(path = maskPath, brush = brush, blendMode = BlendMode.Clear)
- }
- }
- }
- }
-
- onDrawWithContent {
- drawContent()
- translate(pathBounds.left, pathBounds.top) {
- drawImage(cacheImageBitmap, srcSize = pathBoundsSize, colorFilter = colorFilter)
- }
- }
- }
-
-/**
- * Border implementation for simple rounded rects and those with different corner
- * radii
- */
-private fun CacheDrawScope.drawRoundRectBorder(
- borderCacheRef: Ref<BorderCache>,
- brush: Brush,
- outline: Outline.Rounded,
- topLeft: Offset,
- borderSize: Size,
- fillArea: Boolean,
- strokeWidth: Float
-): DrawResult {
- return if (outline.roundRect.isSimple) {
- val cornerRadius = outline.roundRect.topLeftCornerRadius
- val halfStroke = strokeWidth / 2
- val borderStroke = Stroke(strokeWidth)
- onDrawWithContent {
- drawContent()
- when {
- fillArea -> {
- // If the drawing area is smaller than the stroke being drawn
- // drawn all around it just draw a filled in rounded rect
- drawRoundRect(brush, cornerRadius = cornerRadius)
- }
- cornerRadius.x < halfStroke -> {
- // If the corner radius is smaller than half of the stroke width
- // then the interior curvature of the stroke will be a sharp edge
- // In this case just draw a normal filled in rounded rect with the
- // desired corner radius but clipping out the interior rectangle
- clipRect(
- strokeWidth,
- strokeWidth,
- size.width - strokeWidth,
- size.height - strokeWidth,
- clipOp = ClipOp.Difference
- ) {
- drawRoundRect(brush, cornerRadius = cornerRadius)
- }
- }
- else -> {
- // Otherwise draw a stroked rounded rect with the corner radius
- // shrunk by half of the stroke width. This will ensure that the
- // outer curvature of the rounded rectangle will have the desired
- // corner radius.
- drawRoundRect(
- brush = brush,
- topLeft = topLeft,
- size = borderSize,
- cornerRadius = cornerRadius.shrink(halfStroke),
- style = borderStroke
- )
- }
- }
- }
- } else {
- val path = borderCacheRef.obtain().obtainPath()
- val roundedRectPath = createRoundRectPath(path, outline.roundRect, strokeWidth, fillArea)
- onDrawWithContent {
- drawContent()
- drawPath(roundedRectPath, brush = brush)
- }
- }
-}
-
-/**
* Border implementation for rectangular borders
*/
private fun CacheDrawScope.drawRectBorder(
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Image.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Image.kt
index 48a21a8..64b4556 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Image.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Image.kt
@@ -20,7 +20,6 @@
import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.draw.paint
@@ -29,12 +28,13 @@
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.DrawScope.Companion.DefaultFilterQuality
-import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.role
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
index e15bfe4..d0ab687 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Indication.kt
@@ -25,11 +25,11 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
+import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.platform.debugInspectorInfo
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
index 0ce2c64..4eefc4c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Scroll.kt
@@ -33,7 +33,6 @@
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.Saver
@@ -96,7 +95,7 @@
/**
* current scroll position value in pixels
*/
- var value: Int by mutableStateOf(initial)
+ var value: Int by mutableIntStateOf(initial)
private set
/**
@@ -114,7 +113,7 @@
/**
* Size of the viewport on the scrollable axis, or 0 if still unknown.
*/
- internal var viewportSize: Int by mutableStateOf(0)
+ internal var viewportSize: Int by mutableIntStateOf(0)
/**
* [InteractionSource] that will be used to dispatch drag events when this
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ForEachGesture.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ForEachGesture.kt
index 4901cab..fde5758 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ForEachGesture.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ForEachGesture.kt
@@ -19,9 +19,9 @@
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.util.fastAny
+import kotlin.coroutines.cancellation.CancellationException
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.isActive
-import kotlin.coroutines.cancellation.CancellationException
/**
* A gesture was canceled and cannot continue, likely because another gesture has taken
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
index 33c8439..e56a7a43 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/ScrollableState.kt
@@ -18,12 +18,12 @@
import androidx.compose.foundation.MutatePriority
import androidx.compose.foundation.MutatorMutex
+import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import kotlinx.coroutines.coroutineScope
-import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
/**
* An object representing something that can be scrolled. This interface is implemented by states
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TapGestureDetector.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TapGestureDetector.kt
index 2614f34..4a19ae0 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TapGestureDetector.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TapGestureDetector.kt
@@ -16,11 +16,12 @@
package androidx.compose.foundation.gestures
+import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.AwaitPointerEventScope
-import androidx.compose.ui.input.pointer.PointerEventTimeoutCancellationException
import androidx.compose.ui.input.pointer.PointerEvent
import androidx.compose.ui.input.pointer.PointerEventPass
+import androidx.compose.ui.input.pointer.PointerEventTimeoutCancellationException
import androidx.compose.ui.input.pointer.PointerInputChange
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.input.pointer.changedToDown
@@ -35,7 +36,6 @@
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
-import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
/**
* Receiver scope for [detectTapGestures]'s `onPress` lambda. This offers
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
index 8c196ac..39b957b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/TransformableState.kt
@@ -24,13 +24,13 @@
import androidx.compose.animation.core.animateTo
import androidx.compose.foundation.MutatePriority
import androidx.compose.foundation.MutatorMutex
+import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.geometry.Offset
import kotlinx.coroutines.coroutineScope
-import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
/**
* State of [transformable]. Allows for a granular control of how different gesture
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
index 515dfc3..962b9d9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
@@ -78,7 +78,15 @@
layoutInfo.visibleItemsInfo.fastForEach { item ->
val distance =
- calculateDistanceToDesiredSnapPosition(layoutInfo, item, positionInLayout)
+ calculateDistanceToDesiredSnapPosition(
+ mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = item.sizeOnMainAxis(orientation = layoutInfo.orientation),
+ itemOffset = item.offsetOnMainAxis(orientation = layoutInfo.orientation),
+ itemIndex = item.index,
+ snapPositionInLayout = positionInLayout
+ )
// Find item that is closest to the center
if (distance <= 0 && distance > distanceFromItemBeforeTarget) {
@@ -112,32 +120,14 @@
}
}
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
- layoutInfo: LazyGridLayoutInfo,
- item: LazyGridItemInfo,
- positionInLayout: SnapPositionInLayout = SnapPositionInLayout.CenterToCenter
-): Float {
-
- val containerSize =
- with(layoutInfo) { singleAxisViewportSize - beforeContentPadding - afterContentPadding }
-
- val desiredDistance = with(positionInLayout) {
- position(containerSize, item.sizeOnMainAxis(layoutInfo.orientation), item.index)
- }
-
- val itemCurrentPosition = item.offsetOnMainAxis(layoutInfo.orientation)
- return itemCurrentPosition - desiredDistance.toFloat()
-}
-
-private val LazyGridLayoutInfo.singleAxisViewportSize: Int
+internal val LazyGridLayoutInfo.singleAxisViewportSize: Int
get() = if (orientation == Orientation.Vertical) {
viewportSize.height
} else {
viewportSize.width
}
-private fun LazyGridItemInfo.sizeOnMainAxis(orientation: Orientation): Int {
+internal fun LazyGridItemInfo.sizeOnMainAxis(orientation: Orientation): Int {
return if (orientation == Orientation.Vertical) {
size.height
} else {
@@ -145,7 +135,7 @@
}
}
-private fun LazyGridItemInfo.offsetOnMainAxis(orientation: Orientation): Int {
+internal fun LazyGridItemInfo.offsetOnMainAxis(orientation: Orientation): Int {
return if (orientation == Orientation.Vertical) {
offset.y
} else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
index fece172..5df071b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
@@ -22,7 +22,6 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.LazyListLayoutInfo
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
@@ -71,7 +70,15 @@
layoutInfo.visibleItemsInfo.fastForEach { item ->
val offset =
- calculateDistanceToDesiredSnapPosition(layoutInfo, item, positionInLayout)
+ calculateDistanceToDesiredSnapPosition(
+ mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = item.size,
+ itemOffset = item.offset,
+ itemIndex = item.index,
+ snapPositionInLayout = positionInLayout
+ )
// Find item that is closest to the center
if (offset <= 0 && offset > lowerBoundOffset) {
@@ -110,22 +117,5 @@
return rememberSnapFlingBehavior(snappingLayout)
}
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
- layoutInfo: LazyListLayoutInfo,
- item: LazyListItemInfo,
- positionInLayout: SnapPositionInLayout
-): Float {
- val containerSize =
- with(layoutInfo) { singleAxisViewportSize - beforeContentPadding - afterContentPadding }
-
- val desiredDistance = with(positionInLayout) {
- position(containerSize, item.size, item.index)
- }.toFloat()
-
- val itemCurrentPosition = item.offset
- return itemCurrentPosition - desiredDistance
-}
-
-private val LazyListLayoutInfo.singleAxisViewportSize: Int
+internal val LazyListLayoutInfo.singleAxisViewportSize: Int
get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
index 3b3f94f..6a16ff9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
@@ -39,4 +39,23 @@
val CenterToCenter =
SnapPositionInLayout { layoutSize, itemSize, _ -> layoutSize / 2 - itemSize / 2 }
}
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+internal fun Density.calculateDistanceToDesiredSnapPosition(
+ mainAxisViewPortSize: Int,
+ beforeContentPadding: Int,
+ afterContentPadding: Int,
+ itemSize: Int,
+ itemOffset: Int,
+ itemIndex: Int,
+ snapPositionInLayout: SnapPositionInLayout
+): Float {
+ val containerSize = mainAxisViewPortSize - beforeContentPadding - afterContentPadding
+
+ val desiredDistance = with(snapPositionInLayout) {
+ position(containerSize, itemSize, itemIndex)
+ }.toFloat()
+
+ return itemOffset - desiredDistance
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt
deleted file mode 100644
index 8a98269..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/DataIndex.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package androidx.compose.foundation.lazy
-
-/**
- * Represents an index in the list of items of lazy layout.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class DataIndex(val value: Int) {
- inline operator fun inc(): DataIndex = DataIndex(value + 1)
- inline operator fun dec(): DataIndex = DataIndex(value - 1)
- inline operator fun plus(i: Int): DataIndex = DataIndex(value + i)
- inline operator fun minus(i: Int): DataIndex = DataIndex(value - i)
- inline operator fun minus(i: DataIndex): DataIndex = DataIndex(value - i.value)
- inline operator fun compareTo(other: DataIndex): Int = value - other.value
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScope.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScope.kt
index c1c594e..adba3f6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScope.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemScope.kt
@@ -21,11 +21,11 @@
import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
-import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
/**
* Receiver scope being used by the item content parameter of LazyColumn/Row.
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
index 4994b52..05949c7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt
@@ -262,9 +262,9 @@
) { index, key, contentType, placeables ->
// we add spaceBetweenItems as an extra spacing for all items apart from the last one so
// the lazy list measuring logic will take it into account.
- val spacing = if (index.value == itemsCount - 1) 0 else spaceBetweenItems
+ val spacing = if (index == itemsCount - 1) 0 else spaceBetweenItems
LazyListMeasuredItem(
- index = index.value,
+ index = index,
placeables = placeables,
isVertical = isVertical,
horizontalAlignment = horizontalAlignment,
@@ -281,10 +281,10 @@
}
state.premeasureConstraints = measuredItemProvider.childConstraints
- val firstVisibleItemIndex: DataIndex
+ val firstVisibleItemIndex: Int
val firstVisibleScrollOffset: Int
Snapshot.withoutReadObservation {
- firstVisibleItemIndex = DataIndex(state.firstVisibleItemIndex)
+ firstVisibleItemIndex = state.firstVisibleItemIndex
firstVisibleScrollOffset = state.firstVisibleItemScrollOffset
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
index 6def944..5ef94fe 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListBeyondBoundsModifier.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.lazy
import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsState
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsModifierLocal
+import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
index 2631561..978d3a8 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListHeaders.kt
@@ -70,7 +70,7 @@
return null
}
- val measuredHeaderItem = itemProvider.getAndMeasure(DataIndex(currentHeaderListPosition))
+ val measuredHeaderItem = itemProvider.getAndMeasure(currentHeaderListPosition)
var headerOffset = if (currentHeaderOffset != Int.MIN_VALUE) {
maxOf(-beforeContentPadding, currentHeaderOffset)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
index 15ebac4..497ba6d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemPlacementAnimator.kt
@@ -33,7 +33,7 @@
private val activeKeys = mutableSetOf<Any>()
// snapshot of the key to index map used for the last measuring.
- private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
+ private var keyIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
// keeps the index of the first visible item index.
private var firstVisibleIndex = 0
@@ -66,8 +66,8 @@
val previousFirstVisibleIndex = firstVisibleIndex
firstVisibleIndex = positionedItems.firstOrNull()?.index ?: 0
- val previousKeyToIndexMap = keyToIndexMap
- keyToIndexMap = itemProvider.keyToIndexMap
+ val previousKeyToIndexMap = keyIndexMap
+ keyIndexMap = itemProvider.keyIndexMap
val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
@@ -87,7 +87,7 @@
if (item.hasAnimations) {
if (!activeKeys.contains(item.key)) {
activeKeys += item.key
- val previousIndex = previousKeyToIndexMap[item.key]
+ val previousIndex = previousKeyToIndexMap.getIndex(item.key)
if (previousIndex != -1 && item.index != previousIndex) {
if (previousIndex < previousFirstVisibleIndex) {
// the larger index will be in the start of the list
@@ -116,7 +116,7 @@
}
var accumulatedOffset = 0
- movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
+ movingInFromStartBound.sortByDescending { previousKeyToIndexMap.getIndex(it.key) }
movingInFromStartBound.fastForEach { item ->
accumulatedOffset += item.size
val mainAxisOffset = 0 - accumulatedOffset
@@ -124,7 +124,7 @@
startAnimationsIfNeeded(item)
}
accumulatedOffset = 0
- movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
+ movingInFromEndBound.sortBy { previousKeyToIndexMap.getIndex(it.key) }
movingInFromEndBound.fastForEach { item ->
val mainAxisOffset = mainAxisLayoutSize + accumulatedOffset
accumulatedOffset += item.size
@@ -135,12 +135,12 @@
movingAwayKeys.forEach { key ->
// found an item which was in our map previously but is not a part of the
// positionedItems now
- val newIndex = keyToIndexMap[key]
+ val newIndex = keyIndexMap.getIndex(key)
if (newIndex == -1) {
activeKeys.remove(key)
} else {
- val item = itemProvider.getAndMeasure(DataIndex(newIndex))
+ val item = itemProvider.getAndMeasure(newIndex)
// check if we have any active placement animation on the item
var inProgress = false
repeat(item.placeablesCount) {
@@ -149,7 +149,7 @@
return@repeat
}
}
- if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+ if ((!inProgress && newIndex == previousKeyToIndexMap.getIndex(key))) {
activeKeys.remove(key)
} else {
if (newIndex < firstVisibleIndex) {
@@ -162,7 +162,7 @@
}
accumulatedOffset = 0
- movingAwayToStartBound.sortByDescending { keyToIndexMap[it.key] }
+ movingAwayToStartBound.sortByDescending { keyIndexMap.getIndex(it.key) }
movingAwayToStartBound.fastForEach { item ->
accumulatedOffset += item.size
val mainAxisOffset = 0 - accumulatedOffset
@@ -172,7 +172,7 @@
startAnimationsIfNeeded(positionedItem)
}
accumulatedOffset = 0
- movingAwayToEndBound.sortBy { keyToIndexMap[it.key] }
+ movingAwayToEndBound.sortBy { keyIndexMap.getIndex(it.key) }
movingAwayToEndBound.fastForEach { item ->
val mainAxisOffset = mainAxisLayoutSize + accumulatedOffset
accumulatedOffset += item.size
@@ -195,7 +195,7 @@
*/
fun reset() {
activeKeys.clear()
- keyToIndexMap = LazyLayoutKeyIndexMap.Empty
+ keyIndexMap = LazyLayoutKeyIndexMap.Empty
firstVisibleIndex = -1
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemProvider.kt
index 31cbd85..1a5eb66 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemProvider.kt
@@ -19,7 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.foundation.lazy.layout.PinnableItem
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.foundation.lazy.layout.NearestRangeKeyIndexMapState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
@@ -30,7 +30,7 @@
@ExperimentalFoundationApi
internal interface LazyListItemProvider : LazyLayoutItemProvider {
- val keyToIndexMap: LazyLayoutKeyIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap
/** The list of indexes of the sticky header items */
val headerIndexes: List<Int>
/** The scope used by the item content lambdas */
@@ -66,26 +66,28 @@
override val itemCount: Int get() = listContent.itemCount
@Composable
- override fun Item(index: Int) {
- listContent.PinnableItem(index, state.pinnedItems) { localIndex ->
- with(itemScope) { item(localIndex) }
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedItems) {
+ listContent.withInterval(index) { localIndex, content ->
+ content.item(itemScope, localIndex)
+ }
}
}
- override fun getKey(index: Int): Any = listContent.getKey(index)
+ override fun getKey(index: Int): Any = keyIndexMap.getKey(index) ?: listContent.getKey(index)
override fun getContentType(index: Int): Any? = listContent.getContentType(index)
override val headerIndexes: List<Int> get() = listContent.headerIndexes
- override val keyToIndexMap by NearestRangeKeyIndexMapState(
+ override val keyIndexMap by NearestRangeKeyIndexMapState(
firstVisibleItemIndex = { state.firstVisibleItemIndex },
slidingWindowSize = { NearestItemsSlidingWindowSize },
extraItemCount = { NearestItemsExtraItemCount },
content = { listContent }
)
- override fun getIndex(key: Any): Int = keyToIndexMap[key]
+ override fun getIndex(key: Any): Int = keyIndexMap.getIndex(key)
}
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo.kt
index be71365..37612eb 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListLayoutInfo.kt
@@ -17,8 +17,8 @@
package androidx.compose.foundation.lazy
import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.ui.unit.IntSize
import androidx.compose.foundation.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.unit.IntSize
/**
* Contains useful information about the currently displayed layout state of lazy lists like
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
index 0c97ea2..91d0350 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasure.kt
@@ -44,7 +44,7 @@
beforeContentPadding: Int,
afterContentPadding: Int,
spaceBetweenItems: Int,
- firstVisibleItemIndex: DataIndex,
+ firstVisibleItemIndex: Int,
firstVisibleItemScrollOffset: Int,
scrollToBeConsumed: Float,
constraints: Constraints,
@@ -81,10 +81,10 @@
} else {
var currentFirstItemIndex = firstVisibleItemIndex
var currentFirstItemScrollOffset = firstVisibleItemScrollOffset
- if (currentFirstItemIndex.value >= itemsCount) {
+ if (currentFirstItemIndex >= itemsCount) {
// the data set has been updated and now we have less items that we were
// scrolled to before
- currentFirstItemIndex = DataIndex(itemsCount - 1)
+ currentFirstItemIndex = itemsCount - 1
currentFirstItemScrollOffset = 0
}
@@ -96,7 +96,7 @@
currentFirstItemScrollOffset -= scrollDelta
// if the current scroll offset is less than minimally possible
- if (currentFirstItemIndex == DataIndex(0) && currentFirstItemScrollOffset < 0) {
+ if (currentFirstItemIndex == 0 && currentFirstItemScrollOffset < 0) {
scrollDelta += currentFirstItemScrollOffset
currentFirstItemScrollOffset = 0
}
@@ -119,8 +119,8 @@
// we had scrolled backward or we compose items in the start padding area, which means
// items before current firstItemScrollOffset should be visible. compose them and update
// firstItemScrollOffset
- while (currentFirstItemScrollOffset < 0 && currentFirstItemIndex > DataIndex(0)) {
- val previous = DataIndex(currentFirstItemIndex.value - 1)
+ while (currentFirstItemScrollOffset < 0 && currentFirstItemIndex > 0) {
+ val previous = currentFirstItemIndex - 1
val measuredItem = measuredItemProvider.getAndMeasure(previous)
visibleItems.add(0, measuredItem)
maxCrossAxis = maxOf(maxCrossAxis, measuredItem.crossAxisSize)
@@ -151,7 +151,7 @@
// then composing visible items forward until we fill the whole viewport.
// we want to have at least one item in visibleItems even if in fact all the items are
// offscreen, this can happen if the content padding is larger than the available size.
- while (index.value < itemsCount &&
+ while (index < itemsCount &&
(currentMainAxisOffset < maxMainAxis ||
currentMainAxisOffset <= 0 || // filling beforeContentPadding area
visibleItems.isEmpty())
@@ -159,7 +159,7 @@
val measuredItem = measuredItemProvider.getAndMeasure(index)
currentMainAxisOffset += measuredItem.sizeWithSpacings
- if (currentMainAxisOffset <= minOffset && index.value != itemsCount - 1) {
+ if (currentMainAxisOffset <= minOffset && index != itemsCount - 1) {
// this item is offscreen and will not be placed. advance firstVisibleItemIndex
currentFirstItemIndex = index + 1
currentFirstItemScrollOffset -= measuredItem.sizeWithSpacings
@@ -178,9 +178,9 @@
currentFirstItemScrollOffset -= toScrollBack
currentMainAxisOffset += toScrollBack
while (currentFirstItemScrollOffset < beforeContentPadding &&
- currentFirstItemIndex > DataIndex(0)
+ currentFirstItemIndex > 0
) {
- val previousIndex = DataIndex(currentFirstItemIndex.value - 1)
+ val previousIndex = currentFirstItemIndex - 1
val measuredItem = measuredItemProvider.getAndMeasure(previousIndex)
visibleItems.add(0, measuredItem)
maxCrossAxis = maxOf(maxCrossAxis, measuredItem.crossAxisSize)
@@ -305,7 +305,7 @@
return LazyListMeasureResult(
firstVisibleItem = firstItem,
firstVisibleItemScrollOffset = currentFirstItemScrollOffset,
- canScrollForward = index.value < itemsCount || currentMainAxisOffset > maxOffset,
+ canScrollForward = index < itemsCount || currentMainAxisOffset > maxOffset,
consumedScroll = consumedScroll,
measureResult = layout(layoutWidth, layoutHeight) {
positionedItems.fastForEach {
@@ -345,7 +345,7 @@
fun addItem(index: Int) {
if (list == null) list = mutableListOf()
requireNotNull(list).add(
- measuredItemProvider.getAndMeasure(DataIndex(index))
+ measuredItemProvider.getAndMeasure(index)
)
}
@@ -365,25 +365,25 @@
}
private fun createItemsBeforeList(
- currentFirstItemIndex: DataIndex,
+ currentFirstItemIndex: Int,
measuredItemProvider: LazyListMeasuredItemProvider,
beyondBoundsItemCount: Int,
pinnedItems: List<Int>
): List<LazyListMeasuredItem> {
var list: MutableList<LazyListMeasuredItem>? = null
- var start = currentFirstItemIndex.value
+ var start = currentFirstItemIndex
fun addItem(index: Int) {
if (list == null) list = mutableListOf()
requireNotNull(list).add(
- measuredItemProvider.getAndMeasure(DataIndex(index))
+ measuredItemProvider.getAndMeasure(index)
)
}
start = maxOf(0, start - beyondBoundsItemCount)
- for (i in currentFirstItemIndex.value - 1 downTo start) {
+ for (i in currentFirstItemIndex - 1 downTo start) {
addItem(i)
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
index 38baf57..77ec076 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListMeasuredItemProvider.kt
@@ -43,10 +43,10 @@
* Used to subcompose items of lazy lists. Composed placeables will be measured with the
* correct constraints and wrapped into [LazyListMeasuredItem].
*/
- fun getAndMeasure(index: DataIndex): LazyListMeasuredItem {
- val key = itemProvider.getKey(index.value)
- val contentType = itemProvider.getContentType(index.value)
- val placeables = measureScope.measure(index.value, childConstraints)
+ fun getAndMeasure(index: Int): LazyListMeasuredItem {
+ val key = keyIndexMap.getKey(index) ?: itemProvider.getKey(index)
+ val contentType = itemProvider.getContentType(index)
+ val placeables = measureScope.measure(index, childConstraints)
return measuredItemFactory.createItem(index, key, contentType, placeables)
}
@@ -54,13 +54,13 @@
* Contains the mapping between the key and the index. It could contain not all the items of
* the list as an optimization.
**/
- val keyToIndexMap: LazyLayoutKeyIndexMap get() = itemProvider.keyToIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap = itemProvider.keyIndexMap
}
// This interface allows to avoid autoboxing on index param
internal fun interface MeasuredItemFactory {
fun createItem(
- index: DataIndex,
+ index: Int,
key: Any,
contentType: Any?,
placeables: List<Placeable>
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
index 4717a84..16eb1c7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListScrollPosition.kt
@@ -19,7 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.findIndexByKey
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
@@ -31,9 +31,9 @@
initialIndex: Int = 0,
initialScrollOffset: Int = 0
) {
- var index by mutableStateOf(DataIndex(initialIndex))
+ var index by mutableIntStateOf(initialIndex)
- var scrollOffset by mutableStateOf(initialScrollOffset)
+ var scrollOffset by mutableIntStateOf(initialScrollOffset)
private set
private var hadFirstNotEmptyLayout = false
@@ -56,7 +56,7 @@
Snapshot.withoutReadObservation {
update(
- DataIndex(measureResult.firstVisibleItem?.index ?: 0),
+ measureResult.firstVisibleItem?.index ?: 0,
scrollOffset
)
}
@@ -74,7 +74,7 @@
* c) there will be not enough items to fill the viewport after the requested index, so we
* would have to compose few elements before the asked index, changing the first visible item.
*/
- fun requestPosition(index: DataIndex, scrollOffset: Int) {
+ fun requestPosition(index: Int, scrollOffset: Int) {
update(index, scrollOffset)
// clear the stored key as we have a direct request to scroll to [index] position and the
// next [checkIfFirstVisibleItemWasMoved] shouldn't override this.
@@ -91,14 +91,14 @@
fun updateScrollPositionIfTheFirstItemWasMoved(itemProvider: LazyListItemProvider) {
Snapshot.withoutReadObservation {
update(
- DataIndex(itemProvider.findIndexByKey(lastKnownFirstItemKey, index.value)),
+ itemProvider.findIndexByKey(lastKnownFirstItemKey, index),
scrollOffset
)
}
}
- private fun update(index: DataIndex, scrollOffset: Int) {
- require(index.value >= 0f) { "Index should be non-negative (${index.value})" }
+ private fun update(index: Int, scrollOffset: Int) {
+ require(index >= 0f) { "Index should be non-negative ($index)" }
if (index != this.index) {
this.index = index
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
index 760f9fa..3bd36be 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
@@ -23,9 +23,10 @@
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo
-import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
+import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.foundation.lazy.layout.animateScrollToItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
@@ -35,16 +36,11 @@
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
-import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.OnGloballyPositionedModifier
import androidx.compose.ui.layout.Remeasurement
import androidx.compose.ui.layout.RemeasurementModifier
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.suspendCoroutine
import kotlin.math.abs
/**
@@ -107,7 +103,7 @@
* derived state in order to only have recompositions when the derived value changes:
* @sample androidx.compose.foundation.samples.UsingListScrollPositionInCompositionSample
*/
- val firstVisibleItemIndex: Int get() = scrollPosition.index.value
+ val firstVisibleItemIndex: Int get() = scrollPosition.index
/**
* The scroll offset of the first visible item. Scrolling forward is positive - i.e., the
@@ -249,7 +245,7 @@
}
internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
- scrollPosition.requestPosition(DataIndex(index), scrollOffset)
+ scrollPosition.requestPosition(index, scrollOffset)
// placement animation is not needed because we snap into a new position.
placementAnimator.reset()
remeasurement?.forceRemeasure()
@@ -436,25 +432,4 @@
override val beforeContentPadding = 0
override val afterContentPadding = 0
override val mainAxisItemSpacing = 0
-}
-
-internal class AwaitFirstLayoutModifier : OnGloballyPositionedModifier {
- private var wasPositioned = false
- private var continuation: Continuation<Unit>? = null
-
- suspend fun waitForFirstLayout() {
- if (!wasPositioned) {
- val oldContinuation = continuation
- suspendCoroutine<Unit> { continuation = it }
- oldContinuation?.resume(Unit)
- }
- }
-
- override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
- if (!wasPositioned) {
- wasPositioned = true
- continuation?.resume(Unit)
- continuation = null
- }
- }
}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt
deleted file mode 100644
index 7207064..0000000
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/ItemIndex.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 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.
- */
-
-package androidx.compose.foundation.lazy.grid
-
-/**
- * Represents a line index in the lazy grid.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class LineIndex(val value: Int) {
- inline operator fun inc(): LineIndex = LineIndex(value + 1)
- inline operator fun dec(): LineIndex = LineIndex(value - 1)
- inline operator fun plus(i: Int): LineIndex = LineIndex(value + i)
- inline operator fun minus(i: Int): LineIndex = LineIndex(value - i)
- inline operator fun minus(i: LineIndex): LineIndex = LineIndex(value - i.value)
- inline operator fun compareTo(other: LineIndex): Int = value - other.value
-}
-
-/**
- * Represents an item index in the lazy grid.
- */
-@Suppress("NOTHING_TO_INLINE")
-@kotlin.jvm.JvmInline
-internal value class ItemIndex(val value: Int) {
- inline operator fun inc(): ItemIndex = ItemIndex(value + 1)
- inline operator fun dec(): ItemIndex = ItemIndex(value - 1)
- inline operator fun plus(i: Int): ItemIndex = ItemIndex(value + i)
- inline operator fun minus(i: Int): ItemIndex = ItemIndex(value - i)
- inline operator fun minus(i: ItemIndex): ItemIndex = ItemIndex(value - i.value)
- inline operator fun compareTo(other: ItemIndex): Int = value - other.value
-}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
index c752ea4..4f84478 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt
@@ -286,26 +286,24 @@
spans = spans,
slots = resolvedSlots,
isVertical = isVertical,
- slotsPerLine = slotsPerLine,
- layoutDirection = layoutDirection,
mainAxisSpacing = mainAxisSpacing,
)
}
state.prefetchInfoRetriever = { line ->
- val lineConfiguration = spanLayoutProvider.getLineConfiguration(line.value)
- var index = ItemIndex(lineConfiguration.firstItemIndex)
+ val lineConfiguration = spanLayoutProvider.getLineConfiguration(line)
+ var index = lineConfiguration.firstItemIndex
var slot = 0
val result = ArrayList<Pair<Int, Constraints>>(lineConfiguration.spans.size)
lineConfiguration.spans.fastForEach {
val span = it.currentLineSpan
- result.add(index.value to measuredLineProvider.childConstraints(slot, span))
+ result.add(index to measuredLineProvider.childConstraints(slot, span))
++index
slot += span
}
result
}
- val firstVisibleLineIndex: LineIndex
+ val firstVisibleLineIndex: Int
val firstVisibleLineScrollOffset: Int
Snapshot.withoutReadObservation {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
index 2f36dec..fbd96ee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemPlacementAnimator.kt
@@ -34,7 +34,7 @@
private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
// snapshot of the key to index map used for the last measuring.
- private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
+ private var keyIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap.Empty
// keeps the index of the first visible item index.
private var firstVisibleIndex = 0
@@ -68,8 +68,8 @@
val previousFirstVisibleIndex = firstVisibleIndex
firstVisibleIndex = positionedItems.firstOrNull()?.index ?: 0
- val previousKeyToIndexMap = keyToIndexMap
- keyToIndexMap = itemProvider.keyToIndexMap
+ val previousKeyToIndexMap = keyIndexMap
+ keyIndexMap = itemProvider.keyIndexMap
val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
@@ -92,7 +92,7 @@
if (itemInfo == null) {
keyToItemInfoMap[item.key] =
ItemInfo(item.getCrossAxisSize(), item.getCrossAxisOffset())
- val previousIndex = previousKeyToIndexMap[item.key]
+ val previousIndex = previousKeyToIndexMap.getIndex(item.key)
if (previousIndex != -1 && item.index != previousIndex) {
if (previousIndex < previousFirstVisibleIndex) {
// the larger index will be in the start of the list
@@ -125,7 +125,7 @@
var accumulatedOffset = 0
var previousLine = -1
var previousLineMainAxisSize = 0
- movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
+ movingInFromStartBound.sortByDescending { previousKeyToIndexMap.getIndex(it.key) }
movingInFromStartBound.fastForEach { item ->
val line = if (isVertical) item.row else item.column
if (line != -1 && line == previousLine) {
@@ -142,7 +142,7 @@
accumulatedOffset = 0
previousLine = -1
previousLineMainAxisSize = 0
- movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
+ movingInFromEndBound.sortBy { previousKeyToIndexMap.getIndex(it.key) }
movingInFromEndBound.fastForEach { item ->
val line = if (isVertical) item.row else item.column
if (line != -1 && line == previousLine) {
@@ -161,13 +161,13 @@
// found an item which was in our map previously but is not a part of the
// positionedItems now
val itemInfo = keyToItemInfoMap.getValue(key)
- val newIndex = keyToIndexMap[key]
+ val newIndex = keyIndexMap.getIndex(key)
if (newIndex == -1) {
keyToItemInfoMap.remove(key)
} else {
val item = itemProvider.getAndMeasure(
- ItemIndex(newIndex),
+ newIndex,
constraints = if (isVertical) {
Constraints.fixedWidth(itemInfo.crossAxisSize)
} else {
@@ -182,7 +182,7 @@
return@repeat
}
}
- if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+ if ((!inProgress && newIndex == previousKeyToIndexMap.getIndex(key))) {
keyToItemInfoMap.remove(key)
} else {
if (newIndex < firstVisibleIndex) {
@@ -197,9 +197,9 @@
accumulatedOffset = 0
previousLine = -1
previousLineMainAxisSize = 0
- movingAwayToStartBound.sortByDescending { keyToIndexMap[it.key] }
+ movingAwayToStartBound.sortByDescending { keyIndexMap.getIndex(it.key) }
movingAwayToStartBound.fastForEach { item ->
- val line = spanLayoutProvider.getLineIndexOfItem(item.index.value).value
+ val line = spanLayoutProvider.getLineIndexOfItem(item.index)
if (line != -1 && line == previousLine) {
previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.mainAxisSize)
} else {
@@ -225,9 +225,9 @@
accumulatedOffset = 0
previousLine = -1
previousLineMainAxisSize = 0
- movingAwayToEndBound.sortBy { keyToIndexMap[it.key] }
+ movingAwayToEndBound.sortBy { keyIndexMap.getIndex(it.key) }
movingAwayToEndBound.fastForEach { item ->
- val line = spanLayoutProvider.getLineIndexOfItem(item.index.value).value
+ val line = spanLayoutProvider.getLineIndexOfItem(item.index)
if (line != -1 && line == previousLine) {
previousLineMainAxisSize = maxOf(previousLineMainAxisSize, item.mainAxisSize)
} else {
@@ -264,7 +264,7 @@
*/
fun reset() {
keyToItemInfoMap.clear()
- keyToIndexMap = LazyLayoutKeyIndexMap.Empty
+ keyIndexMap = LazyLayoutKeyIndexMap.Empty
firstVisibleIndex = -1
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemProvider.kt
index 2cd5f0a7..95c2af3 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridItemProvider.kt
@@ -19,7 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.foundation.lazy.layout.PinnableItem
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.foundation.lazy.layout.NearestRangeKeyIndexMapState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
@@ -30,7 +30,7 @@
@ExperimentalFoundationApi
internal interface LazyGridItemProvider : LazyLayoutItemProvider {
- val keyToIndexMap: LazyLayoutKeyIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap
val spanLayoutProvider: LazyGridSpanLayoutProvider
}
@@ -58,7 +58,7 @@
LazyGridIntervalContent(latestContent())
}
- override val keyToIndexMap: LazyLayoutKeyIndexMap by NearestRangeKeyIndexMapState(
+ override val keyIndexMap: LazyLayoutKeyIndexMap by NearestRangeKeyIndexMapState(
firstVisibleItemIndex = { state.firstVisibleItemIndex },
slidingWindowSize = { NearestItemsSlidingWindowSize },
extraItemCount = { NearestItemsExtraItemCount },
@@ -67,15 +67,15 @@
override val itemCount: Int get() = gridContent.itemCount
- override fun getKey(index: Int): Any = gridContent.getKey(index)
+ override fun getKey(index: Int): Any = keyIndexMap.getKey(index) ?: gridContent.getKey(index)
override fun getContentType(index: Int): Any? = gridContent.getContentType(index)
@Composable
- override fun Item(index: Int) {
- gridContent.PinnableItem(index, state.pinnedItems) { localIndex ->
- with(LazyGridItemScopeImpl) {
- item(localIndex)
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedItems) {
+ gridContent.withInterval(index) { localIndex, content ->
+ content.item(LazyGridItemScopeImpl, localIndex)
}
}
}
@@ -83,7 +83,7 @@
override val spanLayoutProvider: LazyGridSpanLayoutProvider
get() = gridContent.spanLayoutProvider
- override fun getIndex(key: Any): Int = keyToIndexMap[key]
+ override fun getIndex(key: Any): Int = keyIndexMap.getIndex(key)
}
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
index a2a11fe..d5fa3ec 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasure.kt
@@ -47,7 +47,7 @@
beforeContentPadding: Int,
afterContentPadding: Int,
spaceBetweenLines: Int,
- firstVisibleLineIndex: LineIndex,
+ firstVisibleLineIndex: Int,
firstVisibleLineScrollOffset: Int,
scrollToBeConsumed: Float,
constraints: Constraints,
@@ -92,7 +92,7 @@
currentFirstLineScrollOffset -= scrollDelta
// if the current scroll offset is less than minimally possible
- if (currentFirstLineIndex == LineIndex(0) && currentFirstLineScrollOffset < 0) {
+ if (currentFirstLineIndex == 0 && currentFirstLineScrollOffset < 0) {
scrollDelta += currentFirstLineScrollOffset
currentFirstLineScrollOffset = 0
}
@@ -112,8 +112,8 @@
// we had scrolled backward or we compose items in the start padding area, which means
// items before current firstLineScrollOffset should be visible. compose them and update
// firstLineScrollOffset
- while (currentFirstLineScrollOffset < 0 && currentFirstLineIndex > LineIndex(0)) {
- val previous = LineIndex(currentFirstLineIndex.value - 1)
+ while (currentFirstLineScrollOffset < 0 && currentFirstLineIndex > 0) {
+ val previous = currentFirstLineIndex - 1
val measuredLine = measuredLineProvider.getAndMeasure(previous)
visibleLines.add(0, measuredLine)
currentFirstLineScrollOffset += measuredLine.mainAxisSizeWithSpacings
@@ -143,7 +143,7 @@
// then composing visible lines forward until we fill the whole viewport.
// we want to have at least one line in visibleItems even if in fact all the items are
// offscreen, this can happen if the content padding is larger than the available size.
- while (index.value < itemsCount &&
+ while (index < itemsCount &&
(currentMainAxisOffset < maxMainAxis ||
currentMainAxisOffset <= 0 || // filling beforeContentPadding area
visibleLines.isEmpty())
@@ -155,7 +155,7 @@
currentMainAxisOffset += measuredLine.mainAxisSizeWithSpacings
if (currentMainAxisOffset <= minOffset &&
- measuredLine.items.last().index.value != itemsCount - 1) {
+ measuredLine.items.last().index != itemsCount - 1) {
// this line is offscreen and will not be placed. advance firstVisibleLineIndex
currentFirstLineIndex = index + 1
currentFirstLineScrollOffset -= measuredLine.mainAxisSizeWithSpacings
@@ -172,9 +172,9 @@
currentFirstLineScrollOffset -= toScrollBack
currentMainAxisOffset += toScrollBack
while (currentFirstLineScrollOffset < beforeContentPadding &&
- currentFirstLineIndex > LineIndex(0)
+ currentFirstLineIndex > 0
) {
- val previousIndex = LineIndex(currentFirstLineIndex.value - 1)
+ val previousIndex = currentFirstLineIndex - 1
val measuredLine = measuredLineProvider.getAndMeasure(previousIndex)
visibleLines.add(0, measuredLine)
currentFirstLineScrollOffset += measuredLine.mainAxisSizeWithSpacings
@@ -205,8 +205,8 @@
val visibleLinesScrollOffset = -currentFirstLineScrollOffset
var firstLine = visibleLines.first()
- val firstItemIndex = firstLine.items.firstOrNull()?.index?.value ?: 0
- val lastItemIndex = visibleLines.lastOrNull()?.items?.lastOrNull()?.index?.value ?: 0
+ val firstItemIndex = firstLine.items.firstOrNull()?.index ?: 0
+ val lastItemIndex = visibleLines.lastOrNull()?.items?.lastOrNull()?.index ?: 0
val extraItemsBefore = calculateExtraItems(
pinnedItems,
measuredItemProvider,
@@ -304,17 +304,16 @@
private inline fun calculateExtraItems(
pinnedItems: List<Int>,
measuredItemProvider: LazyGridMeasuredItemProvider,
- itemConstraints: (ItemIndex) -> Constraints,
+ itemConstraints: (Int) -> Constraints,
filter: (Int) -> Boolean
): List<LazyGridMeasuredItem> {
var items: MutableList<LazyGridMeasuredItem>? = null
pinnedItems.fastForEach { index ->
if (filter(index)) {
- val itemIndex = ItemIndex(index)
- val constraints = itemConstraints(itemIndex)
+ val constraints = itemConstraints(index)
val measuredItem = measuredItemProvider.getAndMeasure(
- itemIndex,
+ index,
constraints = constraints
)
if (items == null) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
index 9db0fd0..74a6896 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItem.kt
@@ -28,7 +28,7 @@
* if the user emit multiple layout nodes in the item callback.
*/
internal class LazyGridMeasuredItem(
- val index: ItemIndex,
+ val index: Int,
val key: Any,
private val isVertical: Boolean,
/**
@@ -101,7 +101,7 @@
} else {
IntOffset(mainAxisOffset, crossAxisOffset)
},
- index = index.value,
+ index = index,
key = key,
row = row,
column = column,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
index ae9a1d8e..c984631 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredItemProvider.kt
@@ -37,13 +37,13 @@
* with the provided [constraints] and wrapped into [LazyGridMeasuredItem].
*/
fun getAndMeasure(
- index: ItemIndex,
+ index: Int,
mainAxisSpacing: Int = defaultMainAxisSpacing,
constraints: Constraints
): LazyGridMeasuredItem {
- val key = itemProvider.getKey(index.value)
- val contentType = itemProvider.getContentType(index.value)
- val placeables = measureScope.measure(index.value, constraints)
+ val key = keyIndexMap.getKey(index) ?: itemProvider.getKey(index)
+ val contentType = itemProvider.getContentType(index)
+ val placeables = measureScope.measure(index, constraints)
val crossAxisSize = if (constraints.hasFixedWidth) {
constraints.minWidth
} else {
@@ -64,13 +64,13 @@
* Contains the mapping between the key and the index. It could contain not all the items of
* the list as an optimization.
**/
- val keyToIndexMap: LazyLayoutKeyIndexMap get() = itemProvider.keyToIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap = itemProvider.keyIndexMap
}
// This interface allows to avoid autoboxing on index param
internal fun interface MeasuredItemFactory {
fun createItem(
- index: ItemIndex,
+ index: Int,
key: Any,
contentType: Any?,
crossAxisSize: Int,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
index b70f8bf..0b3f5e0 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLine.kt
@@ -17,7 +17,6 @@
package androidx.compose.foundation.lazy.grid
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.ui.unit.LayoutDirection
/**
* Represents one measured line of the lazy list. Each item on the line can in fact consist of
@@ -25,13 +24,11 @@
*/
@OptIn(ExperimentalFoundationApi::class)
internal class LazyGridMeasuredLine constructor(
- val index: LineIndex,
+ val index: Int,
val items: Array<LazyGridMeasuredItem>,
private val slots: LazyGridSlots,
private val spans: List<GridItemSpan>,
private val isVertical: Boolean,
- private val slotsPerLine: Int,
- private val layoutDirection: LayoutDirection,
/**
* Spacing to be added after [mainAxisSize], in the main axis direction.
*/
@@ -80,8 +77,8 @@
crossAxisOffset = slots.positions[startSlot],
layoutWidth = layoutWidth,
layoutHeight = layoutHeight,
- row = if (isVertical) index.value else startSlot,
- column = if (isVertical) startSlot else index.value
+ row = if (isVertical) index else startSlot,
+ column = if (isVertical) startSlot else index
).also {
usedSpan += span
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
index f0d8250..fe5ff54 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridMeasuredLineProvider.kt
@@ -48,9 +48,9 @@
}
}
- fun itemConstraints(itemIndex: ItemIndex): Constraints {
+ fun itemConstraints(itemIndex: Int): Constraints {
val span = spanLayoutProvider.spanOf(
- itemIndex.value,
+ itemIndex,
spanLayoutProvider.slotsPerLine
)
return childConstraints(0, span)
@@ -60,8 +60,8 @@
* Used to subcompose items on lines of lazy grids. Composed placeables will be measured
* with the correct constraints and wrapped into [LazyGridMeasuredLine].
*/
- fun getAndMeasure(lineIndex: LineIndex): LazyGridMeasuredLine {
- val lineConfiguration = spanLayoutProvider.getLineConfiguration(lineIndex.value)
+ fun getAndMeasure(lineIndex: Int): LazyGridMeasuredLine {
+ val lineConfiguration = spanLayoutProvider.getLineConfiguration(lineIndex)
val lineItemsCount = lineConfiguration.spans.size
// we add space between lines as an extra spacing for all lines apart from the last one
@@ -78,7 +78,7 @@
val span = lineConfiguration.spans[it].currentLineSpan
val constraints = childConstraints(startSlot, span)
measuredItemProvider.getAndMeasure(
- ItemIndex(lineConfiguration.firstItemIndex + it),
+ lineConfiguration.firstItemIndex + it,
mainAxisSpacing,
constraints
).also { startSlot += span }
@@ -95,14 +95,14 @@
* Contains the mapping between the key and the index. It could contain not all the items of
* the list as an optimization.
**/
- val keyToIndexMap: LazyLayoutKeyIndexMap get() = measuredItemProvider.keyToIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap get() = measuredItemProvider.keyIndexMap
}
// This interface allows to avoid autoboxing on index param
@OptIn(ExperimentalFoundationApi::class)
internal fun interface MeasuredLineFactory {
fun createLine(
- index: LineIndex,
+ index: Int,
items: Array<LazyGridMeasuredItem>,
spans: List<GridItemSpan>,
mainAxisSpacing: Int
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
index 32575e7..7b19619 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridScrollPosition.kt
@@ -19,7 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.findIndexByKey
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
@@ -32,10 +32,10 @@
initialIndex: Int = 0,
initialScrollOffset: Int = 0
) {
- var index by mutableStateOf(ItemIndex(initialIndex))
+ var index by mutableIntStateOf(initialIndex)
private set
- var scrollOffset by mutableStateOf(initialScrollOffset)
+ var scrollOffset by mutableIntStateOf(initialScrollOffset)
private set
private var hadFirstNotEmptyLayout = false
@@ -58,9 +58,7 @@
Snapshot.withoutReadObservation {
update(
- ItemIndex(
- measureResult.firstVisibleLine?.items?.firstOrNull()?.index?.value ?: 0
- ),
+ measureResult.firstVisibleLine?.items?.firstOrNull()?.index ?: 0,
scrollOffset
)
}
@@ -78,7 +76,7 @@
* c) there will be not enough items to fill the viewport after the requested index, so we
* would have to compose few elements before the asked index, changing the first visible item.
*/
- fun requestPosition(index: ItemIndex, scrollOffset: Int) {
+ fun requestPosition(index: Int, scrollOffset: Int) {
update(index, scrollOffset)
// clear the stored key as we have a direct request to scroll to [index] position and the
// next [checkIfFirstVisibleItemWasMoved] shouldn't override this.
@@ -94,14 +92,14 @@
fun updateScrollPositionIfTheFirstItemWasMoved(itemProvider: LazyGridItemProvider) {
Snapshot.withoutReadObservation {
update(
- ItemIndex(itemProvider.findIndexByKey(lastKnownFirstItemKey, index.value)),
+ itemProvider.findIndexByKey(lastKnownFirstItemKey, index),
scrollOffset
)
}
}
- private fun update(index: ItemIndex, scrollOffset: Int) {
- require(index.value >= 0f) { "Index should be non-negative (${index.value})" }
+ private fun update(index: Int, scrollOffset: Int) {
+ require(index >= 0f) { "Index should be non-negative ($index)" }
if (index != this.index) {
this.index = index
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
index c5c802a..ac6ac2a 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridSpanLayoutProvider.kt
@@ -167,13 +167,13 @@
/**
* Calculate the line of index [itemIndex].
*/
- fun getLineIndexOfItem(itemIndex: Int): LineIndex {
+ fun getLineIndexOfItem(itemIndex: Int): Int {
if (totalSize <= 0) {
- return LineIndex(0)
+ return 0
}
require(itemIndex < totalSize)
if (!gridContent.hasCustomSpans) {
- return LineIndex(itemIndex / slotsPerLine)
+ return itemIndex / slotsPerLine
}
val lowerBoundBucket = buckets.binarySearch { it.firstItemIndex - itemIndex }.let {
@@ -207,7 +207,7 @@
++currentLine
}
- return LineIndex(currentLine)
+ return currentLine
}
fun spanOf(itemIndex: Int, maxSpan: Int): Int =
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
index 2127ee7..73e2a21 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt
@@ -23,15 +23,16 @@
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.lazy.AwaitFirstLayoutModifier
+import androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo
-import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
+import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.foundation.lazy.layout.animateScrollToItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.collection.mutableVectorOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
@@ -104,7 +105,7 @@
* derived state in order to only have recompositions when the derived value changes:
* @sample androidx.compose.foundation.samples.UsingGridScrollPositionInCompositionSample
*/
- val firstVisibleItemIndex: Int get() = scrollPosition.index.value
+ val firstVisibleItemIndex: Int get() = scrollPosition.index
/**
* The scroll offset of the first visible item. Scrolling forward is positive - i.e., the
@@ -149,7 +150,7 @@
/**
* Needed for [animateScrollToItem]. Updated on every measure.
*/
- internal var slotsPerLine: Int by mutableStateOf(0)
+ internal var slotsPerLine: Int by mutableIntStateOf(0)
/**
* Needed for [animateScrollToItem]. Updated on every measure.
@@ -221,7 +222,7 @@
/**
* Finds items on a line and their measurement constraints. Used for prefetching.
*/
- internal var prefetchInfoRetriever: (line: LineIndex) -> List<Pair<Int, Constraints>> by
+ internal var prefetchInfoRetriever: (line: Int) -> List<Pair<Int, Constraints>> by
mutableStateOf({ emptyList() })
internal val placementAnimator = LazyGridItemPlacementAnimator()
@@ -255,7 +256,7 @@
}
internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int) {
- scrollPosition.requestPosition(ItemIndex(index), scrollOffset)
+ scrollPosition.requestPosition(index, scrollOffset)
// placement animation is not needed because we snap into a new position.
placementAnimator.reset()
remeasurement?.forceRemeasure()
@@ -359,7 +360,7 @@
this.wasScrollingForward = scrollingForward
this.lineToPrefetch = lineToPrefetch
currentLinePrefetchHandles.clear()
- prefetchInfoRetriever(LineIndex(lineToPrefetch)).fastForEach {
+ prefetchInfoRetriever(lineToPrefetch).fastForEach {
currentLinePrefetchHandles.add(
prefetchState.schedulePrefetch(it.first, it.second)
)
@@ -414,7 +415,7 @@
layoutInfoState.value = result
canScrollForward = result.canScrollForward
- canScrollBackward = (result.firstVisibleLine?.index?.value ?: 0) != 0 ||
+ canScrollBackward = (result.firstVisibleLine?.index ?: 0) != 0 ||
result.firstVisibleLineScrollOffset != 0
numMeasurePasses++
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/AwaitFirstLayoutModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/AwaitFirstLayoutModifier.kt
new file mode 100644
index 0000000..c7a7759
--- /dev/null
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/AwaitFirstLayoutModifier.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.foundation.lazy.layout
+
+import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.OnGloballyPositionedModifier
+import kotlin.coroutines.Continuation
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
+
+/**
+ * Internal modifier which allows to delay some interactions (e.g. scroll) until layout is ready.
+ */
+internal class AwaitFirstLayoutModifier : OnGloballyPositionedModifier {
+ private var wasPositioned = false
+ private var continuation: Continuation<Unit>? = null
+
+ suspend fun waitForFirstLayout() {
+ if (!wasPositioned) {
+ val oldContinuation = continuation
+ suspendCoroutine { continuation = it }
+ oldContinuation?.resume(Unit)
+ }
+ }
+
+ override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
+ if (!wasPositioned) {
+ wasPositioned = true
+ continuation?.resume(Unit)
+ continuation = null
+ }
+ }
+}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
index 5623db2..dc2161f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
@@ -92,10 +92,17 @@
} else {
placementAnimationSpec
}
- val startVelocity = placementDeltaAnimation.velocity
- placementDeltaAnimation.snapTo(totalDelta)
- placementDeltaAnimation.animateTo(IntOffset.Zero, spec, startVelocity) {
- placementDelta = value
+ if (!placementDeltaAnimation.isRunning) {
+ // if not running we can snap to the initial value and animate to zero
+ placementDeltaAnimation.snapTo(totalDelta)
+ }
+ // if animation is not currently running the target will be zero, otherwise
+ // we have to continue the animation from the current value, but keep the needed
+ // total delta for the new animation.
+ val animationTarget = placementDeltaAnimation.value - totalDelta
+ placementDeltaAnimation.animateTo(animationTarget, spec) {
+ // placementDelta is calculated as if we always animate to target equal to zero
+ placementDelta = value - animationTarget
}
isAnimationInProgress = false
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
index aeb9028..90665f1 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutIntervalContent.kt
@@ -17,7 +17,6 @@
package androidx.compose.foundation.lazy.layout
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.runtime.Composable
/**
* Common parts backing the interval-based content of lazy layout defined through `item` DSL.
@@ -26,24 +25,37 @@
abstract class LazyLayoutIntervalContent<Interval : LazyLayoutIntervalContent.Interval> {
abstract val intervals: IntervalList<Interval>
+ /**
+ * The total amount of items in all the intervals.
+ */
val itemCount: Int get() = intervals.size
+ /**
+ * Returns item key based on a global index.
+ */
fun getKey(index: Int): Any =
- withLocalIntervalIndex(index) { localIndex, content ->
+ withInterval(index) { localIndex, content ->
content.key?.invoke(localIndex) ?: getDefaultLazyLayoutKey(index)
}
+ /**
+ * Returns content type based on a global index.
+ */
fun getContentType(index: Int): Any? =
- withLocalIntervalIndex(index) { localIndex, content ->
+ withInterval(index) { localIndex, content ->
content.type.invoke(localIndex)
}
- private inline fun <T> withLocalIntervalIndex(
- index: Int,
- block: (localIndex: Int, content: Interval) -> T
+ /**
+ * Runs a [block] on the content of the interval associated with the provided [globalIndex]
+ * with providing a local index in the given interval.
+ */
+ inline fun <T> withInterval(
+ globalIndex: Int,
+ block: (localIntervalIndex: Int, content: Interval) -> T
): T {
- val interval = intervals[index]
- val localIntervalIndex = index - interval.startIndex
+ val interval = intervals[globalIndex]
+ val localIntervalIndex = globalIndex - interval.startIndex
return block(localIntervalIndex, interval.value)
}
@@ -63,25 +75,3 @@
val type: ((index: Int) -> Any?) get() = { null }
}
}
-
-/**
- * Defines a composable content of item in a lazy layout to support focus pinning.
- * See [LazyLayoutPinnableItem] for more details.
- */
-@ExperimentalFoundationApi
-@Composable
-fun <T : LazyLayoutIntervalContent.Interval> LazyLayoutIntervalContent<T>.PinnableItem(
- index: Int,
- pinnedItemList: LazyLayoutPinnedItemList,
- content: @Composable T.(index: Int) -> Unit
-) {
- val interval = intervals[index]
- val localIndex = index - interval.startIndex
- LazyLayoutPinnableItem(
- interval.value.key?.invoke(localIndex),
- index,
- pinnedItemList
- ) {
- interval.value.content(localIndex)
- }
-}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory.kt
index 4023a81..0b3039b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemContentFactory.kt
@@ -19,9 +19,10 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.ReusableContentHost
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.SaveableStateHolder
import androidx.compose.runtime.setValue
@@ -83,7 +84,7 @@
val key: Any,
val type: Any?
) {
- var lastKnownIndex by mutableStateOf(initialIndex)
+ var lastKnownIndex by mutableIntStateOf(initialIndex)
private set
private var _content: (@Composable () -> Unit)? = null
@@ -92,17 +93,20 @@
private fun createContentLambda() = @Composable {
val itemProvider = itemProvider()
- val index = itemProvider.findIndexByKey(key, lastKnownIndex).also {
- lastKnownIndex = it
+
+ var index = lastKnownIndex
+ if (index >= itemProvider.itemCount || itemProvider.getKey(index) != key) {
+ index = itemProvider.getIndex(key)
+ if (index != -1) lastKnownIndex = index
}
- if (index < itemProvider.itemCount) {
- val key = itemProvider.getKey(index)
- if (key == this.key) {
- StableSaveProvider(StableValue(saveableStateHolder), StableValue(key)) {
- itemProvider.Item(index)
- }
- }
+ ReusableContentHost(active = index != -1) {
+ SkippableItem(
+ itemProvider,
+ StableValue(saveableStateHolder),
+ index,
+ StableValue(key)
+ )
}
DisposableEffect(key) {
onDispose {
@@ -119,14 +123,18 @@
private value class StableValue<T>(val value: T)
/**
- * Hack around skippable functions to force restart for unstable saveable state holder that uses
- * [Any] as key.
+ * Hack around skippable functions to force skip SaveableStateProvider and Item block when
+ * nothing changed. It allows us to skip heavy-weight composition local providers.
*/
+@OptIn(ExperimentalFoundationApi::class)
@Composable
-private fun StableSaveProvider(
+private fun SkippableItem(
+ itemProvider: LazyLayoutItemProvider,
saveableStateHolder: StableValue<SaveableStateHolder>,
- key: StableValue<Any>,
- content: @Composable () -> Unit
+ index: Int,
+ key: StableValue<Any>
) {
- saveableStateHolder.value.SaveableStateProvider(key.value, content)
+ saveableStateHolder.value.SaveableStateProvider(key.value) {
+ itemProvider.Item(index, key.value)
+ }
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemProvider.kt
index 98a6b0a..9498578 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutItemProvider.kt
@@ -34,10 +34,10 @@
val itemCount: Int
/**
- * The item for the given [index].
+ * The item for the given [index] and [key].
*/
@Composable
- fun Item(index: Int)
+ fun Item(index: Int, key: Any)
/**
* Returns the content type for the item on this index. It is used to improve the item
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
index c46335a..a6485ee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutKeyIndexMap.kt
@@ -33,14 +33,20 @@
/**
* @return current index for given [key] or `-1` if not found.
*/
- operator fun get(key: Any): Int
+ fun getIndex(key: Any): Int
+
+ /**
+ * @return key for a given [index] if it is known, or null otherwise.
+ */
+ fun getKey(index: Int): Any?
/**
* Empty map implementation, always returning `-1` for any key.
*/
companion object Empty : LazyLayoutKeyIndexMap {
@Suppress("AutoBoxing")
- override fun get(key: Any): Int = -1
+ override fun getIndex(key: Any): Int = -1
+ override fun getKey(index: Int) = null
}
}
@@ -90,44 +96,55 @@
nearestRange: IntRange,
content: LazyLayoutIntervalContent<*>
) : LazyLayoutKeyIndexMap {
- private val map = generateKeyToIndexMap(nearestRange, content.intervals)
+ private val map: Map<Any, Int>
+ private val keys: Array<Any?>
+ private val keysStartIndex: Int
- override fun get(key: Any): Int = map.getOrElse(key) { -1 }
-
- companion object {
- /**
- * Traverses the interval [list] in order to create a mapping from the key to the index for all
- * the indexes in the passed [range].
- * The returned map will not contain the values for intervals with no key mapping provided.
- */
- private fun generateKeyToIndexMap(
- range: IntRange,
- list: IntervalList<LazyLayoutIntervalContent.Interval>
- ): Map<Any, Int> {
- val first = range.first
- check(first >= 0)
- val last = minOf(range.last, list.size - 1)
- return if (last < first) {
- emptyMap()
- } else {
- hashMapOf<Any, Int>().also { map ->
- list.forEach(
- fromIndex = first,
- toIndex = last,
- ) {
- if (it.value.key != null) {
- val keyFactory = requireNotNull(it.value.key)
- val start = maxOf(first, it.startIndex)
- val end = minOf(last, it.startIndex + it.size - 1)
- for (i in start..end) {
- map[keyFactory(i - it.startIndex)] = i
- }
+ init {
+ // Traverses the interval [list] in order to create a mapping from the key to the index for all
+ // the indexes in the passed [range].
+ // The returned map will not contain the values for intervals with no key mapping provided.
+ val list = content.intervals
+ val first = nearestRange.first
+ check(first >= 0)
+ val last = minOf(nearestRange.last, list.size - 1)
+ if (last < first) {
+ map = emptyMap()
+ keys = emptyArray()
+ keysStartIndex = 0
+ } else {
+ var tmpKeys = emptyArray<Any?>()
+ var tmpKeysStartIndex = 0
+ map = hashMapOf<Any, Int>().also { map ->
+ list.forEach(
+ fromIndex = first,
+ toIndex = last,
+ ) {
+ if (it.value.key != null) {
+ val keyFactory = requireNotNull(it.value.key)
+ val start = maxOf(first, it.startIndex)
+ if (tmpKeys.isEmpty()) {
+ tmpKeysStartIndex = start
+ tmpKeys = Array(last - start + 1) { null }
+ }
+ val end = minOf(last, it.startIndex + it.size - 1)
+ for (i in start..end) {
+ val key = keyFactory(i - it.startIndex)
+ map[key] = i
+ tmpKeys[i - tmpKeysStartIndex] = key
}
}
}
}
+ keys = tmpKeys
+ keysStartIndex = tmpKeysStartIndex
}
}
+
+ override fun getIndex(key: Any): Int = map.getOrElse(key) { -1 }
+
+ override fun getKey(index: Int) =
+ keys.getOrElse(index - keysStartIndex) { null }
}
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPinnableItem.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPinnableItem.kt
index 768c234..680f8b5 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPinnableItem.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutPinnableItem.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -101,13 +102,13 @@
/**
* Current index associated with this item.
*/
- override var index by mutableStateOf(-1)
+ override var index by mutableIntStateOf(-1)
/**
* It is a valid use case when users of this class call [pin] multiple times individually,
* so we want to do the unpinning only when all of the users called [release].
*/
- private var pinsCount by mutableStateOf(0)
+ private var pinsCount by mutableIntStateOf(0)
/**
* Handle associated with the current [parentPinnableContainer].
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
index 7faf82e..79423ba 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGrid.kt
@@ -81,6 +81,7 @@
LazyLayout(
modifier = modifier
.then(state.remeasurementModifier)
+ .then(state.awaitLayoutModifier)
.lazyLayoutSemantics(
itemProvider = itemProvider,
state = semanticState,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemPlacementAnimator.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemPlacementAnimator.kt
index 11895ed..f9dec0d 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemPlacementAnimator.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemPlacementAnimator.kt
@@ -34,7 +34,7 @@
private val keyToItemInfoMap = mutableMapOf<Any, ItemInfo>()
// snapshot of the key to index map used for the last measuring.
- private var keyToIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap
+ private var keyIndexMap: LazyLayoutKeyIndexMap = LazyLayoutKeyIndexMap
// keeps the index of the first visible item index.
private var firstVisibleIndex = 0
@@ -68,8 +68,8 @@
val previousFirstVisibleIndex = firstVisibleIndex
firstVisibleIndex = positionedItems.firstOrNull()?.index ?: 0
- val previousKeyToIndexMap = keyToIndexMap
- keyToIndexMap = itemProvider.keyToIndexMap
+ val previousKeyToIndexMap = keyIndexMap
+ keyIndexMap = itemProvider.keyIndexMap
val mainAxisLayoutSize = if (isVertical) layoutHeight else layoutWidth
@@ -92,7 +92,7 @@
if (itemInfo == null) {
keyToItemInfoMap[item.key] =
ItemInfo(item.lane, item.span, item.crossAxisOffset)
- val previousIndex = previousKeyToIndexMap[item.key]
+ val previousIndex = previousKeyToIndexMap.getIndex(item.key)
if (previousIndex != -1 && item.index != previousIndex) {
if (previousIndex < previousFirstVisibleIndex) {
// the larger index will be in the start of the list
@@ -125,7 +125,7 @@
val accumulatedOffsetPerLane = IntArray(laneCount) { 0 }
if (movingInFromStartBound.isNotEmpty()) {
- movingInFromStartBound.sortByDescending { previousKeyToIndexMap[it.key] }
+ movingInFromStartBound.sortByDescending { previousKeyToIndexMap.getIndex(it.key) }
movingInFromStartBound.fastForEach { item ->
accumulatedOffsetPerLane[item.lane] += item.mainAxisSize
val mainAxisOffset = 0 - accumulatedOffsetPerLane[item.lane]
@@ -135,7 +135,7 @@
accumulatedOffsetPerLane.fill(0)
}
if (movingInFromEndBound.isNotEmpty()) {
- movingInFromEndBound.sortBy { previousKeyToIndexMap[it.key] }
+ movingInFromEndBound.sortBy { previousKeyToIndexMap.getIndex(it.key) }
movingInFromEndBound.fastForEach { item ->
val mainAxisOffset = mainAxisLayoutSize + accumulatedOffsetPerLane[item.lane]
accumulatedOffsetPerLane[item.lane] += item.mainAxisSize
@@ -149,7 +149,7 @@
// found an item which was in our map previously but is not a part of the
// positionedItems now
val itemInfo = keyToItemInfoMap.getValue(key)
- val newIndex = keyToIndexMap[key]
+ val newIndex = keyIndexMap.getIndex(key)
if (newIndex == -1) {
keyToItemInfoMap.remove(key)
@@ -166,7 +166,7 @@
return@repeat
}
}
- if ((!inProgress && newIndex == previousKeyToIndexMap[key])) {
+ if ((!inProgress && newIndex == previousKeyToIndexMap.getIndex(key))) {
keyToItemInfoMap.remove(key)
} else {
if (newIndex < firstVisibleIndex) {
@@ -179,7 +179,7 @@
}
if (movingAwayToStartBound.isNotEmpty()) {
- movingAwayToStartBound.sortByDescending { keyToIndexMap[it.key] }
+ movingAwayToStartBound.sortByDescending { keyIndexMap.getIndex(it.key) }
movingAwayToStartBound.fastForEach { item ->
accumulatedOffsetPerLane[item.lane] += item.mainAxisSize
val mainAxisOffset = 0 - accumulatedOffsetPerLane[item.lane]
@@ -193,7 +193,7 @@
accumulatedOffsetPerLane.fill(0)
}
if (movingAwayToEndBound.isNotEmpty()) {
- movingAwayToEndBound.sortBy { keyToIndexMap[it.key] }
+ movingAwayToEndBound.sortBy { keyIndexMap.getIndex(it.key) }
movingAwayToEndBound.fastForEach { item ->
val mainAxisOffset = mainAxisLayoutSize + accumulatedOffsetPerLane[item.lane]
accumulatedOffsetPerLane[item.lane] += item.mainAxisSize
@@ -219,7 +219,7 @@
*/
fun reset() {
keyToItemInfoMap.clear()
- keyToIndexMap = LazyLayoutKeyIndexMap
+ keyIndexMap = LazyLayoutKeyIndexMap
firstVisibleIndex = -1
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemProvider.kt
index b54bd72..b76423c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridItemProvider.kt
@@ -19,7 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
-import androidx.compose.foundation.lazy.layout.PinnableItem
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.foundation.lazy.layout.NearestRangeKeyIndexMapState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
@@ -31,7 +31,7 @@
@OptIn(ExperimentalFoundationApi::class)
internal interface LazyStaggeredGridItemProvider : LazyLayoutItemProvider {
val spanProvider: LazyStaggeredGridSpanProvider
- val keyToIndexMap: LazyLayoutKeyIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap
}
@Composable
@@ -57,7 +57,7 @@
LazyStaggeredGridIntervalContent(latestContent())
}
- override val keyToIndexMap: LazyLayoutKeyIndexMap by NearestRangeKeyIndexMapState(
+ override val keyIndexMap: LazyLayoutKeyIndexMap by NearestRangeKeyIndexMapState(
firstVisibleItemIndex = { state.firstVisibleItemIndex },
slidingWindowSize = { 90 },
extraItemCount = { 200 },
@@ -66,17 +66,18 @@
override val itemCount: Int get() = staggeredGridContent.itemCount
- override fun getKey(index: Int): Any = staggeredGridContent.getKey(index)
+ override fun getKey(index: Int): Any =
+ keyIndexMap.getKey(index) ?: staggeredGridContent.getKey(index)
- override fun getIndex(key: Any): Int = keyToIndexMap[key]
+ override fun getIndex(key: Any): Int = keyIndexMap.getIndex(key)
override fun getContentType(index: Int): Any? = staggeredGridContent.getContentType(index)
@Composable
- override fun Item(index: Int) {
- staggeredGridContent.PinnableItem(index, state.pinnedItems) { localIndex ->
- with(LazyStaggeredGridItemScopeImpl) {
- item(localIndex)
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedItems) {
+ staggeredGridContent.withInterval(index) { localIndex, content ->
+ content.item(LazyStaggeredGridItemScopeImpl, localIndex)
}
}
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
index 62c4e2c..d92ad20 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridMeasure.kt
@@ -1013,7 +1013,7 @@
}
fun getAndMeasure(index: Int, span: SpanRange): LazyStaggeredGridMeasuredItem {
- val key = itemProvider.getKey(index)
+ val key = keyIndexMap.getKey(index) ?: itemProvider.getKey(index)
val contentType = itemProvider.getContentType(index)
val placeables = measureScope.measure(index, childConstraints(span.start, span.size))
return measuredItemFactory.createItem(
@@ -1026,7 +1026,7 @@
)
}
- val keyToIndexMap: LazyLayoutKeyIndexMap get() = itemProvider.keyToIndexMap
+ val keyIndexMap: LazyLayoutKeyIndexMap = itemProvider.keyIndexMap
}
// This interface allows to avoid autoboxing on index param
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridState.kt
index a1b62d6..84f9df6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridState.kt
@@ -22,12 +22,13 @@
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier
import androidx.compose.foundation.lazy.layout.LazyAnimateScrollScope
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState.PrefetchHandle
-import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
import androidx.compose.foundation.lazy.layout.animateScrollToItem
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridLaneInfo.Companion.Unset
import androidx.compose.runtime.Composable
@@ -166,6 +167,12 @@
}
}
+ /**
+ * Provides a modifier which allows to delay some interactions (e.g. scroll)
+ * until layout is ready.
+ */
+ internal val awaitLayoutModifier = AwaitFirstLayoutModifier()
+
internal val beyondBoundsInfo = LazyLayoutBeyondBoundsInfo()
/**
@@ -228,6 +235,7 @@
scrollPriority: MutatePriority,
block: suspend ScrollScope.() -> Unit
) {
+ awaitLayoutModifier.waitForFirstLayout()
scrollableState.scroll(scrollPriority, block)
}
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
index 5d8d4093..d42eaed 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/LazyLayoutPager.kt
@@ -32,9 +32,9 @@
import androidx.compose.foundation.lazy.layout.LazyLayoutIntervalContent
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.foundation.lazy.layout.MutableIntervalList
import androidx.compose.foundation.lazy.layout.NearestRangeKeyIndexMapState
-import androidx.compose.foundation.lazy.layout.PinnableItem
import androidx.compose.foundation.lazy.layout.lazyLayoutSemantics
import androidx.compose.foundation.overscroll
import androidx.compose.runtime.Composable
@@ -199,15 +199,17 @@
get() = pagerContent.itemCount
@Composable
- override fun Item(index: Int) {
- pagerContent.PinnableItem(index, state.pinnedPages) { localIndex ->
- item(pagerScopeImpl, localIndex)
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedPages) {
+ pagerContent.withInterval(index) { localIndex, content ->
+ content.item(pagerScopeImpl, localIndex)
+ }
}
}
- override fun getKey(index: Int): Any = pagerContent.getKey(index)
+ override fun getKey(index: Int): Any = keyToIndexMap.getKey(index) ?: pagerContent.getKey(index)
- override fun getIndex(key: Any): Int = keyToIndexMap[key]
+ override fun getIndex(key: Any): Int = keyToIndexMap.getIndex(key)
}
@OptIn(ExperimentalFoundationApi::class)
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 23c078e..96e93f6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -31,6 +31,7 @@
import androidx.compose.foundation.gestures.snapping.MinFlingVelocityDp
import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
@@ -673,9 +674,13 @@
layoutInfo.visiblePagesInfo.fastForEach { page ->
val offset = calculateDistanceToDesiredSnapPosition(
- layoutInfo,
- page,
- SnapAlignmentStartToStart
+ mainAxisViewPortSize = layoutInfo.mainAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = layoutInfo.pageSize,
+ itemOffset = page.offset,
+ itemIndex = page.index,
+ snapPositionInLayout = SnapAlignmentStartToStart
)
// Find page that is closest to the snap position, but before it
@@ -870,26 +875,6 @@
})
}
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
- layoutInfo: PagerLayoutInfo,
- page: PageInfo,
- positionInLayout: Density.(layoutSize: Float, itemSize: Float) -> Float
-): Float {
- val containerSize =
- with(layoutInfo) { mainAxisViewportSize - beforeContentPadding - afterContentPadding }
-
- val desiredDistance =
- positionInLayout(containerSize.toFloat(), layoutInfo.pageSize.toFloat())
-
- val itemCurrentPosition = page.offset
- return itemCurrentPosition - desiredDistance
-}
-
-@OptIn(ExperimentalFoundationApi::class)
-private val PagerLayoutInfo.mainAxisViewportSize: Int
- get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
-
private const val LowVelocityAnimationDefaultDuration = 500
private const val DEBUG = false
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerBeyondBoundsModifier.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerBeyondBoundsModifier.kt
index 7c9deaf..84d4297 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerBeyondBoundsModifier.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerBeyondBoundsModifier.kt
@@ -17,8 +17,8 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsState
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsModifierLocal
+import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
index 10a25d2..27009c4 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerLayoutInfo.kt
@@ -34,4 +34,8 @@
val viewportSize: IntSize
val orientation: Orientation
val reverseLayout: Boolean
-}
\ No newline at end of file
+}
+
+@ExperimentalFoundationApi
+internal val PagerLayoutInfo.mainAxisViewportSize: Int
+ get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
index 68693ac..2cc255c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
@@ -19,6 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.fastFilter
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
import androidx.compose.ui.Alignment
@@ -349,6 +350,7 @@
else
currentMainAxisOffset
)
+
val layoutHeight = constraints
.constrainHeight(
if (orientation == Orientation.Vertical)
@@ -381,12 +383,13 @@
val closestPageToSnapPosition = visiblePagesInfo.fastMaxBy {
-abs(
calculateDistanceToDesiredSnapPosition(
- viewPortSize,
- beforeContentPadding,
- afterContentPadding,
- pageAvailableSize,
- it,
- SnapAlignmentStartToStart
+ mainAxisViewPortSize = viewPortSize,
+ beforeContentPadding = beforeContentPadding,
+ afterContentPadding = afterContentPadding,
+ itemSize = pageAvailableSize,
+ itemOffset = it.offset,
+ itemIndex = it.index,
+ snapPositionInLayout = SnapAlignmentStartToStart
)
)
}
@@ -415,24 +418,6 @@
}
}
-@OptIn(ExperimentalFoundationApi::class)
-private fun Density.calculateDistanceToDesiredSnapPosition(
- axisViewPortSize: Int,
- beforeContentPadding: Int,
- afterContentPadding: Int,
- pageSize: Int,
- page: PageInfo,
- positionInLayout: Density.(layoutSize: Float, itemSize: Float) -> Float
-): Float {
- val containerSize = axisViewPortSize - beforeContentPadding - afterContentPadding
-
- val desiredDistance =
- positionInLayout(containerSize.toFloat(), pageSize.toFloat())
-
- val itemCurrentPosition = page.offset
- return itemCurrentPosition - desiredDistance
-}
-
private fun createPagesAfterList(
currentLastPage: Int,
pagesCount: Int,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
index cf2cb6b..cecb371 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerScrollPosition.kt
@@ -18,7 +18,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
@@ -31,10 +31,10 @@
initialPage: Int = 0,
initialScrollOffset: Int = 0
) {
- var firstVisiblePage by mutableStateOf(initialPage)
- var currentPage by mutableStateOf(initialPage)
+ var firstVisiblePage by mutableIntStateOf(initialPage)
+ var currentPage by mutableIntStateOf(initialPage)
- var scrollOffset by mutableStateOf(initialScrollOffset)
+ var scrollOffset by mutableIntStateOf(initialScrollOffset)
private set
private var hadFirstNotEmptyLayout = false
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
index 1e9132b..ea799c2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
@@ -25,9 +25,11 @@
import androidx.compose.foundation.gestures.ScrollScope
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.lazy.AwaitFirstLayoutModifier
+import androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier
import androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo
import androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList
import androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState
@@ -35,6 +37,8 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
@@ -181,7 +185,7 @@
* Difference between the last up and last down events of a scroll event.
*/
internal var upDownDifference: Offset by mutableStateOf(Offset.Zero)
- internal var snapRemainingScrollOffset by mutableStateOf(0f)
+ internal var snapRemainingScrollOffset by mutableFloatStateOf(0f)
private val scrollPosition = PagerScrollPosition(initialPage, 0)
@@ -257,9 +261,13 @@
private val distanceToSnapPosition: Float
get() = layoutInfo.closestPageToSnapPosition?.let {
density.calculateDistanceToDesiredSnapPosition(
- layoutInfo,
- it,
- SnapAlignmentStartToStart
+ mainAxisViewPortSize = layoutInfo.mainAxisViewportSize,
+ beforeContentPadding = layoutInfo.beforeContentPadding,
+ afterContentPadding = layoutInfo.afterContentPadding,
+ itemSize = layoutInfo.pageSize,
+ itemOffset = it.offset,
+ itemIndex = it.index,
+ snapPositionInLayout = SnapAlignmentStartToStart
)
} ?: 0f
@@ -283,9 +291,9 @@
*/
val currentPage: Int get() = scrollPosition.currentPage
- private var animationTargetPage by mutableStateOf(-1)
+ private var animationTargetPage by mutableIntStateOf(-1)
- private var settledPageState by mutableStateOf(initialPage)
+ private var settledPageState by mutableIntStateOf(initialPage)
/**
* The page that is currently "settled". This is an animation/gesture unaware page in the sense
@@ -663,8 +671,8 @@
override val fontScale: Float = 1f
}
-internal val SnapAlignmentStartToStart: Density.(layoutSize: Float, itemSize: Float) -> Float =
- { _, _ -> 0f }
+@OptIn(ExperimentalFoundationApi::class)
+internal val SnapAlignmentStartToStart = SnapPositionInLayout { _, _, _ -> 0 }
private const val DEBUG = false
private inline fun debugLog(generateMsg: () -> String) {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
index 5b3869a..fcdba64 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/selection/Selectable.kt
@@ -17,9 +17,9 @@
package androidx.compose.foundation.selection
import androidx.compose.foundation.Indication
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/KeyboardActionRunner.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/KeyboardActionRunner.kt
index 96051ac..1bf9ca7 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/KeyboardActionRunner.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/KeyboardActionRunner.kt
@@ -20,13 +20,13 @@
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.ImeAction.Companion.Default
-import androidx.compose.ui.text.input.ImeAction.Companion.None
+import androidx.compose.ui.text.input.ImeAction.Companion.Done
import androidx.compose.ui.text.input.ImeAction.Companion.Go
+import androidx.compose.ui.text.input.ImeAction.Companion.Next
+import androidx.compose.ui.text.input.ImeAction.Companion.None
+import androidx.compose.ui.text.input.ImeAction.Companion.Previous
import androidx.compose.ui.text.input.ImeAction.Companion.Search
import androidx.compose.ui.text.input.ImeAction.Companion.Send
-import androidx.compose.ui.text.input.ImeAction.Companion.Previous
-import androidx.compose.ui.text.input.ImeAction.Companion.Next
-import androidx.compose.ui.text.input.ImeAction.Companion.Done
import androidx.compose.ui.text.input.TextInputSession
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
index d848b79..fa1811f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/LongPressTextDragObserver.kt
@@ -16,10 +16,10 @@
package androidx.compose.foundation.text
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerInputScope
import androidx.compose.ui.util.fastAny
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
index 0122d8e..e238c52 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/TextFieldScroll.kt
@@ -25,6 +25,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.listSaver
@@ -250,13 +251,13 @@
* Taken with the opposite sign defines the x or y position of the text field in the
* horizontal or vertical scroller container correspondingly.
*/
- var offset by mutableStateOf(initial)
+ var offset by mutableFloatStateOf(initial)
/**
* Maximum length by which the text field can be scrolled. Defined as a difference in
* size between the scroller container and the text field.
*/
- var maximum by mutableStateOf(0f)
+ var maximum by mutableFloatStateOf(0f)
private set
/**
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
index fccf555..76386b2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/modifiers/TextStringSimpleNode.kt
@@ -73,7 +73,7 @@
private var minLines: Int = DefaultMinLines,
private var overrideColor: ColorProducer? = null
) : Modifier.Node(), LayoutModifierNode, DrawModifierNode, SemanticsModifierNode {
- private var baselineCache: Map<AlignmentLine, Int>? = null
+ private var baselineCache: MutableMap<AlignmentLine, Int>? = null
private var _layoutCache: ParagraphLayoutCache? = null
private val layoutCache: ParagraphLayoutCache
@@ -224,10 +224,13 @@
if (didChangeLayout) {
invalidateLayer()
- baselineCache = mapOf(
- FirstBaseline to paragraph.firstBaseline.roundToInt(),
- LastBaseline to paragraph.lastBaseline.roundToInt()
- )
+ var cache = baselineCache
+ if (cache == null) {
+ cache = LinkedHashMap(2)
+ }
+ cache[FirstBaseline] = paragraph.firstBaseline.roundToInt()
+ cache[LastBaseline] = paragraph.lastBaseline.roundToInt()
+ baselineCache = cache
}
// then allow children to measure _inside_ our final box, with the above placeholders
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
index b07e058..27e669c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImpl.kt
@@ -17,9 +17,9 @@
package androidx.compose.foundation.text.selection
import androidx.compose.foundation.AtomicLong
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.LayoutCoordinates
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/BasicContextMenuRepresentation.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/BasicContextMenuRepresentation.desktop.kt
index 86ddbd5..7b68366 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/BasicContextMenuRepresentation.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/BasicContextMenuRepresentation.desktop.kt
@@ -27,9 +27,9 @@
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
index 77c5476..1398ec3 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt
@@ -18,10 +18,10 @@
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.TweenSpec
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.detectTapAndPress
import androidx.compose.foundation.gestures.drag
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.interaction.DragInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -59,11 +59,11 @@
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.runBlocking
import kotlin.math.abs
import kotlin.math.roundToInt
import kotlin.math.sign
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
/**
* [CompositionLocal] used to pass [ScrollbarStyle] down the tree.
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/TooltipArea.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/TooltipArea.desktop.kt
index 0de1a5c..4b9d393 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/TooltipArea.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/TooltipArea.desktop.kt
@@ -24,26 +24,26 @@
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.pointer.changedToDown
import androidx.compose.ui.input.pointer.PointerEventPass
+import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.PointerInputScope
+import androidx.compose.ui.input.pointer.changedToDown
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInWindow
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
-import androidx.compose.ui.window.rememberCursorPositionProvider
import androidx.compose.ui.window.rememberComponentRectPositionProvider
-import kotlinx.coroutines.delay
+import androidx.compose.ui.window.rememberCursorPositionProvider
import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/**
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
index 6314814..2e59356 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/gestures/DesktopScrollable.desktop.kt
@@ -16,14 +16,14 @@
package androidx.compose.foundation.gestures
-import androidx.compose.runtime.Composable
-import androidx.compose.foundation.fastFold
import androidx.compose.foundation.DesktopPlatform
+import androidx.compose.foundation.fastFold
+import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.PointerEvent
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import java.awt.event.MouseWheelEvent
import kotlin.math.sqrt
diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt
index b285b1c..c525ae5 100644
--- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt
+++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.window
-import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -36,6 +36,7 @@
* WindowDraggableArea is a component that allows you to drag the window using the mouse.
*
* @param modifier The modifier to be applied to the layout.
+ * @param content The content lambda.
*/
@Composable
fun WindowScope.WindowDraggableArea(
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
index b086c51..7edf141 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/ScrollbarTest.kt
@@ -33,13 +33,13 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.platform.testTag
import androidx.compose.ui.input.pointer.PointerEvent
+import androidx.compose.ui.input.pointer.PointerEventType
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.InternalTestApi
import androidx.compose.ui.test.TouchInjectionScope
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
index d7820234..b9b7073 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/gestures/DesktopScrollableTest.kt
@@ -32,11 +32,11 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
+import kotlin.math.sqrt
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.math.sqrt
// TODO(demin): convert to ComposeScene instead of TestComposeWindow,
// after that we won't need `window.render`
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
index f4df453..72b92ca 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/DesktopTextFieldSelectionManagerTest.kt
@@ -38,16 +38,16 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(JUnit4::class)
@Ignore("b/271123970 Fails in AOSP. Will be fixed after upstreaming Compose for Desktop")
diff --git a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
index 650354d..1de6bae 100644
--- a/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
+++ b/compose/foundation/foundation/src/desktopTest/kotlin/androidx/compose/foundation/text/selection/StringHelpersTest.kt
@@ -19,7 +19,6 @@
import androidx.compose.foundation.text.findFollowingBreak
import androidx.compose.foundation.text.findPrecedingBreak
import com.google.common.truth.Truth.assertThat
-
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
index a878a1c..c9a1c17 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextDelegateTest.kt
@@ -22,10 +22,10 @@
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Density
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
@OptIn(InternalFoundationTextApi::class)
@RunWith(JUnit4::class)
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
index f936cd5..e80c61f 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldBringIntoViewTest.kt
@@ -33,17 +33,17 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
+import kotlinx.coroutines.runBlocking
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.reset
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyBlocking
import org.mockito.kotlin.whenever
-import kotlinx.coroutines.runBlocking
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@OptIn(InternalFoundationTextApi::class, ExperimentalFoundationApi::class)
@RunWith(JUnit4::class)
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
index 3ced499..f38fa30 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldDelegateTest.kt
@@ -38,6 +38,10 @@
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextDecoration
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.inOrder
@@ -45,10 +49,6 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@OptIn(InternalFoundationTextApi::class)
@RunWith(JUnit4::class)
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldStateTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldStateTest.kt
index 80a615d..c8ab92b 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldStateTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextFieldStateTest.kt
@@ -18,10 +18,10 @@
import androidx.compose.runtime.snapshots.Snapshot
import com.google.common.truth.Truth
-import org.mockito.kotlin.mock
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
@RunWith(JUnit4::class)
internal class TextFieldStateTest {
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
index 4420a2b..d14c552 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/TextLayoutHelperTest.kt
@@ -33,12 +33,12 @@
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(JUnit4::class)
class TextLayoutHelperTest {
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
index 344ce0b..ec961c2 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/MockCoordinates.kt
@@ -16,9 +16,9 @@
package androidx.compose.foundation.text.selection
-import androidx.compose.ui.layout.AlignmentLine
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.layout.AlignmentLine
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.unit.IntSize
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
index 84211e52..15f2365 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionAdjustmentTest.kt
@@ -29,11 +29,11 @@
import androidx.compose.ui.util.packInts
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
@SmallTest
@RunWith(JUnit4::class)
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
index 034e5cd..9bcffd9 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerDragTest.kt
@@ -24,14 +24,14 @@
import androidx.compose.ui.text.style.ResolvedTextDirection
import androidx.compose.ui.unit.IntSize
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@RunWith(JUnit4::class)
class SelectionManagerDragTest {
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
index 2e206d7..a14887a 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionManagerTest.kt
@@ -26,6 +26,10 @@
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.style.ResolvedTextDirection
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.doReturn
@@ -37,10 +41,6 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class SelectionManagerTest {
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
index 0c8f63b..b0e573e 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/SelectionRegistrarImplTest.kt
@@ -17,14 +17,13 @@
package androidx.compose.foundation.text.selection
import androidx.compose.ui.geometry.Offset
-
import androidx.compose.ui.layout.LayoutCoordinates
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@RunWith(JUnit4::class)
class SelectionRegistrarImplTest {
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
index c0a54f5..525e6bf 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.foundation.text.selection
-import androidx.compose.foundation.text.InternalFoundationTextApi
import androidx.compose.foundation.text.HandleState
+import androidx.compose.foundation.text.InternalFoundationTextApi
import androidx.compose.foundation.text.TextFieldState
import androidx.compose.foundation.text.TextLayoutResultProxy
import androidx.compose.ui.focus.FocusRequester
@@ -45,6 +45,11 @@
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.util.packInts
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.invocation.InvocationOnMock
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.isNull
@@ -53,11 +58,6 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.mockito.invocation.InvocationOnMock
import org.mockito.stubbing.Answer
@RunWith(JUnit4::class)
diff --git a/compose/integration-tests/demos/common/src/main/AndroidManifest.xml b/compose/integration-tests/demos/common/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/integration-tests/demos/common/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/Demos.kt b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/Demos.kt
index 8b85bc8..a987eda 100644
--- a/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/Demos.kt
+++ b/compose/integration-tests/demos/src/main/java/androidx/compose/integration/demos/Demos.kt
@@ -18,13 +18,13 @@
import androidx.compose.animation.demos.AnimationDemos
import androidx.compose.foundation.demos.FoundationDemos
+import androidx.compose.foundation.demos.text.TextDemos
import androidx.compose.foundation.layout.demos.LayoutDemos
import androidx.compose.integration.demos.common.DemoCategory
-import androidx.compose.foundation.demos.text.TextDemos
import androidx.compose.material.demos.MaterialDemos
import androidx.compose.material3.demos.Material3Demos
-import androidx.compose.ui.demos.CoreDemos
import androidx.compose.ui.demos.AccessibilityDemos
+import androidx.compose.ui.demos.CoreDemos
import androidx.navigation.compose.demos.NavigationDemos
import androidx.paging.compose.demos.PagingFoundationDemos
diff --git a/compose/integration-tests/docs-snippets/src/main/AndroidManifest.xml b/compose/integration-tests/docs-snippets/src/main/AndroidManifest.xml
deleted file mode 100644
index ae0be49..0000000
--- a/compose/integration-tests/docs-snippets/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2020 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 />
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
index 24e9aeb..6341378 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/interoperability/Interoperability.kt
@@ -48,7 +48,7 @@
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
@@ -169,7 +169,7 @@
private object InteropSnippet5 {
@Composable
fun CustomView() {
- val selectedItem = remember { mutableStateOf(0) }
+ val selectedItem = remember { mutableIntStateOf(0) }
// Adds view to Compose
AndroidView(
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/navigation/NavigationResponsiveUi.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/navigation/NavigationResponsiveUi.kt
index c8b4a9a..440795f 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/navigation/NavigationResponsiveUi.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/navigation/NavigationResponsiveUi.kt
@@ -24,8 +24,8 @@
import androidx.compose.runtime.Composable
import androidx.lifecycle.ViewModel
import androidx.navigation.NavHostController
-import androidx.navigation.compose.composable
import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import androidx.navigation.compose.rememberNavController
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
index 25c3edd..f75a353 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/preview/LayoutPreview.kt
@@ -24,7 +24,7 @@
import androidx.compose.material.ButtonDefaults.buttonColors
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
@@ -88,12 +88,12 @@
@Preview
@Composable
fun PreviewCounter() {
- val counterState = remember { mutableStateOf(0) }
+ val counterState = remember { mutableIntStateOf(0) }
Counter(
- count = counterState.value,
+ count = counterState.intValue,
updateCount = { newCount ->
- counterState.value = newCount
+ counterState.intValue = newCount
}
)
}
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/sideeffects/SideEffects.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/sideeffects/SideEffects.kt
index d2f586f..928fce9 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/sideeffects/SideEffects.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/sideeffects/SideEffects.kt
@@ -53,12 +53,6 @@
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
import kotlin.Boolean
import kotlin.Exception
import kotlin.Long
@@ -67,6 +61,12 @@
import kotlin.Suppress
import kotlin.Unit
import kotlin.random.Random
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
/**
* This file lets DevRel track changes to snippets present in
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt
deleted file mode 100644
index 5d7c893..0000000
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/state/State.kt
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Copyright 2020 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.
- */
-
-// Ignore lint warnings in documentation snippets
-@file:Suppress("unused", "ControlFlowWithEmptyBody", "UNUSED_PARAMETER", "UNUSED_VARIABLE")
-
-package androidx.compose.integration.docs.state
-
-import android.content.res.Resources
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.LazyListState
-import androidx.compose.foundation.lazy.items
-import androidx.compose.material.Button
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.OutlinedTextField
-import androidx.compose.material.Scaffold
-import androidx.compose.material.ScaffoldState
-import androidx.compose.material.Text
-import androidx.compose.material.rememberScaffoldState
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.State
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.saveable.listSaver
-import androidx.compose.runtime.saveable.mapSaver
-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.unit.dp
-import androidx.lifecycle.SavedStateHandle
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewmodel.compose.viewModel
-import androidx.navigation.NavHostController
-import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.rememberNavController
-import kotlinx.coroutines.launch
-
-/**
- * This file lets DevRel track changes to snippets present in
- * https://developer.android.com/jetpack/compose/state
- *
- * No action required if it's modified.
- */
-
-private object StateSnippet1 {
- @Composable
- fun HelloContent() {
- Column(modifier = Modifier.padding(16.dp)) {
- Text(
- text = "Hello!",
- modifier = Modifier.padding(bottom = 8.dp),
- style = MaterialTheme.typography.h5
- )
- OutlinedTextField(
- value = "",
- onValueChange = { },
- label = { Text("Name") }
- )
- }
- }
-}
-
-private object StateSnippet2 {
- /*
- * MutableState is part of the API, so StateSnippet2 can't have the exact code
- * for the published documentation. Instead, use the following commented code
- * in the doc. If FakeState<T> changes, update the commented code accordingly.
- *
- interface MutableState<T> : State<T> {
- override var value: T
- }
- */
- interface FakeState<T> : State<T> {
- override var value: T
- }
-
- interface FakeMutableState<T> : MutableState<String>
-}
-
-private object StateSnippet3 {
- @Composable
- fun HelloContent() {
- Column(modifier = Modifier.padding(16.dp)) {
- var name by remember { mutableStateOf("") }
- if (name.isNotEmpty()) {
- Text(
- text = "Hello, $name!",
- modifier = Modifier.padding(bottom = 8.dp),
- style = MaterialTheme.typography.h5
- )
- }
- OutlinedTextField(
- value = name,
- onValueChange = { name = it },
- label = { Text("Name") }
- )
- }
- }
-}
-
-private object StateSnippet4 {
- @Composable
- fun HelloScreen() {
- var name by rememberSaveable { mutableStateOf("") }
-
- HelloContent(name = name, onNameChange = { name = it })
- }
-
- @Composable
- fun HelloContent(name: String, onNameChange: (String) -> Unit) {
- Column(modifier = Modifier.padding(16.dp)) {
- Text(
- text = "Hello, $name",
- modifier = Modifier.padding(bottom = 8.dp),
- style = MaterialTheme.typography.h5
- )
- OutlinedTextField(
- value = name,
- onValueChange = onNameChange,
- label = { Text("Name") }
- )
- }
- }
-}
-
-private object StateSnippet5 {
- @Parcelize
- data class City(val name: String, val country: String) : Parcelable
-
- @Composable
- fun CityScreen() {
- var selectedCity = rememberSaveable {
- mutableStateOf(City("Madrid", "Spain"))
- }
- }
-}
-
-private object StateSnippet6 {
- data class City(val name: String, val country: String)
-
- val CitySaver = run {
- val nameKey = "Name"
- val countryKey = "Country"
- mapSaver(
- save = { mapOf(nameKey to it.name, countryKey to it.country) },
- restore = { City(it[nameKey] as String, it[countryKey] as String) }
- )
- }
-
- @Composable
- fun CityScreen() {
- var selectedCity = rememberSaveable(stateSaver = CitySaver) {
- mutableStateOf(City("Madrid", "Spain"))
- }
- }
-}
-
-@Composable
-private fun StateSnippets7() {
- data class City(val name: String, val country: String)
-
- val CitySaver = listSaver<City, Any>(
- save = { listOf(it.name, it.country) },
- restore = { City(it[0] as String, it[1] as String) }
- )
-
- @Composable
- fun CityScreen() {
- var selectedCity = rememberSaveable(stateSaver = CitySaver) {
- mutableStateOf(City("Madrid", "Spain"))
- }
- }
-}
-
-@Composable
-private fun StateSnippets8() {
- @Composable
- fun MyApp() {
- MyTheme {
- val scaffoldState = rememberScaffoldState()
- val coroutineScope = rememberCoroutineScope()
-
- Scaffold(scaffoldState = scaffoldState) { innerPadding ->
- MyContent(
- showSnackbar = { message ->
- coroutineScope.launch {
- scaffoldState.snackbarHostState.showSnackbar(message)
- }
- },
- modifier = Modifier.padding(innerPadding)
- )
- }
- }
- }
-}
-
-@Composable
-private fun StateSnippets9() {
-
- // Plain class that manages App's UI logic and UI elements' state
- class MyAppState(
- val scaffoldState: ScaffoldState,
- val navController: NavHostController,
- private val resources: Resources,
- /* ... */
- ) {
- val bottomBarTabs = /* State */
- // DO NOT COPY IN DAC
- Unit
-
- // Logic to decide when to show the bottom bar
- val shouldShowBottomBar: Boolean
- get() = /* ... */
- // DO NOT COPY IN DAC
- false
-
- // Navigation logic, which is a type of UI logic
- fun navigateToBottomBarRoute(route: String) { /* ... */ }
-
- // Show snackbar using Resources
- fun showSnackbar(message: String) { /* ... */ }
- }
-
- @Composable
- fun rememberMyAppState(
- scaffoldState: ScaffoldState = rememberScaffoldState(),
- navController: NavHostController = rememberNavController(),
- resources: Resources = LocalContext.current.resources,
- /* ... */
- ) = remember(scaffoldState, navController, resources, /* ... */) {
- MyAppState(scaffoldState, navController, resources, /* ... */)
- }
-}
-
-@Composable
-private fun StateSnippets10() {
- @Composable
- fun MyApp() {
- MyTheme {
- val myAppState = rememberMyAppState()
- Scaffold(
- scaffoldState = myAppState.scaffoldState,
- bottomBar = {
- if (myAppState.shouldShowBottomBar) {
- BottomBar(
- tabs = myAppState.bottomBarTabs,
- navigateToRoute = {
- myAppState.navigateToBottomBarRoute(it)
- }
- )
- }
- }
- ) { innerPadding ->
- NavHost(
- navController = myAppState.navController,
- startDestination = "initial",
- modifier = Modifier.padding(innerPadding)
- ) { /* ... */ }
- }
- }
- }
-}
-
-@Composable
-private fun StateSnippets11() {
- data class ExampleUiState(
- val dataToDisplayOnScreen: List<Example> = emptyList(),
- val userMessages: List<Message> = emptyList(),
- val loading: Boolean = false
- )
-
- class ExampleViewModel(
- private val repository: MyRepository,
- private val savedState: SavedStateHandle
- ) : ViewModel() {
-
- var uiState by mutableStateOf(ExampleUiState())
- private set
-
- // Business logic
- fun somethingRelatedToBusinessLogic() { /* ... */ }
- }
-
- @Composable
- fun ExampleScreen(viewModel: ExampleViewModel = viewModel()) {
-
- val uiState = viewModel.uiState
- /* ... */
-
- ExampleReusableComponent(
- someData = uiState.dataToDisplayOnScreen,
- onDoSomething = { viewModel.somethingRelatedToBusinessLogic() }
- )
- }
-
- @Composable
- fun ExampleReusableComponent(someData: Any, onDoSomething: () -> Unit) {
- /* ... */
- Button(onClick = onDoSomething) {
- Text("Do something")
- }
- }
-}
-
-@Composable
-private fun StateSnippets12() {
- class ExampleState(
- val lazyListState: LazyListState,
- private val resources: Resources,
- private val expandedItems: List<Item> = emptyList()
- ) {
- fun isExpandedItem(item: Item): Boolean = TODO()
- /* ... */
- }
-
- @Composable
- fun rememberExampleState(/* ... */): ExampleState { TODO() }
-
- @Composable
- fun ExampleScreen(viewModel: ExampleViewModel = viewModel()) {
-
- val uiState = viewModel.uiState
- val exampleState = rememberExampleState()
-
- LazyColumn(state = exampleState.lazyListState) {
- items(uiState.dataToDisplayOnScreen) { item ->
- if (exampleState.isExpandedItem(item)) {
- /* ... */
- }
- /* ... */
- }
- }
- }
-}
-
-/*
- * Fakes needed for snippets to build:
- */
-
-private object binding {
- object helloText {
- var text = ""
- }
-
- object textInput {
- fun doAfterTextChanged(function: () -> Unit) {}
- }
-}
-
-@Composable
-private fun MyTheme(content: @Composable () -> Unit) {}
-
-@Composable
-private fun MyContent(showSnackbar: (String) -> Unit, modifier: Modifier = Modifier) {}
-
-@Composable
-private fun BottomBar(tabs: Unit, navigateToRoute: (String) -> Unit) {}
-
-@Composable
-private fun rememberMyAppState(
- scaffoldState: ScaffoldState = rememberScaffoldState(),
- navController: NavHostController = rememberNavController(),
- resources: Resources = LocalContext.current.resources
-) = remember(scaffoldState, navController, resources) {
- MyAppState(scaffoldState, navController, resources)
-}
-
-private class MyAppState(
- val scaffoldState: ScaffoldState,
- val navController: NavHostController,
- private val resources: Resources,
-) {
- val shouldShowBottomBar: Boolean = false
- val bottomBarTabs = Unit
- fun navigateToBottomBarRoute(route: String) {}
-}
-
-/**
- * Add fake Parcelize and Parcelable to avoid adding AndroidX wide dependency on
- * kotlin-parcelize just for snippets
- */
-private annotation class Parcelize
-private interface Parcelable
-
-private class Example
-private class Item
-private class Message
-private class MyRepository
-
-@Composable
-private fun ExampleReusableComponent(someData: List<Example>, onDoSomething: () -> Unit) {}
-
-private class ExampleViewModel : ViewModel() {
- val uiState = ExampleUiState()
-}
-
-private data class ExampleUiState(
- val dataToDisplayOnScreen: List<Item> = emptyList(),
- val userMessages: List<Message> = emptyList(),
- val loading: Boolean = false
-)
\ No newline at end of file
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt
index 8531dc7e..bda62b5 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/CheatSheet.kt
@@ -20,6 +20,9 @@
package androidx.compose.integration.docs.testing
import android.os.Build
+import android.view.KeyEvent as AndroidKeyEvent
+import android.view.KeyEvent.ACTION_DOWN as ActionDown
+import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
@@ -143,9 +146,6 @@
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
-import android.view.KeyEvent as AndroidKeyEvent
-import android.view.KeyEvent.ACTION_DOWN as ActionDown
-import android.view.KeyEvent.KEYCODE_A as KeyCodeA
/**
* This file lets DevRel track changes to snippets present in
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/Testing.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/Testing.kt
index 559f4b6..ab880fe 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/Testing.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/testing/Testing.kt
@@ -31,7 +31,9 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.KeyEvent
@@ -223,13 +225,13 @@
private object SyncSnippet {
@Test fun counterTest() {
- val myCounter = mutableStateOf(0) // State that can cause recompositions
+ var myCounter by mutableIntStateOf(0) // State that can cause recompositions
var lastSeenValue = 0 // Used to track recompositions
composeTestRule.setContent {
- Text(myCounter.value.toString())
- lastSeenValue = myCounter.value
+ Text(myCounter.toString())
+ lastSeenValue = myCounter
}
- myCounter.value = 1 // The state changes, but there is no recomposition
+ myCounter = 1 // The state changes, but there is no recomposition
// Fails because nothing triggered a recomposition
assertTrue(lastSeenValue == 1)
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Custom.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Custom.kt
deleted file mode 100644
index beb52bb5..0000000
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Custom.kt
+++ /dev/null
@@ -1,364 +0,0 @@
-// ktlint-disable indent https://github.com/pinterest/ktlint/issues/967
-/*
- * Copyright 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.
- */
-
-// Ignore lint warnings in documentation snippets
-@file:Suppress(
- "unused", "UNUSED_PARAMETER", "UNUSED_VARIABLE", "RemoveEmptyParenthesesFromLambdaCall"
-)
-
-package androidx.compose.integration.docs.theming
-
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.shape.ZeroCornerSize
-import androidx.compose.material.Button
-import androidx.compose.material.ButtonDefaults
-import androidx.compose.material.Colors
-import androidx.compose.material.ContentAlpha
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.ProvideTextStyle
-import androidx.compose.material.Shapes
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.staticCompositionLocalOf
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.compositeOver
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-/**
- * This file lets DevRel track changes to snippets present in
- * https://developer.android.com/jetpack/compose/themes/custom
- *
- * No action required if it's modified.
- */
-
-private object CustomSnippet1 {
- // Use with MaterialTheme.colors.snackbarAction
- val Colors.snackbarAction: Color
- get() = if (isLight) Red300 else Red700
-
- // Use with MaterialTheme.typography.textFieldInput
- val Typography.textFieldInput: TextStyle
- get() = TextStyle(/* ... */)
-
- // Use with MaterialTheme.shapes.card
- val Shapes.card: Shape
- get() = RoundedCornerShape(size = 20.dp)
-}
-
-private object CustomSnippet234 {
- // Start snippet 2
- @Immutable
- data class ExtendedColors(
- val tertiary: Color,
- val onTertiary: Color
- )
-
- val LocalExtendedColors = staticCompositionLocalOf {
- ExtendedColors(
- tertiary = Color.Unspecified,
- onTertiary = Color.Unspecified
- )
- }
-
- @Composable
- fun ExtendedTheme(
- /* ... */
- content: @Composable () -> Unit
- ) {
- val extendedColors = ExtendedColors(
- tertiary = Color(0xFFA8EFF0),
- onTertiary = Color(0xFF002021)
- )
- CompositionLocalProvider(LocalExtendedColors provides extendedColors) {
- MaterialTheme(
- /* colors = ..., typography = ..., shapes = ... */
- content = content
- )
- }
- }
-
- // Use with eg. ExtendedTheme.colors.tertiary
- object ExtendedTheme {
- val colors: ExtendedColors
- @Composable
- get() = LocalExtendedColors.current
- }
- // End snippet 2
-
- // Start snippet 3
- @Composable
- fun ExtendedButton(
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- content: @Composable RowScope.() -> Unit
- ) {
- Button(
- colors = ButtonDefaults.buttonColors(
- backgroundColor = ExtendedTheme.colors.tertiary,
- contentColor = ExtendedTheme.colors.onTertiary
- /* Other colors use values from MaterialTheme */
- ),
- onClick = onClick,
- modifier = modifier,
- content = content
- )
- }
- // End snippet 3
-
- // Start snippet 4
- @Composable
- fun ExtendedApp() {
- ExtendedTheme {
- /*...*/
- ExtendedButton(onClick = { /* ... */ }) {
- /* ... */
- }
- }
- }
- // End snippet 4
-}
-
-private object CustomSnippet567 {
- // Start snippet 5
- @Immutable
- data class ReplacementTypography(
- val body: TextStyle,
- val title: TextStyle
- )
-
- @Immutable
- data class ReplacementShapes(
- val component: Shape,
- val surface: Shape
- )
-
- val LocalReplacementTypography = staticCompositionLocalOf {
- ReplacementTypography(
- body = TextStyle.Default,
- title = TextStyle.Default
- )
- }
- val LocalReplacementShapes = staticCompositionLocalOf {
- ReplacementShapes(
- component = RoundedCornerShape(ZeroCornerSize),
- surface = RoundedCornerShape(ZeroCornerSize)
- )
- }
-
- @Composable
- fun ReplacementTheme(
- /* ... */
- content: @Composable () -> Unit
- ) {
- val replacementTypography = ReplacementTypography(
- body = TextStyle(fontSize = 16.sp),
- title = TextStyle(fontSize = 32.sp)
- )
- val replacementShapes = ReplacementShapes(
- component = RoundedCornerShape(percent = 50),
- surface = RoundedCornerShape(size = 40.dp)
- )
- CompositionLocalProvider(
- LocalReplacementTypography provides replacementTypography,
- LocalReplacementShapes provides replacementShapes
- ) {
- MaterialTheme(
- /* colors = ... */
- content = content
- )
- }
- }
-
- // Use with eg. ReplacementTheme.typography.body
- object ReplacementTheme {
- val typography: ReplacementTypography
- @Composable
- get() = LocalReplacementTypography.current
- val shapes: ReplacementShapes
- @Composable
- get() = LocalReplacementShapes.current
- }
- // End snippet 5
-
- // Start snippet 6
- @Composable
- fun ReplacementButton(
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- content: @Composable RowScope.() -> Unit
- ) {
- Button(
- shape = ReplacementTheme.shapes.component,
- onClick = onClick,
- modifier = modifier,
- content = {
- ProvideTextStyle(
- value = ReplacementTheme.typography.body
- ) {
- content()
- }
- }
- )
- }
- // End snippet 6
-
- // Start snippet 7
- @Composable
- fun ReplacementApp() {
- ReplacementTheme {
- /*...*/
- ReplacementButton(onClick = { /* ... */ }) {
- /* ... */
- }
- }
- }
- // End snippet 7
-}
-
-private object CustomSnippet89 {
- // Start snippet 8
- @Immutable
- data class CustomColors(
- val content: Color,
- val component: Color,
- val background: List<Color>
- )
-
- @Immutable
- data class CustomTypography(
- val body: TextStyle,
- val title: TextStyle
- )
-
- @Immutable
- data class CustomElevation(
- val default: Dp,
- val pressed: Dp
- )
-
- val LocalCustomColors = staticCompositionLocalOf {
- CustomColors(
- content = Color.Unspecified,
- component = Color.Unspecified,
- background = emptyList()
- )
- }
- val LocalCustomTypography = staticCompositionLocalOf {
- CustomTypography(
- body = TextStyle.Default,
- title = TextStyle.Default
- )
- }
- val LocalCustomElevation = staticCompositionLocalOf {
- CustomElevation(
- default = Dp.Unspecified,
- pressed = Dp.Unspecified
- )
- }
-
- @Composable
- fun CustomTheme(
- /* ... */
- content: @Composable () -> Unit
- ) {
- val customColors = CustomColors(
- content = Color(0xFFDD0D3C),
- component = Color(0xFFC20029),
- background = listOf(Color.White, Color(0xFFF8BBD0))
- )
- val customTypography = CustomTypography(
- body = TextStyle(fontSize = 16.sp),
- title = TextStyle(fontSize = 32.sp)
- )
- val customElevation = CustomElevation(
- default = 4.dp,
- pressed = 8.dp
- )
- CompositionLocalProvider(
- LocalCustomColors provides customColors,
- LocalCustomTypography provides customTypography,
- LocalCustomElevation provides customElevation,
- content = content
- )
- }
-
- // Use with eg. CustomTheme.elevation.small
- object CustomTheme {
- val colors: CustomColors
- @Composable
- get() = LocalCustomColors.current
- val typography: CustomTypography
- @Composable
- get() = LocalCustomTypography.current
- val elevation: CustomElevation
- @Composable
- get() = LocalCustomElevation.current
- }
- // End snippet 8
-
- // Start snippet 9
- @Composable
- fun CustomButton(
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- content: @Composable RowScope.() -> Unit
- ) {
- Button(
- colors = ButtonDefaults.buttonColors(
- backgroundColor = CustomTheme.colors.component,
- contentColor = CustomTheme.colors.content,
- disabledBackgroundColor = CustomTheme.colors.content
- .copy(alpha = 0.12f)
- .compositeOver(CustomTheme.colors.component),
- disabledContentColor = CustomTheme.colors.content
- .copy(alpha = ContentAlpha.disabled)
- ),
- shape = ButtonShape,
- elevation = ButtonDefaults.elevation(
- defaultElevation = CustomTheme.elevation.default,
- pressedElevation = CustomTheme.elevation.pressed
- /* disabledElevation = 0.dp */
- ),
- onClick = onClick,
- modifier = modifier,
- content = {
- ProvideTextStyle(
- value = CustomTheme.typography.body
- ) {
- content()
- }
- }
- )
- }
-
- val ButtonShape = RoundedCornerShape(percent = 50)
- // End snippet 9
-}
-
-/*
-Fakes needed for snippets to build:
- */
-
-private val Red300 = Color(0xffff0000)
-private val Red700 = Color(0xffff0000)
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material.kt
deleted file mode 100644
index 8885249..0000000
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material.kt
+++ /dev/null
@@ -1,448 +0,0 @@
-// ktlint-disable indent https://github.com/pinterest/ktlint/issues/967
-/*
- * Copyright 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.
- */
-
-// Ignore lint warnings in documentation snippets
-@file:Suppress(
- "unused", "UNUSED_PARAMETER", "UNUSED_VARIABLE", "RemoveEmptyParenthesesFromLambdaCall"
-)
-
-package androidx.compose.integration.docs.theming
-
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.RowScope
-import androidx.compose.foundation.shape.CutCornerShape
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.Button
-import androidx.compose.material.ButtonDefaults
-import androidx.compose.material.ContentAlpha
-import androidx.compose.material.Icon
-import androidx.compose.material.LocalContentAlpha
-import androidx.compose.material.LocalElevationOverlay
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Shapes
-import androidx.compose.material.Surface
-import androidx.compose.material.Text
-import androidx.compose.material.TopAppBar
-import androidx.compose.material.Typography
-import androidx.compose.material.contentColorFor
-import androidx.compose.material.darkColors
-import androidx.compose.material.lightColors
-import androidx.compose.material.primarySurface
-import androidx.compose.material.ripple.LocalRippleTheme
-import androidx.compose.material.ripple.RippleTheme
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Immutable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.compositeOver
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-/**
- * This file lets DevRel track changes to snippets present in
- * https://developer.android.com/jetpack/compose/themes/material
- *
- * No action required if it's modified.
- */
-
-private object MaterialSnippet1 {
- /* Can't be compiled. See snippet below for changes.
- MaterialTheme(
- colors = ...,
- typography = ...,
- shapes = ...
- ) {
- // app content
- }
- */
- @Composable
- fun MaterialTheming() {
- MaterialTheme(
- colors = MaterialTheme.colors,
- typography = MaterialTheme.typography,
- shapes = MaterialTheme.shapes
- ) { }
- }
-}
-
-private object MaterialSnippet2 {
- val Red = Color(0xffff0000)
- val Blue = Color(red = 0f, green = 0f, blue = 1f)
-}
-
-private object MaterialSnippet3 {
- private val Yellow200 = Color(0xffffeb46)
- private val Blue200 = Color(0xff91a4fc)
- // ...
-
- private val DarkColors = darkColors(
- primary = Yellow200,
- secondary = Blue200,
- // ...
- )
- private val LightColors = lightColors(
- primary = Yellow500,
- primaryVariant = Yellow400,
- secondary = Blue700,
- // ...
- )
-}
-
-private object MaterialSnippet4 {
- @Composable
- fun MaterialTheming() {
- MaterialTheme(
- colors = if (darkTheme) DarkColors else LightColors
- ) {
- // app content
- }
- }
-}
-
-private object MaterialSnippet5 {
- @Composable
- fun MaterialTheming() {
- Text(
- text = "Hello theming",
- color = MaterialTheme.colors.primary
- )
- }
-}
-
-private object MaterialSnippet6 {
- @Composable
- fun MaterialTheming() {
- /* This snippet comes from the API. It needs to be updated if the snippet below is modified:
-Surface(
- color: Color = MaterialTheme.colors.surface,
- contentColor: Color = contentColorFor(color),
- ...
-
-TopAppBar(
- backgroundColor: Color = MaterialTheme.colors.primarySurface,
- contentColor: Color = contentColorFor(backgroundColor),
- ...
- */
- Column {
- Surface(
- color = MaterialTheme.colors.surface,
- contentColor = contentColorFor(MaterialTheme.colors.surface)
- ) {}
- TopAppBar(
- backgroundColor = MaterialTheme.colors.primarySurface,
- contentColor = contentColorFor(MaterialTheme.colors.primarySurface)
- ) {}
- }
- }
-}
-
-private object MaterialSnippet7 {
- @Composable
- fun MaterialTheming() {
- // By default, both Icon & Text use the combination of LocalContentColor &
- // LocalContentAlpha. De-emphasize content by setting content alpha
- CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
- Text(/*...*/)
- }
- CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
- Icon(/*...*/)
- Text(/*...*/)
- }
- }
- @Composable private fun Icon() { }
- @Composable private fun Text() { }
-}
-
-private object MaterialSnippet8 {
- @Composable
- fun MyTheme(
- darkTheme: Boolean = isSystemInDarkTheme(),
- content: @Composable () -> Unit
- ) {
- MaterialTheme(
- colors = if (darkTheme) DarkColors else LightColors,
- /*...*/
- content = content
- )
- }
-}
-
-private object MaterialSnippet9 {
- @Composable
- fun MaterialTheming() {
- val isLightTheme = MaterialTheme.colors.isLight
- Icon(
- painterResource(
- id = if (isLightTheme) {
- R.drawable.ic_sun_24dp
- } else {
- R.drawable.ic_moon_24dp
- }
- ),
- contentDescription = "Theme"
- )
- }
-}
-
-private object MaterialSnippet10 {
- @Composable
- fun MaterialTheming() {
- Surface(
- elevation = 2.dp,
- color = MaterialTheme.colors.surface, // color will be adjusted for elevation
- /*...*/
- ) { /*...*/ }
- }
-}
-
-private object MaterialSnippet11 {
- @Composable
- fun MaterialTheming() {
- // Elevation overlays
- // Implemented in Surface (and any components that use it)
- val color = MaterialTheme.colors.surface
- val elevation = 4.dp
- val overlaidColor = LocalElevationOverlay.current?.apply(
- color, elevation
- )
- }
-}
-
-private object MaterialSnippet12 {
- @Composable
- fun MaterialTheming() {
- MyTheme {
- CompositionLocalProvider(LocalElevationOverlay provides null) {
- // Content without elevation overlays
- }
- }
- }
-}
-
-private object MaterialSnippet13 {
- @Composable
- fun MaterialTheming() {
- Surface(
- // Switches between primary in light theme and surface in dark theme
- color = MaterialTheme.colors.primarySurface,
- /*...*/
- ) { /*...*/ }
- }
-}
-
-private object MaterialSnippet14 {
- @Composable
- fun MaterialTheming() {
- val Rubik = FontFamily(
- Font(R.font.rubik_regular),
- Font(R.font.rubik_medium, FontWeight.W500),
- Font(R.font.rubik_bold, FontWeight.Bold)
- )
-
- val MyTypography = Typography(
- h1 = TextStyle(
- fontFamily = Rubik,
- fontWeight = FontWeight.W300,
- fontSize = 96.sp
- ),
- body1 = TextStyle(
- fontFamily = Rubik,
- fontWeight = FontWeight.W600,
- fontSize = 16.sp
- )
- /*...*/
- )
- MaterialTheme(typography = MyTypography, /*...*/)
- }
- @Composable private fun MaterialTheme(typography: Typography) { }
-}
-
-private object MaterialSnippet15 {
- @Composable
- fun MaterialTheming() {
- val typography = Typography(defaultFontFamily = Rubik)
- MaterialTheme(typography = typography, /*...*/)
- }
- @Composable private fun MaterialTheme(typography: Typography) { }
-}
-
-private object MaterialSnippet16 {
- @Composable
- fun MaterialTheming() {
- Text(
- text = "Subtitle2 styled",
- style = MaterialTheme.typography.subtitle2
- )
- }
-}
-
-private object MaterialSnippet17 {
- @Composable
- fun MaterialTheming() {
- val Shapes = Shapes(
- small = RoundedCornerShape(percent = 50),
- medium = RoundedCornerShape(0f),
- large = CutCornerShape(
- topStart = 16.dp,
- topEnd = 0.dp,
- bottomEnd = 0.dp,
- bottomStart = 16.dp
- )
- )
-
- MaterialTheme(shapes = Shapes, /*...*/)
- }
- @Composable private fun MaterialTheme(shapes: Shapes) { }
-}
-
-private object MaterialSnippet18 {
- @Composable
- fun MaterialTheming() {
- Surface(
- shape = MaterialTheme.shapes.medium, /*...*/
- ) {
- /*...*/
- }
- }
-}
-
-private object MaterialSnippet19 {
- @Composable
- fun MyButton(
- onClick: () -> Unit,
- modifier: Modifier = Modifier,
- content: @Composable RowScope.() -> Unit
- ) {
- Button(
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MaterialTheme.colors.secondary
- ),
- onClick = onClick,
- modifier = modifier,
- content = content
- )
- }
-}
-
-private object MaterialSnippet20 {
- @Composable
- fun DetailsScreen(/* ... */) {
- PinkTheme {
- // other content
- RelatedSection()
- }
- }
-
- @Composable
- fun RelatedSection(/* ... */) {
- BlueTheme {
- // content
- }
- }
-}
-
-private object MaterialSnippet21 {
- @Composable
- fun MaterialTheming() {
- Button(
- onClick = { /* ... */ },
- enabled = true,
- // Custom colors for different states
- colors = ButtonDefaults.buttonColors(
- backgroundColor = MaterialTheme.colors.secondary,
- disabledBackgroundColor = MaterialTheme.colors.onBackground
- .copy(alpha = 0.2f)
- .compositeOver(MaterialTheme.colors.background)
- // Also contentColor and disabledContentColor
- ),
- // Custom elevation for different states
- elevation = ButtonDefaults.elevation(
- defaultElevation = 8.dp,
- disabledElevation = 2.dp,
- // Also pressedElevation
- )
- ) { /* ... */ }
- }
-}
-
-private object MaterialSnippet22 {
- @Composable
- fun MyApp() {
- MaterialTheme {
- CompositionLocalProvider(
- LocalRippleTheme provides SecondaryRippleTheme
- ) {
- // App content
- }
- }
- }
-
- @Immutable
- private object SecondaryRippleTheme : RippleTheme {
- @Composable
- override fun defaultColor() = RippleTheme.defaultRippleColor(
- contentColor = MaterialTheme.colors.secondary,
- lightTheme = MaterialTheme.colors.isLight
- )
-
- @Composable
- override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
- contentColor = MaterialTheme.colors.secondary,
- lightTheme = MaterialTheme.colors.isLight
- )
- }
-}
-
-/*
-Fakes needed for snippets to build:
- */
-
-private val Yellow500 = Color(0xffffeb46)
-private val Yellow400 = Color(0xffffeb46)
-private val Blue700 = Color(0xffffeb46)
-
-private const val darkTheme = true
-private val DarkColors = darkColors()
-private val LightColors = lightColors()
-
-@Composable private fun MyTheme(content: @Composable () -> Unit) {}
-@Composable private fun PinkTheme(content: @Composable () -> Unit) {}
-@Composable private fun BlueTheme(content: @Composable () -> Unit) {}
-
-@Suppress("ClassName")
-internal object R {
- object drawable {
- const val ic_sun_24dp = 1
- const val ic_moon_24dp = 1
- }
- object font {
- const val rubik_regular = 1
- const val rubik_medium = 1
- const val rubik_bold = 1
- const val karla_regular = 1
- const val karla_bold = 1
- }
-}
-
-private val Rubik = FontFamily()
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material3.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material3.kt
deleted file mode 100644
index d10cdb2..0000000
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/theming/Material3.kt
+++ /dev/null
@@ -1,193 +0,0 @@
-// ktlint-disable indent https://github.com/pinterest/ktlint/issues/967
-/*
- * Copyright 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.
- */
-
-// Ignore lint warnings in documentation snippets
-@file:Suppress(
- "unused", "UNUSED_PARAMETER", "UNUSED_VARIABLE", "RemoveEmptyParenthesesFromLambdaCall"
-)
-
-package androidx.compose.integration.docs.theming
-
-import android.annotation.SuppressLint
-import android.os.Build
-import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Surface
-import androidx.compose.material3.Text
-import androidx.compose.material3.Typography
-import androidx.compose.material3.darkColorScheme
-import androidx.compose.material3.dynamicDarkColorScheme
-import androidx.compose.material3.dynamicLightColorScheme
-import androidx.compose.material3.lightColorScheme
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.FontFamily
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-/**
- * This file lets DevRel track changes to snippets present in
- * https://developer.android.com/jetpack/compose/themes/material#material3
- *
- * No action required if it's modified.
- */
-
-private object Material3Snippet1 {
- /* Can't be compiled. See snippet below for changes.
- MaterialTheme(
- colorScheme = …,
- typography = …
- // Updates to shapes coming soon
- ) {
- // M3 app content
- }
- */
- @Composable
- fun MaterialTheming() {
- MaterialTheme(
- colorScheme = MaterialTheme.colorScheme,
- typography = MaterialTheme.typography
- ) { }
- }
-}
-
-private object Material3Snippet2 {
- private val Blue40 = Color(0xff1e40ff)
- private val DarkBlue40 = Color(0xff3e41f4)
- private val Yellow40 = Color(0xff7d5700)
- // Remaining colors from tonal palettes
-
- private val LightColorScheme = lightColorScheme(
- primary = Blue40,
- secondary = DarkBlue40,
- tertiary = Yellow40,
- // error, primaryContainer, onSecondary, etc.
- )
- private val DarkColorScheme = darkColorScheme(
- primary = Blue80,
- secondary = DarkBlue80,
- tertiary = Yellow80,
- // error, primaryContainer, onSecondary, etc.
- )
-}
-
-private object Material3Snippet3 {
- @Composable
- fun Material3Theming() {
- val darkTheme = isSystemInDarkTheme()
- MaterialTheme(
- colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
- ) {
- // M3 app content
- }
- }
-}
-
-private object Material3Snippet4 {
- @SuppressLint("NewApi")
- @Composable
- fun Material3Theming() {
- // Dynamic color is available on Android 12+
- val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
- val colorScheme = when {
- dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current)
- dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
- darkTheme -> DarkColorScheme
- else -> LightColorScheme
- }
- }
-}
-
-private object Material3Snippet5 {
- @Composable
- fun Material3Theming() {
- Text(
- text = "Hello M3 theming",
- color = MaterialTheme.colorScheme.tertiary
- )
- }
-}
-
-private object Material3Snippet6 {
- val KarlaFontFamily = FontFamily(
- Font(R.font.karla_regular),
- Font(R.font.karla_bold, FontWeight.Bold)
- )
-
- val AppTypography = Typography(
- bodyLarge = TextStyle(
- fontFamily = KarlaFontFamily,
- fontWeight = FontWeight.Normal,
- fontSize = 16.sp,
- lineHeight = 24.sp,
- letterSpacing = 0.15.sp
- ),
- // titleMedium, labelSmall, etc.
- )
-}
-
-private object Material3Snippet7 {
- @Composable
- fun Material3Theming() {
- MaterialTheme(
- typography = AppTypography
- ) {
- // M3 app content
- }
- }
-}
-
-private object Material3Snippet8 {
- @Composable
- fun Material3Theming() {
- Text(
- text = "Hello M3 theming",
- style = MaterialTheme.typography.bodyLarge
- )
- }
-}
-
-private object Material3Snippet9 {
- @Composable
- fun Material3Theming() {
- Surface(
- tonalElevation = 16.dp,
- shadowElevation = 16.dp
- ) {
- // Surface content
- }
- }
-}
-
-/*
-Fakes needed for snippets to build:
- */
-
-private val Blue80 = Color(0xff1e40ff)
-private val DarkBlue80 = Color(0xff3e41f4)
-private val Yellow80 = Color(0xff7d5700)
-
-private val DarkColorScheme = darkColorScheme()
-private val LightColorScheme = lightColorScheme()
-
-private const val darkTheme = true
-
-private val AppTypography = Typography()
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/tutorial/Tutorial.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/tutorial/Tutorial.kt
index da8c1bc..4f9fd87 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/tutorial/Tutorial.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/docs/tutorial/Tutorial.kt
@@ -24,8 +24,8 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
diff --git a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/tutorial/Tutorial.kt b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/tutorial/Tutorial.kt
index b0b7e65..b17b824 100644
--- a/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/tutorial/Tutorial.kt
+++ b/compose/integration-tests/docs-snippets/src/main/java/androidx/compose/integration/tutorial/Tutorial.kt
@@ -38,8 +38,8 @@
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.integration.tutorial.Lesson2_Layouts.Snippet4.MessageCard
import androidx.compose.integration.tutorial.Lesson2_Layouts.Snippet1.Message
+import androidx.compose.integration.tutorial.Lesson2_Layouts.Snippet4.MessageCard
import androidx.compose.integration.tutorial.Lesson4_ListsAnimations.Snippet1.Conversation
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
diff --git a/compose/integration-tests/macrobenchmark/build.gradle b/compose/integration-tests/macrobenchmark/build.gradle
index 5cb3474..7739110 100644
--- a/compose/integration-tests/macrobenchmark/build.gradle
+++ b/compose/integration-tests/macrobenchmark/build.gradle
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -27,25 +25,22 @@
minSdkVersion 23
}
namespace "androidx.compose.integration.macrobenchmark"
+ targetProjectPath = ":compose:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":compose:integration-tests:macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":compose:integration-tests:macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":benchmark:benchmark-junit4"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
}
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/AndroidViewListScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/AndroidViewListScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/AndroidViewListScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/AndroidViewListScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/AndroidViewPagerBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/AndroidViewPagerBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/AndroidViewPagerBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/AndroidViewPagerBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/DifferentTypesListScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/DifferentTypesListScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/DifferentTypesListScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/DifferentTypesListScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/FullyDrawnStartupBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/FullyDrawnStartupBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/FullyDrawnStartupBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/FullyDrawnStartupBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/GridBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/GridBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/GridBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/GridBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/IoSettingsStartupBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/IoSettingsStartupBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/IoSettingsStartupBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/IoSettingsStartupBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/LazyBoxWithConstraintsScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/LazyBoxWithConstraintsScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/LazyBoxWithConstraintsScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/LazyBoxWithConstraintsScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/NestedListsScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/NestedListsScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/NestedListsScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/NestedListsScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/PagerAsCarouselBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/PagerAsCarouselBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/PagerAsCarouselBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/PagerAsCarouselBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/PagerBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/PagerBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/PagerBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/PagerBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/RecyclerViewAsCarouselBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/RecyclerViewAsCarouselBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/RecyclerViewAsCarouselBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/RecyclerViewAsCarouselBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/RecyclerViewListScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/RecyclerViewListScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/RecyclerViewListScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/RecyclerViewListScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/SmallListBaselineProfile.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/SmallListBaselineProfile.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/SmallListBaselineProfile.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/SmallListBaselineProfile.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/SmallListStartupBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/SmallListStartupBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/SmallListStartupBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/SmallListStartupBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialListScrollBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialListScrollBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialListScrollBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialListScrollBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialStartupBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialStartupBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialStartupBenchmark.kt
diff --git a/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialTracingBenchmark.kt b/compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialTracingBenchmark.kt
similarity index 100%
rename from compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/compose/integration/macrobenchmark/TrivialTracingBenchmark.kt
rename to compose/integration-tests/macrobenchmark/src/main/java/androidx/compose/integration/macrobenchmark/TrivialTracingBenchmark.kt
diff --git a/compose/integration-tests/material-catalog/build.gradle b/compose/integration-tests/material-catalog/build.gradle
index c6afe8e..6fc989b 100644
--- a/compose/integration-tests/material-catalog/build.gradle
+++ b/compose/integration-tests/material-catalog/build.gradle
@@ -29,8 +29,8 @@
android {
defaultConfig {
applicationId "androidx.compose.material.catalog"
- versionCode 2100
- versionName "2.1.0"
+ versionCode 2200
+ versionName "2.2.0"
}
buildTypes {
release {
diff --git a/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/NavGraph.kt b/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/NavGraph.kt
index 21bee2a..22f5db5 100644
--- a/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/NavGraph.kt
+++ b/compose/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/NavGraph.kt
@@ -18,8 +18,8 @@
import androidx.compose.material.catalog.library.MaterialCatalogApp
import androidx.compose.material.catalog.library.MaterialRoute
-import androidx.compose.material.catalog.model.MaterialSpecification
import androidx.compose.material.catalog.model.Material3Specification
+import androidx.compose.material.catalog.model.MaterialSpecification
import androidx.compose.material.catalog.model.Specifications
import androidx.compose.material.catalog.ui.specification.Specification
import androidx.compose.material3.catalog.library.Material3CatalogApp
diff --git a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
index dd46067..1d2a07a 100644
--- a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
+++ b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
@@ -21,8 +21,8 @@
import com.android.tools.lint.checks.infrastructure.LintDetectorTest.kotlin
import com.android.tools.lint.checks.infrastructure.TestFile
import com.android.tools.lint.checks.infrastructure.TestFiles.bytecode
-import org.intellij.lang.annotations.Language
import java.util.Locale
+import org.intellij.lang.annotations.Language
/**
* Common Compose-related bytecode lint stubs used for testing
@@ -219,6 +219,69 @@
"""
)
+ val Composables: TestFile = bytecodeStub(
+ filename = "Composables.kt",
+ filepath = "androidx/compose/runtime",
+ checksum = 0x92d0959f,
+ source = """
+ package androidx.compose.runtime
+
+ @Composable
+ inline fun <T> key(
+ @Suppress("UNUSED_PARAMETER")
+ vararg keys: Any?,
+ block: @Composable () -> T
+ ) = block()
+
+ @Composable
+ inline fun ReusableContent(
+ key: Any?,
+ content: @Composable () -> Unit
+ ) {
+ content()
+ }
+
+ @Composable
+ inline fun ReusableContentHost(
+ active: Boolean,
+ crossinline content: @Composable () -> Unit
+ ) {
+ if (active) { content() }
+ }
+ """,
+ """
+ META-INF/main.kotlin_module:
+ H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMuWSSMxLKcrPTKnQS87PLcgvTtUr
+ Ks0rycxNFeJ1BgskJuWkFnuXCHEFpeam5ialFnmXcPFxsZSkFpcIsYUASe8S
+ JQYtBgDjkUhNXwAAAA==
+ """,
+ """
+ androidx/compose/runtime/ComposablesKt.class:
+ H4sIAAAAAAAA/51VzXLbVBT+rvwnK04sy05xXEhT103tGCrHpfzUaaBNKfHg
+ BiY2gWlW17IaFNtSR5I9ZZdhwzN0yxPArrBgMmHHg/AUDMORLCdO7GkK49H5
+ P+d+55wr+c9/fvsdwPv4jGGVmx3bMjovVM3qP7ccXbUHpmv0dXXL13m7pztf
+ uDEwBvmQD7na4+aB+mX7UNfIGmIIdfXvGT4v7jcuumuNruX2DFM9HPbVZwNT
+ cw3LdNTHgVSplaZTGFobrXvT9s3/UX+j3GrVNmslogw3G2/QKcXdaFj2gXqo
+ u22bG1SNm6bl8lHlHcvdGfR6FBWmph0REsPyBAbDdHXb5D21bro2JRuaE0OC
+ YVH7Tte6QfZX3OZ9nQIZbhVn9HRmaXpFDmqlvQQWkJQwD5kh0u5ZWleEcv7o
+ Ge3HkGGIGubQ6uoMmeKMaSdwBW/NYRFZBrFgFJ4V/GWyOkN6xrwZVi5bKUNy
+ Vx/4w9yyaBymy3B3VpuXXY09hkf/PW9j7P/aNFxv91Sm8LqN0kKCxce0EV4R
+ eZqWP4ypTpRZM0lfCNu2HAotFJ++SY93Lg2b1VJ2FrzRuVFOaUNaOHvKkBrn
+ PtFd3uEuJ7hCfxiit595RPQIKLbrCQI5XxieVCGps87w1/HRmnR8JAmyMGJE
+ PJ4VRo9IjzwX8JTHcyWKyQkVVhVlIRfOskqompLDuXklrJC1Ejn5KSqI0e2T
+ H8U/XjEKLckxPzwqi8Tj1bQYfl34Q6oqbEv5sHh8JEvVK/JcLqGIIlP8oyqJ
+ /PjI+VGNbWmqhqfKCyc/CDEpIp68rFaY122VeYNQxgObvNGsxbAw8Tm83aU5
+ h7esDk052TBMfWfQb+t2y3N6JSyN9/a4bXh6YIw3jQOTuwOb5Ku7o+9O3Rwa
+ jkHuB2cXku7NRe/p9+Jc2HzT5Vr3CX8eHCA1rYGt6Y8NT1kKauxN1cc6BIS9
+ pSOEJUQQJW2DtCbZvc0vrilzr5AqK2miofvlX7HE8LN3OXCfaJRmtIA4Nkle
+ oYQFxJDDVfJSKiS87ZdehIJ3KPITPy+GT4NMkfgDeuYFUuL+zfPoEpZxLcCx
+ G+CQy8qNCQTf/HIKQSIuQkYSqVMYIv0KAQyZurrpw5CRn4CxMhvG9QkYq7gV
+ wGgHMDJjGLmXkCaghPBwVOxvpNkErCzSVOcMVgKlAFYGayj7sDLnYBWnYMWF
+ U0gCtnxawyPi35L1XeruvX2E6rhdh1pHBet1VHGnTn/nd/fBHHyAD/eRdLDs
+ 4CMHEZ/mHXzsQHSw6mDNt9xzIPmC4iD6Lx9Lm/oRCAAA
+ """
+ )
+
val Modifier: TestFile = bytecodeStub(
filename = "Modifier.kt",
filepath = "androidx/compose/ui",
@@ -382,7 +445,7 @@
val Remember: TestFile = bytecodeStub(
filename = "Remember.kt",
filepath = "androidx/compose/runtime",
- checksum = 0xc78323f1,
+ checksum = 0x736631c7,
source = """
package androidx.compose.runtime
@@ -392,76 +455,110 @@
inline fun <T> remember(calculation: () -> T): T = calculation()
@Composable
- inline fun <T, V1> remember(
- v1: V1,
- calculation: () -> T
+ inline fun <T> remember(
+ key1: Any?,
+ crossinline calculation: () -> T
): T = calculation()
@Composable
- inline fun <T, V1, V2> remember(
- v1: V1,
- v2: V2,
- calculation: () -> T
+ inline fun <T> remember(
+ key1: Any?,
+ key2: Any?,
+ crossinline calculation: () -> T
): T = calculation()
@Composable
- inline fun <T, V1, V2, V3> remember(
- v1: V1,
- v2: V2,
- v3: V3,
- calculation: () -> T
+ inline fun <T> remember(
+ key1: Any?,
+ key2: Any?,
+ key3: Any?,
+ crossinline calculation: () -> T
): T = calculation()
@Composable
inline fun <V> remember(
vararg inputs: Any?,
- calculation: () -> V
+ crossinline calculation: () -> V
): V = calculation()
""",
-"""
- META-INF/main.kotlin_module:
- H4sIAAAAAAAAAGNgYGBmYGBgBGJWKM3ApcYlkZiXUpSfmVKhl5yfW5BfnKpX
- VJpXkpmbKsQVlJqbmpuUWuRdwqXJJYyhrjRTSMgZwk7xzU/JTMsEK+XjYilJ
- LS4RYgsBkt4lSgxaDACMRj6sewAAAA==
+ """
+ META-INF/main.kotlin_module:
+ H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgUuOSSMxLKcrPTKnQS87PLcgvTtUr
+ Ks0rycxNFeIKSs1NzU1KLfIu4eLjYilJLS4RYgsBkt4lSgxaDAC9VMzjUAAA
+ AA==
+ """,
+ """
+ androidx/compose/runtime/RememberKt.class:
+ H4sIAAAAAAAA/61WWXPbVBT+rrzJjhfFWUgcCCFL62yV44YCdeoSAqEe3MDU
+ HsNMnmRbTeVF6kiyKW8ZXvgNvPILeCw8MJnwxo9iOFeWHW9JXdIHXZ17dO53
+ vnO/u+iff//8C8A+vmRYU/SqaWjVV3LFaL40LFU2W7qtNVX5mdpUm2XV/MYO
+ gDFINaWtyA1FP5O/LdfUCnk9DKLpRjHsJ/N1w25oulxrN+XnLb1ia4Zuyceu
+ lcps5ocxMgyHB8WHo/7sm8AOtovFTDazSS3DRv7aKo6cvlJuqBS3ljfMM7mm
+ 2mVT0QhN0XXDVjrIJ4Z90mo0KGqqojQqrYbjFxFiWO6joum2aupKQ87ptkkY
+ WsUKIMwwV3mhVuouyHeKqTRVm8/K3eRocX2eAgc5y2yWwogiFkIE0mC+MaUH
+ EGfwa3rbqKsMs8kx0xrGLOamMIN5hsi6tv58/UonlmNYeZNUDMfjiP8fgQvX
+ Cfy28AOSr98kJUngKu6tqz/tMcTHEfvhZmluU7M6ec23mgVeXpqhNhnwu6nt
+ x9vUdutq7zN8nTx9R6UUD0pjS3l7fOJZcniWMs7efNmyLRFJhpkxWAzTXbin
+ qq1UFVshn9Bse+hUZrwReQPaq3VuCPTxlcatFFnVPcZeXJwnQoLoCQkLAr3p
+ kS7OyQiQMR2ijxvUTwhP2KpXvDiXWDosCQkx7o2TK+V5cvmL+PdrdnF++Ztf
+ kLyJvaFgUfIlvAss5U9HRe/1AwOJzLUDRUmcBCKY+GoCCFEKTQI2lXjcAQt3
+ wMLpeSmSCMdFkcWd4ano6ihMeBgmdvmzEAj5xMtf0ynG55s2GCvyM8TVrP+U
+ 5BqV6MroXpb36jat0yOjSidzLK/p6kmLu4v8OOIQBt0tJcXUeN91Bgvama7Y
+ LZPspWedayuntzVLo8+HV8canXnDX3v3zEBYqGC0zIp6rHH0RXdMaQQPexDg
+ 5esMPizS46feAfWOyC/QO7YVn3qNac/B1h94j+F3vhLxiFo/VS0igCzZ8+Tj
+ 9gJBMD4IISTo/diJDuDzXjxwSE+AJgxBMnjGJTfjUwrlyzu23cn4aHtsxoiT
+ cYVCuxkdmljGh04ZndzMzf3+SO6IQJ0PnI3VZbDiMvjenYvYTodBdmcsg1mH
+ wRaFdhl4hhisknU1D4LL5aMRLjOeHpdBRmsuozIN89Fb2u0weuDdHUMpSGVm
+ nX85H9kdSrwOqUdJ6lGSsEGW4FicnMcltz5CbtE7RG6Q4h2XYsGVbW4rvkkU
+ bxIvSiy64kX7xJtDkqYTjtUv3t3x4gV7PAR84bQZWq7AKXm3idnOKTw57OZw
+ LwcZqRyt8XQO97FPARY+xoNTSBZ8Fj6xELLwqQW/hWULn1lYsrBqYcXChoU1
+ Cw8tJB3/nf8A7cabHS4LAAA=
+ """
+ )
+
+ val StateFactoryMarker: TestFile = bytecodeStub(
+ filename = "StateFactoryMarker.kt",
+ filepath = "androidx/compose/runtime/snapshots",
+ checksum = 0x79ef0e9d,
+ source = """
+ package androidx.compose.runtime.snapshots
+
+ @MustBeDocumented
+ @Target(AnnotationTarget.FUNCTION)
+ @Retention(AnnotationRetention.BINARY)
+ annotation class StateFactoryMarker
""",
"""
- androidx/compose/runtime/RememberKt.class:
- H4sIAAAAAAAAAK1WXVPbRhQ9K38J29jCfJSYJiFgyndkG5q2MZBSWhpPCekE
- j9opT8JWqMCWMlrZk0emL33pH+hrf0Ef0z50GPrWH9XpXVlgg4UJTTzW3qvr
- u+ecu3el9T///vkXgFV8xTCtWzXHNmuv1ardeGVzQ3Walms2DPWF0TAaB4bz
- jRsDY1CO9Jau1nXrUH1+cGRUKRpikB0/i2F1bufYduumpR61GurLplV1Tdvi
- 6rbv5UvzO1cxSgyba5XHvfGNm8DWFiuV0kZpnkaGmZ1rq9jy7vWDukF50zu2
- c6geGe6Bo5uEpluW7ept5F3b3W3W65SVqOr1arPuxWXEGe51STEt13Asva6W
- LdchDLPKY0gyjFZ/NKrHPsi3uqM3DFesyuxcb3FdkT0Bclia15JIIR3HIJTL
- fAGlx5BhiJpWyz42GEbmApY1iRGMJjCMMYbBnJl7mev0iZUZJm9qFcN2kPD/
- 0+AfAhusFQK7XtEKN7Fc6rzUKjBkgmi/77/w71IRf/uKtOK1ZVa04i1LLTIc
- vV1V76fOX96xTm2lb/EVbeWWC7DC8PXc/nuqrrKmBcq7PT6p1DyVWsl7MF81
- XS5jlmE4AIth6BzumeHqNd3VRW2NVoheyUwMEXpGj4UjUfy1Kbw8ebUCY+7p
- yVhckkNxaVwim4xLyhBdpyfx05PsDNms9JRNheXTE4UVk4qUlTPhDIXyoadn
- P8t/v2GnJ2e/RSUlnF25nEyGKZFiVIlSMNJvaiy7GTSVRkmRLwCiygBZuR9Q
- PPv8eiAaQ0qiBy6qJMkm+sEOZtfbsKk2bKo4pqSzyYwss0x4nOWH8sqUZ7tA
- UldBMmc/SbF4RD77tZhnYu3p0WMV8abxW9f9ppS0ghiKYqAdyjRGjUTi/Px8
- eOwyhLfsGr2s0zumZew2RbgiziSBaNNxo+mOKe794MCeeWjpbtMhf+JF+yQr
- Wy2Tm/TzZufQYshd/fXi6LmUFt+zm07V2DYF+h1/jtaDhwIkhCE+EdyhK0p3
- 63S3RXGJbHohk3iDodDawh/4gOF3sUmxQWOUKpYRwxPyxygm/HGCYGIS4siS
- /dzLjmHzIh/4gq4YrRkGyBGMEz7jM0oVOz+92GZcXwxkHPQYJyn1nNGTibu4
- 55XR5mY+94c93AMivcN+32f/zl+H9FKbfWMpkH3EY1+g1HP20BX2B+R11kDy
- dUz26EiEvAkdJVO+kgNKj5BVlttKHoWXA6QMUGlPvL90EfLbUoR+5UKKciFF
- QY48yfOEqJAvarpH1GB7K3TLmvFl7fntGV3IzJGsfk1KUS3nTUp1NWkUs5j3
- 4EcvNemjXh2Sr6A9SrQdxbiGL8nWKLpAyhb3ESpjqYxlGvGwDBX5Mm3o4j4Y
- xwpW9zHMEeH4mCPO8YgjyvEJx12OCY5POR5w3Of4jCPHMcXxmGOWo+R9Z/4D
- oSNh5zILAAA=
- """
+ META-INF/main.kotlin_module:
+ H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMueSSMxLKcrPTKnQS87PLcgvTtUr
+ Ks0rycxNFeIKSs1NzU1KLfIuEeIPzkssKM7ILwkuSSxJ9S7hUuOSwaVRLy0/
+ X4gtJLW4xLtEiUGLAQDM+x9weQAAAA==
+ """,
+ """
+ androidx/compose/runtime/snapshots/StateFactoryMarker.class:
+ H4sIAAAAAAAA/51STW/TQBB965AmBCgpUEhaSj8o6Q2XCsSBU9I2wlI+UJIi
+ oZy29qq4dryRdx2aW278Jw4o4siPQsw2IgnCAglZGr+ZefPxdvf7jy9fAbzE
+ AcMrHnmx9L0r25WDoVTCjpNI+wNhq4gP1Uepld3VXIs6d7WMx00eByLOgTEU
+ L/mI2yGPLuz2+aVwdQ4Zhu1FlEeRpFJfRnZ1DnPIMuw3AqlDP1qmNBOla+JE
+ uslARFp4bxg2Umg9Hl8ITclVHobyk/BmAZXedDF3Xpevn7WOe067xbCVUtER
+ msYTImp2xMNEMBz8tfNyxUrNaVU7Hxh2G6nn8Ju8nXTOcr/KPyjvZOi7Y7Pq
+ caPa7RpJqQVz9Xvp+dNQmLV646EwKpqnvbftE4a1X8KbQnOPa05JazDK0Oth
+ xuSNAQMLKH7lG++QkPeCoTyd5AtWySpYxc38t89WaTo5sg5ZbToxhCOG143/
+ enq0AQ1c/zPxPNAMha5MYlfU/ZCurdyZ9XvvK/88FIsbUxXaATeoz4rZn/Cz
+ a7uPCv0D5OgjcZS/2QcTKOAWbpN3R2AVd1Gk5NrMvYf7eGDgNW8dD/EIWZT6
+ yDgoO9hwsInHBLHl4Am2iaWwg90+LIU9hac/AcQycP6LAwAA
+ """
)
val SnapshotState: TestFile = bytecodeStub(
filename = "SnapshotState.kt",
filepath = "androidx/compose/runtime",
- checksum = 0x9907976f,
+ checksum = 0xa797b7e1,
source = """
package androidx.compose.runtime
import kotlin.reflect.KProperty
+ import androidx.compose.runtime.snapshots.StateFactoryMarker
interface State<out T> {
val value: T
@@ -473,6 +570,7 @@
private class DerivedStateImpl<T>(override var value: T) : DerivedState<T>
+ @StateFactoryMarker
fun <T> derivedStateOf(value: T): DerivedState<T> = DerivedStateImpl(value)
interface MutableState<T> : State<T> {
@@ -481,11 +579,17 @@
private class MutableStateImpl<T>(override var value: T) : MutableState<T>
- fun <T> mutableStateOf(value: T): MutableState<T> = MutableStateImpl(value)
+ @StateFactoryMarker
+ fun <T> mutableStateOf(
+ value: T,
+ policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
+ ): MutableState<T> = MutableStateImpl(value)
+ @StateFactoryMarker
fun <T> mutableStateListOf() = SnapshotStateList<T>()
class SnapshotStateList<T>
+ @StateFactoryMarker
fun <K, V> mutableStateMapOf() = SnapshotStateMap<K, V>()
class SnapshotStateMap<K, V>
@@ -500,6 +604,29 @@
}
}
+ @Composable
+ fun <T> produceState(
+ initialValue: T,
+ key1: Any?,
+ key2: Any?,
+ producer: suspend ProduceStateScope<T>.() -> Unit
+ ): State<T> {
+ return object : State<T> {
+ override val value = initialValue
+ }
+ }
+
+ @Composable
+ fun <T> produceState(
+ initialValue: T,
+ vararg keys: Any?,
+ producer: suspend ProduceStateScope<T>.() -> Unit
+ ): State<T> {
+ return object : State<T> {
+ override val value = initialValue
+ }
+ }
+
interface ProduceStateScope<T> : MutableState<T> {
suspend fun awaitDispose(onDispose: () -> Unit): Nothing
}
@@ -513,184 +640,638 @@
) {
this.value = value
}
+
+ interface SnapshotMutationPolicy<T> {
+ fun equivalent(a: T, b: T): Boolean
+ fun merge(previous: T, current: T, applied: T): T? = null
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T> referentialEqualityPolicy(): SnapshotMutationPolicy<T> =
+ ReferentialEqualityPolicy as SnapshotMutationPolicy<T>
+
+ private object ReferentialEqualityPolicy : SnapshotMutationPolicy<Any?> {
+ override fun equivalent(a: Any?, b: Any?) = a === b
+ override fun toString() = "ReferentialEqualityPolicy"
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T> structuralEqualityPolicy(): SnapshotMutationPolicy<T> =
+ StructuralEqualityPolicy as SnapshotMutationPolicy<T>
+
+ private object StructuralEqualityPolicy : SnapshotMutationPolicy<Any?> {
+ override fun equivalent(a: Any?, b: Any?) = a == b
+ override fun toString() = "StructuralEqualityPolicy"
+ }
+ @Suppress("UNCHECKED_CAST")
+ fun <T> neverEqualPolicy(): SnapshotMutationPolicy<T> =
+ NeverEqualPolicy as SnapshotMutationPolicy<T>
+
+ private object NeverEqualPolicy : SnapshotMutationPolicy<Any?> {
+ override fun equivalent(a: Any?, b: Any?) = false
+ override fun toString() = "NeverEqualPolicy"
+ }
""",
+
"""
META-INF/main.kotlin_module:
- H4sIAAAAAAAAAGNgYGBmYGBgBGJ2KM3Apc8ln5iXUpSfmVKhl5yfW5BfnKqX
- mJeZm1iSmZ8HFClKFeJxBPMTk3JSvUu4zLkkMDQUleaVZOamCnEFpeam5ial
- FnmXCPEH5yUWFGfklwSXJJaANCpg0ViaqVeal1kixOJS4F2ixKDFAAA4Rqdc
- pAAAAA==
+ H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMueSSMxLKcrPTKnQS87PLcgvTtUr
+ Ks0rycxNFeIKSs1NzU1KLfIuEeIPzkssKM7ILwkuSSxJ9S7hUuOSwaVRLy0/
+ X4gtJLW4xLtEiUGLAQDM+x9weQAAAA==
""",
"""
androidx/compose/runtime/DerivedState.class:
- H4sIAAAAAAAAAIVRTW/TQBB9Yzuxk4bghhbSAKVCQk044FJxQKSqhPgQkVIh
- NVGElNM2XtJtHLvybqIe81s48CM4IKtHfhRinKIKERUuM/Nm37zdffPj57fv
- AF5gh/BExGGaqPAiGCXT80TLIJ3FRk1l8Famai7DnhFGuiDC0UH/VfdMzEUQ
- iXgcfDw5kyPTPlxtdW/UXIod9PvtwzbB/3vQhUPY/vewiyLBG0szENFMEjaa
- rdUHEArNFt/CTH3N3GyuElsDQrHJzLxY704SE6k4OJJGhMIInremc5utojy4
- BJpw60LlaI+r8DnhXbaolq26Vc4Wy2R5Be9zPVs8dbxs4dO+V3Nq1gfas47r
- vt2wXmaLT5dfq5dfipWG4zl+4bHjFX03F9sn7N5s3Z/r4IdRn7DzH6NzH+ZX
- n/d7sTjXp4lZHjybGEKpp8axMLOUj8u9ZJaO5HsVMdg6vhIZKK1OIvk6jhMe
- Ukms2XoLBRBcNsDiZXkoMXqYI5QZr6FyjW/B/l3Z2F7mB3jE+Q0zqqxyewi7
- A7+DdY6o5eFOBxvYHII07uLekLeHusaWRkPjvs5hSWNNo/ILV3pR08ICAAA=
+ H4sIAAAAAAAA/4VRTW/TQBB9Yzuxk4bghhbSAG1BQiQccKk4IFJVQnyISKmQ
+ mihCymkbL2Ebx668m6jH/BYO/AgOyOqRH4UYp6hCRIXLzLzZN29Hb378/PYd
+ wHM8IDwScZgmKjwPRsn0LNEySGexUVMZvJGpmsuwZ4SRLohwdNB/2T0VcxFE
+ Ih4HH05O5ci0D1db3Ws1l2IH/X77sE3w/x504RC2/z3sokjwxtIMRDSThI1m
+ a3UBQqHZ4l+Yqa+Ym81VYmtAKDaZmRfr3UliIhUHR9KIUBjB89Z0brNVlAcv
+ DyDQhPvnKkd7XIXPCG+zRbVs1a1ytlgmyyt4n+rZ4onjZQuf9r2aU7Pe0551
+ XPfthvUiW3y8+Fq9+FKsNBzP8QsPHa/ou7nYPuHx9f79eRPejvqE3f+4nZsx
+ v3TA78XiTH9OzPLh6cQQSj01joWZpfxc7iWzdCTfqYjB1vGlyEBpdRLJV3Gc
+ 8JBKYs3+WyiwDy4bYPHFPJQYbecIZcZrqFzhG7B/VzZ2lvk+djm/ZkaVVW4O
+ YXfgd7DeQQ23uMRGB5u4PQRp3EF9yCfElkZD467GPZ3DksaaRuUXZ2oGC8cC
+ AAA=
""",
"""
androidx/compose/runtime/DerivedStateImpl.class:
- H4sIAAAAAAAAAI1R227TQBA9u3Yc16Spm6ZXyq1QmqQUl4oH1EZBXFQ1UgCp
- iSJEn7aJ1W6T2JXXifqYr+AD+AKQQEg8oKiPfBRi7EQVECTy4Lkcn5kzs/Pj
- 57fvAB5jiyEvvGbgy+aF0/A7575ynaDrhbLjOi/dQPbcZjUUoVvunLeTYAy1
- Ym23ciZ6wmkL78R5c3zmNsK90jhUmahvsVbbK+0x2H/XJ6EzrE/UIwmDwShK
- T4Ylhvnc+Cz5OhFyJBUFWi5fT8HENQsJpBgSPdHuugyZ8boU0piZAofNoIen
- UjFsTrZX9F60lnnihvVh+2wuPy5A6rk8zUVMdcVMFineekq7aPGv2UrLD9vS
- c165oWiKUBDGOz2NLsgik2RgLYIuZJRtU9R8xPBu0E9bfIlbg37suGmYfGnQ
- L+jmoG+zHTOjZ/gB2+bPpzOGra3wJ4P+5QeD2/rh6ih9e/k+TZBtcdtc0c2E
- bazpZtLWI4UdEq0xbEz2HNGFq544V6d+GAMPWyHDVFWeeCLsBrS0/sJvkpup
- SM993e0cu0FNHLfjs/gN0a6LQEb5CLSqfjdouPsySpYPh4p1qST9feZ5PklI
- 31PYptslQE9KH4+OSX6DHoljGRrFJqLr5ggpkefkrcJXTBc2v2D2U8zLkzWI
- CaoukF0YspDBHBBHv3e1KMpiftTToSyqTBQ+Y/bjP9ulhoRRu2GTBcIWrwbb
- HQ1m/Hco42ooA0t/DKWNIg2bsb+PB+T3ibFC2tePoJWxWsYNsrgZmVtl3Mad
- IzCFNdw9wpTCnMI9hXWFtIrSrMK8wqLCzC+1g+gKTQQAAA==
+ H4sIAAAAAAAA/41S204TURRd58x0OoylDOWOeEORtgiDxAcDTY2XEJtUTWjT
+ GHk6tBM40M6QOacNj/0KP8Av0ERj4oNpePSjjHvahqg1sS97r71mn732ZX78
+ /PYdwCNsMeRE0IhC2bjw6mHrPFS+F7UDLVu+98KPZMdvVLTQfql13kyCMVQL
+ 1d3yqegIrymCY+/N0alf13vFUao8Vt1CtbpX3GNw/36fhMmwNlaNJCwGqyAD
+ qYsMc9nRXnI1SsiSVAyMbK6Wgo1rDhJIMSQ6otn2GTKj71JIY2oCHC6DqU+k
+ YtgYb654XzSWfezr2qD8bDY3KkDq2Rz1RZnqKjNZILz5hGYx+p+my2ehbsrA
+ e+Vr0RBaEMdbHYMuyGJjxwYM7Iz4CxlH24QaDxne9bpphy9yp9ftO25bNl/s
+ dfOm3eu6bMfOmBn+km3zZ5MZyzWW+eNe9/KDxV3zYGUYvr18nybKdbhrL5t2
+ wrVWTTvpmrHCDolWGdbH20l85kogztVJqPvE1plmmKjI40DodkSTm8/DBrmp
+ sgz81+3WkR9VxVGzf5uwLpo1Eck4HpJOJWxHdX9fxsHSwUCxJpWkr0+DICQJ
+ GQYK23TABO2H/l9CdFHyWVoSxxIMwjbiE+eIKZLn5J38V0zmN75g+lM/L0/W
+ okzQ2w2y84MsZDATr57Q71UdQrOYG9b04suQT+Q/Y/rjP8ulBgnDcoMi88Qt
+ XDW2O2zM+m9T1lVTFhb/aMoYIgMP+n4dm+T3KWOZtK8fwihhpYQbJdzELYK4
+ XcIdrB6CKdzFvUNMKMworCncV0irOJxVmFNYUJj6BY25tQRSBAAA
""",
"""
androidx/compose/runtime/MutableState.class:
- H4sIAAAAAAAAAIVRwW7TQBB9s3ZiJw3BDS2kAUqFhEg44FJxQKSqhBCISImQ
- miiqlNM2McGNs66y66hHfwsHPoIDsnrkoxDjFFWIqHCZmbf75s3umx8/v30H
- 8BJ7hCdSTRZxOLnwx/H8PNaBv0iUCeeB30uMPI2CvpEmcECE3uHgdfdMLqUf
- STX1P56eBWPTPlo/6t6ouRI7HAzaR22C93ejA5uw++9mB0WCOw3MUEZJQNhq
- ttYfQCg0WzyFmfqaud1cJ7aGhGKTmXmx2Z3FJgqV3wuMnEgjuV/MlxZbRXlw
- CDTjo4swR/tcTV4Q3mVptSzqopylqyTcgvupnqXPbDdLPTpwa3ZNfKB9cVz3
- rIZ4laUnl1+rl1+KlYbt2l7hse0WPScXOyA8vdm6P9fBD6MBYe8/Ruc+LK8+
- 7/WVPNefY7O6eD4zhFI/nCppkgVfl/txshgH78OIwc7xlcgw1CFPfKNUzE1h
- rDRbL1AAwWEDBC/LRYnRwxyhzHgDlWt8C9bvysLuKj/AI85vmVFlldsjWB14
- HWxyRC0PdzrYwvYIpHEX90a8PdQ1djQaGvd1DksaGxqVX2k2HnjCAgAA
+ H4sIAAAAAAAA/4VR0WoTURA9c3eT3aQxbmOradRaBTHxwa3FBzGlIKIYSBCa
+ EIQ83SZrvM1mt+TeDX3cb/HBj/BBlj76UeJsKkUM1Zc7c+aeOTOc+fHz23cA
+ L/CQ8FhGk0WsJuf+OJ6fxTrwF0lk1Dzwe4mRJ2HQN9IEDojQOxy86p7KpfRD
+ GU39Dyenwdi0j9ZL3Ws1V2KHg0H7qE3w/m50YBN2/93soEhwp4EZyjAJCFvN
+ 1voChEKzxVOYqa+Y2811YmtIKDaZmSeb3VlsQhX5vcDIiTSS+8V8abFVlD9u
+ /oBAM66fqxztczZ5TnibpdWyqItylq6CcAvup3qWPrXdLPXowK3ZNfGe9sVx
+ 3bMa4mWWfrz4Wr34Uqw0bNf2Co9st+g5udgB4cn1/v15E96OBoS9/7idm7G8
+ dMDrR/JMf47N6uPZzBBKfTWNpEkW/F3ux8liHLxTIYOd40uRodKKJ76Oopib
+ VBxp9l+gwD44bIDgi7koMdrNEcqMN1C5wjdg/c4sPFjF+9jj+IYZVVa5OYLV
+ gdfBZgc13OIUWx1s4/YIpHEH9RGfEDsaDY27Gvd0DksaGxqVX4ySaL/HAgAA
""",
"""
androidx/compose/runtime/MutableStateImpl.class:
- H4sIAAAAAAAAAI1RXU8TQRQ9M7vdLrWUpXwjfqFIW8RF4oOBpkZNjE2KJrRp
- jDwN7QYG2l3SmRIe+yv8Af4CTTQmPpiGR3+U8c62IWpN7MPej7Pn3nPv3B8/
- v30H8BibDHkRNjuRbF74jah9FqnA73RDLduBv9fV4rAVVLXQQbl91kqCMdSK
- tZ3KiTgXfkuER/6bw5OgoXdLo1BlrL7FWm23tMvg/V2fhM2wNlaPJBwGpyhD
- qUsMc7nRWfJ1IuRIygRWLl9Pw8W1FBJIMyTORasbMGRH69LIYGoCHB6DrY+l
- YtgYby/zXrSWexTo+qD9bC4/KkDquTzNRUx1xUwWKd58SrtY8a/pymmkWzL0
- 9wItmkILwnj73KILMmOSDOyUoAtpsi2Kmo8Y3vV7mRRf5Kl+L3bcdVy+2O8V
- bLff89i2m7Wz/BXb4s8ns45nLfMn/d7lB4d79v7KMH17+T5DkJfinrtsuwnP
- WbXdpGcbhW0SrTGsj/cc5sLVUJyp40jHwMNTzTBRlUeh0N0OLW2/iJrkpioy
- DF5324dBp2aqzVmihmjVRUeafAimqlG30wheSpMs7Q8U61JJ+vssDCOSkFGo
- sEW3S4CelD5ujkl+nR6JYwkWxS7MdXOElMhz8qnCV0wWNr5g+lPMy5N1iAnM
- oxDbmIUsZoA4+r1riqJZzA17+pSZykThM6Y//rNdekAYths0mSds4WqwneFg
- zn+Hcq6GcrD4x1DWMLKwEfv7eED+JTGWSfv6AawyVsq4QRY3jblVxm3cOQBT
- WMXdA0wozCjcU1hTyCiTzirMKSwoTP0Cc/1T9U0EAAA=
+ H4sIAAAAAAAA/41S224SURRdZ2YYpiOFKb3XeqvWArWd2vhgWoJRk0YSqkkh
+ xNinU5jQU2Cm4RyaPvIVfoBfoInGxAdD+uhHGfcB0jRiIi97rb1mn32dX79/
+ /ATwDNsMWR7WO5GoX/q1qH0eycDvdEMl2oF/2FX8pBWUFVdBsX3eioMxVPKV
+ vdIZv+B+i4cN/93JWVBT+4VxqTRR3nylsl/YZ/D+fh+HxbA+UY44bAY7L0Kh
+ CgzzmfFeslUKyFApTcxMtpqAg1suYkgwxC54qxswpMffJZBEagoGPAZLnQrJ
+ sDnZXHpfNJbTCFR1mH4ukx0vQNUzWeqLIuV1ZDxPfOsFzWIOPs2UmpFqidA/
+ DBSvc8VJM9oXJl2QaeNoAwbWJP1SaG+HWP0pw4d+L+kaS4bb7w3AcGzHWOr3
+ cpbT73ls10lbaeMN2zFeTadtz1wxnvd7V59sw7OOVkfu+6uPSZI81/CcFcuJ
+ efaa5cQ9S1fYpaIVho3JdqLPXA75uTyN1EDYbiqGqbJohFx1OzS59TqqE6RK
+ IgzedtsnQaeiX+vbRDXeqvKO0P5IdMtRt1MLDoR2lo+GFatCCvr6MgwjKiGi
+ UGKHDhij/dD/S4wuSpihJRlYhkncgT5xlpQCoUHo5r5jOrf5DTNfBnE5sjZF
+ AkvYJLswjEIas3r1xG5mdYnNYX6U09eXIYzlvmLm8z/TJYYBo3TDJAukLV43
+ tjdqzP5vU/Z1UzbpN5syR8zEkwFuYIvwgCJWqPbtY5hFrBZxp4i7uEcU94t4
+ gLVjMImHeHSMKYlZiXWJxxJJqd05iXmJRYnUH5JR7zxSBAAA
+ """,
+ """
+ androidx/compose/runtime/NeverEqualPolicy.class:
+ H4sIAAAAAAAA/5VU3W8bRRD/7Z0/zhcndZyQpmn4KA3UTpqeE8pnTNoSinqR
+ ayJcBUGe1vbibnK+c+/2rCJeIv4Unnmg4qEIJBTBW/8oxOydCcFJUSLLO7Mz
+ s7/5zc7svfjr198B3MZdhir3u2Egu0+dTtAfBJFwwthXsi+cphiK8P6TmHs7
+ gSc73+bBGL5s7PMhdzzu95zP2/uiozYaL0Vo+XwQPQ7Uw1hxJQM/xamfhtjc
+ YCiNW/PIMDgXBM8jx5CrS1+qTQazUt0twkLBRhY2Q0Y9lhHDysspjxdNxGzx
+ JJZD7glfMdyonHEBpyzVrxmWGkHYc/aFaodc+hEV4gcp08hpxp7H254gdMYZ
+ yqcRyNFmsFTQUqH0ewyzleqJqNRKUdf/L0ugdCJ9t+NlWbjMkO2LsCcYts9V
+ 0xlVnkW7fsGGLX0qvuGxp9z+wIvyuMrwXeWiE3UutufiX8QVvGpjEa/R5Q9C
+ MZRBTAOT78RhmPQ/zwcDT4ouuesdLxkzG4aeLcttth7da27dL+ItTBbI+DbD
+ dOMgUBTmPBSKd7nidENGf2jS62N6sfQCavYB2Z9KvauR1l1jEEeHi7Yxb6T/
+ 0tGhbVhamSBpkpyy/vzemD86XLfLuXJmntWMGvskbxl//JAzSub2YimzYNSy
+ 61Ypt5B4Scun2oO5batkkbfwYE4nW2dYu/CVM027eLJ5NGb/xLYoVNw6oPu6
+ +kUK4/pDGUka+Xv/Dii9x62gSwN4qSF90Yz7bRE+0s9Cv4igw71dHkq9HxmX
+ xrF2eMj7QonwP6BF1/dFuOXxKBK0LbRkz+cqDgnBbgVx2BGfSQ13ZQS3e4oY
+ atS9LNVHnzwaCGonyfepNzmScySz5KevCu0+oJ2jG6ity88x8YwUAx+OgoEQ
+ H9FaTANITib9nsIlitKH79JOt90wfxw7GSUn30i9o5Nam0Y58RuYIc3ABumT
+ BplKCXS6zuKVUYLVETuzPP/TWAZ1gps5ynCyTF38Ank0zA4y9KOJXV65ufoL
+ Xh/HSutcTmOO2VrEP2Vr4VrCVmtvkmYeZ9KEdQ0z5lgNpST4+vE9X06OAxO/
+ wfjqOZZ+xo1niSGDOq02hS1Sy94l1h8n7ExsJvI93CHpkr9CPajuwXSx7GLF
+ xU2skopbLjWxtgcWYQ3re7AjTEZ4J8LtCIUIU4kyHWEmwizpfwOnXXg5QAcA
+ AA==
""",
"""
androidx/compose/runtime/ProduceStateScope.class:
- H4sIAAAAAAAAAI1T328SQRCeXSh3INUr/gJarVqNSox3Ep+EEI2GFEO1EfSF
- p+U4cOHYJbd72Efin+KDf4PxwRB8848yzkFpY7G2DzezM/PNN/vju1+/v/8A
- gKewQ6DARCeQvHNgu3I4ksqzg1BoPvTs/UB2QtdraKa9hitHngGEQLPcfFbv
- szGzfSZ69tt233N1qbKaqp9KvBdq1vYXxOVms1QpEbBO9hsQJ3DvXBwGJAik
- 2SfG9SuuIhhu80F9ILXPhd0fD+1uKFzNpVB29XDllJZ1VwYy1Fx4yn4pkVyE
- LAKUHq4eiUD3LNrysv5ecLyWs6aUC5V/D7pbl0HP7nu6HTCOA5gQUrPFsDeh
- 70eHR9jO/2BSR0hEbSx3sedp1mGaYY4OxzHUAImMQYAMMHXAo8jBVecJnnU6
- 2UrRLE1NJ0fOIsuIWlHG7Gank0LcnE4sUjQz8QzdJQ59vW3F8tSJF9PWWn6e
- dQwnsTv7+vznNzKdzL4kqGXOPtN4ipq5aFqRwKPT9bIiRNw+aRK4fz6JIRoI
- JKU4EkdmeR/HakAFNgQbqY9Sz5seDzT2NHhPMB0G2LP5bkFdE2OuOHK/OL5q
- fK6T1X0WsKGnveAvWKohw8D1qtxHxtxhz4cVPpQzhTXctBG9EP4HJiQhBjcx
- opCCbfQJrF5Afwu/dYpBOoLO7RIYg9tzfwPuoK9idR1JL7YgVoNLNbDQwkZk
- MjW4DFdaQBRchWstSCq4riCrIKfAVJBXsKlga75I/gEnsHRUOwQAAA==
+ H4sIAAAAAAAA/41T328SQRCeXSgcSPWKv4BWq7ZGJcY7iU9CiEbTFENrI+gL
+ T8tx4MKxS273sI/EP8UH/wbjgyH45h9lnINeG4u1fbid2ZlvvtnZ/e7X7+8/
+ AOAZbBMoMtHxJe8cWo4cjqRyLT8Qmg9d68CXncBxG5ppt+HIkZsEQqBZaT6v
+ 99mYWR4TPettu+86ulxdDtXPJN4LNGt7C+JKs1mulgmYp+uTECdw/0IcSUgQ
+ yLBPjOvXXIUwPObD+kBqjwurPx5a3UA4mkuhrJ0jzy5HeUf6MtBcuMp6JZFc
+ BCwElB8tj0Sgex5tJcq/Fxyv5bwulWL1342269LvWX1Xt33GsQETQmq2aLYf
+ eF44PMK2/geTOkQiai06xZ6rWYdphjE6HMdQAyRcjHABAmSA8UMe7mz0Ok9x
+ 4OlkI01zND2dHBuTRDtqhhGjm5tOinFjOjFJycjGs3SX2PTNphkrUDteypgr
+ hXnUTtqJ3dnXFz+/kelk9iVBTWP2mcbT1MiH3UoEHp8tmiU14gykSeDBxXSG
+ aBwwJcWxQrLRpZxIAmXYEGykPko9L3oy0FjT4D3BdOBjzfq7BXVNjLniyP3y
+ 5L7xzU5nD5jPhq52/b9g6YYMfMfd4R4y5o9qPizxoaYprOChk+Hb4M9gQApi
+ sIk7Cmm4gzaB2Uto7+K3SnGTmT9juEbAGNyb29uwhXYHs6tIerkFsRpcqYFZ
+ gzXIogtXa3ANrreAKLgBN1uQUpBTkFdQUGAoWFewoeDW3En9Ae+dQkpABAAA
+ """,
+ """
+ androidx/compose/runtime/ReferentialEqualityPolicy.class:
+ H4sIAAAAAAAA/5VUW08bRxT+ZteX9WITYygBQq8hiblljUuvuDSUpoqRIShG
+ RC1PY3viDKx3nb1YifqC+lP60L70oVEfUrVShdq3/qiqZ3Zd6hqoQJbnnDnn
+ zHe+M+fM/vnXL78BWMUGQ5k7Lc+VredW0+10XV9YXugEsiOsR+KJ8ATp3L7/
+ LOS2DF7surZsvkiDMTyuHfIet2zutK2HjUPRDNZqF0LVHd71n7rBdhjwQLpO
+ jFM5C7G+xpAftqaRYLCuCJ5GiiFVkY4M1hn04vx+FgYyJpIwGRLBU+kzrF5M
+ +cLqiaEpnoWyx21yM9wpnnMTZyzzXzHM1VyvbR2KoOFx6fhUkePGlH1rJ7Rt
+ 3rAFoTPOUDiLQI4GgxG49cCTTpthojg/EBVbKerm/2VxA5WIoqYvrM/AdYZk
+ R3htwbB1qeLOKfc8/pUrtnDuc/GEh3ZQ7XRtP40bDF8Xrzpjl2J7Kf5ZTON1
+ E7N4g7rQ9URPuiGNULoZel40CGne7dpStMhdadrR4JnQ1LQZ1Z363sbO5v0s
+ biGXIeNthrHakRtQmLUtAt7iAacb0jo9nR4mU4uhFlDXj8j+XKpdibTWCoM4
+ OZ41tSkt/udPjk3NUMoISZ3kqPHHN9rUyXHZLKQKiSlW0krss7Sh/f5tSsvr
+ W7P5xIxWSpaNfGom8pKWjrUHk1tG3iBv5sGkSlZmWLnylTNFOzvYPHrU/8TW
+ KVTcPaL7uvEohqk6PelLmv2NfyeVXuim26IBvFaTjtgJOw3h7an3oZ6G2+T2
+ Pvek2veNOYJtHm3zbn8/N4y9yz3eEYHw/pMkW3Uc4W3a3PcFbTN12XZ4EHqE
+ YNbd0GuKL6SCm+7D7Z8hihJ1M0n10keRBoTaS/ID6lWK5CTJJPnpu0O7D2ln
+ qYYq68IrjLwkRcNH/WCA42Nas3EAyVzU/1Fcoyh1eI+kGoORxaXvkE58j4T+
+ A211rMV5MvfYAFojQnsrPtFHU9oYCpF/BOOkaaiQntPIlI/SxesEXusnXe4z
+ 1gtTPw7xbQ7w1fsZBktXFzJDHgWziwT9aKoXFpeWf8abw1hx7QtxzClbg/jH
+ bA28HbFV2juk6aeZFGFVw7g+VEM+Cr55evfXo+NU+K/QvnyFuZ9w52VkSOAT
+ Wk0Km6U2vkes1yN2Oj6N5Pu4R7JK/iJd8/wB9CoWqlisYgnLpOJulRpbOgDz
+ sYLyAUwfOR/v+lj1kfExGiljPsZ9TJD+NyU9ROd/BwAA
+ """,
+ """
+ androidx/compose/runtime/SnapshotMutationPolicy$DefaultImpls.class:
+ H4sIAAAAAAAA/5VSTW/TQBB96yR1GlL6wWcotEADohwwlTiRqBIqQjJKS0Wi
+ Hspp4yzpJvautV5HRfwpzhz4AfwoxKyTCmgQIpY9++bNm5n17H7/8fUbgBd4
+ zNDmamC0HJwHkU5SnYnA5MrKRARdxdPsTNvD3HIrtTrWsYw+NV+LjzyPbZik
+ ceaDMayN+IQHMVfD4F1/JCLro8RQSYQZCobPTzoLdmh1Lhf8L2Z3nmI4bfde
+ zvP7C++p3eu19ltkpu8ufQzNjjbDYCRs33CpsoArpadJWXCUxzHvx4JkO/+S
+ aeuUpKo07ZnMGPYWHhdDNTViInVO6Rt/m4If5cYIZQnxNI2lGDCsd8baxlIF
+ h8LyAbecdF4yKdG9YM5UnQEDGztAB+qdS4eeMwQL7tBHg6H++72hS3Mh7ZJS
+ PBvT3soHekAXZrUjlTjKk74wPTdB90864vEJN9L5M3K5K4eK29wQ3nw/7R+q
+ icwkhV/9GjEd0+XoMTc8EVaYP2T1UClhDmKeZYLcWlfnJhJvpGvWmJU4mSuP
+ PXgoYzqrZVSwRN498t6S73iPfXEWW2SXiANOsU326TSKGq4U2R7qWCniHq4S
+ 8gq0SqiE+wX28WBWo0rrQ/pWykXTi6eEHbI14jzcwSYaaBaJd/GI1i3i10iz
+ /gGlEBshroW4jhshbuJWiNs/Ac089AgUBAAA
+ """,
+ """
+ androidx/compose/runtime/SnapshotMutationPolicy.class:
+ H4sIAAAAAAAA/5VTzW7TQBD+1kltx2mLC6WkKeU3NCkHnFYcEK2QEAjhKgXU
+ RBzoaZNswybOOnjtqHDKs/AYHFDEkYdCjJ1WINIDlbzz/83szox//vr2HcBj
+ bDN4XHWjUHZPvU44HIVaeFGiYjkUXlPxkf4YxodJzGMZqndhIDufLTCG2n7r
+ aaPPx9wLuOp5b9t90Yn3ns2bGNx/bRbyDI74lMgxD4SKGaq1eeC8ZfsDQ6HW
+ au3Rl8oLQxH1BMPBf6EvyHfRbZfPCqQ16DBUGmHU8/oibkdcKk3dUuGsHdp7
+ kwQBbweCwlYagzAOpPIORcy7POZkM4bjHHWZpcROCRjYgOynMtXqJHV3GL5M
+ J6uOUTKc6cQxXCIZLzqGbdsnpenkYd6eTly2a9SNg003Vzbq+V3TXSgbT6YT
+ EsxMeL3146tpuNZB1bXL+RKb+QrnQc65UJxFr2XRi+kNdhl2GpfcAXoca7Hs
+ PZxOm8EeRWIsw0QzWJ0kirK5Wnw0CqToMuxfskDlpTjhSRD7w1GgLdxhWPzb
+ Qlt1jmsSTDwaULVCU/YUj5OIdmLjaJbeV2OpJY3o+Z+xUS5fKRG9CLjWglSn
+ GSZRR7ySASHXz5Dv53AmdQsL6Rhh0AaboD8BlVSDTXoBDkkzvYgHxE3yLxLP
+ Y4uoQ9pd8t3D+llUDtWM30eN+BH5lyj/8jFyPq74cH2s4CqJuOZjFdePwTTW
+ cOMYSxoljXWNsoaZ0Q2NmxqWRkFjU+OWxm0N5zfYvY915wMAAA==
""",
"""
androidx/compose/runtime/SnapshotStateKt$produceState$1.class:
- H4sIAAAAAAAAAI1T3U4TURD+znb7w1poqYCAf6gVtkVZICZqCiSGSNJYNaGk
- MeFq2V3Kge1Zsnu24bJP4QP4BJpoTLwwDZc+lHHOtjEoCF7s/GXmm2/OzP74
- +e07gCdYZXhqCzcMuHtiOUHnOIg8K4yF5B3Pagr7ODoIZFPa0nsly8dh4MaO
- l7jllSwYFTcO7a5t+bZoW2/3Dj1H1hr/xlOFazs7tY0aQ/Hvwix0hjuXF2eR
- YcisccHlBsOkeb57pUUJJvVQRsqstPLI4ZqBNPIM6a7txx5D6XxdHmMojEBD
- kUGXBzxieH7JJJe+DE03WlYcue23Bh1zbU8OzQmzcr49cTMrxJo4J3K8cRRI
- nwvrtSdt15Y2xbRON0VLY0pkGdgRhU648pbJclcY1vu9UaPfM7RpzdByepX1
- ezljut9bzZX0kvas31tm21NFbVaZ707f66cfMoahFdOzei5V1BUI3cPcFQsk
- Jub/PkwWZYb82ddh2L9gaxdEhvMfdjvWfiwcyQMRWVtDa7VWuYplHvNYoDP7
- g9HSkWQYafK2sGUcEhl9M3BJFRpceG/izp4X7th7fnIigaO2F3LlD4P5uhBe
- uOnbUeTRgRReCscPIi7atKWDwGUwmkEcOt4WV9kz2wNCLR5xKn8hREAc1BxY
- oUNLg4H+IZTU5ZGu0iI1TNMHOll1iotkbZFWEaP6FaPVxS8Y/5TkPSI5BrX8
- eehYoPx5PCZvapBNqNeBxJo4g26QNZnkKGyLPEY6Xf2M8Y+/YTNJcCGByw8S
- hnADkBvkLyXQLGkGzBAUiMZDmMOcFJYTXaFRgXXKnKGq2V2k6rhZxy2SuK3E
- nTruYm4XLMI93N9FJlLmgwhjESYjTEUo/AJAwj8ArQQAAA==
+ H4sIAAAAAAAA/41T0U4TURA9d7ttl7XQUgGhKqJW3RZloZqoKZAYIklj1YSS
+ xoSnZXcpF9q7ZPe24bFf4Qf4BZpoTHwwDY9+lHHutjEoCKbpzLmTmTPn3pn9
+ 8fPbdwBP8JjhqSO8MODese0GnaMg8u2wKyTv+HZDOEfRfiAb0pH+K1k8CgOv
+ 6/rxsbiSBqPi+oHTc+y2I1r2290D35XV+r/5VOHq9nZ1vcqQ+7swDZ1h/uLi
+ NFIMqVUuuFxnmLbOdi81KcGiHgokrFIzAwNXTCSRYUj2nHbXZ8ifrctgAtkx
+ aMgx6HKfRwzPL7jJhS9DtxsvKo3caTeHHY2WL0dwyiqdbU/arBKpJs2xnawf
+ BrLNhf3al47nSIdiWqeXoKExZQxlwMAOKX7M1WmZkLfCsDboj5uDvqnNaqZm
+ 6GU26Bvm7KBfMfJ6Xns26C+zrZmcVlDw3cl7/eRDyjS1XLKgG4mcrkgqDAuX
+ TJHkWP/7OmncY8icfiKGvXNGd05k9AgHvY691xWu5IGI7M0RqlRLl6nM4AEs
+ 2rU/FC0dSoaxBm8JR3ZDEqNvBB65bJ0L/023s+uH285uO96TwFUjDLk6j4KZ
+ mhB+uNF2osinLcm+FG47iLho0aj2A4/BbATd0PU3ucqe2xoKavKIU/kLIQLS
+ oO6BFdq2JM2QPiTk1fqRX6RBapilP80Yah8fEtokryJm+SvGy4tfMPkpzntE
+ dgJq+EvQYVP+Ev2AmWE2sV5Va0Jo6hS7SWg6zlHcttoi8snyZ0x+/E2bioN2
+ TJcZJozohiTX6GzH1CxuBsxhmayO+yiNchJ0ReXLqJBfo8w5qirsIFHD9Rpu
+ 1HAT8wRxq4YF3N4Bi3AHd3eQihQsRpiIMB1hJkL2F+yJDPSyBAAA
+ """,
+ """
+ androidx/compose/runtime/SnapshotStateKt$produceState$2.class:
+ H4sIAAAAAAAA/41TUU8TQRD+9nptj7PQUgEBFVGrXotyUE1UCiSGQNJYNaGk
+ MeFpac+y0O6Ru23DY3+FP8BfoInGxAfT8OiPMs5eG4OiwMPNfDuZ+ebbnbkf
+ P799B/AEjxmectkIfNE4dut++8gPPTfoSCXanluV/Cjc91VVceW9VLmjwG90
+ 6l50zBWTYFRcOeBd7ra4bLpv9g68uipV/s+nC1d3dkrrJYbM34VJmAxz5xcn
+ kWBIrAop1DrDpHO2e75GCQ710CDm5GspWLhiI44UQ7zLWx2PIXu2LoUxpEdg
+ IMNgqn0RMjw/5ybnvgzdbjSnNQreqg06Wk1PDeGEkz/bnrQ5eVJNmiM7Xjn0
+ VUtI95WneIMrTjGj3Y3R0Jg2ljZgYIcUPxb6tESoscyw1u+N2v2ebUwbtmGZ
+ BdbvWfZ0v1e0smbWeNbvLbHtqYwxq+Hbk/fmyYeEbRuZ+KxpxTKmJikyzF8w
+ RZLjXPZ1krjHkDr9RAzH/xjdpSLDZznott13HVlXwpehuzVExVL+It0pPIBD
+ 2/eHxsVDxTBSFU3JVScgeeaG3yCXrgjpve6097xgh++1os3x63qogdDnYTBV
+ ltILNlo8DD3am/SmrLf8UMgmDW/fbzDYVb8T1L0tobNntgeCaiIUVP5CSp80
+ 6HtgmfYvTlOlXwtZvZDkF2i0Bqbpo6lDb+hDQlvkdcQufMVoYeELxj9FeY/I
+ jkGvwwpMlCh/BYt0mhpkE+tVvTiEJk6x24QmoxzN7eq9Ih8vfMb4x9+0iShY
+ iuhSg4Qh3YDkGp3diJpFzYAZLJE1cR/5YU6Mrqh9AUXya5Q5Q1Wzu4iVcb2M
+ G2XcxBxB3CpjHrd3wULcwd1dJEINcyHGQkyGmAqR/gVj7U/wxAQAAA==
+ """,
+ """
+ androidx/compose/runtime/SnapshotStateKt$produceState$3.class:
+ H4sIAAAAAAAA/41TXU8TURA9d7v9YF1oqYCAiqhVt0VZKCZqCiSG0KSxakJJ
+ Y9KnpV3Lhe1dsnvb8Nhf4Q/wF2iiMfHBNDz6o4xzt41BQeBhZ87czJw5987s
+ z1/ffwB4ijWGZ45oBT5vHdtNv3Pkh64ddIXkHdeuCeco3PdlTTrSfSVzR4Hf
+ 6jbdKMytJcGouHrg9Bzbc0Tbfrt34DZlqfp/PlW4vrtb2iwxZP4tTEJnWLi4
+ OIkEQ2KdCy43Gaats93zdUqwqIcCMStfN5HCNQNxmAzxnuN1XYbs2ToTE0iP
+ QUOGQZf7PGR4ccFNLnwZut14Tmnkjlcfdky1XTmCU1b+bHvSZuVJNWmO7GT1
+ 0JceF/ZrVzotRzp0pnV6MRoaUyalDBjYIZ0fcxWtEGqtMmwM+uPGoG9os5qh
+ pfQCG/RTxuygX0xl9az2fNBfYTszGW1ewXcnH/STjwnD0DLxeT0Vy+iKpMiw
+ eMkUSY511ddJ4gGDefqJGNrnjK5xzi6NXuGg17Hfd0VTcl+EdnmEiqX8ZTJN
+ PIJFy/aXpOVDyTBW423hyG5AavQtv0UuXeXCfdPt7LnBrrPnRYviN9UMA67i
+ 0aFZEcINtjwnDF1ak/S2aHp+yEWbZrXvtxiMmt8Nmm6Zq+y5naGgOg85lb8U
+ wicN6h5YpXWL0xDpT0JW7R/5JZqkhln6aMhQC/mYUJm8OjEK3zBeWPqKyc9R
+ 3hOyE1DT34ZOWWPklymaGWYT63W1J4SmTrEbhKajHMVtqzUiHy98weSnP7SJ
+ 6LAc0ZnDhBHdkOQGxXZEzaJmwBxWyOp4iPwoJ0ZXVL6AIvkNypyjqvkGYhXc
+ rOBWBbexQBB3KljE3QZYiHu430AiVDAXYiLEdIiZEOnfCWOj1bMEAAA=
""",
"""
androidx/compose/runtime/SnapshotStateKt.class:
- H4sIAAAAAAAAAKVYW1PbVhD+jm1sIxwQBgKIBEjiBDAXG5ombXBJU3LB5drg
- 0KY0TYQtQGBLro5MkzemD33sj+gvaJ+SNDMdJn3rT+mP6HSPLBvb2AZSz0jn
- tvudb/fs2dX473//+BPATRwwjKpGxjL1zMtY2szlTa7FrIJh6zkttm6oeb5r
- 2uu2amuLdgCMQd5TD9RYVjV2Yqtbe1qaZr0M7RnN0g+0jCO5us0wO7pUKzg7
- ttRwp/sV6rMMjxKpOyf150ZTqbOCJEh0jpCuLZnWTmxPs7csVTd4TDUMk9Z1
- k/orpr1SyGZJauxMmMlcPhtAK4M/oRu6PcfQU8/KjRDaEJIg4QLD9TMhB9DB
- 0HKgZgsaQ/gkJjk4V7DVraz2oQ5erlD/YAdXgpQc3Nh1ldJF112U0NvcKZU6
- AfSTMyrtXtK5LWyfGm1CsipohQaRTDYw9zwwJYOjZ1cJYJDBO1qMiGEJQ7jC
- 0Flp0bKaFwZNnpkJKRCH54nFOvZs/C8bCTmRWpxNbZxyrLVKAdyQMCIsC+Ut
- M1NIFy1j2K4ToXVm9k07qxuxvYNcbLtgpItX86Hbm2kWjqVg/qdxMJ97v8Rk
- 4/3WKsxbT5t59w5MliDTpmUWbN3QeGzeJBWj4CSaRFngCWUNUhivQ/ZUO0vh
- d72x3LwzFrFFcpFmiY+ynisWdM/MCmKKYbDCObpha5ahZmNJw7YIQU/zAOKU
- 89K7WnrfzZ1rqqXmNBJkGGl+3OsCZMfJjjP4SMI0bjLcPmvpiVSGVmQ6gFsS
- botUMtjcawF8SnEpsrWuZjeK+dW3r72aZhg+LfLIOTua7Sq9GD0tDhuHmqVt
- Z2kcW6QAymuW/YoOu06KzzcI49MCY9yJjHNsn4hSuJGSKGT2rs7ngrhXjARn
- OYh5hu7ROhxDmMODNtzBQ4YLET2yHTl2EEtSkYoIuIrJ4dMvb0CoED6D0thf
- xI6XQXebeKSqzJ3nROrVcYYfz30kJ0vkOQ9GVGC6IysItUHBVyVHH5vvOvl4
- YuTMVb+ztPOyZqsZ1VZpzpM78NKXIBOvAB3jvuh4aP6lLnp04T2ZacbeHB2u
- SEeHkqfPI3mCPqctD71u6zluZVosrZce2VOlTnrKEMkpwbAv7FnwxNlVX/Do
- UPbM+GWvQhPvf/V7ZJ8SllvKIn5XRBmUA0q7M9nqvKV4sLjUSg2TJUJuK2uF
- 6gFfUJ7J7WWRjmMRWYjMBOVOxdfH4uGZSblLGQuysBQuCfeU+vHe+MWwP+zI
- xbsFbLBvIfDXG3Z06OzRr9yUFQHnokfL2xH+gIsvyZcUf5i8Eb+88P5nyVEc
- VBLykEL4tYqh+ooly8oAw+9/8pCbg/3i/GaaBknNtzdLMUyc7/Nq/FwfL2yR
- HrpcEJ+6bkBWZt0mm5+owLMVebxB+SWRwZLIg5e2RpXMNEr7pV45GHIVzal9
- m6rEvJmhy9WxRIArhdyWZqXEVRKczbSoJZYuxu5k67q+Y6h2waL+wOMi26Rx
- oHOdlu8dl16qy7Wr5RJaJRZKGoZmzWdVzjUaSutmwUprD3WxWb8LsXECnqqq
- Bz6IH309owV+eJGj0S1qyeMIvYP0NPoa7UeQfxMXHQa9/c6aDFNIFOXQiTC1
- eUcmgB9cqSC1/ehC90ncXoHbdwSlFrevIW5PDe4ALrm4w7QqfsF3GHr6GlcF
- JqvAVFyEyzUI1xA5iTBCCKO1CJddhOs1CGOIkgcFwhohiRQYngjH3uDjd7gt
- LPzkCHeqLfTjhmPhcFEas46Fopeghzm9KXxGGsUdx50dJepNCH70WPR0OFkY
- k867SGUOd11jnrnH2hMNf0FUJsL36e2di77FI4ZqNu2IOWyEFe10cgtIOrx6
- 8CUWHV49WHJ59WAey2Venzs8urzu/tVcVrDqcsmRaAu1vVVcbvmik2/x2IPf
- y2yEhR0UIRfpS810/mxooXEQ68RIGNOLFJ44jHrLjHpdRqInIsXrcltzuPX4
- 6nADCXFnO/qedMb9sB2lLArU/kLzG7T115vwJvFNEk/pjW+T2MR3SfLs95tg
- HM/xYhNXOFo4VI4tjk4OP8cAR5rjGkeGQ+PY5ujieMLRzTHGscgxy5Hg2OGY
- 4tjl0Dn2nOE+R5RjjmOJY55jmeMuxwrH6n8UZ3xFehEAAA==
+ H4sIAAAAAAAA/91Ya1cb1xXdV4AkZAHjsTEgO0S2IWAwCLCT1IY6dokxCg9T
+ g6mJ6ziDGGCMmFHmjohpm8RNW/f9Th9pkz7Sd5u2br/EqdfqYrnf+lPav9DV
+ 9tyrkRBiRiC7WcurH6R758557LPPua/5+7//8lcAJ3GHoVMzF2zLWLiZSFmr
+ GYvrCTtrOsaqnpg2tQxftpxpR3P0MScExqDc0Na0RFozlxIX52/oKRqtYqhf
+ 0G1jTV+QkhcXGQY7x0sFB4+N+3p6tkh9kOHC0Mzp7fpnOmdmdmtkiETPkKWn
+ /cW5Gx1PSI0RLeVY9vqEZq/oNmkeHbfspcQN3Zm3NcPkCc00LZIzLOpPWs5k
+ Np0mqWO7QpNczaRDiDAEhwzTcM4wNHrxMxtFFHUR7EE9Q/uuLIegMNSsaems
+ zqBut0mpWc062nxaL6Qm7eHan6V8DUxkc8FPWWkjtV4uDRNF/sj/K/65rNRr
+ Lqm7dJ2vgGBG6obRxNC6Yjlpw0zcWFtNGKaj26aWTiRNx6YEGykeQgtlJrWs
+ p1bcDE9ptraqkyBDhxdtmyPTwsiSzOFBHIoghsfKVUcx0lx1PB5BvHzei3VC
+ OMLQX3HaGA5sLYe2BX1Ry6Ydhtf+F2WRrGjWl1RKM3fsbMrJ2lr6/EtZLW04
+ 6zmzDCc6y5jxwRJFBzojCOBYFPvRKHrdNEeK4x83uCOmRO9uzBc0CGrSp6gr
+ MZMv0K7dq4TQx1DVmVsoBiLoxwmGvcURTWgZEVDPrpGQAmG4PjTmEc/sQ8VI
+ lodmxgZnZmWU/lOhVCmED0VwSkQWzdjWQjaVi4xhsfwMzI8UzfHFrJnKrdgj
+ bm+gXD3mC/EfZZasSv0N9fj7myoKbzplZdw1qydvMmXZVtYxTJ0nhi1SMbOy
+ vocKApdpMyGFbg+wO8aZL792f7lh+Sxqi+Tayu2HtFS6YmE3Z3YYZ2n73e3Z
+ oq041W39IXwkgmGxHLaWjyKE81QnYlM1tPRsbhusXtHX+xniO1UCw83dVdQH
+ UWP/qqjG/u+q7gELYyCE8QgmRGGILA8wLHmk8OoHkrF/+mescoePfIIEvTyM
+ Sw+cqhMhzERwWaRqnwc/tFIs6Y47Y1/s3Il+f4JtfTFNz4kxoi2j2444m3p4
+ y/hkbyc6uiUfFbgf6iKSSUkc9p1lg58J42puWZSvw7jGsL/TA2MUV3B9D0bw
+ IkNdm9G22LZJEEvSQb5NmCsajO9csyGhQvYZYv58ETpeMLpchpEt57VKMuJ1
+ 12F4ueKUbD/fV5gYcYGkw9My6vbgKFbyRG+G75K8OdCx6+NrC3nUbd0UO1Hp
+ +XXywc+LXlcghgFfvUt+KEKgW0w4OTk9c25ymHbNk/6+fW1QkTrI1oJjjeFt
+ k7b9eEoeBOLzOvW4E3esuGmZPfKVs57R43knva6TXtdJr1+AcWtxZyV3yen1
+ 5Zym3U06GRRf5qL4RO5m9kmGRIW8h/AK3bfKzDfvm0sIr9Hlpdw89daTPH+6
+ FrfwOsNbjwDPflczovmzDIqpr+m2fJOveP/z/mSJbAifZ+j256hUXnLzxVp8
+ AV9ieOMR4KY0eOLkK3Qtyy9EE7qjLWiORrM2sLpWBYCJv7D4Ay3tK6IToJc3
+ DdGjG15goZ8F/rNx64XIxq1IoDkQCYSrZVt4rPJ6DITpp4hB0Wku+imBTUFl
+ L7XB/HPsMCnEwmq1GhgN9LEj1eGNW0pgIKhUxWhgNHT/nWBAqY7tV2oKQkFX
+ aDQUiyuhWL0crpX/kb5w7mUtNUyJkEi/sqegGS0xP1AfDih1hdf1rruGmKoo
+ m6OuUmxJ2VsYVDct7ZOWwsr+WHUz62uk3gG316M0xY6FmRpR82ot+X7fwb6Y
+ GlSlXF+z8Bo+NBr62122cUtCeCx2bXfeHsJHa2ylnI8DyuOxqBom2zkL8SMP
+ 7fEwEXtkO7GqcnT74EmlTcBwH7sKMCn2djf2iPJELKhSEfV1jN6/HZEuOmND
+ yrEYISlVjHorFiotb6Dr/usBKvZwi5gGA2X335KPxmyG4Xhln3HKrDoeH0nY
+ GP3o3ALxpdWd3MW3yTLOtx3pB4vupz7neRJpzYucv+noJqfBvL+ZdWlD2QKz
+ d8Whg/uwtUDnloZxMjiZXZ3X7RlxShGYrZS4I9uGeHYHa6eNJVOjhZ36By/l
+ 0CbNNYMb9Prc5hWf7v+lbwvfRreI1RGS1AoR5jqIJk1Tt4fTGuc6vY5MW1k7
+ pY8Y4l2La3J2mzv0I4BqsUCiDi2oQRBV+CU9PUUtZQDRe9gz1/UeGjaw945Y
+ P/Er+g/Kdyp+LSRycvS0j9rfSJkQfkut+BIYpraWfi3i0yB5ErZHyHZA6Her
+ zXfReg9x4eHwBo5u9RBEq/RwICftehC9JrTR+5yvA9t8/U60Abno06NSi3Y8
+ QX3h+pQbrnKo5tU3EbqLrvGu7rs4nnP8Lv1T2BGJoB5ilzhIKB4j6wcpgh70
+ uuzEJSLaW+6hf+49nLwjnW0yc9jFlvDg4UnJbYmVU2TldKmVdtfK0x5WBjHk
+ sjlF1gRS9bh6TrI5LNh8dgMjpWz2SjbjOWlcKLA5Sr1cPs8iSRo5rx8ueD1T
+ xGuD3FfxTJ5dCeU5F8rzZFqwq/a4UCYElEkPKKcllK6ctCeUi9QLFEBVuaDG
+ PEE1VheB2gptyoU267LU3K1OE7Q8V5cFwNltAKM4X8RVcwFgMy7hYxJg8xau
+ PlqOq9oiQFcw5yb/mluJjV3qxyWgF+i/6kzX+9AYtqKpx2SBrnqaW/NISVyN
+ WIAucTVi0SWukQwvFXA9L3HsqyqgKCZnGYaLZZVEa6ht2oLlqequnveRDuBP
+ BTQiwgZcpjk3KxGdJLUGqspVQiSCaYIJSyJqKiBqchGJnpjB+VTeyKduOzaB
+ LoNOF127DJYWqD/j5Tl1/S4+tYFXS+fKddfqSzITwUKQHV5mPjOnfs7bzLKP
+ mdteZr48p37V20zG00wVfk//MWqH3SAn3Pay2/5Bav0Cf6T2XdL6GvH79auo
+ SuIbSXwziW/h20m8ge8k8V187yoYx/fx5lV0c9Rw/IDjhxwqR5Cjh+Mtjic5
+ 3ub4EcePOfZzWBxNHG0cjRy3OQY5dI4LHKMcP+G4yHGW46cc73D8TI78nOM5
+ jiGOS/JxiiPD0cFxhWOR4xrHEsccxzKH8V81aexK6B4AAA==
""",
"""
androidx/compose/runtime/SnapshotStateList.class:
- H4sIAAAAAAAAAI1QXUsbQRQ9M5tkdY26ftTGj9pXG8Q1UhCsCFYoBLYWmpCX
- PE2yg45JZmRnInnc3+I/6FOhD7L46I8S70ZftC/OwLn3nDncj3l4/HcH4Cs+
- M9SFTlKjkknUN6NrY2WUjrVTIxm1tLi2l8a1nHAyVtb5YAw7x+2j+ErciGgo
- 9EX0q3cl++7byf8SQ/hW81FiqBwrrdwJg7fzpVNFBX6AMmYYSu5SWYbd+P0T
- UZOleGDcUOnop3QiEU6Qxkc3Hu3HCvAZ2ICkiSrYPmVJg7bIs2rAazzIs4CH
- BHlWy7N6aSbPQnbA9/n38v1thYde4T+gEm1G9RC+mmBv4GjqM5NIhsVYaXk+
- HvVk2ha9ISnLsemLYUekquAv4mxLXWjhxinlQcuM0778oYqH9d/PO3aUVeQ8
- 1dpQC2W0RQOcPqg4NEfxX4TrxKIpB8r1v5j9QwnHBmFlKm7SBarPBgSYo+hh
- a+ry8Gkaa9imeEieKnnmu/CaWGhikRBhAUtNLGOlC2axig9dlCzmLNYsPlr4
- TxVS9+dFAgAA
+ H4sIAAAAAAAA/41QTUsjQRSs7smXY3YdXT/irruKJzcsOyqCoCKoIARmd8GE
+ XHLqZBptk3TLdEc8zm/xH3gSPMjg0R8lvoleVi9e6r2qLt571Y9Pd/cAtrDC
+ UBc6ToyKr8KeGV4YK8NkpJ0ayrCpxYU9M67phJORsq4MxrC219qJzsWlCAdC
+ n4b/uuey53b330sMwVutjAJDaU9p5fYZvLWf7SpKKPsoosJQcGfKMvyKPn4R
+ LZmO+sYNlA7/SCdi4QRpfHjpUT6WQyUHMLA+6VcqZ+vUxRsUJUurPq9xP0t9
+ HhBkaS1L64VKlgZsk6/zw+LDdYkHXu7fpBEtlk8K/jvjd9/R6UcmlgxTkdLy
+ 72jYlUlLdAekzESmJwZtkaicv4oTTXWqhRsl1PtNM0p68ljlD4snL0Hbyipy
+ HmhtaIUy2mIDnH7pNUr+aYRfiYVjDhTrt5i4oYbjG2FpLK5iibD6YoCPSaoe
+ vo9dHn6M6yKWqW6Tp0qeTx14DXxuYKqBANPUYqaBL5jtgFnMYb6DgsWkxYJF
+ zaL8DHqS9VZKAgAA
""",
"""
androidx/compose/runtime/SnapshotStateMap.class:
- H4sIAAAAAAAAAI1QTU8bMRB99ibZsKSwQKGBftBjoVIXUE80QqKVkCKWVmqq
- veTkZC0wSexo7SCO+1v4Bz1V6qFa9ciPqjoOvbTlgCW/N/P8bM/M7a/vPwC8
- xUuGHaHzwqj8OhmaydRYmRQz7dREJj0tpvbCuJ4TTp6JaQjG0OmcHqaX4kok
- Y6HPk0+DSzl077J7tKP/JYb4Xy1EjaHRUVq5I4bg1U7WQgNhhDqaDDV3oSzD
- 6/TBRdIfK+nIuLHSyZl0IhdOkMYnVwF1zDyEDGxE0rXy2R5F+T5DUpVLEW/z
- iDdpx1UZVWW7KndrzaqMGRGL+QHfC97Xf940eFzz1w7opVPaGaOnEf9Vy5uR
- o/o/mFwyLKdKy4+zyUAWX8RgTMpqaoZinIlC+fyPuNBT51q4WUFx1DOzYihP
- lD/Y/HzXbaasIuex1oa+UEZb7IPTqPyiOvzkCLcoS+Y5UN/9hoWvFHA8JWzM
- xRd4Rti6MyDCInGA53NXQKeeN7FNfEieFnke9RF0sdTFMiFiDytdrGKtD2bx
- GOt91C0WLTYsnli0LcLftbcdUGUCAAA=
+ H4sIAAAAAAAA/41QyU4bQRB91eONwYGBbCZ7LlEgUgZQTsRCSiJFshgSKY7m
+ 4lPb04LGdrc13UYc51vyB5yQOKBRjvmoKDWGS5ZDDvWq6vXr2n78vLwC8AbP
+ CZvSZLnV2Vk8stOZdSrO58brqYr7Rs7csfV9L706lLMmiNDtHuwlJ/JUxhNp
+ juLPwxM18m/Tf3D7f1OE6E+uiRqh0dVG+31C8HIzbaOBZog6WoSaP9aO8Cr5
+ 7yG5x1oytn6iTXyovMykl8yJ6WnAG1MFrQpAoDHzZ7rKtjnKdghxWayEoiNC
+ 0WKLyiIsi05ZbNVaZRERO4rErtgO3te/f2uIqFZ92+VKB2wpVUWj3wZ6Pfa8
+ xAebKcJqoo36NJ8OVf5VDifMrCd2JCepzHWV35BLfX1kpJ/nHId9O89H6qOu
+ Hja+XK+caqdZ+c4Yyy20NQ47EHyvm62q8zE+5Cxe5EB96wJL5xwIPGJsLMgX
+ eMzYvhYgxDL7AE8WqgBPF/4BnrHfY02bNbcGCHpY6WG1hwhrHGK9h9u4MwA5
+ 3MW9AeoOyw73HToOGw7NXygOZ4ZqAgAA
""",
"""
androidx/compose/runtime/State.class:
- H4sIAAAAAAAAAH1QTUvDQBB9k7RpjF/xu1YQj9WDUfEgfoEXoVARbBGhp7Vd
- 69p0I91t8Zjf4sEf4UGCR3+UOFFPKu7hzbw3O7Nv5+39+QXALlYIq0J3Bonq
- PETtpH+fGBkNhtqqvowaVlhZAhGqh839+p0YiSgWuhudX9/Jtj04/i0Rwp9a
- CQWC35X2UsRDSZivrv/VV6yuN5scZ+q9xMZKR2fSio6wgjWnP3LZLuVQIlCP
- pQeVsy3OOtuEwyydCpyyE2Rp4IQ5+K5/U87SDc/P0pDWaMfZci5mQ7fi7GXp
- 1etT4fXR8yoFvxAW8xk7hLX6/5tgI9QktoHi6OsrYUOLe3Ob2M/6Zs8Sxhqq
- q4UdDrgcNJLhoC1PVcxk+eJr1qUy6jqWJ1on3KQSbTx+H0Xkh3hVHnjlKDNz
- 4MP9zlwsf8YlVDge8Y0x7glacGsYr2GCEZM5TNUwjbAFMpjBbAuewZzBvMGC
- waLJaekDuDg1Tf4BAAA=
+ H4sIAAAAAAAA/31Qy07jQBCsthPHmJeT5RECQhzDHtaAOKx4SXtBihSERCKE
+ lNOQDGGIM0aZScTR38KBj+CALI77USvaYU+AuHR1VU/3VPfff88vAPaxQdgU
+ ujdKVO8h6ibD+8TIaDTWVg1l1LLCyhKIUD9qHzTvxEREsdD96Pz6Tnbt4cln
+ iRB+1EooEPy+tJciHkvCUn37q75ifbvdZiw3B4mNlY7OpBU9YQVrznDisl3K
+ g58HEGjA+oPK2Q5nvV3CUZYuBE7VCbI0cMI8+K5/U83Sn56fpSFt0Z6z41xU
+ Qrfm/M7Sq9enwuuj59UKfiEs5jP2CFvN78/BbqhNuYHi5H2fsKXFvblN7LT+
+ a2AJMy3V18KOR1wOWsl41JWnKmaydvE+61IZdR3LP1on3KQSbTz+H0VMd+N7
+ eeC7Y42ZAx/u/8xFbYpVrDMe84sZ7gk6cBuYbWCugXkscIrFBkKUOyCDCn50
+ 4BksGSwbrBismpyW3gBNs/uhAwIAAA==
+ """,
+ """
+ androidx/compose/runtime/StructuralEqualityPolicy.class:
+ H4sIAAAAAAAA/5VVW08bRxT+ZteX9WLAcVJqCE2ThjbmljWkdygtIVQxciiq
+ I6qWp7E9dcasd53dWStRX1B/Sp/70KgPiVqpQu1bflTVM7suIQYikOU5Z845
+ c+Y7t9mX//7xF4APscmwxL1W4MvWE6fpd3t+KJwg8pTsCqeugqipooC7m48j
+ 7kr1dMd3ZfNpFozhu1qH97njcq/tfNPoiKZaqZ3tyeO98JGvHkSKK+l7iZ/V
+ ky7WVhgKw9IsUgzOBZ1nkWHIrEpPqjUGszy7m4eFnI00bIaUeiRDhjtvgHxG
+ 8ATQFo8j2eeu8BTDrfIpiTghmf2BYabmB22nI1Qj4NILKSDPTxCHznbkurzh
+ CvJ+bd9XrvScTr/rSE+JwOOuU/VUQGdkM8ziEoPFAxHDyuMyxm0UcYWBcYbi
+ yatJ0aATyq9rF22GK+XZY1aJlKxuvgmerzRCsiqdlRcL0wzprgjagmHrXEk5
+ JU2nwV+9YOVn7okfeeSqarfnUrquM/xUvmhrngvtufDncQ3v2biBm1SEXiD6
+ 0o+o87LNKAjiBsryXs+VokXq1aYb96sNQzepVd2uP1zf3tjMYw6jORLOM1yq
+ DfrjgVC8xRWnDBndvknjzPRi6QVU9H2SP5F6VyGutcQgDg+mbaNkJP/C4YFt
+ WJoZIWoSHbP++dkoHR4s28VMMVViFaPC7mYt4+9fMkbB3JoupKaMSnrZKmSm
+ Yi1x2YS7P7FlFSzS5u5P6MuW6Vm5cMqZhp0/Xjx6C/63rZOpuL1P+br6beKm
+ 6vVlKGlm1l81Kg32ht+iBhyvSU9sR92GCB7qudKT4Te5u8sDqfcD4cywrx0e
+ 8K6goXvNab7qeSLYcHkYCtrm6rLtcZoB8mDX/Shoiq+ldjc5cLd7AhgqVL00
+ xUdvJyZ1OYmuUm0yRK8STZOenifafUE7RxdQS+eeY+QZMQbWBsZAB1/Smk8M
+ iI7G9R7DOFnpw/eI6rJn5hde4K1fh07vx6evJxaD05qbwNuxPoMScQa+In7U
+ IFEhdp+sk5gaXLI4QGgW3/lt6Ab3GD5zcMPxUOmJw7uk0W52kKIfde3c/MLi
+ C8wM+0pinUtsjtBaeH+A1sIHMVrN3SLOPLpJA9YxXDaHYijExuWjXCfHgZE/
+ YXz/HLO/Y+FZLEhhnVabzG5Q2T6n4O/G6ExsxHSFMg1USb9Idbi9B7MKp4pK
+ FUtYJhZ3qvSF/WgPLMTH+GQPdojREJ+G+CxELsRYzEyEKIWYJP4//rdNjpUH
+ AAA=
+ """
+ )
+
+ val Effects: TestFile = bytecodeStub(
+ filename = "Effects.kt",
+ filepath = "androidx/compose/runtime",
+ checksum = 0xb63b1aec,
+ """
+ package androidx.compose.runtime
+
+ @Composable
+ fun SideEffect(
+ effect: () -> Unit
+ ) {
+ effect()
+ }
+
+ class DisposableEffectScope {
+ inline fun onDispose(
+ crossinline onDisposeEffect: () -> Unit
+ ): DisposableEffectResult = object : DisposableEffectResult {
+ override fun dispose() {
+ onDisposeEffect()
+ }
+ }
+ }
+
+ interface DisposableEffectResult {
+ fun dispose()
+ }
+
+ private class DisposableEffectImpl(
+ private val effect: DisposableEffectScope.() -> DisposableEffectResult
+ )
+
+ @Composable
+ @Deprecated("Provide at least one key", level = DeprecationLevel.ERROR)
+ fun DisposableEffect(
+ effect: DisposableEffectScope.() -> DisposableEffectResult
+ ): Unit = error("Provide at least one key.")
+
+ @Composable
+ fun DisposableEffect(
+ key1: Any?,
+ effect: DisposableEffectScope.() -> DisposableEffectResult
+ ) {
+ remember(key1) { DisposableEffectImpl(effect) }
+ }
+
+ @Composable
+ fun DisposableEffect(
+ key1: Any?,
+ key2: Any?,
+ effect: DisposableEffectScope.() -> DisposableEffectResult
+ ) {
+ remember(key1, key2) { DisposableEffectImpl(effect) }
+ }
+
+ @Composable
+ fun DisposableEffect(
+ key1: Any?,
+ key2: Any?,
+ key3: Any?,
+ effect: DisposableEffectScope.() -> DisposableEffectResult
+ ) {
+ remember(key1, key2, key3) { DisposableEffectImpl(effect) }
+ }
+
+ @Composable
+ fun DisposableEffect(
+ vararg keys: Any?,
+ effect: DisposableEffectScope.() -> DisposableEffectResult
+ ) {
+ remember(*keys) { DisposableEffectImpl(effect) }
+ }
+
+ internal class LaunchedEffectImpl(
+ private val task: suspend () -> Unit
+ )
+
+ @Deprecated("Provide at least one key", level = DeprecationLevel.ERROR)
+ @Composable
+ fun LaunchedEffect(
+ block: suspend () -> Unit
+ ): Unit = error("Provide at least one key")
+
+ @Composable
+ fun LaunchedEffect(
+ key1: Any?,
+ block: suspend () -> Unit
+ ) {
+ remember(key1) { LaunchedEffectImpl(block) }
+ }
+
+ @Composable
+ fun LaunchedEffect(
+ key1: Any?,
+ key2: Any?,
+ block: suspend () -> Unit
+ ) {
+ remember(key1, key2) { LaunchedEffectImpl(block) }
+ }
+
+ @Composable
+ fun LaunchedEffect(
+ key1: Any?,
+ key2: Any?,
+ key3: Any?,
+ block: suspend () -> Unit
+ ) {
+ remember(key1, key2, key3) { LaunchedEffectImpl(block) }
+ }
+
+ @Composable
+ fun LaunchedEffect(
+ vararg keys: Any?,
+ block: suspend () -> Unit
+ ) {
+ remember(*keys) { LaunchedEffectImpl(block) }
+ }
+ """,
+ """
+ META-INF/main.kotlin_module:
+ H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMuSSSMxLKcrPTKnQS87PLcgvTtUr
+ Ks0rycxNFeJ0TUtLTS4p9i4R4gpKzU3NTUot8i7h4uNiKUktLhFiCwGS3iVK
+ DFoMAHVSFrpbAAAA
+ """,
+ """
+ androidx/compose/runtime/DisposableEffectImpl.class:
+ H4sIAAAAAAAA/51TS08UQRD+enbZx4iyLPJGQEFZQJgFvS0hUYRkkxUNS4gJ
+ p2a2gV5me8h0L8Eb0Yu/w3/gwWg8GMLRH2Ws3ocgxgAmM9VV1f1VfV1V/ePn
+ t+8AnuIJwxxXlSiUlWPPD2uHoRZeVFdG1oT3Qmqy+U4gVnd3hW+KtcMgCcaQ
+ qfIj7gVc7Xmvdqq0k0SMIbEklTTLDBO50kFoAqm86lHN260r38hQaW+tpS0U
+ prcYPlx1ammudG1qZT88FIXZ6wM2hK4HprDcoDJRCqM9ryrMTsQlUeBKhYY3
+ 6ayHZr0eBAW6n2ggU0gzjF6gLpURkeKBV1QmIrj0dRK3GHr9feEftPCvecRr
+ gg4yTOVKl+tXuOAp2yB7xKsTt3HHRSe6GGI5a3eg20UcWYbxqyrciTTupuGg
+ lyFu9qVm8K5fHdtpuvH7qzp00wb9R38YutssXgrDK9xw8jm1oxgNMLMiZQUY
+ 2AH5j6W18qRVFhii05MR1xlwXCdzeuLS19Av/KcnKWfg9GTRybPno9n+jDPU
+ k41nnXy8ITvysbOPCSeVsDKT3Bj71/6bs3dxq1E8m3mRWT7ZNu/zrjDkb1oy
+ hoUbV43ms5179dgIGslQtUlsvm0EdZsAPX9gGNJluae4qUeCYXijGbuojqSW
+ FPnZ+WOgUVoJK3SoqySVWK/XdkS0abPby4Y+D7Z4JK3dck5ejvX7FfwR1C2H
+ 9cgXa9JiBluYrb+yI0/jHG+0Omunm6xZshwM4jGtCfKnmoNADyWBGObIKtG+
+ Q2tmNut+RWbmC3pmZj+j71MDOU/yDp1MUAwXQ+ii1SNfXxODfgzY2SLN5mOt
+ fEliAiRZK6GDhYacwSKtK+QdIgLD24gVMVLEvSJGMUYqxou4jwfbYBoTmNxG
+ SmNA46FGWuORxpRGTmNaI/ELZm5MUZ8FAAA=
+ """,
+ """
+ androidx/compose/runtime/DisposableEffectResult.class:
+ H4sIAAAAAAAA/5VPzU4CMRicrwvsuiou/qIPQPTiAjHx4MlEjWswJphw4VTY
+ YgrL1tBCOPJcHgxnH8r4LTyBSTOd+X4605/fr28ANzgjxDJPZ0any3hopp/G
+ qng2z52eqvhBW9ZykKnH0UgNXVfZeeZ8ECEay4WMM5l/xG+DMfd8eAQ/3Wwo
+ gnd51SPUOhPjMp3Hr8rJVDp5RxDThcfWVEBQAAg04fpSF6rJLG0RGutVNRR1
+ EYpovQr5iEgEo/p61RZNegkicSGa3nOjmG4TWp1/foKDsG+4LdnriWPxbuaz
+ oXrSGec/727Xe9pqXr3Pc+Ok0ya3FbZECZvgJUIZFWYCJxs8xinft/y0z52g
+ Dy/BToIwwS72mGI/QRUHfZBFhFofJYtDiyOLMuMfURqWxJYBAAA=
+ """,
+ """
+ androidx/compose/runtime/DisposableEffectScope$onDispose$1.class:
+ H4sIAAAAAAAA/8VUXVPTQBQ9mxZaQoHwIQIqVkFtA5Km4hcwzDBYxmpRh2p9
+ 4CltQ1mabpgk7fDk9CfpjI6jD06f/VGON0mRjjry8eJD9t69e/bs3bP35vuP
+ r98ALGOVYcUQVcfm1SOtYjcObdfUnKbweMPUnnCX5kbZMnN7e2bFK1bsQ3Pe
+ FmHcnNdjYAzKgdEyNMsQNe1l+YBgMUQYtDOz7phu06JNfQz9a1xwb51hLlWo
+ 257FhXbQamh7TVHxuC1cbavrZVbTJYbsaai14/U3RLu6HmxSTi4Qns+QPO2w
+ BGQMDkBCgiGSSpcSiGFYRhQjDFFvn7sMa4WLy0iPEKuGE4bZf+cSwwTpxEXL
+ rhN4IpUu/C4/ZTuJy4O4hCl6hnMqxDB6HNk2PaNqeAbFpEYrQuXC/CHuD2Bg
+ dYofcX/2nryqzpDqtEfkTluWpqTAKJLKOu24PNVpZ6UMexZXpBkpE3k66eOz
+ DPrZNQuLhFKhk5fOp3QMKYaBX3IzFE8vrnMnloCKBQY5DLpLdSortfcYLjzT
+ EYalFe2mUzGfmOVmLXfkmcKlE+lefS3DalJy74rbG696aOTnAYesFpPH3pa8
+ kNSTPZCLV56sFmR9Tl/U9eUVmuRkUqrIa8Lwmg4lE920q2RGClyYL5qNsum8
+ 9skYxgp2xbBKhsP9eTeYyAthOpuW4bomdcRITlQs2+WiRpW0b1dJnfDuW9xH
+ T/xNCIbpnTD3Enc5sW4IYXtG8D4MV7predH6YxU6tWeUqqMfTFH8fiVfp+KU
+ MEMfdRjiZLMUWScrkZXVhU8YUj9D+RDg7tFIu9GHYfozgrooQGEUY37Jk9fL
+ OkDeOCFZwPnY7wiyg+pHDH3BNMPbE1I5IFICKp84EUK7xP24H2BYgAKm8YDG
+ KNJYxMOA4y4ekf3PlUFXBOVDr0ACXd1FJI9reczmcR1JcnEjj5uY2wVzMY9b
+ u4i6vnvbxbiLO1ihzb5WS/RpASjzE1u+Yp2EBgAA
+ """,
+ """
+ androidx/compose/runtime/DisposableEffectScope.class:
+ H4sIAAAAAAAA/51UW2/TSBT+xrnYNaVJw603CgsBWgq1E9gLpCBBF7RBoSAC
+ lVCfJs60TOuMkcep+ljxsP9hX/cX7D4VLdIqKm/8KMQZJy3d7kMpljzn/p05
+ c87Mp8///AvgNu4wzHPVjiPZ3vKCqPM20sKLuyqRHeH9KjXJvBWKR6urIkia
+ QfRW2GAMxXW+yb2QqzXvWWudTDYyDPkFqWRynyEzM7s8jBzyLrKwGbLJG6kZ
+ /MbxUtUYhiLVNwmG5kxjI0pCqbz1zY632lVBIiOlvccDzq/NfnuCF0J3w4Qy
+ tI5CXdizv6Liave/K8nlRhSveesiacVcEjhXKkp4P9FSlCx1w5C8CvvF9sMd
+ FBimD+xOqkTEiodeXSUx4chA2xhlOBO8EcHGAOg5j3lHkCPDtZnG4UbVDmia
+ BmStZnp1CqddlHCG4e7xelTe33O5YuMclXp0l9LZGHcxhgkG75inaWOKYaQs
+ y6vlA7PB6gwXj0rMMLrn8lQkvM0TTjqrs5mhu8DM4pgFBLdB+i1pJJ+4doVh
+ pbc94VpjlmsVe9uu5VipYNhUZ431tquWzx7mdv/Mk/hkqpiZsPxsdcTJFnMT
+ Tilbsnzbz/+2+7vz8T3rbe++s2w35+z+UfWZSVFlJnHlO4artFfUwUrdvpOe
+ 30jo/i1GbTqkQkMqsdTttET80uCY0Cjg4TKPpZEHyqGmXFM86cbET77oZ6+r
+ TaklmR98nVyG8mHr/uz9x224rpSIF0OutSDRbUbdOBCPpUk2PoBY/h88KrDo
+ +TCfRSdDrwmtPkmeaRDR3PUdOH+n5gqt+VR5AlVah/sOGIJLdJS0wwRlgpeR
+ gWnr6blS8T3OZu59wNjruR1M9nD+r30sl6iDEboWpRTvIsU4hDGNC2Sh6AGy
+ 4QpkZbiVxp6kJ7W/kxGiP9Jvs4GQwU8pMKOxN984fk5DPPxCdJH0P9CGL60g
+ U8flOsp1XMFVYnGtjhnMroBpXMfcChwNV+OGRl7jhMZNjYLGPGm+AB149ZDV
+ BQAA
+ """,
+ """
+ androidx/compose/runtime/EffectsKt.class:
+ H4sIAAAAAAAA/+1Y21Mb1xn/Vhe0LALL4q6kjmJIA8JYWnExWBjH5hKrljGV
+ bKhL63QRC16QdhXtSgYnbdxmOtOX/APpQ2f63Je8JG4z43qat/5Rnf7O0UpI
+ aAHBOEwfyoz2fHvOd/l9t3P28O///OM1EU3S7wW6quhbRUPb2o9mjXzBMNVo
+ saRbWl6NLm1vq1nLvG/5SBAosKuUlWhO0XeiDzd3seAjt0BSRttSK4wCDY2k
+ 9gwrp+nR3XI+ul3Ss5Zm6GZ02aZiidE1geKncc1V1x/rmpWY50IfpI6FucDf
+ lc2cmgCElFHcie6q1mZR0aBU0XXDUioGVgxrpZTLgatN5YhFkgS6UgdG0y21
+ qCu5aFK3ihDXsqaP/AL1Zp+p2T1bflUpKnkVjAJ9OJI6GpVE3UyGKdkBfj91
+ 0SWJOinQaM/BeR8FgU/Ty8aeKlDPyGizBT/1UG8HdVOfQOHTIo7ELWqmHaBW
+ EyXzmP/pNK658eOzctRoJmsU1MRY6wJp1SzlqunvriJZVAtFNatY6hY88+VV
+ 01R2EKeB1aJRRiWGFSucUxXTChu6Gt5TDwTy5tSymhNo8KgKeJBiS1DkXUqn
+ H6YFeu8w1slcTt1RchkUj7q0n1ULjN9HV6HoOFvXRRoWSLSMSt6PZs+uBj/9
+ lD6UyEMjyPOchhKfR4GNOJdNhMYkGqJrpyZahhdTTtXYQp6/PrvcxWV++KSG
+ RjfafT/esvZkvpDzUZzFNiTRBE0KNDasDSvD40U1r+Y31eJ4beMbPio8LAsk
+ JAXqhMT2cFVAIA/Sj6VgcyAF+vjkTeIMifrb29B0cak7Q1jjlRBieNKaj+eK
+ 3+sfR/f/ZEQnKhHFMD2ycb5w/fkcghcXC+adKdJS9cukZGm56J1iUTnAmf0x
+ 9lZoP3i4LdCokxvJUYdJPyXpZxLdo/tnCjV2kHZNL5Qsc1gr46xy0CxQV0pB
+ jJ6pW9UzWGvhdLUZskbRgHu6auJjB6HRS3wDPGSwP5TGmg1XYuXdzBnZPZHS
+ Il0R6LNz7fdvC8vYselujFBln16TaJ1t0aPHpqNRim3QX72lbfJtedwydmx/
+ f/nRtqgL9wZbz+fn20EuHCoK7HJV6QPVUrYUS0HPuvJlN65JAnuI7EE4/fcY
+ 4cLivsaoGKgtWXD98ObltPTmpeQKuPgw4Gr48RX2EN0gLldGtiZ62Rh6H4sh
+ V0yI9wdcoe6gJ+iKefjTG3P/669tLrHtni80VmUSA76QZ0CIiSeyTzWzi4H2
+ FgRvnyQoBqQWVMxXVfQFOkL+oCgKQS4U8189VZiNgc5QKtDVAoh3A5dCA9Au
+ BUWuR4gFgm22Lfc93w+vhDcvucLLobsnKGxZTTA006SmZeHu0LItfFxYWlbV
+ Gbpuq2pZpCfUF+jlIn4Ev8rch4D/weVBJQ6yUsYeROxD1u6G+vtF7KxHu0Dy
+ mQ93XJCrtpf2LRV3cEOvgnh0wJWGT9kgEg742UVYsvv/+h6O30j9NlS792eM
+ UjGrLqqbpZ2adXY/LCu5kioIZubBndU6NdJ9rkOKZMJValkaC8vhOpbT/70C
+ iXg4bW9SJ4pUmSATSUnykHxNlidvypI8MRS/KctTUjzGiWkpPsOJG9LEJCdm
+ qjyzNk88ZvPEZZsnHj/0g0fgfM4A2GRsSOZwJmc5MS1NVYgb0vQNTsxIM1Oc
+ mJVmJxkBOHKsQsEdOc4pAFqS8KW3YGzhjn8phUyvlJj/j1jZsCwbWSW3phQ1
+ 9m5Ptme0HV2xSkXQ76Qr8JJ6WTM1LN85vD3ianl0tfafnQY26fB/Drj82zJr
+ DvqkSvUsawxGj1MpkUwu3PzZXwcNkpfa8PYcb3OYR+NRVyTY8YouR/5O/QKt
+ f8NOGtrHU8LYRiJ1Ujsd4N1f4cb8AMYXnM9Hn2Fsw4qI8XP8fDiuIEAwNUgh
+ LDFTt8jNhbsrpr6noSfBD76l0e9o/J81e0yLRO/X2erG+/WarXfot9yL3+EX
+ xPq7mPuJSVfoPZXCkDsRSdR2Og8kLBi9YxyJ+5Z7/nuaeDL2HU3V+97H4zQC
+ XSYwjMCeST00yrFFoEDCyjTdgDIRUZ0B5WJKaZZucoy9HLlgI481YetkoZf5
+ 4V5FmLAR7kOpl0G4VkE47572MIjXHCHKUGkBgoxgWTAb5xAnsdaBlVsA5sHo
+ 5xDdXKoKsY/mQQmcYmBdNti5JrDd7hrYRsi3bchfQnUbxv7xCuRpj3vayzCP
+ O2JOQEEJmBIIaQlzcxzzPFb8sHkHSL3gqGBmueqvYe6vYe6nu6BcnGLo3Tb6
+ j5rQD3qOoG/0YcH24Y922IciwWX4UCmPSOT1K0o9qOXAqUz8UNFLZTTFAsqw
+ TFdpsZaDAaB4wL3oreWgGy20Qg859iFaAkWcqi+YReeCaa9DvurUXJlqcz1y
+ bq6VhuZK1zXXz8/fXKtOzZWpNdc6i9ovmqvgMXQ9B6bHsPcclbDW0FxPTmyu
+ dF2sHp/eXKtOzZU5bK511lwOEJ9C5T4gPEWw9mH2k4bm2mixudJ1zfXLVptr
+ 1am5MnXNtc6aywHzM75b+zH2YOwjraG5fn3m5krXNdevztZcq8c3V6apuZzL
+ xE8FxP0FGqmAMnyB5vq0obk+abG56gvm6WnN5aEvOKNJLzH1/++vi//+4ttQ
+ Aen4DfKsbJA7SZtJyiZpi9QkbdNOEvWtbSA5tEt7G9Rv0qBJOZzVJuVN0k0y
+ TCqYNMsn5026a9ISpxdMWjUpbdKnJt02KWFS1KSQSV6TirwuumDVwq/EtZf/
+ C7XJpgW2HAAA
+ """,
+ """
+ androidx/compose/runtime/LaunchedEffectImpl.class:
+ H4sIAAAAAAAA/5VSW08TURD+znbZbleUsgKWi4iCUKiwhfhWQqJETJOKBpSY
+ 8HS6Xcppt2fJXhoeG179F/4DH4zEB9Pgmz/KONuLIKiEZPfM5Xwz852Z+fHz
+ 6zcAT7HKkOOy4nuicmzZXuPICxzLj2QoGo5V4pG0D53Ki4MDxw6LjSM3CcaQ
+ rvEmt1wuq9brco1ukkgwaOtCinCDYTZbqnuhK6RVazasA0oRCk8G1lZPWy0s
+ 7jGI61Dry32A7fleFArpBNamR8xkxGPEOeAdFS5sFHKly8TIGdeaLXl+1ao5
+ YdnngmpwKb2Qd+tte+F25LoFBjXkQV1HimH6AjMhQ8eX3LWKMvQpWNhBErcY
+ Rqkxdr0X/Yb7vOEQkGEhe5XFBc9unKRKrAZxG3cMDGKIIZGN7QEMG1BhMsxc
+ 18BBpDCSgoLRmPahCBiWSzcYI722cl37b9r9vzWfYbiPeuWEvMJDTj6l0UzQ
+ 8rH40OMDDKxO/mMRW3nSKrSXH9qtCUPJKIaSbrcM+jp6x6ZfV/R2K9NurSl5
+ 9nzenEorExmdmYapm6qp5AfyqqmZaoblWT7x/ZS1W2cfNSWt7Sz+D/j+7ETt
+ g1Wqkzw7UUjq4zGlNRYTNfsPOp/GhYH9o1kEMbrdD1bqIUNqV1QlDyPfYZjc
+ 6Y6pKJsiEGXXeXa+nTTdTa9CoKES5dyOGmXHf8sJE/PwbO7ucV/Eds85dznX
+ 78X8I6mx60W+7WyJOGa8F7N3pTpWacPUznjMeOHIWiRLwTiWSGrk17vDo93V
+ kECOrBLdKyTTOdM4RXrpC+4u5T5j7FMn8gmddwipYQsGXmKI5DL5xroxuIdM
+ vA+kxfVYr14SKySTrFdQgdU5s8iT3CTvBBGY3EeiiKki7hcxjQekYqaIh3i0
+ DxZgFnP70ANkAjwOkAowH2Cho2sBRn4Bxaa1HQ8FAAA=
"""
)
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt b/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
index 9ec00a4..5a39288 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
@@ -16,12 +16,17 @@
package androidx.compose.lint
+import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.ULambdaExpression
+import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
+import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
+import org.jetbrains.uast.sourcePsiElement
import org.jetbrains.uast.toUElement
/**
@@ -143,3 +148,10 @@
else -> true
}
}
+
+fun KotlinUFunctionCallExpression.resolveCall() =
+ (sourcePsiElement as KtElement).getResolvedCall(
+ context = sourcePsi.project
+ .getService(KotlinUastResolveProviderService::class.java)
+ .getBindingContext(sourcePsi)
+ )
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
index 48cb5ef..f51de29 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
@@ -41,10 +41,20 @@
val State = Name(PackageName, "State")
val MutableState = Name(PackageName, "MutableState")
val MutableStateOf = Name(PackageName, "mutableStateOf")
+ val MutableIntStateOf = Name(PackageName, "mutableIntStateOf")
+ val MutableLongStateOf = Name(PackageName, "mutableLongStateOf")
+ val MutableFloatStateOf = Name(PackageName, "mutableFloatStateOf")
+ val MutableDoubleStateOf = Name(PackageName, "mutableDoubleStateOf")
val MutableStateListOf = Name(PackageName, "mutableStateListOf")
val MutableStateMapOf = Name(PackageName, "mutableStateMapOf")
val ProduceState = Name(PackageName, "produceState")
val Remember = Name(PackageName, "remember")
+ val DisposableEffect = Name(PackageName, "DisposableEffect")
+ val RememberSaveable = Name(PackageName, "rememberSaveable")
+ val LaunchedEffect = Name(PackageName, "LaunchedEffect")
+ val ReusableContent = Name(PackageName, "ReusableContent")
+ val Key = Name(PackageName, "key")
+ val StructuralEqualityPolicy = Name(PackageName, "structuralEqualityPolicy")
}
object Ui {
val PackageName = Package("androidx.compose.ui")
diff --git a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
index e8aa463..6c011af 100644
--- a/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
+++ b/compose/lint/internal-lint-checks/src/test/java/androidx/compose/lint/UnnecessaryLambdaCreationDetectorTest.kt
@@ -20,15 +20,15 @@
import androidx.compose.lint.test.Stubs
import androidx.compose.lint.test.kotlinAndBytecodeStub
-import com.android.tools.lint.checks.infrastructure.TestLintResult
-import org.junit.Test
-import org.junit.runner.RunWith
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintResult
import com.android.tools.lint.checks.infrastructure.TestMode
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Issue
import org.intellij.lang.annotations.Language
+import org.junit.Test
+import org.junit.runner.RunWith
import org.junit.runners.Parameterized
/* ktlint-disable max-line-length */
diff --git a/compose/material/material-icons-core/build.gradle b/compose/material/material-icons-core/build.gradle
index 0276b88..615b415 100644
--- a/compose/material/material-icons-core/build.gradle
+++ b/compose/material/material-icons-core/build.gradle
@@ -15,65 +15,100 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
import androidx.compose.material.icons.generator.tasks.IconGenerationTask
+
plugins {
id("AndroidXPlugin")
id("com.android.library")
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.compose.ui:ui:1.2.1")
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation(libs.kotlinStdlib)
-
- samples(project(":compose:material:material-icons-core:material-icons-core-samples"))
- }
-}
-
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
-
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:ui:ui"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
implementation(libs.kotlinStdlib)
}
}
- }
- dependencies {
- samples(project(":compose:material:material-icons-core:material-icons-core-samples"))
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:ui:ui"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
+ }
+ }
}
}
IconGenerationTask.registerCoreIconProject(
project,
android,
- AndroidXComposePlugin.isMultiplatformEnabled(project)
+ true
)
androidx {
diff --git a/compose/material/material-icons-core/samples/build.gradle b/compose/material/material-icons-core/samples/build.gradle
index 040d910..0977215 100644
--- a/compose/material/material-icons-core/samples/build.gradle
+++ b/compose/material/material-icons-core/samples/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "AndroidX Compose UI Core Material Icons Samples"
+ name = "Compose UI Core Material Icons Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Core Material Icons"
diff --git a/compose/material/material-icons-core/samples/src/main/AndroidManifest.xml b/compose/material/material-icons-core/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 820b02a..0000000
--- a/compose/material/material-icons-core/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/compose/material/material-icons-core/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-core/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-core/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-core/src/commonMain/kotlin/androidx/compose/material/icons/Icons.kt b/compose/material/material-icons-core/src/commonMain/kotlin/androidx/compose/material/icons/Icons.kt
index 3031458..813f3ad 100644
--- a/compose/material/material-icons-core/src/commonMain/kotlin/androidx/compose/material/icons/Icons.kt
+++ b/compose/material/material-icons-core/src/commonMain/kotlin/androidx/compose/material/icons/Icons.kt
@@ -27,8 +27,8 @@
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.DefaultFillType
-import androidx.compose.ui.graphics.vector.PathBuilder
import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.graphics.vector.PathBuilder
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
diff --git a/compose/material/material-icons-extended-filled/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended-filled/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended-filled/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended-outlined/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended-outlined/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended-outlined/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended-rounded/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended-rounded/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended-rounded/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended-sharp/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended-sharp/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended-sharp/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended-twotone/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended-twotone/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended-twotone/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended/build.gradle b/compose/material/material-icons-extended/build.gradle
index 0903147..b7e2fea 100644
--- a/compose/material/material-icons-extended/build.gradle
+++ b/compose/material/material-icons-extended/build.gradle
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
import androidx.build.RunApiTasks
import androidx.compose.material.icons.generator.tasks.IconGenerationTask
-import androidx.compose.material.icons.generator.tasks.ExtendedIconGenerationTask
plugins {
id("AndroidXPlugin")
@@ -26,7 +25,7 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
IconGenerationTask.registerExtendedIconMainProject(
project,
@@ -35,38 +34,62 @@
apply from: "shared-dependencies.gradle"
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make an analogous update in the
- * corresponding block below
- */
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.kotlinReflect)
- androidTestImplementation(libs.truth)
+ sourceSets {
+ commonMain {
+ dependencies {
+ api(project(":compose:material:material-icons-core"))
+ implementation(libs.kotlinStdlibCommon)
+ implementation(project(":compose:runtime:runtime"))
+ }
+ }
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation(project(":compose:foundation:foundation-layout"))
- androidTestImplementation(project(":compose:ui:ui"))
- androidTestImplementation(project(":test:screenshot:screenshot"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation("androidx.activity:activity-compose:1.3.1")
- androidTestImplementation("androidx.appcompat:appcompat:1.3.0")
- }
-}
+ commonTest {
+ dependencies {
+ }
+ }
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- kotlin {
- /*
- * When updating dependencies, make sure to make an analogous update in the
- * corresponding block above
- */
- sourceSets {
- androidAndroidTest.dependencies {
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:foundation:foundation"))
implementation(project(":compose:foundation:foundation-layout"))
implementation(project(":compose:ui:ui"))
@@ -83,6 +106,21 @@
implementation(libs.truth)
}
}
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
+ }
+ }
}
}
@@ -102,43 +140,7 @@
}
-if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- def allThemeProjects = [
- project(":compose:material:material-icons-extended-filled"),
- project(":compose:material:material-icons-extended-outlined"),
- project(":compose:material:material-icons-extended-rounded"),
- project(":compose:material:material-icons-extended-sharp"),
- project(":compose:material:material-icons-extended-twotone")
- ]
-
- for (themeProject in allThemeProjects) {
- project.dependencies.add("embedThemesDebug", themeProject)
- project.dependencies.add("embedThemesRelease", themeProject)
- }
- // Compiling all of the icons in this project takes a while,
- // so when possible, we compile each theme in its own project and merge them here.
- // Hopefully we can revert this when parallel compilation is supported:
- // https://youtrack.jetbrains.com/issue/KT-46085
- android {
- libraryVariants.all { v ->
- if (v.name.toLowerCase().contains("debug")) {
- v.registerPostJavacGeneratedBytecode(configurations.embedThemesDebug)
- } else {
- v.registerPostJavacGeneratedBytecode(configurations.embedThemesRelease)
- }
- // Manually set up source jar generation
- ExtendedIconGenerationTask.registerSourceJarOnly(project, v)
- }
- }
-} else {
- // We're not sure how to compile these icons in parallel when multiplatform is enabled
- IconGenerationTask.registerExtendedIconThemeProject(
- project,
- android,
- AndroidXComposePlugin.isMultiplatformEnabled(project)
- )
-}
-
+IconGenerationTask.registerExtendedIconThemeProject(project, android)
androidx {
name = "Compose Material Icons Extended"
diff --git a/compose/material/material-icons-extended/generate.gradle b/compose/material/material-icons-extended/generate.gradle
index aed94d9..eb45afa 100644
--- a/compose/material/material-icons-extended/generate.gradle
+++ b/compose/material/material-icons-extended/generate.gradle
@@ -25,17 +25,9 @@
apply plugin: "com.android.library"
apply plugin: "AndroidXComposePlugin"
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
apply from: "${buildscript.sourceFile.parentFile}/shared-dependencies.gradle"
-if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- // We're not sure how to merge icons jars when multiplatform is enabled
- IconGenerationTask.registerExtendedIconThemeProject(
- project,
- android,
- AndroidXComposePlugin.isMultiplatformEnabled(project)
- )
-}
+IconGenerationTask.registerExtendedIconThemeProject(project, android)
dependencies.attributesSchema {
attribute(iconExportAttr)
diff --git a/compose/material/material-icons-extended/shared-dependencies.gradle b/compose/material/material-icons-extended/shared-dependencies.gradle
index f2cbca1..2de0ef0 100644
--- a/compose/material/material-icons-extended/shared-dependencies.gradle
+++ b/compose/material/material-icons-extended/shared-dependencies.gradle
@@ -18,36 +18,25 @@
// by its specific theme projects (each of which compile a specific theme)
import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
-dependencies {
- if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make an analogous update in the
- * corresponding block below
- */
- api(project(":compose:material:material-icons-core"))
- implementation(libs.kotlinStdlibCommon)
- implementation(project(":compose:runtime:runtime"))
- }
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
+
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
}
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
- api(project(":compose:material:material-icons-core"))
- implementation(libs.kotlinStdlibCommon)
- implementation(project(":compose:runtime:runtime"))
- }
+kotlin {
+ /*
+ * When updating dependencies, make sure to make an analogous update in the
+ * corresponding block above
+ */
+ sourceSets {
+ commonMain.dependencies {
+ api(project(":compose:material:material-icons-core"))
+ implementation(libs.kotlinStdlibCommon)
+ implementation(project(":compose:runtime:runtime"))
}
}
}
diff --git a/compose/material/material-icons-extended/src/androidAndroidTest/AndroidManifest.xml b/compose/material/material-icons-extended/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-icons-extended/src/androidMain/AndroidManifest.xml b/compose/material/material-icons-extended/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/material/material-icons-extended/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/material/material-lint/src/main/java/androidx/compose/material/lint/ColorsDetector.kt b/compose/material/material-lint/src/main/java/androidx/compose/material/lint/ColorsDetector.kt
index 0e1a911..cedd663 100644
--- a/compose/material/material-lint/src/main/java/androidx/compose/material/lint/ColorsDetector.kt
+++ b/compose/material/material-lint/src/main/java/androidx/compose/material/lint/ColorsDetector.kt
@@ -33,6 +33,7 @@
import com.android.tools.lint.detector.api.UastLintUtils
import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiVariable
+import java.util.EnumSet
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UElement
@@ -40,7 +41,6 @@
import org.jetbrains.uast.toUElement
import org.jetbrains.uast.tryResolve
import org.jetbrains.uast.util.isConstructorCall
-import java.util.EnumSet
/**
* [Detector] that checks `Colors` definitions for correctness.
diff --git a/compose/material/material-ripple/build.gradle b/compose/material/material-ripple/build.gradle
index 31a99bb..999f59f 100644
--- a/compose/material/material-ripple/build.gradle
+++ b/compose/material/material-ripple/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,48 +23,15 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- api("androidx.compose.foundation:foundation:1.2.1")
- api("androidx.compose.runtime:runtime:1.2.1")
-
- implementation(libs.kotlinStdlibCommon)
- implementation("androidx.compose.animation:animation:1.2.1")
- implementation("androidx.compose.ui:ui-util:1.2.1")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:foundation:foundation"))
api(project(":compose:runtime:runtime"))
@@ -73,19 +39,55 @@
implementation(project(":compose:animation:animation"))
implementation(project(":compose:ui:ui-util"))
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
+ commonTest {
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:foundation:foundation"))
+ api(project(":compose:runtime:runtime"))
+ implementation(project(":compose:animation:animation"))
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:test-utils"))
implementation(libs.testRules)
@@ -94,6 +96,29 @@
implementation(libs.truth)
}
}
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
+ }
+ }
}
}
@@ -105,7 +130,7 @@
// Disable strict API mode for MPP builds as it will fail to compile androidAndroidTest
// sources, as it doesn't understand that they are tests and thinks they should have explicit
// visibility
- legacyDisableKotlinStrictApiMode = AndroidXComposePlugin.isMultiplatformEnabled(project)
+ legacyDisableKotlinStrictApiMode = true
}
android {
diff --git a/compose/material/material-ripple/src/androidAndroidTest/AndroidManifest.xml b/compose/material/material-ripple/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index e865f27..0000000
--- a/compose/material/material-ripple/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
- -->
-<manifest />
diff --git a/compose/material/material-ripple/src/androidMain/AndroidManifest.xml b/compose/material/material-ripple/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/compose/material/material-ripple/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
index 2c574e4..928b4ff 100644
--- a/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
+++ b/compose/material/material-ripple/src/androidMain/kotlin/androidx/compose/material/ripple/Ripple.android.kt
@@ -37,8 +37,8 @@
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.isUnspecified
-import kotlinx.coroutines.CoroutineScope
import kotlin.math.roundToInt
+import kotlinx.coroutines.CoroutineScope
/**
* Android specific Ripple implementation that uses a [RippleDrawable] under the hood, which allows
diff --git a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
index 6005049..b4aa27b 100644
--- a/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
+++ b/compose/material/material-ripple/src/commonMain/kotlin/androidx/compose/material/ripple/RippleAnimation.kt
@@ -33,10 +33,10 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.isUnspecified
import androidx.compose.ui.util.lerp
+import kotlin.math.max
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
-import kotlin.math.max
/**
* [RippleAnimation]s are drawn as part of [Ripple] as a visual indicator for an
diff --git a/compose/material/material-ripple/src/test/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt b/compose/material/material-ripple/src/test/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
index 31838e1..2bb2aec 100644
--- a/compose/material/material-ripple/src/test/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
+++ b/compose/material/material-ripple/src/test/kotlin/androidx/compose/material/ripple/RippleAnimationTest.kt
@@ -19,10 +19,10 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
+import kotlin.math.sqrt
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.math.sqrt
@RunWith(JUnit4::class)
class RippleAnimationTest {
diff --git a/compose/material/material/api/current.txt b/compose/material/material/api/current.txt
index 4eea647..c9c5c53 100644
--- a/compose/material/material/api/current.txt
+++ b/compose/material/material/api/current.txt
@@ -7,7 +7,8 @@
}
public final class AndroidMenu_androidKt {
- method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<? extends kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,? extends kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
diff --git a/compose/material/material/api/public_plus_experimental_current.txt b/compose/material/material/api/public_plus_experimental_current.txt
index d9fe905..7fd3fdd 100644
--- a/compose/material/material/api/public_plus_experimental_current.txt
+++ b/compose/material/material/api/public_plus_experimental_current.txt
@@ -7,7 +7,8 @@
}
public final class AndroidMenu_androidKt {
- method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<? extends kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,? extends kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
@@ -80,7 +81,7 @@
method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? expand(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public androidx.compose.material.BottomDrawerValue getCurrentValue();
- method public Float? getOffset();
+ method public float getOffset();
method public androidx.compose.material.BottomDrawerValue getTargetValue();
method public boolean isClosed();
method public boolean isExpanded();
@@ -90,7 +91,7 @@
property public final boolean isClosed;
property public final boolean isExpanded;
property public final boolean isOpen;
- property public final Float? offset;
+ property public final float offset;
property public final androidx.compose.material.BottomDrawerValue targetValue;
field public static final androidx.compose.material.BottomDrawerState.Companion Companion;
}
@@ -384,7 +385,7 @@
method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public suspend Object? animateTo(androidx.compose.material.DrawerValue targetValue, androidx.compose.animation.core.AnimationSpec<java.lang.Float> anim, kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public suspend Object? close(kotlin.coroutines.Continuation<? super kotlin.Unit>);
method public androidx.compose.material.DrawerValue getCurrentValue();
- method @androidx.compose.material.ExperimentalMaterialApi public Float? getOffset();
+ method @androidx.compose.material.ExperimentalMaterialApi public float getOffset();
method @androidx.compose.material.ExperimentalMaterialApi public androidx.compose.material.DrawerValue getTargetValue();
method public boolean isAnimationRunning();
method public boolean isClosed();
@@ -395,7 +396,7 @@
property public final boolean isAnimationRunning;
property public final boolean isClosed;
property public final boolean isOpen;
- property @androidx.compose.material.ExperimentalMaterialApi public final Float? offset;
+ property @androidx.compose.material.ExperimentalMaterialApi public final float offset;
property @androidx.compose.material.ExperimentalMaterialApi public final androidx.compose.material.DrawerValue targetValue;
field public static final androidx.compose.material.DrawerState.Companion Companion;
}
@@ -426,7 +427,7 @@
}
@androidx.compose.material.ExperimentalMaterialApi @kotlin.jvm.JvmDefaultWithCompatibility public interface ExposedDropdownMenuBoxScope {
- method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.foundation.ScrollState scrollState, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
}
@@ -531,7 +532,7 @@
}
public final class ModalBottomSheetKt {
- method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static void ModalBottomSheetLayout(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> sheetContent, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.material.ModalBottomSheetState sheetState, optional boolean sheetGesturesEnabled, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, androidx.compose.ui.unit.Density density, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
method @Deprecated @androidx.compose.material.ExperimentalMaterialApi public static androidx.compose.material.ModalBottomSheetState ModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean isSkipHalfExpanded);
method @androidx.compose.material.ExperimentalMaterialApi @androidx.compose.runtime.Composable public static androidx.compose.material.ModalBottomSheetState rememberModalBottomSheetState(androidx.compose.material.ModalBottomSheetValue initialValue, optional androidx.compose.animation.core.AnimationSpec<java.lang.Float> animationSpec, optional kotlin.jvm.functions.Function1<? super androidx.compose.material.ModalBottomSheetValue,java.lang.Boolean> confirmValueChange, optional boolean skipHalfExpanded);
diff --git a/compose/material/material/api/restricted_current.txt b/compose/material/material/api/restricted_current.txt
index 4eea647..c9c5c53 100644
--- a/compose/material/material/api/restricted_current.txt
+++ b/compose/material/material/api/restricted_current.txt
@@ -7,7 +7,8 @@
}
public final class AndroidMenu_androidKt {
- method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.foundation.ScrollState scrollState, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @Deprecated @androidx.compose.runtime.Composable public static void DropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<? extends kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, optional long offset, optional androidx.compose.ui.window.PopupProperties properties, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,? extends kotlin.Unit> content);
method @androidx.compose.runtime.Composable public static void DropdownMenuItem(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
}
diff --git a/compose/material/material/build.gradle b/compose/material/material/build.gradle
index 82e2838..3019ae0 100644
--- a/compose/material/material/build.gradle
+++ b/compose/material/material/build.gradle
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
plugins {
@@ -24,70 +24,15 @@
id("AndroidXPaparazziPlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- api("androidx.compose.animation:animation-core:1.2.1")
- api(project(":compose:foundation:foundation"))
- api(project(":compose:material:material-icons-core"))
- api(project(":compose:material:material-ripple"))
- api("androidx.compose.runtime:runtime:1.2.1")
- api("androidx.compose.ui:ui:1.2.1")
- api(project(":compose:ui:ui-text"))
-
- implementation(libs.kotlinStdlibCommon)
- implementation("androidx.compose.animation:animation:1.2.1")
- implementation("androidx.compose.foundation:foundation-layout:1.2.1")
- implementation("androidx.compose.ui:ui-util:1.2.1")
-
- // TODO: remove next 3 dependencies when b/202810604 is fixed
- implementation("androidx.savedstate:savedstate:1.2.1")
- implementation("androidx.lifecycle:lifecycle-runtime:2.6.1")
- implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:material:material:material-samples"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":test:screenshot:screenshot"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.mockitoKotlin)
- androidTestImplementation(libs.testUiautomator)
-
- lintPublish project(":compose:material:material-lint")
-
- samples(project(":compose:material:material:material-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
-
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:animation:animation-core"))
api(project(":compose:foundation:foundation"))
@@ -101,8 +46,37 @@
implementation(project(":compose:foundation:foundation-layout"))
implementation(project(":compose:ui:ui-util"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:animation:animation-core"))
+ api(project(":compose:runtime:runtime"))
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-text"))
+ implementation(project(":compose:animation:animation"))
+ implementation(project(":compose:foundation:foundation-layout"))
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
// TODO: remove next 3 dependencies when b/202810604 is fixed
@@ -110,23 +84,27 @@
implementation("androidx.lifecycle:lifecycle-runtime:2.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ }
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:material:material:material-samples"))
implementation(project(":compose:test-utils"))
implementation(project(":test:screenshot:screenshot"))
@@ -140,18 +118,39 @@
implementation(libs.mockitoKotlin)
implementation(libs.testUiautomator)
}
+ }
- desktopTest.dependencies {
- implementation(project(":compose:ui:ui-test-junit4"))
- implementation(libs.truth)
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
implementation(libs.junit)
- implementation(libs.skikoCurrentOs)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ implementation(project(":compose:ui:ui-test-junit4"))
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.skikoCurrentOs)
+ }
}
}
}
- dependencies {
- samples(project(":compose:material:material:material-samples"))
- }
+}
+
+dependencies {
+ lintPublish project(":compose:material:material-lint")
}
androidx {
diff --git a/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconGenerationTask.kt b/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconGenerationTask.kt
index 2fe5d63..f264ab4 100644
--- a/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconGenerationTask.kt
+++ b/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconGenerationTask.kt
@@ -19,24 +19,24 @@
import androidx.compose.material.icons.generator.Icon
import androidx.compose.material.icons.generator.IconProcessor
import com.android.build.gradle.LibraryExtension
+import java.io.File
+import java.util.Locale
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskProvider
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-import java.io.File
-import java.util.Locale
/**
* Base [org.gradle.api.Task] for tasks relating to icon generation.
@@ -157,15 +157,10 @@
@JvmStatic
fun registerExtendedIconThemeProject(
project: Project,
- libraryExtension: LibraryExtension,
- isMpp: Boolean
+ libraryExtension: LibraryExtension
) {
- if (isMpp) {
- ExtendedIconGenerationTask.register(project, null)
- } else {
- libraryExtension.libraryVariants.all { variant ->
- ExtendedIconGenerationTask.register(project, variant)
- }
+ libraryExtension.libraryVariants.all { variant ->
+ ExtendedIconGenerationTask.register(project, variant)
}
// b/175401659 - disable lint as it takes a long time, and most errors should
diff --git a/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconSourceTasks.kt b/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconSourceTasks.kt
index 4e62a3d..9e8c3fe 100644
--- a/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconSourceTasks.kt
+++ b/compose/material/material/icons/generator/src/main/kotlin/androidx/compose/material/icons/generator/tasks/IconSourceTasks.kt
@@ -18,12 +18,12 @@
import androidx.compose.material.icons.generator.CoreIcons
import androidx.compose.material.icons.generator.IconWriter
+import java.io.File
import org.gradle.api.Project
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-import java.io.File
/**
* Task responsible for converting core icons from xml to a programmatic representation.
diff --git a/compose/material/material/icons/generator/src/test/kotlin/androidx/compose/material/icons/generator/IconProcessorTest.kt b/compose/material/material/icons/generator/src/test/kotlin/androidx/compose/material/icons/generator/IconProcessorTest.kt
index 0e11d8c..15c45cb 100644
--- a/compose/material/material/icons/generator/src/test/kotlin/androidx/compose/material/icons/generator/IconProcessorTest.kt
+++ b/compose/material/material/icons/generator/src/test/kotlin/androidx/compose/material/icons/generator/IconProcessorTest.kt
@@ -17,13 +17,13 @@
package androidx.compose.material.icons.generator
import com.google.common.truth.Truth
+import java.io.File
import org.junit.Assert.fail
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.File
/**
* Test for [IconProcessor].
diff --git a/compose/material/material/integration-tests/material-catalog/src/main/AndroidManifest.xml b/compose/material/material/integration-tests/material-catalog/src/main/AndroidManifest.xml
deleted file mode 100644
index ccc91d4..0000000
--- a/compose/material/material/integration-tests/material-catalog/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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
- -->
-
-<manifest />
diff --git a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/model/Examples.kt b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/model/Examples.kt
index ccbd6ff..4154cf1 100644
--- a/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/model/Examples.kt
+++ b/compose/material/material/integration-tests/material-catalog/src/main/java/androidx/compose/material/catalog/library/model/Examples.kt
@@ -25,8 +25,8 @@
import androidx.compose.material.samples.AlertDialogSample
import androidx.compose.material.samples.BackdropScaffoldSample
import androidx.compose.material.samples.BottomDrawerSample
-import androidx.compose.material.samples.BottomNavigationSample
import androidx.compose.material.samples.BottomNavigationItemWithBadge
+import androidx.compose.material.samples.BottomNavigationSample
import androidx.compose.material.samples.BottomNavigationWithOnlySelectedLabelsSample
import androidx.compose.material.samples.BottomSheetScaffoldSample
import androidx.compose.material.samples.ButtonSample
@@ -50,6 +50,7 @@
import androidx.compose.material.samples.LeadingIconTabs
import androidx.compose.material.samples.LinearProgressIndicatorSample
import androidx.compose.material.samples.MenuSample
+import androidx.compose.material.samples.MenuWithScrollStateSample
import androidx.compose.material.samples.ModalBottomSheetSample
import androidx.compose.material.samples.ModalDrawerSample
import androidx.compose.material.samples.NavigationRailBottomAlignSample
@@ -398,6 +399,13 @@
MenuSample()
},
Example(
+ name = ::MenuWithScrollStateSample.name,
+ description = MenusExampleDescription,
+ sourceUrl = MenusExampleSourceUrl
+ ) {
+ MenuWithScrollStateSample()
+ },
+ Example(
name = ::ExposedDropdownMenuSample.name,
description = MenusExampleDescription,
sourceUrl = MenusExampleSourceUrl
@@ -703,14 +711,18 @@
description = TextFieldsExampleDescription,
sourceUrl = TextFieldsExampleSourceUrl
) {
- TextArea()
+ TextArea()
}
).map {
// By default text field samples are minimal and don't have a `width` modifier to restrict the
// width. As a result, they grow horizontally if enough text is typed. To prevent this behavior
// in Catalog app the code below restricts the width of every text field sample
it.copy(content = {
- Box(Modifier.wrapContentWidth().width(280.dp)) { it.content() }
+ Box(
+ Modifier
+ .wrapContentWidth()
+ .width(280.dp)
+ ) { it.content() }
})
}
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BadgeDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BadgeDemo.kt
index 0330c3c5..e03a6c9 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BadgeDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/BadgeDemo.kt
@@ -41,6 +41,7 @@
import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -56,7 +57,7 @@
@Composable
fun BadgeDemo() {
Column(Modifier.verticalScroll(rememberScrollState())) {
- var badgeCount by remember { mutableStateOf(8) }
+ var badgeCount by remember { mutableIntStateOf(8) }
Spacer(Modifier.requiredHeight(24.dp))
TopAppBarWithBadge(
{ badgeCount = 0 },
@@ -146,7 +147,7 @@
onArtistsBadgeClick: () -> Unit,
artistsBadgeCount: Int
) {
- var selectedItem by remember { mutableStateOf(initialSelectedIndex) }
+ var selectedItem by remember { mutableIntStateOf(initialSelectedIndex) }
val items = listOf("Songs", "Artists", "Playlists", "Something else")
var showSongsBadge by remember { mutableStateOf(true) }
@@ -222,7 +223,7 @@
onTab1BadgeClick: () -> Unit,
tab1BadgeCount: Int
) {
- var state by remember { mutableStateOf(initialSelectedIndex) }
+ var state by remember { mutableIntStateOf(initialSelectedIndex) }
val titles = listOf("TAB 1", "TAB 2", "TAB 3 WITH LOTS OF TEXT")
val showTabBadgeList = remember { mutableStateListOf(true, true) }
@@ -277,7 +278,7 @@
onTab1BadgeClick: () -> Unit,
tab1BadgeCount: Int,
) {
- var state by remember { mutableStateOf(0) }
+ var state by remember { mutableIntStateOf(0) }
val titlesAndIcons = listOf(
"TAB" to Icons.Filled.Favorite,
"TAB & ICON" to Icons.Filled.Favorite,
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
index 4aff510..a2e1d22 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ColorPickerDemo.kt
@@ -24,8 +24,8 @@
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/DynamicThemeActivity.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/DynamicThemeActivity.kt
index 9cd8b82..8612e36 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/DynamicThemeActivity.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/DynamicThemeActivity.kt
@@ -23,8 +23,8 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
@@ -42,7 +42,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -57,12 +57,12 @@
* as the user scrolls. This has the effect of going from a 'light' theme to a 'dark' theme.
*/
class DynamicThemeActivity : ComponentActivity() {
- private val scrollFraction = mutableStateOf(0f)
+ private val scrollFraction = mutableFloatStateOf(0f)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- val palette = interpolateTheme(scrollFraction.value)
+ val palette = interpolateTheme(scrollFraction.floatValue)
val darkenedPrimary = palette.darkenedPrimary
window.statusBarColor = darkenedPrimary
window.navigationBarColor = darkenedPrimary
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialDemos.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialDemos.kt
index 6eaf8ed..111e82d 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialDemos.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialDemos.kt
@@ -22,12 +22,12 @@
import androidx.compose.material.samples.AlertDialogSample
import androidx.compose.material.samples.BackdropScaffoldSample
import androidx.compose.material.samples.BottomDrawerSample
-import androidx.compose.material.samples.CustomAlertDialogSample
-import androidx.compose.material.samples.ModalBottomSheetSample
-import androidx.compose.material.samples.ModalDrawerSample
import androidx.compose.material.samples.BottomSheetScaffoldSample
import androidx.compose.material.samples.ContentAlphaSample
+import androidx.compose.material.samples.CustomAlertDialogSample
import androidx.compose.material.samples.CustomPullRefreshSample
+import androidx.compose.material.samples.ModalBottomSheetSample
+import androidx.compose.material.samples.ModalDrawerSample
import androidx.compose.material.samples.PullRefreshIndicatorTransformSample
import androidx.compose.material.samples.PullRefreshSample
import androidx.compose.material.samples.ScaffoldWithBottomBarAndCutout
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
index 858e9de..77c8de6 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MaterialTextField.kt
@@ -24,12 +24,12 @@
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredHeightIn
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MenuDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MenuDemo.kt
index caf5517..c5cb10f 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MenuDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/MenuDemo.kt
@@ -33,10 +33,10 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ProgressIndicatorDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ProgressIndicatorDemo.kt
index f1f3651..c3edd69 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ProgressIndicatorDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/ProgressIndicatorDemo.kt
@@ -18,9 +18,9 @@
import android.os.Handler
import android.os.Looper
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -36,7 +36,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -92,7 +92,7 @@
}
private class ProgressState {
- var progress by mutableStateOf(0f)
+ var progress by mutableFloatStateOf(0f)
fun start() {
handler.postDelayed(updateProgress, 500)
diff --git a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/TabDemo.kt b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/TabDemo.kt
index 43a42d1..2837fc3 100644
--- a/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/TabDemo.kt
+++ b/compose/material/material/integration-tests/material-demos/src/main/java/androidx/compose/material/demos/TabDemo.kt
@@ -18,8 +18,8 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Button
@@ -29,10 +29,10 @@
import androidx.compose.material.samples.FancyIndicatorTabs
import androidx.compose.material.samples.FancyTabs
import androidx.compose.material.samples.IconTabs
+import androidx.compose.material.samples.LeadingIconTabs
import androidx.compose.material.samples.ScrollingFancyIndicatorContainerTabs
import androidx.compose.material.samples.ScrollingTextTabs
import androidx.compose.material.samples.TextAndIconTabs
-import androidx.compose.material.samples.LeadingIconTabs
import androidx.compose.material.samples.TextTabs
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/material/material/samples/build.gradle b/compose/material/material/samples/build.gradle
index 0b5f612..73cef10 100644
--- a/compose/material/material/samples/build.gradle
+++ b/compose/material/material/samples/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "AndroidX Compose Material Components Samples"
+ name = "Compose Material Components Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the AndroidX Compose Material components."
diff --git a/compose/material/material/samples/src/main/AndroidManifest.xml b/compose/material/material/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index dc2f180..0000000
--- a/compose/material/material/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/BottomSheetScaffoldSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/BottomSheetScaffoldSamples.kt
index 85a3567..d9155c8 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/BottomSheetScaffoldSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/BottomSheetScaffoldSamples.kt
@@ -22,8 +22,8 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.BottomSheetScaffold
import androidx.compose.material.Button
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/MenuSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/MenuSamples.kt
index bf6f420..f9c6a77 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/MenuSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/MenuSamples.kt
@@ -20,6 +20,7 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.Divider
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
@@ -29,6 +30,7 @@
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
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
@@ -41,7 +43,9 @@
fun MenuSample() {
var expanded by remember { mutableStateOf(false) }
- Box(modifier = Modifier.fillMaxSize().wrapContentSize(Alignment.TopStart)) {
+ Box(modifier = Modifier
+ .fillMaxSize()
+ .wrapContentSize(Alignment.TopStart)) {
IconButton(onClick = { expanded = true }) {
Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
}
@@ -61,4 +65,37 @@
}
}
}
-}
\ No newline at end of file
+}
+
+@Sampled
+@Composable
+fun MenuWithScrollStateSample() {
+ var expanded by remember { mutableStateOf(false) }
+ val scrollState = rememberScrollState()
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .wrapContentSize(Alignment.TopStart)
+ ) {
+ IconButton(onClick = { expanded = true }) {
+ Icon(Icons.Default.MoreVert, contentDescription = "Localized description")
+ }
+ DropdownMenu(
+ expanded = expanded,
+ onDismissRequest = { expanded = false },
+ scrollState = scrollState
+ ) {
+ repeat(30) {
+ DropdownMenuItem(onClick = { /* Handle item! */ }) {
+ Text("Item ${it + 1}")
+ }
+ }
+ }
+ LaunchedEffect(expanded) {
+ if (expanded) {
+ // Scroll to show the bottom menu items.
+ scrollState.scrollTo(scrollState.maxValue)
+ }
+ }
+ }
+}
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ScaffoldSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ScaffoldSamples.kt
index 370b121..66e071f 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ScaffoldSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/ScaffoldSamples.kt
@@ -57,12 +57,12 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
+import kotlin.math.abs
+import kotlin.math.roundToInt
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
-import kotlin.math.abs
-import kotlin.math.roundToInt
private val colors = listOf(
Color(0xFFffd7d7.toInt()),
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
index cdad91a..dd3ae10 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SelectionControlsSamples.kt
@@ -17,18 +17,18 @@
package androidx.compose.material.samples
import androidx.annotation.Sampled
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.width
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.Checkbox
import androidx.compose.material.CheckboxDefaults
@@ -38,22 +38,22 @@
import androidx.compose.material.Text
import androidx.compose.material.TriStateCheckbox
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.input.InputMode.Companion.Keyboard
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalInputModeManager
-import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.role
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.ExperimentalComposeUiApi
@Sampled
@Composable
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SwipeableSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SwipeableSamples.kt
index e38cd70..afe146a 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SwipeableSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/SwipeableSamples.kt
@@ -18,6 +18,7 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
@@ -30,7 +31,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
diff --git a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TabSamples.kt b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TabSamples.kt
index 93f09c5..6ac79a1 100644
--- a/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TabSamples.kt
+++ b/compose/material/material/samples/src/main/java/androidx/compose/material/samples/TabSamples.kt
@@ -29,21 +29,21 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
+import androidx.compose.material.LeadingIconTab
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ScrollableTabRow
import androidx.compose.material.Tab
-import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material.TabPosition
import androidx.compose.material.TabRow
-import androidx.compose.material.LeadingIconTab
+import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
diff --git a/compose/material/material/src/androidAndroidTest/AndroidManifest.xml b/compose/material/material/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/compose/material/material/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
index 7af8d54..64a43ff 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/BottomNavigationTest.kt
@@ -199,24 +199,24 @@
.getUnclippedBoundsInRoot()
val textBounds = rule.onNodeWithText("ItemText").getUnclippedBoundsInRoot()
- // Distance from the bottom to the text baseline and from the text baseline to the
- // bottom of the icon
+ val topPadding = 8.dp
+ // Distance from the text baseline to the bottom of the icon
val textBaseline = 12.dp
// Relative position of the baseline to the top of text
- val relativeTextBaseline = rule.onNodeWithText("ItemText").getLastBaselinePosition()
+ val relativeTextBaseline = rule.onNodeWithText("ItemText").getFirstBaselinePosition()
// Absolute y position of the text baseline
val absoluteTextBaseline = textBounds.top + relativeTextBaseline
- val itemBottom = itemBounds.height + itemBounds.top
- // Text baseline should be 12.dp from the bottom of the item
- absoluteTextBaseline.assertIsEqualTo(itemBottom - textBaseline)
+ val iconBottom = iconBounds.height + iconBounds.top
+ // Text baseline should be 12.dp from the bottom of the icon
+ absoluteTextBaseline.assertIsEqualTo(iconBottom + textBaseline)
rule.onNodeWithTag("icon", useUnmergedTree = true)
- // The icon should be centered in the item
+ // The icon should be horizontally centered in the item
.assertLeftPositionInRootIsEqualTo((itemBounds.width - iconBounds.width) / 2)
- // The bottom of the icon is 12.dp above the text baseline
- .assertTopPositionInRootIsEqualTo(absoluteTextBaseline - 12.dp - iconBounds.height)
+ // The icon is 8.dp from the top
+ .assertTopPositionInRootIsEqualTo(topPadding)
}
@Test
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonTest.kt
index 323ee25..863e352 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ButtonTest.kt
@@ -79,10 +79,10 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import kotlin.math.abs
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.abs
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxTest.kt
index 7d233e4..64005ba 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/CheckboxTest.kt
@@ -28,18 +28,18 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.focused
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.state.ToggleableState
import androidx.compose.ui.state.ToggleableState.Indeterminate
import androidx.compose.ui.state.ToggleableState.Off
import androidx.compose.ui.state.ToggleableState.On
-import androidx.compose.ui.test.assertHasClickAction
-import androidx.compose.ui.test.assertHasNoClickAction
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertHasNoClickAction
import androidx.compose.ui.test.assertHeightIsEqualTo
import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsOff
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DividerUiTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DividerUiTest.kt
index 5b9920e..5609447 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DividerUiTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/DividerUiTest.kt
@@ -37,10 +37,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ExposedDropdownMenuTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ExposedDropdownMenuTest.kt
index 17c6cc8..23300d9 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ExposedDropdownMenuTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ExposedDropdownMenuTest.kt
@@ -22,7 +22,9 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.rememberScrollState
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
@@ -35,9 +37,11 @@
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsFocused
+import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.assertTextContains
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
@@ -336,6 +340,47 @@
// Should not have crashed.
}
+ @Test
+ fun withScrolledContent() {
+ rule.setMaterialContent {
+ Box(Modifier.fillMaxSize()) {
+ ExposedDropdownMenuBox(
+ modifier = Modifier.align(Alignment.Center),
+ expanded = true,
+ onExpandedChange = { }
+ ) {
+ val scrollState = rememberScrollState()
+ TextField(
+ value = "",
+ onValueChange = { },
+ label = { Text("Label") },
+ )
+ ExposedDropdownMenu(
+ expanded = true,
+ onDismissRequest = { },
+ scrollState = scrollState
+ ) {
+ repeat(100) {
+ Box(
+ Modifier
+ .testTag("MenuContent ${it + 1}")
+ .size(with(LocalDensity.current) { 70.toDp() })
+ )
+ }
+ }
+ LaunchedEffect(Unit) {
+ scrollState.scrollTo(scrollState.maxValue)
+ }
+ }
+ }
+ }
+
+ rule.waitForIdle()
+
+ rule.onNodeWithTag("MenuContent 1").assertIsNotDisplayed()
+ rule.onNodeWithTag("MenuContent 100").assertIsDisplayed()
+ }
+
@Composable
fun ExposedDropdownMenuForTest(
expanded: Boolean,
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonTest.kt
index bfb6224..6ae0c2a 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/FloatingActionButtonTest.kt
@@ -20,8 +20,8 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/IconTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/IconTest.kt
index 77af7e3..e22a0c14 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/IconTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/IconTest.kt
@@ -26,8 +26,8 @@
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
-import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ListItemTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ListItemTest.kt
index c16b858..e1e7ffd 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ListItemTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ListItemTest.kt
@@ -37,10 +37,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MenuTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MenuTest.kt
index ace0f2a..4d0270f 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MenuTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/MenuTest.kt
@@ -19,8 +19,10 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.requiredSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@@ -29,6 +31,8 @@
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.hasAnyDescendant
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.isPopup
@@ -36,11 +40,11 @@
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
@@ -128,6 +132,42 @@
}
@Test
+ fun menu_scrolledContent() {
+ rule.setContent {
+ with(LocalDensity.current) {
+ Box(
+ Modifier
+ .requiredSize(20.toDp())
+ .background(color = Color.Blue)
+ ) {
+ val scrollState = rememberScrollState()
+ DropdownMenu(
+ expanded = true,
+ onDismissRequest = {},
+ scrollState = scrollState
+ ) {
+ repeat(100) {
+ Box(
+ Modifier
+ .testTag("MenuContent ${it + 1}")
+ .size(70.toDp())
+ )
+ }
+ }
+ LaunchedEffect(Unit) {
+ scrollState.scrollTo(scrollState.maxValue)
+ }
+ }
+ }
+ }
+
+ rule.waitForIdle()
+
+ rule.onNodeWithTag("MenuContent 1").assertIsNotDisplayed()
+ rule.onNodeWithTag("MenuContent 100").assertIsDisplayed()
+ }
+
+ @Test
fun menu_positioning_bottomEnd() {
val screenWidth = 500
val screenHeight = 1000
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
index 9043b15..d5d6e55 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ModalBottomSheetTest.kt
@@ -36,6 +36,10 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.testTag
@@ -56,11 +60,13 @@
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeDown
import androidx.compose.ui.test.swipeUp
+import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.coerceAtMost
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@@ -875,6 +881,7 @@
}
}
},
+ sheetGesturesEnabled = true,
content = { Box(Modifier.fillMaxSize()) }
)
}
@@ -926,6 +933,53 @@
}
@Test
+ fun modalBottomSheet_gesturesDisabled_doesNotParticipateInNestedScroll() =
+ runBlocking(AutoTestFrameClock()) {
+ lateinit var sheetState: ModalBottomSheetState
+ val sheetContentTag = "sheetContent"
+ val scrollConnection = object : NestedScrollConnection {}
+ val scrollDispatcher = NestedScrollDispatcher()
+ val sheetHeight = 300.dp
+ val sheetHeightPx = with(rule.density) { sheetHeight.toPx() }
+
+ rule.setContent {
+ sheetState = rememberModalBottomSheetState(
+ initialValue = ModalBottomSheetValue.Expanded,
+ )
+ ModalBottomSheetLayout(
+ sheetState = sheetState,
+ sheetContent = {
+ Box(
+ Modifier
+ .fillMaxWidth()
+ .requiredHeight(sheetHeight)
+ .nestedScroll(scrollConnection, scrollDispatcher)
+ .testTag(sheetContentTag),
+ )
+ },
+ sheetGesturesEnabled = false,
+ content = { Box(Modifier.fillMaxSize()) },
+ )
+ }
+
+ assertThat(sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Expanded)
+
+ val offsetBeforeScroll = sheetState.requireOffset()
+ scrollDispatcher.dispatchPreScroll(
+ Offset(x = 0f, y = -sheetHeightPx),
+ NestedScrollSource.Drag,
+ )
+ rule.waitForIdle()
+ assertWithMessage("Offset after scroll is equal to offset before scroll")
+ .that(sheetState.requireOffset()).isEqualTo(offsetBeforeScroll)
+
+ val highFlingVelocity = Velocity(x = 0f, y = with(rule.density) { 500.dp.toPx() })
+ scrollDispatcher.dispatchPreFling(highFlingVelocity)
+ rule.waitForIdle()
+ assertThat(sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Expanded)
+ }
+
+ @Test
fun modalBottomSheet_anchorsChange_retainsCurrentValue() {
lateinit var state: ModalBottomSheetState
var amountOfItems by mutableStateOf(0)
@@ -1266,7 +1320,7 @@
ModalBottomSheetState(ModalBottomSheetValue.HalfExpanded, density = rule.density)
assertThat(sheetState.anchoredDraggableState.anchors).isEmpty()
- assertThat(sheetState.anchoredDraggableState.offset).isNull()
+ assertThat(sheetState.anchoredDraggableState.offset).isNaN()
stateRestorationTester.emulateSavedInstanceStateRestore()
rule.waitForIdle()
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ObservableThemeTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ObservableThemeTest.kt
index b3ed829..b653c19 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ObservableThemeTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/ObservableThemeTest.kt
@@ -18,9 +18,9 @@
import androidx.activity.ComponentActivity
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
index d34df51..04cd5e3 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/RadioButtonTest.kt
@@ -21,8 +21,8 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.SemanticsProperties
import androidx.compose.ui.semantics.focused
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.test.SemanticsMatcher
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
index 5feb341..7eff0db 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SnackbarHostTest.kt
@@ -34,10 +34,6 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth
-import org.mockito.kotlin.any
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
@@ -47,6 +43,10 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.AdditionalMatchers.not
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
index 126b642..26b529d 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwipeableTest.kt
@@ -51,6 +51,7 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.sign
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
@@ -61,7 +62,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.sign
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
index 01414b2..cb03029 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/SwitchScreenshotTest.kt
@@ -29,10 +29,10 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.InputMode
import androidx.compose.ui.input.InputModeManager
import androidx.compose.ui.platform.LocalInputModeManager
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
index b791476..d666189 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/OutlinedTextFieldTest.kt
@@ -100,16 +100,16 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import kotlin.math.max
import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
@MediumTest
@RunWith(AndroidJUnit4::class)
@@ -425,6 +425,28 @@
}
@Test
+ fun testOutlinedTextField_labelHeight_contributesToTextFieldMeasurements_whenUnfocused() {
+ val tfSize = Ref<IntSize>()
+ val labelHeight = 200.dp
+ rule.setMaterialContent {
+ OutlinedTextField(
+ value = "",
+ onValueChange = {},
+ modifier = Modifier.testTag(TextfieldTag).onGloballyPositioned {
+ tfSize.value = it.size
+ },
+ label = {
+ Box(Modifier.size(width = 50.dp, height = labelHeight))
+ },
+ )
+ }
+
+ rule.runOnIdleWithDensity {
+ assertThat(tfSize.value!!.height).isAtLeast(labelHeight.roundToPx())
+ }
+ }
+
+ @Test
fun testOutlinedTextField_labelWidth_isNotAffectedByTrailingIcon_whenFocused() {
val textFieldWidth = 100.dp
val labelRequestedWidth = 65.dp
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldDecorationBoxTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldDecorationBoxTest.kt
index f3fecc2..777adeb 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldDecorationBoxTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldDecorationBoxTest.kt
@@ -38,6 +38,8 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertPixels
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
@@ -523,6 +525,7 @@
) {
var size: IntSize? = null
var position: Offset? = null
+ val focusRequester = FocusRequester()
rule.setMaterialContent {
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
@@ -534,6 +537,7 @@
BasicTextField(
value = value,
onValueChange = {},
+ modifier = Modifier.focusRequester(focusRequester),
singleLine = singleLine,
interactionSource = interactionSource
) {
@@ -560,6 +564,10 @@
}
}
+ rule.runOnUiThread {
+ focusRequester.requestFocus()
+ }
+
rule.runOnIdle {
with(Density) {
assertThat(size).isNotNull()
@@ -624,6 +632,7 @@
) {
var size: IntSize? = null
var position: Offset? = null
+ val focusRequester = FocusRequester()
rule.setMaterialContent {
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
@@ -635,6 +644,7 @@
BasicTextField(
value = value,
onValueChange = {},
+ modifier = Modifier.focusRequester(focusRequester),
singleLine = singleLine,
interactionSource = interactionSource
) {
@@ -664,6 +674,10 @@
}
}
+ rule.runOnUiThread {
+ focusRequester.requestFocus()
+ }
+
rule.runOnIdle {
with(Density) {
assertThat(size).isNotNull()
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
index 63a61ef..e57bdd9 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/textfield/TextFieldTest.kt
@@ -20,21 +20,21 @@
import android.os.Build
import android.view.View
import android.view.inputmethod.InputMethodManager
+import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.FocusInteraction
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.Divider
@@ -116,18 +116,18 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material/material/src/androidMain/AndroidManifest.xml b/compose/material/material/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/compose/material/material/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
index 94c0373..e1bd14d 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/AndroidMenu.android.kt
@@ -17,11 +17,13 @@
package androidx.compose.material
import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -70,6 +72,15 @@
* tapping outside the menu's bounds
* @param offset [DpOffset] to be added to the position of the menu
*/
+@Deprecated(
+ level = DeprecationLevel.HIDDEN,
+ replaceWith = ReplaceWith(
+ expression = "DropdownMenu(expanded,onDismissRequest, modifier, offset, " +
+ "rememberScrollState(), properties, content)",
+ "androidx.compose.foundation.rememberScrollState"
+ ),
+ message = "Replaced by a DropdownMenu function with a ScrollState parameter"
+)
@Composable
fun DropdownMenu(
expanded: Boolean,
@@ -78,6 +89,69 @@
offset: DpOffset = DpOffset(0.dp, 0.dp),
properties: PopupProperties = PopupProperties(focusable = true),
content: @Composable ColumnScope.() -> Unit
+) = DropdownMenu(
+ expanded = expanded,
+ onDismissRequest = onDismissRequest,
+ modifier = modifier,
+ offset = offset,
+ scrollState = rememberScrollState(),
+ properties = properties,
+ content = content
+)
+
+/**
+ * <a href="https://material.io/components/menus#dropdown-menu" class="external" target="_blank">Material Design dropdown menu</a>.
+ *
+ * A dropdown menu is a compact way of displaying multiple choices. It appears upon interaction with
+ * an element (such as an icon or button) or when users perform a specific action.
+ *
+ * ![Menus image](https://developer.android.com/images/reference/androidx/compose/material/menus.png)
+ *
+ * A [DropdownMenu] behaves similarly to a [Popup], and will use the position of the parent layout
+ * to position itself on screen. Commonly a [DropdownMenu] will be placed in a [Box] with a sibling
+ * that will be used as the 'anchor'. Note that a [DropdownMenu] by itself will not take up any
+ * space in a layout, as the menu is displayed in a separate window, on top of other content.
+ *
+ * The [content] of a [DropdownMenu] will typically be [DropdownMenuItem]s, as well as custom
+ * content. Using [DropdownMenuItem]s will result in a menu that matches the Material
+ * specification for menus. Also note that the [content] is placed inside a scrollable [Column],
+ * so using a [LazyColumn] as the root layout inside [content] is unsupported.
+ *
+ * [onDismissRequest] will be called when the menu should close - for example when there is a
+ * tap outside the menu, or when the back key is pressed.
+ *
+ * [DropdownMenu] changes its positioning depending on the available space, always trying to be
+ * fully visible. It will try to expand horizontally, depending on layout direction, to the end of
+ * its parent, then to the start of its parent, and then screen end-aligned. Vertically, it will
+ * try to expand to the bottom of its parent, then from the top of its parent, and then screen
+ * top-aligned. An [offset] can be provided to adjust the positioning of the menu for cases when
+ * the layout bounds of its parent do not coincide with its visual bounds. Note the offset will
+ * be applied in the direction in which the menu will decide to expand.
+ *
+ * Example usage:
+ * @sample androidx.compose.material.samples.MenuSample
+ *
+ * Example usage with a [ScrollState] to control the menu items scroll position:
+ * @sample androidx.compose.material.samples.MenuWithScrollStateSample
+ *
+ * @param expanded whether the menu is expanded or not
+ * @param onDismissRequest called when the user requests to dismiss the menu, such as by tapping
+ * outside the menu's bounds
+ * @param modifier [Modifier] to be applied to the menu's content
+ * @param offset [DpOffset] to be added to the position of the menu
+ * @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
+ * @param properties [PopupProperties] for further customization of this popup's behavior
+ * @param content the content of this dropdown menu, typically a [DropdownMenuItem]
+ */
+@Composable
+fun DropdownMenu(
+ expanded: Boolean,
+ onDismissRequest: () -> Unit,
+ modifier: Modifier = Modifier,
+ offset: DpOffset = DpOffset(0.dp, 0.dp),
+ scrollState: ScrollState = rememberScrollState(),
+ properties: PopupProperties = PopupProperties(focusable = true),
+ content: @Composable ColumnScope.() -> Unit
) {
val expandedStates = remember { MutableTransitionState(false) }
expandedStates.targetState = expanded
@@ -100,6 +174,7 @@
DropdownMenuContent(
expandedStates = expandedStates,
transformOriginState = transformOriginState,
+ scrollState = scrollState,
modifier = modifier,
content = content
)
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
index 4a46e56..7cba51b 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/ExposedDropdownMenu.kt
@@ -21,6 +21,7 @@
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.tween
+import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.waitForUpOrCancellation
@@ -30,6 +31,7 @@
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.material.internal.ExposedDropdownMenuPopup
@@ -39,6 +41,7 @@
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -93,8 +96,8 @@
) {
val density = LocalDensity.current
val view = LocalView.current
- var width by remember { mutableStateOf(0) }
- var menuHeight by remember { mutableStateOf(0) }
+ var width by remember { mutableIntStateOf(0) }
+ var menuHeight by remember { mutableIntStateOf(0) }
val verticalMarginInPx = with(density) { MenuVerticalMargin.roundToPx() }
val coordinates = remember { Ref<LayoutCoordinates>() }
@@ -223,6 +226,7 @@
* @param onDismissRequest Called when the user requests to dismiss the menu, such as by
* tapping outside the menu's bounds
* @param modifier The modifier to apply to this layout
+ * @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
* @param content The content of the [ExposedDropdownMenu]
*/
@Composable
@@ -230,6 +234,7 @@
expanded: Boolean,
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
+ scrollState: ScrollState = rememberScrollState(),
content: @Composable ColumnScope.() -> Unit
) {
// TODO(b/202810604): use DropdownMenu when PopupProperties constructor is stable
@@ -261,6 +266,7 @@
DropdownMenuContent(
expandedStates = expandedStates,
transformOriginState = transformOriginState,
+ scrollState = scrollState,
modifier = modifier.exposedDropdownSize(),
content = content
)
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.kt
index 006240b..d6f140d 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.kt
@@ -65,8 +65,8 @@
import androidx.compose.ui.util.fastMap
import androidx.compose.ui.window.PopupPositionProvider
import androidx.lifecycle.findViewTreeLifecycleOwner
-import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
index 6e204b8..c93036a 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/AnchoredDraggable.kt
@@ -31,6 +31,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
@@ -168,37 +169,38 @@
val targetValue: T by derivedStateOf {
animationTarget ?: run {
val currentOffset = offset
- if (currentOffset != null) {
+ if (!currentOffset.isNaN()) {
computeTarget(currentOffset, currentValue, velocity = 0f)
} else currentValue
}
}
/**
- * The current offset, or null if it has not been initialized yet.
+ * The current offset, or [Float.NaN] if it has not been initialized yet.
*
- * The offset will be initialized during the first measurement phase of the node that the
- * [anchoredDraggable] modifier is attached to. These are the phases:
- * Composition { -> Effects } -> Layout { Measurement -> Placement } -> Drawing
- * During the first composition, the offset will be null. In subsequent compositions, the offset
- * will be derived from the anchors of the previous pass.
- * Always prefer accessing the offset from a LaunchedEffect as it will be scheduled to be
- * executed the next frame, after layout.
+ * The offset will be initialized when the anchors are first set through [updateAnchors].
*
- * To guarantee stricter semantics, consider using [requireOffset].
+ * Strongly consider using [requireOffset] which will throw if the offset is read before it is
+ * initialized. This helps catch issues early in your workflow.
*/
- @get:Suppress("AutoBoxing")
- var offset: Float? by mutableStateOf(null)
+ // Todo: Use primitive state when b/281205384 is fixed
+ @Suppress("AutoboxingStateCreation")
+ var offset: Float by mutableStateOf(Float.NaN)
private set
/**
* Require the current offset.
*
+ * @see offset
+ *
* @throws IllegalStateException If the offset has not been initialized yet
*/
- fun requireOffset(): Float = checkNotNull(offset) {
- "The offset was read before being initialized. Did you access the offset in a phase " +
- "before layout, like effects or composition?"
+ fun requireOffset(): Float {
+ check(!offset.isNaN()) {
+ "The offset was read before being initialized. Did you access the offset in a phase " +
+ "before layout, like effects or composition?"
+ }
+ return offset
}
/**
@@ -228,7 +230,7 @@
* You can use this value to provide smooth reconciliation behavior when re-targeting an
* animation.
*/
- var lastVelocity: Float by mutableStateOf(0f)
+ var lastVelocity: Float by mutableFloatStateOf(0f)
private set
/**
@@ -412,12 +414,12 @@
}
} finally {
if (targetValue != null) animationTarget = null
- val endState = offset?.let { endOffset ->
+ val endState =
anchors
.entries
- .firstOrNull { (_, anchorOffset) -> abs(anchorOffset - endOffset) < 0.5f }
+ .firstOrNull { (_, anchorOffset) -> abs(anchorOffset - offset) < 0.5f }
?.key
- }
+
if (endState != null && confirmValueChange.invoke(endState)) {
currentValue = endState
}
@@ -428,7 +430,7 @@
}
internal fun newOffsetForDelta(delta: Float) =
- ((offset ?: 0f) + delta).coerceIn(minOffset, maxOffset)
+ ((if (offset.isNaN()) 0f else offset) + delta).coerceIn(minOffset, maxOffset)
/**
* Drag by the [delta], coerce it in the bounds and dispatch it to the [AnchoredDraggableState].
@@ -437,7 +439,7 @@
*/
fun dispatchRawDelta(delta: Float): Float {
val newOffset = newOffsetForDelta(delta)
- val oldOffset = offset ?: 0f
+ val oldOffset = if (offset.isNaN()) 0f else offset
offset = newOffset
return newOffset - oldOffset
}
@@ -550,7 +552,7 @@
anchoredDrag(targetValue = targetValue) { anchors ->
val targetOffset = anchors[targetValue]
if (targetOffset != null) {
- var prev = offset ?: 0f
+ var prev = if (offset.isNaN()) 0f else offset
animate(prev, targetOffset, velocity, animationSpec) { value, velocity ->
// Our onDrag coerces the value within the bounds, but an animation may
// overshoot, for example a spring animation or an overshooting interpolator
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
index de183dc..ed10ccf 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BackdropScaffold.kt
@@ -59,11 +59,11 @@
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMap
import androidx.compose.ui.zIndex
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.launch
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.launch
/**
* Possible values of [BackdropScaffoldState].
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
index 60b56ac..cad60b6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomNavigation.kt
@@ -27,8 +27,8 @@
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material.ripple.rememberRipple
@@ -41,7 +41,7 @@
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.lerp
-import androidx.compose.ui.layout.LastBaseline
+import androidx.compose.ui.layout.FirstBaseline
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
@@ -337,20 +337,19 @@
): MeasureResult {
val height = constraints.maxHeight
- // TODO: consider multiple lines of text here, not really supported by spec but we should
- // have a better strategy than overlapping the icon and label
- val baseline = labelPlaceable[LastBaseline]
-
+ val firstBaseline = labelPlaceable[FirstBaseline]
val baselineOffset = CombinedItemTextBaseline.roundToPx()
+ val netBaselineAdjustment = baselineOffset - firstBaseline
- // Label should be [baselineOffset] from the bottom
- val labelY = height - baseline - baselineOffset
+ val contentHeight = iconPlaceable.height + labelPlaceable.height + netBaselineAdjustment
+ val contentVerticalPadding = ((height - contentHeight) / 2).coerceAtLeast(0)
val unselectedIconY = (height - iconPlaceable.height) / 2
+ // Icon should be [contentVerticalPadding] from the top
+ val selectedIconY = contentVerticalPadding
- // Icon should be [baselineOffset] from the text baseline, which is itself
- // [baselineOffset] from the bottom
- val selectedIconY = height - (baselineOffset * 2) - iconPlaceable.height
+ // Label's first baseline should be [baselineOffset] below the icon
+ val labelY = selectedIconY + iconPlaceable.height + netBaselineAdjustment
val containerWidth = max(labelPlaceable.width, iconPlaceable.width)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
index c674017..a8f712b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/BottomSheetScaffold.kt
@@ -23,9 +23,9 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeightIn
+import androidx.compose.material.AnchoredDraggableState.AnchorChangedCallback
import androidx.compose.material.BottomSheetValue.Collapsed
import androidx.compose.material.BottomSheetValue.Expanded
-import androidx.compose.material.AnchoredDraggableState.AnchorChangedCallback
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Divider.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Divider.kt
index e8c9fad..53b3b31 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Divider.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Divider.kt
@@ -16,11 +16,11 @@
package androidx.compose.material
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
index c791f90..d7162a6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Drawer.kt
@@ -30,10 +30,10 @@
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
+import androidx.compose.material.AnchoredDraggableState.AnchorChangedCallback
import androidx.compose.material.BottomDrawerValue.Closed
import androidx.compose.material.BottomDrawerValue.Expanded
import androidx.compose.material.BottomDrawerValue.Open
-import androidx.compose.material.AnchoredDraggableState.AnchorChangedCallback
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
@@ -221,15 +221,14 @@
get() = anchoredDraggableState.targetValue
/**
- * The current position (in pixels) of the drawer sheet, or null before the offset is
+ * The current position (in pixels) of the drawer sheet, or [Float.NaN] before the offset is
* initialized.
* @see [AnchoredDraggableState.offset] for more information.
*/
@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
- @get:Suppress("AutoBoxing")
@ExperimentalMaterialApi
@get:ExperimentalMaterialApi
- val offset: Float?
+ val offset: Float
get() = anchoredDraggableState.offset
internal fun requireOffset(): Float = anchoredDraggableState.requireOffset()
@@ -313,11 +312,10 @@
get() = anchoredDraggableState.targetValue
/**
- * The current offset, or null if it has not been initialized yet.
+ * The current offset, or [Float.NaN] if it has not been initialized yet.
**/
@Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
- @get:Suppress("AutoBoxing")
- val offset: Float?
+ val offset: Float
get() = anchoredDraggableState.offset
internal fun requireOffset(): Float = anchoredDraggableState.requireOffset()
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
index 8ffc43d..fc5182e 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/IconButton.kt
@@ -16,9 +16,9 @@
package androidx.compose.material
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material.ripple.rememberRipple
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ListItem.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ListItem.kt
index 6b1cd00..d3b5ef5 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ListItem.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ListItem.kt
@@ -18,8 +18,8 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.Composable
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTextSelectionColors.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTextSelectionColors.kt
index aea6370..3cbb183 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTextSelectionColors.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTextSelectionColors.kt
@@ -16,13 +16,13 @@
package androidx.compose.material
+import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.graphics.takeOrElse
-import androidx.compose.foundation.text.selection.TextSelectionColors
import kotlin.math.max
import kotlin.math.min
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
index 50396c8..eaf511a 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/MaterialTheme.kt
@@ -17,15 +17,15 @@
package androidx.compose.material
import androidx.compose.foundation.LocalIndication
+import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.material.ripple.LocalRippleTheme
import androidx.compose.material.ripple.RippleTheme
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.Immutable
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.remember
-import androidx.compose.foundation.text.selection.LocalTextSelectionColors
/**
* <a href="https://material.io/design/material-theming/overview.html" class="external" target="_blank">Material Theming</a>.
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
index 3e80837..9d3dadbd 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Menu.kt
@@ -21,8 +21,9 @@
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
-import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.IntrinsicSize
@@ -33,14 +34,13 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
-import androidx.compose.runtime.getValue
import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -57,11 +57,11 @@
import kotlin.math.max
import kotlin.math.min
-@Suppress("ModifierParameter")
@Composable
internal fun DropdownMenuContent(
expandedStates: MutableTransitionState<Boolean>,
transformOriginState: MutableState<TransformOrigin>,
+ scrollState: ScrollState,
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit
) {
@@ -126,7 +126,7 @@
modifier = modifier
.padding(vertical = DropdownMenuVerticalPadding)
.width(IntrinsicSize.Max)
- .verticalScroll(rememberScrollState()),
+ .verticalScroll(scrollState),
content = content
)
}
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
index 9d1da3f..8b9eef6 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/ModalBottomSheet.kt
@@ -528,6 +528,7 @@
* @param sheetContent The content of the bottom sheet.
* @param modifier Optional [Modifier] for the entire component.
* @param sheetState The state of the bottom sheet.
+ * @param sheetGesturesEnabled Whether the bottom sheet can be interacted with by gestures.
* @param sheetShape The shape of the bottom sheet.
* @param sheetElevation The elevation of the bottom sheet.
* @param sheetBackgroundColor The background color of the bottom sheet.
@@ -547,6 +548,7 @@
modifier: Modifier = Modifier,
sheetState: ModalBottomSheetState =
rememberModalBottomSheetState(Hidden),
+ sheetGesturesEnabled: Boolean = true,
sheetShape: Shape = MaterialTheme.shapes.large,
sheetElevation: Dp = ModalBottomSheetDefaults.Elevation,
sheetBackgroundColor: Color = MaterialTheme.colors.surface,
@@ -585,13 +587,17 @@
.align(Alignment.TopCenter) // We offset from the top so we'll center from there
.widthIn(max = MaxModalBottomSheetWidth)
.fillMaxWidth()
- .nestedScroll(
- remember(sheetState.anchoredDraggableState, orientation) {
- ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(
- state = sheetState.anchoredDraggableState,
- orientation = orientation
+ .then(
+ if (sheetGesturesEnabled) {
+ Modifier.nestedScroll(
+ remember(sheetState.anchoredDraggableState, orientation) {
+ ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(
+ state = sheetState.anchoredDraggableState,
+ orientation = orientation
+ )
+ }
)
- }
+ } else Modifier
)
.offset {
IntOffset(
@@ -604,7 +610,8 @@
.anchoredDraggable(
state = sheetState.anchoredDraggableState,
orientation = orientation,
- enabled = sheetState.anchoredDraggableState.currentValue != Hidden,
+ enabled = sheetGesturesEnabled &&
+ sheetState.anchoredDraggableState.currentValue != Hidden,
)
.onSizeChanged { sheetSize ->
val anchors = buildMap {
@@ -619,37 +626,45 @@
}
sheetState.anchoredDraggableState.updateAnchors(anchors, anchorChangeCallback)
}
- .semantics {
- if (sheetState.isVisible) {
- dismiss {
- if (sheetState.anchoredDraggableState.confirmValueChange(Hidden)) {
- scope.launch { sheetState.hide() }
- }
- true
- }
- if (sheetState.anchoredDraggableState.currentValue == HalfExpanded) {
- expand {
- if (sheetState.anchoredDraggableState.confirmValueChange(
- Expanded
- )
- ) {
- scope.launch { sheetState.expand() }
+ .then(
+ if (sheetGesturesEnabled) {
+ Modifier.semantics {
+ if (sheetState.isVisible) {
+ dismiss {
+ if (
+ sheetState.anchoredDraggableState.confirmValueChange(Hidden)
+ ) {
+ scope.launch { sheetState.hide() }
+ }
+ true
}
- true
- }
- } else if (sheetState.hasHalfExpandedState) {
- collapse {
- if (sheetState.anchoredDraggableState.confirmValueChange(
- HalfExpanded
- )
+ if (sheetState.anchoredDraggableState.currentValue
+ == HalfExpanded
) {
- scope.launch { sheetState.halfExpand() }
+ expand {
+ if (sheetState.anchoredDraggableState.confirmValueChange(
+ Expanded
+ )
+ ) {
+ scope.launch { sheetState.expand() }
+ }
+ true
+ }
+ } else if (sheetState.hasHalfExpandedState) {
+ collapse {
+ if (sheetState.anchoredDraggableState.confirmValueChange(
+ HalfExpanded
+ )
+ ) {
+ scope.launch { sheetState.halfExpand() }
+ }
+ true
+ }
}
- true
}
}
- }
- },
+ } else Modifier
+ ),
shape = sheetShape,
elevation = sheetElevation,
color = sheetBackgroundColor,
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
index 6555ac1..5f3120a 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/OutlinedTextField.kt
@@ -589,16 +589,15 @@
)
// measure label
- val isLabelInMiddleSection = animationProgress < 1f
val labelHorizontalPaddingOffset =
paddingValues.calculateLeftPadding(layoutDirection).roundToPx() +
paddingValues.calculateRightPadding(layoutDirection).roundToPx()
val labelConstraints = relaxedConstraints.offset(
- horizontal = if (isLabelInMiddleSection) {
- -occupiedSpaceHorizontally - labelHorizontalPaddingOffset
- } else {
- -labelHorizontalPaddingOffset
- },
+ horizontal = lerp(
+ -occupiedSpaceHorizontally - labelHorizontalPaddingOffset,
+ -labelHorizontalPaddingOffset,
+ animationProgress,
+ ),
vertical = -bottomPadding
)
val labelPlaceable =
@@ -633,21 +632,22 @@
textFieldPlaceableWidth = textFieldPlaceable.width,
labelPlaceableWidth = widthOrZero(labelPlaceable),
placeholderPlaceableWidth = widthOrZero(placeholderPlaceable),
- isLabelInMiddleSection = isLabelInMiddleSection,
+ animationProgress = animationProgress,
constraints = constraints,
density = density,
paddingValues = paddingValues,
)
val height =
calculateHeight(
- heightOrZero(leadingPlaceable),
- heightOrZero(trailingPlaceable),
- textFieldPlaceable.height,
- heightOrZero(labelPlaceable),
- heightOrZero(placeholderPlaceable),
- constraints,
- density,
- paddingValues
+ leadingPlaceableHeight = heightOrZero(leadingPlaceable),
+ trailingPlaceableHeight = heightOrZero(trailingPlaceable),
+ textFieldPlaceableHeight = textFieldPlaceable.height,
+ labelPlaceableHeight = heightOrZero(labelPlaceable),
+ placeholderPlaceableHeight = heightOrZero(placeholderPlaceable),
+ animationProgress = animationProgress,
+ constraints = constraints,
+ density = density,
+ paddingValues = paddingValues,
)
val borderPlaceable = measurables.first { it.layoutId == BorderId }.measure(
@@ -738,7 +738,7 @@
textFieldPlaceableWidth = textFieldWidth,
labelPlaceableWidth = labelWidth,
placeholderPlaceableWidth = placeholderWidth,
- isLabelInMiddleSection = animationProgress < 1f,
+ animationProgress = animationProgress,
constraints = ZeroConstraints,
density = density,
paddingValues = paddingValues,
@@ -770,6 +770,7 @@
textFieldPlaceableHeight = textFieldHeight,
labelPlaceableHeight = labelHeight,
placeholderPlaceableHeight = placeholderHeight,
+ animationProgress = animationProgress,
constraints = ZeroConstraints,
density = density,
paddingValues = paddingValues
@@ -787,27 +788,25 @@
textFieldPlaceableWidth: Int,
labelPlaceableWidth: Int,
placeholderPlaceableWidth: Int,
- isLabelInMiddleSection: Boolean,
+ animationProgress: Float,
constraints: Constraints,
density: Float,
paddingValues: PaddingValues,
): Int {
val middleSection = maxOf(
textFieldPlaceableWidth,
- if (isLabelInMiddleSection) labelPlaceableWidth else 0,
+ lerp(labelPlaceableWidth, 0, animationProgress),
placeholderPlaceableWidth
)
val wrappedWidth =
leadingPlaceableWidth + middleSection + trailingPlaceableWidth
+
+ // Actual LayoutDirection doesn't matter; we only need the sum
+ val labelHorizontalPadding = (paddingValues.calculateLeftPadding(LayoutDirection.Ltr) +
+ paddingValues.calculateRightPadding(LayoutDirection.Ltr)).value * density
val focusedLabelWidth =
- if (!isLabelInMiddleSection) {
- // Actual LayoutDirection doesn't matter; we only need the sum
- val labelHorizontalPadding = (paddingValues.calculateLeftPadding(LayoutDirection.Ltr) +
- paddingValues.calculateRightPadding(LayoutDirection.Ltr)).value * density
- labelPlaceableWidth + labelHorizontalPadding.roundToInt()
- } else {
- 0
- }
+ ((labelPlaceableWidth + labelHorizontalPadding) * animationProgress).roundToInt()
+
return maxOf(wrappedWidth, focusedLabelWidth, constraints.minWidth)
}
@@ -821,23 +820,25 @@
textFieldPlaceableHeight: Int,
labelPlaceableHeight: Int,
placeholderPlaceableHeight: Int,
+ animationProgress: Float,
constraints: Constraints,
density: Float,
paddingValues: PaddingValues
): Int {
- // middle section is defined as a height of the text field or placeholder ( whichever is
- // taller) plus 16.dp or half height of the label if it is taller, given that the label
- // is vertically centered to the top edge of the resulting text field's container
- val inputFieldHeight = max(
+ val inputFieldHeight = maxOf(
textFieldPlaceableHeight,
- placeholderPlaceableHeight
+ placeholderPlaceableHeight,
+ lerp(labelPlaceableHeight, 0, animationProgress),
)
val topPadding = paddingValues.calculateTopPadding().value * density
- val bottomPadding = paddingValues.calculateBottomPadding().value * density
- val middleSectionHeight = inputFieldHeight + bottomPadding + max(
+ val actualTopPadding = lerp(
topPadding,
- labelPlaceableHeight / 2f
+ max(topPadding, labelPlaceableHeight / 2f),
+ animationProgress,
)
+ val bottomPadding = paddingValues.calculateBottomPadding().value * density
+ val middleSectionHeight = actualTopPadding + inputFieldHeight + bottomPadding
+
return max(
constraints.minHeight,
maxOf(
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
index 316474c..3f01485 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Slider.kt
@@ -27,10 +27,10 @@
import androidx.compose.foundation.gestures.DraggableState
import androidx.compose.foundation.gestures.GestureCancellationException
import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.draggable
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.horizontalDrag
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.indication
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
index 5e00644..e1af01b 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SnackbarHost.kt
@@ -42,12 +42,12 @@
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.util.fastForEach
+import kotlin.coroutines.resume
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.delay
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
-import kotlin.coroutines.resume
/**
* State of the [SnackbarHost], controls the queue and the current [Snackbar] being shown inside
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
index 0aa1377..1cda288 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeToDismiss.kt
@@ -38,8 +38,8 @@
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.CancellationException
import kotlin.math.roundToInt
+import kotlinx.coroutines.CancellationException
/**
* The directions in which a [SwipeToDismiss] can be dismissed.
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
index b30abb2..b3361e0 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/Swipeable.kt
@@ -194,7 +194,7 @@
internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
- internal var velocityThreshold by mutableStateOf(0f)
+ internal var velocityThreshold by mutableFloatStateOf(0f)
internal var resistance: ResistanceConfig? by mutableStateOf(null)
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
index 96983f1..746c057 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/pullrefresh/PullRefreshState.kt
@@ -24,6 +24,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -121,10 +122,10 @@
private val adjustedDistancePulled by derivedStateOf { distancePulled * DragMultiplier }
private var _refreshing by mutableStateOf(false)
- private var _position by mutableStateOf(0f)
- private var distancePulled by mutableStateOf(0f)
- private var _threshold by mutableStateOf(threshold)
- private var _refreshingOffset by mutableStateOf(refreshingOffset)
+ private var _position by mutableFloatStateOf(0f)
+ private var distancePulled by mutableFloatStateOf(0f)
+ private var _threshold by mutableFloatStateOf(threshold)
+ private var _refreshingOffset by mutableFloatStateOf(refreshingOffset)
internal fun onPull(pullDelta: Float): Float {
if (_refreshing) return 0f // Already refreshing, do nothing.
diff --git a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopAlertDialog.desktop.kt b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopAlertDialog.desktop.kt
index 1c886e0..125aaed 100644
--- a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopAlertDialog.desktop.kt
+++ b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopAlertDialog.desktop.kt
@@ -31,15 +31,15 @@
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.window.Dialog as CoreDialog
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import androidx.compose.ui.window.rememberDialogState
-import androidx.compose.ui.window.Dialog as CoreDialog
/**
* Alert dialog is a Dialog which interrupts the user with urgent information, details or actions.
diff --git a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
index 4da69f2..ba88fef 100644
--- a/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
+++ b/compose/material/material/src/desktopMain/kotlin/androidx/compose/material/DesktopMenu.desktop.kt
@@ -17,10 +17,12 @@
package androidx.compose.material
import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.rememberScrollState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.mutableStateOf
@@ -30,14 +32,14 @@
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.DpOffset
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.window.rememberCursorPositionProvider
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
+import androidx.compose.ui.window.rememberCursorPositionProvider
/**
* A Material Design [dropdown menu](https://material.io/components/menus#dropdown-menu).
@@ -74,7 +76,15 @@
* @param offset [DpOffset] to be added to the position of the menu
* @param content content lambda
*/
-@Suppress("ModifierParameter")
+@Deprecated(
+ level = DeprecationLevel.HIDDEN,
+ replaceWith = ReplaceWith(
+ expression = "DropdownMenu(expanded,onDismissRequest, focusable, modifier, offset, " +
+ "rememberScrollState(), content)",
+ "androidx.compose.foundation.rememberScrollState"
+ ),
+ message = "Replaced by a DropdownMenu function with a ScrollState parameter"
+)
@Composable
fun DropdownMenu(
expanded: Boolean,
@@ -83,6 +93,64 @@
modifier: Modifier = Modifier,
offset: DpOffset = DpOffset(0.dp, 0.dp),
content: @Composable ColumnScope.() -> Unit
+) = DropdownMenu(
+ expanded = expanded,
+ onDismissRequest = onDismissRequest,
+ focusable = focusable,
+ modifier = modifier,
+ offset = offset,
+ scrollState = rememberScrollState(),
+ content = content
+)
+
+/**
+ * A Material Design [dropdown menu](https://material.io/components/menus#dropdown-menu).
+ *
+ * A [DropdownMenu] behaves similarly to a [Popup], and will use the position of the parent layout
+ * to position itself on screen. Commonly a [DropdownMenu] will be placed in a [Box] with a sibling
+ * that will be used as the 'anchor'. Note that a [DropdownMenu] by itself will not take up any
+ * space in a layout, as the menu is displayed in a separate window, on top of other content.
+ *
+ * The [content] of a [DropdownMenu] will typically be [DropdownMenuItem]s, as well as custom
+ * content. Using [DropdownMenuItem]s will result in a menu that matches the Material
+ * specification for menus. Also note that the [content] is placed inside a scrollable [Column],
+ * so using a [LazyColumn] as the root layout inside [content] is unsupported.
+ *
+ * [onDismissRequest] will be called when the menu should close - for example when there is a
+ * tap outside the menu, or when the back key is pressed.
+ *
+ * [DropdownMenu] changes its positioning depending on the available space, always trying to be
+ * fully visible. It will try to expand horizontally, depending on layout direction, to the end of
+ * its parent, then to the start of its parent, and then screen end-aligned. Vertically, it will
+ * try to expand to the bottom of its parent, then from the top of its parent, and then screen
+ * top-aligned. An [offset] can be provided to adjust the positioning of the menu for cases when
+ * the layout bounds of its parent do not coincide with its visual bounds. Note the offset will
+ * be applied in the direction in which the menu will decide to expand.
+ *
+ * Example usage:
+ * @sample androidx.compose.material.samples.MenuSample
+ *
+ * Example usage with a [ScrollState] to control the menu items scroll position:
+ * @sample androidx.compose.material.samples.MenuWithScrollStateSample
+ *
+ * @param expanded Whether the menu is currently open and visible to the user
+ * @param onDismissRequest Called when the user requests to dismiss the menu, such as by
+ * tapping outside the menu's bounds
+ * @param focusable Whether the dropdown can capture focus
+ * @param modifier [Modifier] to be applied to the menu's content
+ * @param offset [DpOffset] to be added to the position of the menu
+ * @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
+ * @param content the content of this dropdown menu, typically a [DropdownMenuItem]
+ */
+@Composable
+fun DropdownMenu(
+ expanded: Boolean,
+ onDismissRequest: () -> Unit,
+ focusable: Boolean = true,
+ modifier: Modifier = Modifier,
+ offset: DpOffset = DpOffset(0.dp, 0.dp),
+ scrollState: ScrollState = rememberScrollState(),
+ content: @Composable ColumnScope.() -> Unit
) {
val expandedStates = remember { MutableTransitionState(false) }
expandedStates.targetState = expanded
@@ -110,6 +178,7 @@
expandedStates = expandedStates,
transformOriginState = transformOriginState,
modifier = modifier,
+ scrollState = scrollState,
content = content
)
}
@@ -163,8 +232,19 @@
* @param expanded Whether the menu is currently open and visible to the user
* @param onDismissRequest Called when the user requests to dismiss the menu, such as by
* tapping outside the menu's bounds
+ * @param focusable Sets the ability for the menu to capture focus
+ * @param modifier The modifier for this layout.
+ * @param content The content lambda.
*/
-@Suppress("ModifierParameter")
+@Deprecated(
+ level = DeprecationLevel.HIDDEN,
+ replaceWith = ReplaceWith(
+ expression = "CursorDropdownMenu(expanded,onDismissRequest, focusable, modifier, " +
+ "rememberScrollState(), content)",
+ "androidx.compose.foundation.rememberScrollState"
+ ),
+ message = "Replaced by a CursorDropdownMenu function with a ScrollState parameter"
+)
@Composable
fun CursorDropdownMenu(
expanded: Boolean,
@@ -172,6 +252,40 @@
focusable: Boolean = true,
modifier: Modifier = Modifier,
content: @Composable ColumnScope.() -> Unit
+) = CursorDropdownMenu(
+ expanded = expanded,
+ onDismissRequest = onDismissRequest,
+ focusable = focusable,
+ modifier = modifier,
+ scrollState = rememberScrollState(),
+ content = content
+)
+
+/**
+ *
+ * A [CursorDropdownMenu] behaves similarly to [Popup] and will use the current position of the mouse
+ * cursor to position itself on screen.
+ *
+ * The [content] of a [CursorDropdownMenu] will typically be [DropdownMenuItem]s, as well as custom
+ * content. Using [DropdownMenuItem]s will result in a menu that matches the Material
+ * specification for menus.
+ *
+ * @param expanded Whether the menu is currently open and visible to the user
+ * @param onDismissRequest Called when the user requests to dismiss the menu, such as by
+ * tapping outside the menu's bounds
+ * @param focusable Whether the dropdown can capture focus
+ * @param modifier [Modifier] to be applied to the menu's content
+ * @param scrollState a [ScrollState] to used by the menu's content for items vertical scrolling
+ * @param content the content of this dropdown menu, typically a [DropdownMenuItem]
+ */
+@Composable
+fun CursorDropdownMenu(
+ expanded: Boolean,
+ onDismissRequest: () -> Unit,
+ focusable: Boolean = true,
+ modifier: Modifier = Modifier,
+ scrollState: ScrollState = rememberScrollState(),
+ content: @Composable ColumnScope.() -> Unit
) {
val expandedStates = remember { MutableTransitionState(false) }
expandedStates.targetState = expanded
@@ -188,6 +302,7 @@
expandedStates = expandedStates,
transformOriginState = transformOriginState,
modifier = modifier,
+ scrollState = scrollState,
content = content
)
}
diff --git a/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopAlertDialogTest.kt b/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopAlertDialogTest.kt
index 0537f91..cc5e759 100644
--- a/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopAlertDialogTest.kt
+++ b/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopAlertDialogTest.kt
@@ -18,20 +18,20 @@
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
-import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
-import org.junit.runners.JUnit4
-import org.junit.runner.RunWith
import org.junit.Rule
import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class DesktopAlertDialogTest {
diff --git a/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopMenuTest.kt b/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopMenuTest.kt
index d658276..7ec3efcb 100644
--- a/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopMenuTest.kt
+++ b/compose/material/material/src/desktopTest/kotlin/androidx/compose/material/DesktopMenuTest.kt
@@ -23,9 +23,9 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import com.google.common.truth.Truth.assertThat
-import org.junit.runners.JUnit4
-import org.junit.runner.RunWith
import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class DesktopMenuTest {
diff --git a/compose/material3/material3-adaptive/build.gradle b/compose/material3/material3-adaptive/build.gradle
index c263c79..b1aaced 100644
--- a/compose/material3/material3-adaptive/build.gradle
+++ b/compose/material3/material3-adaptive/build.gradle
@@ -17,7 +17,7 @@
import androidx.build.AndroidXComposePlugin
import androidx.build.LibraryType
import androidx.build.Publish
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import androidx.build.KmpPlatformsKt
plugins {
id("AndroidXPlugin")
@@ -25,49 +25,61 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
-
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
-
- api("androidx.annotation:annotation:1.1.0")
-
- api(project(":compose:foundation:foundation"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:foundation:foundation"))
}
+ }
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.1.0")
+ commonTest {
+ dependencies {
}
+ }
- desktopMain.dependencies {
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
implementation(libs.kotlinStdlib)
}
}
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
+
+ androidTest {
+ dependsOn(jvmTest)
+ }
}
}
diff --git a/compose/material3/material3-window-size-class/build.gradle b/compose/material3/material3-window-size-class/build.gradle
index 9eb3383..495dd73 100644
--- a/compose/material3/material3-window-size-class/build.gradle
+++ b/compose/material3/material3-window-size-class/build.gradle
@@ -14,10 +14,10 @@
* limitations under the License.
*/
+import androidx.build.KmpPlatformsKt
import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import androidx.build.Publish
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,69 +25,73 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
- api("androidx.compose.runtime:runtime:1.2.1")
- api("androidx.compose.ui:ui:1.2.1")
- api("androidx.compose.ui:ui-unit:1.2.1")
- implementation("androidx.window:window:1.0.0")
-
- testImplementation(libs.kotlinTest)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
-
- samples(project(":compose:material3:material3-window-size-class:material3-window-size-class-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- kotlin {
- android()
- jvm("desktop")
-
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:runtime:runtime"))
api(project(":compose:ui:ui"))
api(project(":compose:ui:ui-unit"))
}
+ }
- jvmMain.dependencies {
+ commonTest {
+ dependencies {
+
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
implementation(libs.kotlinStdlib)
}
+ }
- androidMain.dependencies {
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ // Because dependencies are pinned in the android/common code.
+ api(project(":compose:runtime:runtime"))
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-unit"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
implementation("androidx.window:window:1.0.0")
}
+ }
- androidMain.dependsOn(jvmMain)
- desktopMain.dependsOn(jvmMain)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
- androidTest.dependencies {
- implementation(libs.kotlinTest)
- implementation(libs.truth)
+ }
}
+ }
- androidAndroidTest.dependencies {
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:test-utils"))
implementation(project(":compose:foundation:foundation"))
implementation(libs.testRules)
@@ -96,9 +100,24 @@
implementation(libs.truth)
}
}
- }
- dependencies {
- samples(project(":compose:material3:material3-window-size-class:material3-window-size-class-samples"))
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.kotlinTest)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+
+ }
+ }
+ }
}
}
diff --git a/compose/material3/material3-window-size-class/samples/build.gradle b/compose/material3/material3-window-size-class/samples/build.gradle
index 4dc7891..71ffc63d1 100644
--- a/compose/material3/material3-window-size-class/samples/build.gradle
+++ b/compose/material3/material3-window-size-class/samples/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "AndroidX Compose Material 3 Window Size Class Samples"
+ name = "Compose Material 3 Window Size Class Samples"
type = LibraryType.SAMPLES
inceptionYear = "2022"
description = "Contains the sample code for the Material 3 Window Size Class APIs"
diff --git a/compose/material3/material3-window-size-class/samples/src/main/AndroidManifest.xml b/compose/material3/material3-window-size-class/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index a7cd314..0000000
--- a/compose/material3/material3-window-size-class/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ 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 />
diff --git a/compose/material3/material3-window-size-class/src/androidAndroidTest/AndroidManifest.xml b/compose/material3/material3-window-size-class/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index a9ad70f..0000000
--- a/compose/material3/material3-window-size-class/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
- -->
-
-<manifest />
\ No newline at end of file
diff --git a/compose/material3/material3-window-size-class/src/androidMain/AndroidManifest.xml b/compose/material3/material3-window-size-class/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index a9ad70f..0000000
--- a/compose/material3/material3-window-size-class/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
- -->
-
-<manifest />
\ No newline at end of file
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index 1f5b379..b6e6d45 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -758,16 +758,20 @@
}
@androidx.compose.runtime.Immutable public final class TabPosition {
+ method public float getContentWidth();
method public float getLeft();
method public float getRight();
method public float getWidth();
+ property public final float contentWidth;
property public final float left;
property public final float right;
property public final float width;
}
public final class TabRowDefaults {
- method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @Deprecated @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @androidx.compose.runtime.Composable public void PrimaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional long color, optional androidx.compose.ui.graphics.Shape shape);
+ method @androidx.compose.runtime.Composable public void SecondaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public long getContentColor();
method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index b2471cb..a2231ee 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -1145,16 +1145,20 @@
}
@androidx.compose.runtime.Immutable public final class TabPosition {
+ method public float getContentWidth();
method public float getLeft();
method public float getRight();
method public float getWidth();
+ property public final float contentWidth;
property public final float left;
property public final float right;
property public final float width;
}
public final class TabRowDefaults {
- method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @Deprecated @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @androidx.compose.runtime.Composable public void PrimaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional long color, optional androidx.compose.ui.graphics.Shape shape);
+ method @androidx.compose.runtime.Composable public void SecondaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public long getContentColor();
method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index 1f5b379..b6e6d45 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -758,16 +758,20 @@
}
@androidx.compose.runtime.Immutable public final class TabPosition {
+ method public float getContentWidth();
method public float getLeft();
method public float getRight();
method public float getWidth();
+ property public final float contentWidth;
property public final float left;
property public final float right;
property public final float width;
}
public final class TabRowDefaults {
- method @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @Deprecated @androidx.compose.runtime.Composable public void Indicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
+ method @androidx.compose.runtime.Composable public void PrimaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float width, optional float height, optional long color, optional androidx.compose.ui.graphics.Shape shape);
+ method @androidx.compose.runtime.Composable public void SecondaryIndicator(optional androidx.compose.ui.Modifier modifier, optional float height, optional long color);
method @androidx.compose.runtime.Composable public long getContainerColor();
method @androidx.compose.runtime.Composable public long getContentColor();
method public androidx.compose.ui.Modifier tabIndicatorOffset(androidx.compose.ui.Modifier, androidx.compose.material3.TabPosition currentTabPosition);
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index f300862c..9583afe 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -16,6 +16,7 @@
import androidx.build.AndroidXComposePlugin
import androidx.build.LibraryType
+import androidx.build.KmpPlatformsKt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -25,71 +26,15 @@
id("AndroidXPaparazziPlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
-
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
- implementation("androidx.activity:activity-compose:1.5.0")
- implementation(project(":compose:animation:animation"))
- implementation(project(":compose:foundation:foundation-layout"))
- implementation("androidx.compose.ui:ui-util:1.4.2")
- api(project(":compose:foundation:foundation"))
- api("androidx.compose.material:material-icons-core:1.4.2")
- api("androidx.compose.material:material-ripple:1.4.2")
- api("androidx.compose.runtime:runtime:1.4.2")
- api("androidx.compose.ui:ui-graphics:1.4.2")
- api("androidx.compose.ui:ui:1.4.2")
- api(project(":compose:ui:ui-text"))
-
- // TODO: remove next 3 dependencies when b/202810604 is fixed
- implementation("androidx.savedstate:savedstate-ktx:1.2.1")
- implementation("androidx.lifecycle:lifecycle-runtime:2.6.1")
- implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
-
- implementation("androidx.lifecycle:lifecycle-common-java8:2.6.1")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:material3:material3:material3-samples"))
- androidTestImplementation(project(":compose:foundation:foundation-layout"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":test:screenshot:screenshot"))
- androidTestImplementation(project(":core:core"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.dexmakerMockitoInlineExtended)
- androidTestImplementation(libs.mockitoKotlin)
- androidTestImplementation(libs.testUiautomator)
-
- lintPublish project(":compose:material3:material3-lint")
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
implementation(project(":compose:animation:animation-core"))
@@ -103,8 +48,37 @@
implementation(project(":compose:ui:ui-util"))
implementation(project(":compose:foundation:foundation-layout"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:animation:animation-core"))
+ api(project(":compose:runtime:runtime"))
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-text"))
+ implementation(project(":compose:animation:animation"))
+ implementation(project(":compose:foundation:foundation-layout"))
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
implementation("androidx.activity:activity-compose:1.5.0")
@@ -115,23 +89,41 @@
implementation("androidx.lifecycle:lifecycle-common-java8:2.6.1")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ }
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.junit)
implementation(libs.truth)
}
+ }
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:material3:material3:material3-samples"))
implementation(project(":compose:test-utils"))
implementation(project(':compose:foundation:foundation-layout'))
@@ -146,9 +138,26 @@
implementation(libs.testUiautomator)
}
}
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ implementation(project(":compose:ui:ui-test-junit4"))
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.skikoCurrentOs)
+ }
+ }
+ }
}
}
+dependencies {
+ lintPublish project(":compose:material3:material3-lint")
+}
+
androidx {
name = "Compose Material3 Components"
type = LibraryType.PUBLISHED_LIBRARY
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/AndroidManifest.xml b/compose/material3/material3/integration-tests/material3-catalog/src/main/AndroidManifest.xml
deleted file mode 100644
index ccc91d4..0000000
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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
- -->
-
-<manifest />
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
index 1d6480b..aef2f9c 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
@@ -101,6 +101,7 @@
import androidx.compose.material3.samples.PinnedTopAppBar
import androidx.compose.material3.samples.PlainTooltipSample
import androidx.compose.material3.samples.PlainTooltipWithManualInvocationSample
+import androidx.compose.material3.samples.PrimaryTabs
import androidx.compose.material3.samples.RadioButtonSample
import androidx.compose.material3.samples.RadioGroupSample
import androidx.compose.material3.samples.RangeSliderSample
@@ -113,8 +114,11 @@
import androidx.compose.material3.samples.ScaffoldWithMultilineSnackbar
import androidx.compose.material3.samples.ScaffoldWithSimpleSnackbar
import androidx.compose.material3.samples.ScrollingFancyIndicatorContainerTabs
+import androidx.compose.material3.samples.ScrollingPrimaryTabs
+import androidx.compose.material3.samples.ScrollingSecondaryTabs
import androidx.compose.material3.samples.ScrollingTextTabs
import androidx.compose.material3.samples.SearchBarSample
+import androidx.compose.material3.samples.SecondaryTabs
import androidx.compose.material3.samples.SimpleBottomAppBar
import androidx.compose.material3.samples.SimpleBottomSheetScaffoldSample
import androidx.compose.material3.samples.SimpleCenterAlignedTopAppBar
@@ -894,6 +898,20 @@
private const val TabsExampleSourceUrl = "$SampleSourceUrl/TabSamples.kt"
val TabsExamples = listOf(
Example(
+ name = ::PrimaryTabs.name,
+ description = TabsExampleDescription,
+ sourceUrl = TabsExampleSourceUrl
+ ) {
+ PrimaryTabs()
+ },
+ Example(
+ name = ::SecondaryTabs.name,
+ description = TabsExampleDescription,
+ sourceUrl = TabsExampleSourceUrl
+ ) {
+ SecondaryTabs()
+ },
+ Example(
name = ::TextTabs.name,
description = TabsExampleDescription,
sourceUrl = TabsExampleSourceUrl
@@ -922,6 +940,20 @@
LeadingIconTabs()
},
Example(
+ name = ::ScrollingPrimaryTabs.name,
+ description = TabsExampleDescription,
+ sourceUrl = TabsExampleSourceUrl
+ ) {
+ ScrollingPrimaryTabs()
+ },
+ Example(
+ name = ::ScrollingSecondaryTabs.name,
+ description = TabsExampleDescription,
+ sourceUrl = TabsExampleSourceUrl
+ ) {
+ ScrollingSecondaryTabs()
+ },
+ Example(
name = ::ScrollingTextTabs.name,
description = TabsExampleDescription,
sourceUrl = TabsExampleSourceUrl
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
index 8aef861..ca9d5d4 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/ui/theme/ThemePicker.kt
@@ -46,7 +46,7 @@
import androidx.compose.material3.catalog.library.model.ThemeMode
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -242,7 +242,7 @@
)
}
- var fontScale by remember { mutableStateOf(theme.fontScale) }
+ var fontScale by remember { mutableFloatStateOf(theme.fontScale) }
FontScaleItem(
modifier = Modifier
.fillMaxWidth()
diff --git a/compose/material3/material3/integration-tests/material3-demos/build.gradle b/compose/material3/material3/integration-tests/material3-demos/build.gradle
index fc83ff8..76ba389 100644
--- a/compose/material3/material3/integration-tests/material3-demos/build.gradle
+++ b/compose/material3/material3/integration-tests/material3-demos/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "AndroidX Compose Material3 Components Demos"
+ name = "Compose Material3 Components Demos"
publish = Publish.NONE
inceptionYear = "2022"
description = "Contains the demo code for the AndroidX Compose Material 3 components."
diff --git a/compose/material3/material3/integration-tests/material3-demos/src/main/AndroidManifest.xml b/compose/material3/material3/integration-tests/material3-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index a7cd314..0000000
--- a/compose/material3/material3/integration-tests/material3-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ 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 />
diff --git a/compose/material3/material3/samples/build.gradle b/compose/material3/material3/samples/build.gradle
index 075b5f4..eb9d9a3 100644
--- a/compose/material3/material3/samples/build.gradle
+++ b/compose/material3/material3/samples/build.gradle
@@ -47,7 +47,7 @@
}
androidx {
- name = "AndroidX Compose Material3 Components Samples"
+ name = "Compose Material3 Components Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the AndroidX Compose Material You components."
diff --git a/compose/material3/material3/samples/src/main/AndroidManifest.xml b/compose/material3/material3/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index dc2f180..0000000
--- a/compose/material3/material3/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ButtonSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ButtonSamples.kt
index cc1daef..5521ab9 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ButtonSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ButtonSamples.kt
@@ -17,8 +17,8 @@
package androidx.compose.material3.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.Button
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
index bbeb8b3..c19a692 100644
--- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/TabSamples.kt
@@ -19,6 +19,7 @@
import androidx.annotation.Sampled
import androidx.compose.animation.animateColor
import androidx.compose.animation.core.animateDp
+import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.BorderStroke
@@ -29,24 +30,25 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.Icon
+import androidx.compose.material3.LeadingIconTab
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.Tab
-import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.TabPosition
import androidx.compose.material3.TabRow
-import androidx.compose.material3.LeadingIconTab
+import androidx.compose.material3.TabRowDefaults
+import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
import androidx.compose.material3.Text
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -59,6 +61,58 @@
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+@Composable
+fun PrimaryTabs() {
+ var state by remember { mutableStateOf(0) }
+ val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
+ Column {
+ TabRow(selectedTabIndex = state, indicator = @Composable { tabPositions ->
+ if (state < tabPositions.size) {
+ val width by animateDpAsState(targetValue = tabPositions[state].contentWidth)
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[state]),
+ width = width
+ )
+ }
+ }) {
+ titles.forEachIndexed { index, title ->
+ Tab(
+ selected = state == index,
+ onClick = { state = index },
+ text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
+ )
+ }
+ }
+ Text(
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ text = "Primary tab ${state + 1} selected",
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+}
+
+@Composable
+fun SecondaryTabs() {
+ var state by remember { mutableStateOf(0) }
+ val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
+ Column {
+ TabRow(selectedTabIndex = state) {
+ titles.forEachIndexed { index, title ->
+ Tab(
+ selected = state == index,
+ onClick = { state = index },
+ text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
+ )
+ }
+ }
+ Text(
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ text = "Secondary tab ${state + 1} selected",
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+}
+
@Preview
@Sampled
@Composable
@@ -160,6 +214,80 @@
}
@Composable
+fun ScrollingPrimaryTabs() {
+ var state by remember { mutableStateOf(0) }
+ val titles = listOf(
+ "Tab 1",
+ "Tab 2",
+ "Tab 3 with lots of text",
+ "Tab 4",
+ "Tab 5",
+ "Tab 6 with lots of text",
+ "Tab 7",
+ "Tab 8",
+ "Tab 9 with lots of text",
+ "Tab 10"
+ )
+ Column {
+ ScrollableTabRow(selectedTabIndex = state, indicator = @Composable { tabPositions ->
+ if (state < tabPositions.size) {
+ val width by animateDpAsState(targetValue = tabPositions[state].contentWidth)
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[state]),
+ width = width
+ )
+ }
+ }) {
+ titles.forEachIndexed { index, title ->
+ Tab(
+ selected = state == index,
+ onClick = { state = index },
+ text = { Text(title) }
+ )
+ }
+ }
+ Text(
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ text = "Scrolling primary tab ${state + 1} selected",
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+}
+
+@Composable
+fun ScrollingSecondaryTabs() {
+ var state by remember { mutableStateOf(0) }
+ val titles = listOf(
+ "Tab 1",
+ "Tab 2",
+ "Tab 3 with lots of text",
+ "Tab 4",
+ "Tab 5",
+ "Tab 6 with lots of text",
+ "Tab 7",
+ "Tab 8",
+ "Tab 9 with lots of text",
+ "Tab 10"
+ )
+ Column {
+ ScrollableTabRow(selectedTabIndex = state) {
+ titles.forEachIndexed { index, title ->
+ Tab(
+ selected = state == index,
+ onClick = { state = index },
+ text = { Text(title) }
+ )
+ }
+ }
+ Text(
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ text = "Scrolling secondary tab ${state + 1} selected",
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+}
+
+@Composable
fun ScrollingTextTabs() {
var state by remember { mutableStateOf(0) }
val titles = listOf(
@@ -201,7 +329,11 @@
Column {
TabRow(selectedTabIndex = state) {
titles.forEachIndexed { index, title ->
- FancyTab(title = title, onClick = { state = index }, selected = (index == state))
+ FancyTab(
+ title = title,
+ onClick = { state = index },
+ selected = (index == state)
+ )
}
}
Text(
@@ -334,7 +466,8 @@
.align(Alignment.CenterHorizontally)
.background(
color = if (selected) MaterialTheme.colorScheme.primary
- else MaterialTheme.colorScheme.background)
+ else MaterialTheme.colorScheme.background
+ )
)
Text(
text = title,
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
index 7374b08..9cce0ba 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerScreenshotTest.kt
@@ -31,6 +31,8 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.test.screenshot.AndroidXScreenshotTestRule
+import org.junit.Assume.assumeFalse
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -63,7 +65,10 @@
}
@Test
+ @Ignore("b/272301182")
fun darkTheme() {
+ assumeFalse("See b/272301182", Build.VERSION.SDK_INT == 33)
+
composeTestRule.setMaterialContent(darkColorScheme()) {
Column(Modifier.testTag(Tag)) {
Spacer(Modifier.size(10.dp))
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerUiTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerUiTest.kt
index a11f610..9e19fbb 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerUiTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/DividerUiTest.kt
@@ -38,10 +38,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt
index 24bde2e..95357cf 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt
@@ -54,8 +54,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import com.google.common.truth.Truth.assertThat
+import org.junit.Assume.assumeNotNull
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -75,7 +78,7 @@
private val OptionName = "Option 1"
@Test
- fun expandedBehaviour_expandsOnClickAndCollapsesOnOutside() {
+ fun edm_expandsOnClick_andCollapsesOnClickOutside() {
var textFieldBounds = Rect.Zero
rule.setMaterialContent(lightColorScheme()) {
var expanded by remember { mutableStateOf(false) }
@@ -106,7 +109,7 @@
}
@Test
- fun expandedBehaviour_collapseOnTextFieldClick() {
+ fun edm_collapsesOnTextFieldClick() {
rule.setMaterialContent(lightColorScheme()) {
var expanded by remember { mutableStateOf(true) }
ExposedDropdownMenuForTest(
@@ -126,7 +129,39 @@
}
@Test
- fun expandedBehaviour_expandsAndFocusesTextFieldOnTrailingIconClick() {
+ fun edm_doesNotCollapse_whenTypingOnSoftKeyboard() {
+ rule.setMaterialContent(lightColorScheme()) {
+ var expanded by remember { mutableStateOf(false) }
+ ExposedDropdownMenuForTest(
+ expanded = expanded,
+ onExpandChange = { expanded = it }
+ )
+ }
+
+ rule.onNodeWithTag(TFTag).performClick()
+
+ rule.onNodeWithTag(TFTag).assertIsDisplayed()
+ rule.onNodeWithTag(TFTag).assertIsFocused()
+ rule.onNodeWithTag(EDMTag).assertIsDisplayed()
+ rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+
+ val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+ val zKey = device.findObject(By.desc("z")) ?: device.findObject(By.text("z"))
+ // Only run the test if we can find a key to type, which might fail for any number of
+ // reasons (keyboard doesn't appear, unexpected locale, etc.)
+ assumeNotNull(zKey)
+
+ repeat(3) {
+ zKey.click()
+ rule.waitForIdle()
+ }
+
+ rule.onNodeWithTag(TFTag).assertTextContains("zzz")
+ rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+ }
+
+ @Test
+ fun edm_expandsAndFocusesTextField_whenTrailingIconClicked() {
rule.setMaterialContent(lightColorScheme()) {
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuForTest(
@@ -146,7 +181,7 @@
}
@Test
- fun expandedBehaviour_doesNotExpandIfTouchEndsOutsideBounds() {
+ fun edm_doesNotExpand_ifTouchEndsOutsideBounds() {
var textFieldBounds = Rect.Zero
rule.setMaterialContent(lightColorScheme()) {
var expanded by remember { mutableStateOf(false) }
@@ -184,7 +219,7 @@
}
@Test
- fun expandedBehaviour_doesNotExpandIfTouchIsPartOfScroll() {
+ fun edm_doesNotExpand_ifTouchIsPartOfScroll() {
val testIndex = 2
var textFieldSize = IntSize.Zero
rule.setMaterialContent(lightColorScheme()) {
@@ -268,7 +303,7 @@
}
@Test
- fun uiProperties_menuMatchesTextWidth() {
+ fun edm_widthMatchesTextFieldWidth() {
var textFieldBounds by mutableStateOf(Rect.Zero)
var menuBounds by mutableStateOf(Rect.Zero)
rule.setMaterialContent(lightColorScheme()) {
@@ -294,7 +329,7 @@
}
@Test
- fun EDMBehaviour_rightOptionIsChosen() {
+ fun edm_collapsesWithSelection_whenMenuItemClicked() {
rule.setMaterialContent(lightColorScheme()) {
var expanded by remember { mutableStateOf(true) }
ExposedDropdownMenuForTest(
@@ -314,8 +349,9 @@
rule.onNodeWithTag(TFTag).assertTextContains(OptionName)
}
+ @Ignore("b/266109857")
@Test
- fun doesNotCrashWhenAnchorDetachedFirst() {
+ fun edm_doesNotCrash_whenAnchorDetachedFirst() {
var parent: FrameLayout? = null
rule.setContent {
AndroidView(
@@ -323,12 +359,20 @@
FrameLayout(context).apply {
addView(ComposeView(context).apply {
setContent {
- Box {
- ExposedDropdownMenuBox(expanded = true, onExpandedChange = {}) {
- Box(
- Modifier
- .menuAnchor()
- .size(20.dp))
+ ExposedDropdownMenuBox(expanded = true, onExpandedChange = {}) {
+ TextField(
+ value = "Text",
+ onValueChange = {},
+ modifier = Modifier.menuAnchor().size(20.dp),
+ )
+ ExposedDropdownMenu(
+ expanded = true,
+ onDismissRequest = {},
+ ) {
+ DropdownMenuItem(
+ text = { Text(OptionName) },
+ onClick = {},
+ )
}
}
}
@@ -349,7 +393,7 @@
@OptIn(ExperimentalMaterial3Api::class)
@Test
- fun withScrolledContent() {
+ fun edm_withScrolledContent() {
rule.setMaterialContent(lightColorScheme()) {
Box(Modifier.fillMaxSize()) {
ExposedDropdownMenuBox(
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
index 1abb4ea..1b21463 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ListItemTest.kt
@@ -36,11 +36,11 @@
import androidx.compose.ui.unit.width
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
-import com.google.common.truth.Truth.assertThat
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/MenuTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/MenuTest.kt
index 0df58c9..26f91f1 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/MenuTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/MenuTest.kt
@@ -146,7 +146,6 @@
}
}
- @OptIn(ExperimentalMaterial3Api::class)
@Test
fun menu_scrolledContent() {
rule.setContent {
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
index 3693245..3b58b83 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarScreenshotTest.kt
@@ -21,6 +21,7 @@
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
@@ -33,6 +34,7 @@
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
@@ -112,6 +114,25 @@
}
@Test
+ fun lightTheme_customHeight() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setMaterialContent(lightColorScheme()) {
+ scope = rememberCoroutineScope()
+ DefaultNavigationBar(interactionSource, Modifier.height(64.dp))
+ }
+
+ assertNavigationBarMatches(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "navigationBar_lightTheme_customHeight"
+ )
+ }
+
+ @Test
fun darkTheme_defaultColors() {
val interactionSource = MutableInteractionSource()
@@ -211,14 +232,16 @@
*
* @param interactionSource the [MutableInteractionSource] for the first [NavigationBarItem], to
* control its visual state.
+ * @param modifier the [Modifier] applied to the navigation bar
* @param setUnselectedItemsAsDisabled when true, marks unselected items as disabled
*/
@Composable
private fun DefaultNavigationBar(
interactionSource: MutableInteractionSource,
+ modifier: Modifier = Modifier,
setUnselectedItemsAsDisabled: Boolean = false,
) {
- Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+ Box(modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
NavigationBar {
NavigationBarItem(
icon = { Icon(Icons.Filled.Favorite, null) },
@@ -242,4 +265,4 @@
}
}
-private const val Tag = "NavigationBar"
\ No newline at end of file
+private const val Tag = "NavigationBar"
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarTest.kt
index e9a0168..2f6c21f 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/NavigationBarTest.kt
@@ -19,6 +19,7 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.tokens.NavigationBarTokens
@@ -266,42 +267,43 @@
@Test
fun navigationBarItemContent_withLabel_sizeAndPosition() {
rule.setMaterialContent(lightColorScheme()) {
- Box {
- NavigationBar {
- NavigationBarItem(
- modifier = Modifier.testTag("item"),
- icon = {
- Icon(Icons.Filled.Favorite, null, Modifier.testTag("icon"))
- },
- label = {
- Text("ItemText")
- },
- selected = true,
- onClick = {}
- )
- }
+ NavigationBar {
+ NavigationBarItem(
+ modifier = Modifier.testTag("item"),
+ icon = {
+ Icon(Icons.Filled.Favorite, null, Modifier.testTag("icon"))
+ },
+ label = {
+ Text("ItemText")
+ },
+ selected = true,
+ onClick = {}
+ )
}
}
val itemBounds = rule.onNodeWithTag("item").getUnclippedBoundsInRoot()
val iconBounds = rule.onNodeWithTag("icon", useUnmergedTree = true)
.getUnclippedBoundsInRoot()
- val textBounds = rule.onNodeWithText("ItemText", useUnmergedTree = true)
- .getUnclippedBoundsInRoot()
- // Distance from the bottom of the item to the text bottom, and from the top of the icon to
- // the top of the item
- val verticalPadding = NavigationBarItemVerticalPadding
-
- val itemBottom = itemBounds.height + itemBounds.top
- // Text bottom should be `verticalPadding` from the bottom of the item
- textBounds.bottom.assertIsEqualTo(itemBottom - verticalPadding)
+ // Distance from the top of the item to the top of the icon for the default height
+ val verticalPadding = 16.dp
rule.onNodeWithTag("icon", useUnmergedTree = true)
- // The icon should be centered in the item
+ // The icon should be horizontally centered in the item
.assertLeftPositionInRootIsEqualTo((itemBounds.width - iconBounds.width) / 2)
// The top of the icon is `verticalPadding` below the top of the item
.assertTopPositionInRootIsEqualTo(itemBounds.top + verticalPadding)
+
+ val iconBottom = iconBounds.top + iconBounds.height
+ // Text should be `IndicatorVerticalPadding + NavigationBarIndicatorToLabelPadding` from the
+ // bottom of the icon
+ rule.onNodeWithText("ItemText", useUnmergedTree = true)
+ .getUnclippedBoundsInRoot()
+ .top
+ .assertIsEqualTo(
+ iconBottom + IndicatorVerticalPadding + NavigationBarIndicatorToLabelPadding
+ )
}
@Test
@@ -367,6 +369,49 @@
}
@Test
+ fun navigationBarItemContent_customHeight_withLabel_sizeAndPosition() {
+ val defaultHeight = NavigationBarTokens.ContainerHeight
+ val customHeight = 64.dp
+
+ rule.setMaterialContent(lightColorScheme()) {
+ NavigationBar(Modifier.height(customHeight)) {
+ NavigationBarItem(
+ modifier = Modifier.testTag("item"),
+ icon = {
+ Icon(Icons.Filled.Favorite, null, Modifier.testTag("icon"))
+ },
+ label = { Text("Label") },
+ selected = true,
+ onClick = {}
+ )
+ }
+ }
+
+ // Vertical padding is removed symmetrically from top and bottom for smaller heights
+ val verticalPadding = 16.dp - (defaultHeight - customHeight) / 2
+
+ val itemBounds = rule.onNodeWithTag("item").getUnclippedBoundsInRoot()
+ val iconBounds = rule.onNodeWithTag("icon", useUnmergedTree = true)
+ .getUnclippedBoundsInRoot()
+
+ rule.onNodeWithTag("icon", useUnmergedTree = true)
+ // The icon should be horizontally centered in the item
+ .assertLeftPositionInRootIsEqualTo((itemBounds.width - iconBounds.width) / 2)
+ // The top of the icon is `verticalPadding` below the top of the item
+ .assertTopPositionInRootIsEqualTo(itemBounds.top + verticalPadding)
+
+ val iconBottom = iconBounds.top + iconBounds.height
+ // Text should be `IndicatorVerticalPadding + NavigationBarIndicatorToLabelPadding` from the
+ // bottom of the item
+ rule.onNodeWithText("Label", useUnmergedTree = true)
+ .getUnclippedBoundsInRoot()
+ .top
+ .assertIsEqualTo(
+ iconBottom + IndicatorVerticalPadding + NavigationBarIndicatorToLabelPadding
+ )
+ }
+
+ @Test
fun navigationBar_selectNewItem() {
rule.setMaterialContent(lightColorScheme()) {
var selectedItem by remember { mutableStateOf(0) }
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
index 91fa287..c8a4298 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/OutlinedTextFieldTest.kt
@@ -395,6 +395,28 @@
}
@Test
+ fun testOutlinedTextField_labelHeight_contributesToTextFieldMeasurements_whenUnfocused() {
+ val tfSize = Ref<IntSize>()
+ val labelHeight = 200.dp
+ rule.setMaterialContent(lightColorScheme()) {
+ OutlinedTextField(
+ value = "",
+ onValueChange = {},
+ modifier = Modifier.testTag(TextFieldTag).onGloballyPositioned {
+ tfSize.value = it.size
+ },
+ label = {
+ Box(Modifier.size(width = 50.dp, height = labelHeight))
+ },
+ )
+ }
+
+ rule.runOnIdleWithDensity {
+ assertThat(tfSize.value!!.height).isAtLeast(labelHeight.roundToPx())
+ }
+ }
+
+ @Test
fun testOutlinedTextField_labelWidth_isNotAffectedByTrailingIcon_whenFocused() {
val textFieldWidth = 100.dp
val labelRequestedWidth = 65.dp
@@ -1135,6 +1157,34 @@
}
@Test
+ fun testOutlinedTextField_supportingText_widthIsNotWiderThanTextField() {
+ val tfSize = Ref<IntSize>()
+ val supportingSize = Ref<IntSize>()
+ rule.setMaterialContent(lightColorScheme()) {
+ OutlinedTextField(
+ value = "",
+ onValueChange = {},
+ modifier = Modifier.onGloballyPositioned {
+ tfSize.value = it.size
+ },
+ supportingText = {
+ Text(
+ text = "Long long long long long long long long long long long long " +
+ "long long long long long long long long long long long long",
+ modifier = Modifier.onGloballyPositioned {
+ supportingSize.value = it.size
+ }
+ )
+ }
+ )
+ }
+
+ rule.runOnIdleWithDensity {
+ assertThat(supportingSize.value!!.width).isAtMost(tfSize.value!!.width)
+ }
+ }
+
+ @Test
fun testOutlinedTextField_supportingText_contributesToTextFieldMeasurements() {
val tfSize = Ref<IntSize>()
rule.setMaterialContent(lightColorScheme()) {
@@ -1156,6 +1206,24 @@
}
@Test
+ fun testOutlinedTextField_supportingText_remainsVisibleWithTallInput() {
+ rule.setMaterialContent(lightColorScheme()) {
+ OutlinedTextField(
+ value = buildString {
+ repeat(200) {
+ append("line $it\n")
+ }
+ },
+ onValueChange = {},
+ modifier = Modifier.size(width = ExpectedDefaultTextFieldWidth, height = 150.dp),
+ supportingText = { Text("Supporting", modifier = Modifier.testTag("Supporting")) }
+ )
+ }
+
+ rule.onNodeWithTag("Supporting", useUnmergedTree = true).assertIsDisplayed()
+ }
+
+ @Test
fun testOutlinedTextField_supportingText_clickFocusesTextField() {
var focused = false
rule.setMaterialContent(lightColorScheme()) {
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
index a5d5e9f..e67aa28 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SnackbarHostTest.kt
@@ -36,10 +36,6 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth
-import org.mockito.kotlin.any
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
@@ -49,6 +45,10 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.AdditionalMatchers.not
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
index 30162ba..5fcafa4 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/SwitchScreenshotTest.kt
@@ -33,10 +33,10 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.InputMode
import androidx.compose.ui.input.InputModeManager
import androidx.compose.ui.platform.LocalInputModeManager
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
index cced64f..318b5c0 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabScreenshotTest.kt
@@ -59,7 +59,7 @@
val screenshotRule = AndroidXScreenshotTestRule(GOLDEN_MATERIAL3)
@Test
- fun lightTheme() {
+ fun lightTheme_primary() {
val interactionSource = MutableInteractionSource()
var scope: CoroutineScope? = null
@@ -67,7 +67,7 @@
composeTestRule.setContent {
scope = rememberCoroutineScope()
MaterialTheme(lightColorScheme()) {
- DefaultTabs(interactionSource)
+ DefaultPrimaryTabs(interactionSource)
}
}
@@ -75,12 +75,12 @@
scope = scope!!,
interactionSource = interactionSource,
interaction = null,
- goldenIdentifier = "tabs_lightTheme"
+ goldenIdentifier = "tabs_lightTheme_primary"
)
}
@Test
- fun lightTheme_pressed() {
+ fun lightTheme_secondary() {
val interactionSource = MutableInteractionSource()
var scope: CoroutineScope? = null
@@ -88,7 +88,28 @@
composeTestRule.setContent {
scope = rememberCoroutineScope()
MaterialTheme(lightColorScheme()) {
- DefaultTabs(interactionSource)
+ DefaultSecondaryTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_lightTheme_secondary"
+ )
+ }
+
+ @Test
+ fun lightTheme_primary_pressed() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ DefaultPrimaryTabs(interactionSource)
}
}
@@ -96,54 +117,12 @@
scope = scope!!,
interactionSource = interactionSource,
interaction = PressInteraction.Press(Offset(10f, 10f)),
- goldenIdentifier = "tabs_lightTheme_pressed"
+ goldenIdentifier = "tabs_lightTheme_primary_pressed"
)
}
@Test
- fun darkTheme() {
- val interactionSource = MutableInteractionSource()
-
- var scope: CoroutineScope? = null
-
- composeTestRule.setContent {
- scope = rememberCoroutineScope()
- MaterialTheme(darkColorScheme()) {
- DefaultTabs(interactionSource)
- }
- }
-
- assertTabsMatch(
- scope = scope!!,
- interactionSource = interactionSource,
- interaction = null,
- goldenIdentifier = "tabs_darkTheme"
- )
- }
-
- @Test
- fun darkTheme_pressed() {
- val interactionSource = MutableInteractionSource()
-
- var scope: CoroutineScope? = null
-
- composeTestRule.setContent {
- scope = rememberCoroutineScope()
- MaterialTheme(darkColorScheme()) {
- DefaultTabs(interactionSource)
- }
- }
-
- assertTabsMatch(
- scope = scope!!,
- interactionSource = interactionSource,
- interaction = PressInteraction.Press(Offset(10f, 10f)),
- goldenIdentifier = "tabs_darkTheme_pressed"
- )
- }
-
- @Test
- fun leadingIconTabs_lightTheme() {
+ fun lightTheme_secondary_pressed() {
val interactionSource = MutableInteractionSource()
var scope: CoroutineScope? = null
@@ -151,20 +130,20 @@
composeTestRule.setContent {
scope = rememberCoroutineScope()
MaterialTheme(lightColorScheme()) {
- DefaultLeadingIconTabs(interactionSource)
+ DefaultSecondaryTabs(interactionSource)
}
}
assertTabsMatch(
scope = scope!!,
interactionSource = interactionSource,
- interaction = null,
- goldenIdentifier = "leadingIconTabs_lightTheme"
+ interaction = PressInteraction.Press(Offset(10f, 10f)),
+ goldenIdentifier = "tabs_lightTheme_secondary_pressed"
)
}
@Test
- fun leadingIconTabs_darkTheme() {
+ fun darkTheme_primary() {
val interactionSource = MutableInteractionSource()
var scope: CoroutineScope? = null
@@ -172,7 +151,7 @@
composeTestRule.setContent {
scope = rememberCoroutineScope()
MaterialTheme(darkColorScheme()) {
- DefaultLeadingIconTabs(interactionSource)
+ DefaultPrimaryTabs(interactionSource)
}
}
@@ -180,7 +159,342 @@
scope = scope!!,
interactionSource = interactionSource,
interaction = null,
- goldenIdentifier = "leadingIconTabs_darkTheme"
+ goldenIdentifier = "tabs_darkTheme_primary"
+ )
+ }
+
+ @Test
+ fun darkTheme_secondary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultSecondaryTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_darkTheme_secondary"
+ )
+ }
+
+ @Test
+ fun darkTheme_primary_pressed() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultPrimaryTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = PressInteraction.Press(Offset(10f, 10f)),
+ goldenIdentifier = "tabs_darkTheme_primary_pressed"
+ )
+ }
+
+ @Test
+ fun darkTheme_secondary_pressed() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultSecondaryTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = PressInteraction.Press(Offset(10f, 10f)),
+ goldenIdentifier = "tabs_darkTheme_secondary_pressed"
+ )
+ }
+
+ @Test
+ fun customTabs_lightTheme_primary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ CustomPrimaryTabs(
+ interactionSource,
+ containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+ selectedContentColor = MaterialTheme.colorScheme.onTertiary,
+ unselectedContentColor = Color.Black
+ )
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "customTabs_lightTheme_primary"
+ )
+ }
+
+ @Test
+ fun customTabs_lightTheme_secondary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ CustomSecondaryTabs(
+ interactionSource,
+ containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+ selectedContentColor = MaterialTheme.colorScheme.onTertiary,
+ unselectedContentColor = Color.Black
+ )
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "customTabs_lightTheme_secondary"
+ )
+ }
+
+ @Test
+ fun customTabs_darkTheme_primary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ CustomPrimaryTabs(
+ interactionSource,
+ containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+ selectedContentColor = MaterialTheme.colorScheme.onTertiary,
+ unselectedContentColor = Color.Black
+ )
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "customTabs_darkTheme_primary"
+ )
+ }
+
+ @Test
+ fun customTabs_darkTheme_secondary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ CustomSecondaryTabs(
+ interactionSource,
+ containerColor = MaterialTheme.colorScheme.tertiaryContainer,
+ selectedContentColor = MaterialTheme.colorScheme.onTertiary,
+ unselectedContentColor = Color.Black
+ )
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "customTabs_darkTheme_secondary"
+ )
+ }
+
+ @Test
+ fun leadingIconTabs_lightTheme_primary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ DefaultPrimaryLeadingIconTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "leadingIconTabs_lightTheme_primary"
+ )
+ }
+
+ @Test
+ fun leadingIconTabs_lightTheme_secondary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ DefaultSecondaryLeadingIconTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "leadingIconTabs_lightTheme_secondary"
+ )
+ }
+
+ @Test
+ fun leadingIconTabs_darkTheme_primary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultPrimaryLeadingIconTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "leadingIconTabs_darkTheme_primary"
+ )
+ }
+
+ @Test
+ fun leadingIconTabs_darkTheme_secondary() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultSecondaryLeadingIconTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "leadingIconTabs_darkTheme_secondary"
+ )
+ }
+
+ @Test
+ fun lightTheme_primary_scrollable() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ DefaultPrimaryScrollableTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_lightTheme_primary_scrollable"
+ )
+ }
+
+ @Test
+ fun lightTheme_secondary_scrollable() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(lightColorScheme()) {
+ DefaultSecondaryScrollableTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_lightTheme_secondary_scrollable"
+ )
+ }
+
+ @Test
+ fun darkTheme_primary_scrollable() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultPrimaryScrollableTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_darkTheme_primary_scrollable"
+ )
+ }
+
+ @Test
+ fun darkTheme_secondary_scrollable() {
+ val interactionSource = MutableInteractionSource()
+
+ var scope: CoroutineScope? = null
+
+ composeTestRule.setContent {
+ scope = rememberCoroutineScope()
+ MaterialTheme(darkColorScheme()) {
+ DefaultSecondaryScrollableTabs(interactionSource)
+ }
+ }
+
+ assertTabsMatch(
+ scope = scope!!,
+ interactionSource = interactionSource,
+ interaction = null,
+ goldenIdentifier = "tabs_darkTheme_secondary_scrollable"
)
}
@@ -213,23 +527,66 @@
}
// Capture and compare screenshots
- composeTestRule.onNodeWithTag(Tag)
+ composeTestRule.onNodeWithTag(TAG)
.captureToImage()
.assertAgainstGolden(screenshotRule, goldenIdentifier)
}
}
/**
- * Default colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ * Default primary colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
*
* @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
* visual state.
*/
@Composable
-private fun DefaultTabs(
+private fun DefaultPrimaryTabs(
interactionSource: MutableInteractionSource
) {
- Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
+ TabRow(selectedTabIndex = 0, indicator = @Composable { tabPositions ->
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
+ width = tabPositions[0].contentWidth
+ )
+ }) {
+ Tab(
+ selected = true,
+ onClick = {},
+ text = { Text("TAB") },
+ interactionSource = interactionSource
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ }
+ }
+}
+
+/**
+ * Default secondary colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ *
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
+ */
+@Composable
+private fun DefaultSecondaryTabs(
+ interactionSource: MutableInteractionSource
+) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
TabRow(selectedTabIndex = 0) {
Tab(
selected = true,
@@ -252,7 +609,7 @@
}
/**
- * Custom colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ * Custom primary colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
*
* @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
* visual state.
@@ -261,17 +618,75 @@
* @param unselectedContentColor the content color for an unselected [Tab] (second and third tabs)
*/
@Composable
-private fun CustomTabs(
+private fun CustomPrimaryTabs(
interactionSource: MutableInteractionSource,
containerColor: Color,
selectedContentColor: Color,
unselectedContentColor: Color
) {
- Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
TabRow(selectedTabIndex = 0,
containerColor = containerColor,
indicator = @Composable { tabPositions ->
- TabRowDefaults.Indicator(
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
+ width = tabPositions[0].contentWidth,
+ color = selectedContentColor
+ )
+ }) {
+ Tab(
+ selected = true,
+ onClick = {},
+ text = { Text("TAB") },
+ selectedContentColor = selectedContentColor,
+ unselectedContentColor = unselectedContentColor,
+ interactionSource = interactionSource
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") },
+ selectedContentColor = selectedContentColor,
+ unselectedContentColor = unselectedContentColor
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") },
+ selectedContentColor = selectedContentColor,
+ unselectedContentColor = unselectedContentColor
+ )
+ }
+ }
+}
+
+/**
+ * Custom secondary colored [TabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ *
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
+ * @param containerColor the containerColor of the [TabRow]
+ * @param selectedContentColor the content color for a selected [Tab] (first tab)
+ * @param unselectedContentColor the content color for an unselected [Tab] (second and third tabs)
+ */
+@Composable
+private fun CustomSecondaryTabs(
+ interactionSource: MutableInteractionSource,
+ containerColor: Color,
+ selectedContentColor: Color,
+ unselectedContentColor: Color
+) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
+ TabRow(selectedTabIndex = 0,
+ containerColor = containerColor,
+ indicator = @Composable { tabPositions ->
+ TabRowDefaults.SecondaryIndicator(
modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
color = selectedContentColor
)
@@ -303,17 +718,64 @@
}
/**
- * Default colored [TabRow] with three [LeadingIconTab]s. The first [LeadingIconTab] is selected,
+ * Default primary colored [TabRow] with three [LeadingIconTab]s. The first [LeadingIconTab] is selected,
* and the rest are not.
*
* @param interactionSource the [MutableInteractionSource] for the first [LeadingIconTab], to control its
* visual state.
*/
@Composable
-private fun DefaultLeadingIconTabs(
+private fun DefaultPrimaryLeadingIconTabs(
interactionSource: MutableInteractionSource
) {
- Box(Modifier.semantics(mergeDescendants = true) {}.testTag(Tag)) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
+ TabRow(selectedTabIndex = 0, indicator = @Composable { tabPositions ->
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
+ width = tabPositions[0].contentWidth
+ )
+ }) {
+ LeadingIconTab(
+ selected = true,
+ onClick = {},
+ text = { Text("TAB") },
+ icon = { Icon(Icons.Filled.Favorite, contentDescription = "Favorite") },
+ interactionSource = interactionSource
+ )
+ LeadingIconTab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") },
+ icon = { Icon(Icons.Filled.Favorite, contentDescription = "Favorite") }
+ )
+ LeadingIconTab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") },
+ icon = { Icon(Icons.Filled.Favorite, contentDescription = "Favorite") }
+ )
+ }
+ }
+}
+
+/**
+ * Default secondary colored [TabRow] with three [LeadingIconTab]s. The first [LeadingIconTab] is selected,
+ * and the rest are not.
+ *
+ * @param interactionSource the [MutableInteractionSource] for the first [LeadingIconTab], to control its
+ * visual state.
+ */
+@Composable
+private fun DefaultSecondaryLeadingIconTabs(
+ interactionSource: MutableInteractionSource
+) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
TabRow(selectedTabIndex = 0) {
LeadingIconTab(
selected = true,
@@ -338,4 +800,79 @@
}
}
-private const val Tag = "Tab"
+/**
+ * Default primary colored [ScrollableTabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ *
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
+ */
+@Composable
+private fun DefaultPrimaryScrollableTabs(
+ interactionSource: MutableInteractionSource
+) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
+ ScrollableTabRow(selectedTabIndex = 0, indicator = @Composable { tabPositions ->
+ TabRowDefaults.PrimaryIndicator(
+ modifier = Modifier.tabIndicatorOffset(tabPositions[0]),
+ width = tabPositions[0].contentWidth
+ )
+ }) {
+ Tab(
+ selected = true,
+ onClick = {},
+ text = { Text("TAB") },
+ interactionSource = interactionSource
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ }
+ }
+}
+
+/**
+ * Default secondary colored [ScrollableTabRow] with three [Tab]s. The first [Tab] is selected, and the rest are not.
+ *
+ * @param interactionSource the [MutableInteractionSource] for the first [Tab], to control its
+ * visual state.
+ */
+@Composable
+private fun DefaultSecondaryScrollableTabs(
+ interactionSource: MutableInteractionSource
+) {
+ Box(
+ Modifier
+ .semantics(mergeDescendants = true) {}
+ .testTag(TAG)) {
+ ScrollableTabRow(selectedTabIndex = 0) {
+ Tab(
+ selected = true,
+ onClick = {},
+ text = { Text("TAB") },
+ interactionSource = interactionSource
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ Tab(
+ selected = false,
+ onClick = {},
+ text = { Text("TAB") }
+ )
+ }
+ }
+}
+
+private const val TAG = "Tab"
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabTest.kt
index 4ff880a..7b9ed6e 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TabTest.kt
@@ -27,7 +27,7 @@
import androidx.compose.material3.samples.LeadingIconTabs
import androidx.compose.material3.samples.ScrollingTextTabs
import androidx.compose.material3.samples.TextTabs
-import androidx.compose.material3.tokens.PrimaryNavigationTabTokens
+import androidx.compose.material3.tokens.DividerTokens
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
@@ -326,9 +326,9 @@
rule.onNodeWithTag("divider", true)
.assertPositionInRootIsEqualTo(
expectedLeft = 0.dp,
- expectedTop = tabRowBounds.height - PrimaryNavigationTabTokens.DividerHeight
+ expectedTop = tabRowBounds.height - DividerTokens.Thickness
)
- .assertHeightIsEqualTo(PrimaryNavigationTabTokens.DividerHeight)
+ .assertHeightIsEqualTo(DividerTokens.Thickness)
}
@Test
@@ -435,7 +435,7 @@
}
@Test
- fun LeadingIconTab_textAndIconPosition() {
+ fun leadingIconTab_textAndIconPosition() {
rule.setMaterialContent(lightColorScheme()) {
Box {
TabRow(
@@ -564,9 +564,9 @@
rule.onNodeWithTag("divider", true)
.assertPositionInRootIsEqualTo(
expectedLeft = 0.dp,
- expectedTop = tabRowBounds.height - PrimaryNavigationTabTokens.DividerHeight,
+ expectedTop = tabRowBounds.height - DividerTokens.Thickness,
)
- .assertHeightIsEqualTo(PrimaryNavigationTabTokens.DividerHeight)
+ .assertHeightIsEqualTo(DividerTokens.Thickness)
}
@Test
@@ -593,8 +593,10 @@
TextTabs()
}
+ val nodes = rule.onAllNodes(isSelectable())
+
// Only the first tab should be selected
- rule.onAllNodes(isSelectable())
+ nodes
.assertCountEquals(3)
.apply {
get(0).assertIsSelected()
@@ -603,10 +605,10 @@
}
// Click the last tab
- rule.onAllNodes(isSelectable())[2].performClick()
+ nodes[2].performClick()
// Now only the last tab should be selected
- rule.onAllNodes(isSelectable())
+ nodes
.assertCountEquals(3)
.apply {
get(0).assertIsNotSelected()
@@ -747,7 +749,7 @@
val titles = listOf("TAB 1", "TAB 2", "TAB 3 WITH LOTS OF TEXT")
val indicator = @Composable { tabPositions: List<TabPosition> ->
- TabRowDefaults.Indicator(
+ TabRowDefaults.SecondaryIndicator(
Modifier
.tabIndicatorOffset(tabPositions[state])
.testTag("indicator")
@@ -791,7 +793,7 @@
@Test
fun testInspectorValue() {
- val pos = TabPosition(10.0.dp, 200.0.dp)
+ val pos = TabPosition(10.0.dp, 200.0.dp, 0.dp)
rule.setContent {
val modifier = Modifier.tabIndicatorOffset(pos) as InspectableValue
assertThat(modifier.nameFallback).isEqualTo("tabIndicatorOffset")
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
index 89dbd0d..1938541 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
@@ -30,6 +30,8 @@
import androidx.compose.runtime.remember
import androidx.compose.testutils.assertPixels
import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
@@ -605,6 +607,7 @@
) {
var size: IntSize? = null
var position: Offset? = null
+ val focusRequester = FocusRequester()
rule.setMaterialContent(lightColorScheme()) {
CompositionLocalProvider(
LocalLayoutDirection provides layoutDirection,
@@ -616,6 +619,7 @@
BasicTextField(
value = value,
onValueChange = {},
+ modifier = Modifier.focusRequester(focusRequester),
singleLine = singleLine,
interactionSource = interactionSource
) {
@@ -656,6 +660,10 @@
}
}
+ rule.runOnUiThread {
+ focusRequester.requestFocus()
+ }
+
rule.runOnIdle {
with(Density) {
assertThat(size).isNotNull()
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
index c0f9b3f..ef94485 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
@@ -69,6 +69,7 @@
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertHeightIsEqualTo
+import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertWidthIsEqualTo
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.click
@@ -98,17 +99,17 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
@OptIn(ExperimentalMaterial3Api::class)
@MediumTest
@@ -1121,6 +1122,34 @@
}
@Test
+ fun testTextField_supportingText_widthIsNotWiderThanTextField() {
+ val tfSize = Ref<IntSize>()
+ val supportingSize = Ref<IntSize>()
+ rule.setMaterialContent(lightColorScheme()) {
+ TextField(
+ value = "",
+ onValueChange = {},
+ modifier = Modifier.onGloballyPositioned {
+ tfSize.value = it.size
+ },
+ supportingText = {
+ Text(
+ text = "Long long long long long long long long long long long long " +
+ "long long long long long long long long long long long long",
+ modifier = Modifier.onGloballyPositioned {
+ supportingSize.value = it.size
+ }
+ )
+ }
+ )
+ }
+
+ rule.runOnIdleWithDensity {
+ assertThat(supportingSize.value!!.width).isAtMost(tfSize.value!!.width)
+ }
+ }
+
+ @Test
fun testTextField_supportingText_contributesToTextFieldMeasurements() {
val tfSize = Ref<IntSize>()
rule.setMaterialContent(lightColorScheme()) {
@@ -1142,6 +1171,24 @@
}
@Test
+ fun testTextField_supportingText_remainsVisibleWithTallInput() {
+ rule.setMaterialContent(lightColorScheme()) {
+ TextField(
+ value = buildString {
+ repeat(200) {
+ append("line $it\n")
+ }
+ },
+ onValueChange = {},
+ modifier = Modifier.size(width = ExpectedDefaultTextFieldWidth, height = 150.dp),
+ supportingText = { Text("Supporting", modifier = Modifier.testTag("Supporting")) }
+ )
+ }
+
+ rule.onNodeWithTag("Supporting", useUnmergedTree = true).assertIsDisplayed()
+ }
+
+ @Test
fun testTextField_supportingText_clickFocusesTextField() {
var focused = false
rule.setMaterialContent(lightColorScheme()) {
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
index 0acd46a..5948252 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/AndroidMenu.android.kt
@@ -75,7 +75,6 @@
* @param content the content of this dropdown menu, typically a [DropdownMenuItem]
*/
@OptIn(ExperimentalMaterial3Api::class)
-@Suppress("ModifierParameter")
@Deprecated(
level = DeprecationLevel.HIDDEN,
replaceWith = ReplaceWith(
@@ -147,7 +146,6 @@
* @param properties [PopupProperties] for further customization of this popup's behavior
* @param content the content of this dropdown menu, typically a [DropdownMenuItem]
*/
-@Suppress("ModifierParameter")
@Composable
fun DropdownMenu(
expanded: Boolean,
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
index b863609..cd1d852 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
@@ -41,6 +41,7 @@
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -108,8 +109,8 @@
) {
val density = LocalDensity.current
val view = LocalView.current
- var width by remember { mutableStateOf(0) }
- var menuHeight by remember { mutableStateOf(0) }
+ var width by remember { mutableIntStateOf(0) }
+ var menuHeight by remember { mutableIntStateOf(0) }
val verticalMarginInPx = with(density) { MenuVerticalMargin.roundToPx() }
val coordinates = remember { Ref<LayoutCoordinates>() }
@@ -122,12 +123,8 @@
onGloballyPositioned {
width = it.size.width
coordinates.value = it
- updateHeight(
- view.rootView,
- coordinates.value,
- verticalMarginInPx
- ) { newHeight ->
- menuHeight = newHeight
+ updateHeight(view.rootView, coordinates.value, verticalMarginInPx) {
+ newHeight -> menuHeight = newHeight
}
}.expandable(
expanded = expanded,
@@ -1044,18 +1041,18 @@
private fun updateHeight(
view: View,
- coordinates: LayoutCoordinates?,
+ anchorCoordinates: LayoutCoordinates?,
verticalMarginInPx: Int,
onHeightUpdate: (Int) -> Unit
) {
- coordinates ?: return
+ anchorCoordinates ?: return
val visibleWindowBounds = Rect().let {
view.getWindowVisibleDisplayFrame(it)
it
}
- val heightAbove = coordinates.boundsInWindow().top - visibleWindowBounds.top
- val heightBelow =
- visibleWindowBounds.bottom - visibleWindowBounds.top - coordinates.boundsInWindow().bottom
+ val heightAbove = anchorCoordinates.boundsInWindow().top - visibleWindowBounds.top
+ val heightBelow = visibleWindowBounds.bottom - visibleWindowBounds.top -
+ anchorCoordinates.boundsInWindow().bottom
onHeightUpdate(max(heightAbove, heightBelow).toInt() - verticalMarginInPx)
}
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/TouchExplorationStateProvider.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/TouchExplorationStateProvider.android.kt
index cbb7308..955ebc5 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/TouchExplorationStateProvider.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/TouchExplorationStateProvider.android.kt
@@ -25,9 +25,9 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt
index d18f90d..67a996d 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt
@@ -32,7 +32,6 @@
import androidx.compose.runtime.CompositionContext
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -64,9 +63,9 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastMap
import androidx.compose.ui.window.PopupPositionProvider
-import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
@@ -85,7 +84,6 @@
) {
val view = LocalView.current
val density = LocalDensity.current
- val testTag = LocalPopupTestTag.current
val layoutDirection = LocalLayoutDirection.current
val parentComposition = rememberCompositionContext()
val currentContent by rememberUpdatedState(content)
@@ -93,10 +91,9 @@
val popupLayout = remember {
PopupLayout(
onDismissRequest = onDismissRequest,
- testTag = testTag,
composeView = view,
+ positionProvider = popupPositionProvider,
density = density,
- initialPositionProvider = popupPositionProvider,
popupId = popupId
).apply {
setContent(parentComposition) {
@@ -121,7 +118,6 @@
popupLayout.show()
popupLayout.updateParameters(
onDismissRequest = onDismissRequest,
- testTag = testTag,
layoutDirection = layoutDirection
)
onDispose {
@@ -134,17 +130,10 @@
SideEffect {
popupLayout.updateParameters(
onDismissRequest = onDismissRequest,
- testTag = testTag,
layoutDirection = layoutDirection
)
}
- DisposableEffect(popupPositionProvider) {
- popupLayout.positionProvider = popupPositionProvider
- popupLayout.updatePosition()
- onDispose {}
- }
-
// TODO(soboleva): Look at module arrangement so that Box can be
// used instead of this custom Layout
// Get the parent's position, size and layout direction
@@ -167,11 +156,6 @@
}
}
-// TODO(b/139861182): This is a hack to work around Popups not using Semantics for test tags
-// We should either remove it, or come up with an abstracted general solution that isn't specific
-// to Popup
-internal val LocalPopupTestTag = compositionLocalOf { "DEFAULT_TEST_TAG" }
-
// TODO(soboleva): Look at module dependencies so that we can get code reuse between
// Popup's SimpleStack and Box.
@Suppress("NOTHING_TO_INLINE")
@@ -214,21 +198,18 @@
@SuppressLint("ViewConstructor")
private class PopupLayout(
private var onDismissRequest: (() -> Unit)?,
- var testTag: String,
private val composeView: View,
+ private val positionProvider: PopupPositionProvider,
density: Density,
- initialPositionProvider: PopupPositionProvider,
popupId: UUID
) : AbstractComposeView(composeView.context),
ViewRootForInspector,
ViewTreeObserver.OnGlobalLayoutListener {
+
private val windowManager =
composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val params = createLayoutParams()
- /** The logic of positioning the popup relative to its parent. */
- var positionProvider = initialPositionProvider
-
// Position params
var parentLayoutDirection: LayoutDirection = LayoutDirection.Ltr
var parentBounds: IntRect? by mutableStateOf(null)
@@ -247,15 +228,6 @@
override val subCompositionView: AbstractComposeView get() = this
- // Specific to exposed dropdown menus.
- private val dismissOnOutsideClick = { offset: Offset?, bounds: IntRect ->
- if (offset == null) false
- else {
- offset.x < bounds.left || offset.x > bounds.right ||
- offset.y < bounds.top || offset.y > bounds.bottom
- }
- }
-
init {
id = android.R.id.content
setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner())
@@ -304,9 +276,7 @@
content()
}
- /**
- * Taken from PopupWindow
- */
+ // Taken from PopupWindow. Calls [onDismissRequest] when back button is pressed.
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event.keyCode == KeyEvent.KEYCODE_BACK) {
if (keyDispatcherState == null) {
@@ -329,11 +299,9 @@
fun updateParameters(
onDismissRequest: (() -> Unit)?,
- testTag: String,
layoutDirection: LayoutDirection
) {
this.onDismissRequest = onDismissRequest
- this.testTag = testTag
superSetLayoutDirection(layoutDirection)
}
@@ -383,28 +351,18 @@
// matter whether we return true or false as some upper layer decides on whether the
// event is propagated to other windows or not. So for focusable the event is consumed but
// for not focusable it is propagated to other windows.
- if (
- (
- (event.action == MotionEvent.ACTION_DOWN) &&
- (
- (event.x < 0) ||
- (event.x >= width) ||
- (event.y < 0) ||
- (event.y >= height)
- )
- ) ||
- event.action == MotionEvent.ACTION_OUTSIDE
+ if (event.action == MotionEvent.ACTION_OUTSIDE ||
+ (event.action == MotionEvent.ACTION_DOWN &&
+ (event.x < 0 || event.x >= width || event.y < 0 || event.y >= height))
) {
val parentBounds = parentBounds
val shouldDismiss = parentBounds == null || dismissOnOutsideClick(
- if (event.x != 0f || event.y != 0f) {
- Offset(
- params.x + event.x,
- params.y + event.y
- )
- } else null,
+ // Keep menu open if ACTION_OUTSIDE event is reported as raw coordinates of (0, 0).
+ // This means it belongs to another owner, e.g., the soft keyboard or other window.
+ if (event.rawX != 0f && event.rawY != 0f) Offset(event.rawX, event.rawY) else null,
parentBounds
)
+
if (shouldDismiss) {
onDismissRequest?.invoke()
return true
@@ -427,6 +385,15 @@
super.setLayoutDirection(direction)
}
+ // Specific to exposed dropdown menus.
+ private fun dismissOnOutsideClick(offset: Offset?, bounds: IntRect): Boolean =
+ if (offset == null) {
+ false
+ } else {
+ offset.x < bounds.left || offset.x > bounds.right ||
+ offset.y < bounds.top || offset.y > bounds.bottom
+ }
+
/**
* Initialize the LayoutParams specific to [android.widget.PopupWindow].
*/
diff --git a/compose/material3/material3/src/androidMain/res/values-af/strings.xml b/compose/material3/material3/src/androidMain/res/values-af/strings.xml
new file mode 100644
index 0000000..52938d3
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-af/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialoog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Uitgevou"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Ingevou"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Maak toe"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Soek"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Voorstelle hieronder"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Kies datum"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Gekose datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Skakel oor na kies van ’n jaar"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swiep om ’n jaar te kies of tik om terug te skakel om ’n dag te kies"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Verander na volgende maand"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Verander na vorige maand"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Gaan na jaar %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Huidige keuse: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Geen"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Vandag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Jaarkieser sigbaar"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Kies datum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Datum wat ingevoer is"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Datum wat ingevoer is: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Geen"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datum word nie toegelaat nie: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum pas nie by die verwagte patroon nie: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum val buite verwagte jaardatumreeks %1$s-%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Skakel oor na kalenderinvoermodus"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Skakel oor na teksinvoermodus"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Rollees om later jare te wys"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Rollees om vroeër jare te wys"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Kies datums"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Begindatum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Einddatum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Rollees om die volgende maand te wys"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Rollees om die vorige maand te wys"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Binne datumreeks"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Voer datums in"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Ongeldige datumreeksinvoer"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Sleephandvatsel"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Vou onderste blad in"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Maak onderste blad toe"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Vou onderste blad uit"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Nutswenk"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Wys nutswenk"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"nm."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"vm."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Kies vm. of nm."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Kies uur"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Kies minute"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d uur"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d uur"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minute"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Uur"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"vir minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"vir uur"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-am/strings.xml b/compose/material3/material3/src/androidMain/res/values-am/strings.xml
new file mode 100644
index 0000000..a91d248
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-am/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"መገናኛ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ተዘርግቷል"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ተሰብስቧል"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"አሰናብት"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ፈልግ"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"የአስተያየት ጥቆማዎች ከታች"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ቀን ይምረጡ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"የተመረጠው ቀን"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ወደ ዓመት መምረጥ ይቀይሩ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ዓመት ለመምረጥ ያንሸራትቱ ወይም ወደ ቀንን መምረጥ መልሶ ለመቀየር መታ ያድርጉ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ወደ የሚቀጥለው ወር ይቀይሩ"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ወደ ቀዳሚው ወር ይቀይሩ"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"ወደ ዓመት %1$s ያስሱ"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"የአሁን ምርጫ፦ %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ምንም"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ዛሬ"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ዓመት መራጭ ይታያል"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ቀን ይምረጡ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"የገባው ቀን"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ቀን"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"የገባው ቀን፦ %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ምንም"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ቀን አልተፈቀደም፦ %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ቀኑ ከተጠበቀው ስርዓተ ጥለት ጋር አይዛመድም፦ %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ቀን ከተጠበቀው የዓመት ክልል ውጪ ነው %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ወደ የቀን መቁጠሪያ ግቤት ሁነታ ይቀይሩ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ወደ የጽሁፍ ግቤት ሁነታ ይቀይሩ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"ከዚህ በኋላ ያሉ ዓመታትን ለማሳየት ያሸብልሉ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ቀደም ያሉ ዓመታትን ለማሳየት ያሸብልሉ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ቀናትን ይምረጡ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"መጀመሪያ ቀን"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"የማብቂያ ቀን"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ቀጣዩን ወር ለማሳየት ያሸብልሉ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ቀዳሚውን ወር ለማሳየት ያሸብልሉ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"በክልል ውስጥ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ቀናትን ያስገቡ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ልክ ያልሆነ የቀን ክልል ግቤት"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"መያዣ ይጎትቱ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"የግርጌ ሉህን ይሰብስቡ"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"የግርጌ ሉህን ያሰናብቱ"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"የግርጌ ሉህ ይዘርጉ"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"የመሣሪያ ጥቆማ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"መሣሪያ ጥቆማን አሳይ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ፒኤም"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ኤኤም"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"ኤኤም ወይም ፒኤምን ይምረጡ"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ሰዓት ምረጥ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ደቂቃዎችን ምረጥ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d ሰዓት"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ሰዓታት"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d ደቂቃዎች"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"ደቂቃ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ሰዓት"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ለደቂቃዎች"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ለሰዓት"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ar/strings.xml b/compose/material3/material3/src/androidMain/res/values-ar/strings.xml
new file mode 100644
index 0000000..c133e1c5
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ar/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"مربّع حوار"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"موسَّعة"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"مصغَّرة"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"إغلاق"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"شريط بحث"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"إليك الاقتراحات"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"اختيار تاريخ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"التاريخ المحدَّد"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"التبديل لاختيار سنة"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"مرِّر سريعًا لتحديد سنة، أو انقر للرجوع إلى تحديد يوم."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"التغيير إلى الشهر التالي"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"التغيير إلى الشهر السابق"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"الانتقال إلى سنة %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"الاختيار الحالي: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"بدون تاريخ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"اليوم"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"أداة اختيار السنوات مرئية"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"اختيار تاريخ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"التاريخ الذي تم إدخاله"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"التاريخ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"التاريخ الذي تم إدخاله: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"بدون تاريخ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"التاريخ غير مسموح به: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"لا يتوافق التاريخ مع النمط المتوقَّع: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"التاريخ خارج نطاق السنوات المتوقَّع: %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"التبديل إلى وضع \"الإدخال في التقويم\""</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"التبديل إلى \"وضع إدخال النص\""</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"انتقِل للأسفل أو للأعلى لإظهار السنوات التالية."</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"انتقِل للأسفل أو للأعلى لإظهار السنوات السابقة."</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"اختيار التواريخ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"تاريخ البدء"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"تاريخ الانتهاء"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"انتقِل للأسفل أو للأعلى لإظهار الشهر التالي."</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"انتقِل للأسفل أو للأعلى لإظهار الشهر السابق."</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"في النطاق"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"إدخال التواريخ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"إدخال نطاق زمني غير صالح"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"مقبض السحب"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"تصغير البطاقة السفلية"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"إغلاق البطاقة السفلية"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"توسيع البطاقة السفلية"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"تلميح"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"إظهار التلميح"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"م"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ص"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"يُرجى اختيار \"ص\" أو \"م\"."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"اختيار الساعة"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"اختيار الدقائق"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"الساعة %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ساعة"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d دقيقة"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"دقيقة"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ساعة"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"الدقائق"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"الساعات"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-as/strings.xml b/compose/material3/material3/src/androidMain/res/values-as/strings.xml
new file mode 100644
index 0000000..20cbe7e
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-as/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ডায়ল’গ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"বিস্তাৰ কৰা আছে"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"সংকোচন কৰা আছে"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"অগ্ৰাহ্য কৰক"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"সন্ধান কৰক"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"তলত পৰামৰ্শ দেখুওৱা হৈছে"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"তাৰিখ বাছনি কৰক"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"বাছনি কৰা তাৰিখ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"বছৰ বাছনি কৰাৰ সুবিধাটোলৈ সলনি কৰক"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"এটা বছৰ বাছনি কৰিবলৈ ছোৱাইপ কৰক অথবা এটা দিন বাছনি কৰাৰ সুবিধাটোলৈ উভতি যাবলৈ টিপক"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"পৰৱৰ্তী মাহলৈ সলনি কৰক"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"পূৰ্বৱৰ্তী মাহলৈ সলনি কৰক"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"বৰ্ষ %1$sলৈ নেভিগে’ট কৰক"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"বৰ্তমানৰ বাছনি: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"নাই"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"আজি"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"বছৰ বাছনিকৰ্তা দৃশ্যমান"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"তাৰিখ বাছনি কৰক"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"দিয়া তাৰিখ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"তাৰিখ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"দিয়া তাৰিখ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"নাই"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"অনুমোদিত নোহোৱা তাৰিখ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"তাৰিখটো এই প্ৰত্যাশিত আৰ্হিটোৰ সৈতে মিলা নাই: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"তাৰিখটো প্ৰত্যাশিত বছৰৰ পৰিসৰ %1$s - %2$sৰ বাহিৰৰ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"কেলেণ্ডাৰ ইনপুট ম’ডলৈ সলনি কৰক"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"পাঠ ইনপুট ম’ডলৈ সলনি কৰক"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"পাছৰ বছৰবোৰ দেখুৱাবলৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"আগৰ বছৰবোৰ দেখুৱাবলৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"তাৰিখ বাছনি কৰক"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"আৰম্ভণিৰ তাৰিখ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"সমাপ্তিৰ তাৰিখ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"পৰৱৰ্তী মাহটো দেখুৱাবলৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"পূৰ্বৱৰ্তী মাহটো দেখুৱাবলৈ স্ক্ৰ’ল কৰক"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"পৰিসৰৰ ভিতৰত আছে"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"তাৰিখ দিয়ক"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"অমান্য তাৰিখৰ পৰিসৰৰ ইনপুট"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ড্ৰেগ হেণ্ডেল"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"তলৰ শ্বীটখন সংকোচন কৰক"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"তলৰ শ্বীটখন অগ্ৰাহ্য কৰক"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"তলৰ শ্বীটখন বিস্তাৰ কৰক"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"টুলটিপ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"টুলটিপ দেখুৱাওক"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM অথবা PM বাছনি কৰক"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ঘণ্টা বাছনি কৰক"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"মিনিট বাছনি কৰক"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d বাজিছে"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ঘণ্টা"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d মিনিট"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"মিনিট"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ঘণ্টা"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"মিনিটৰ বাবে"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ঘণ্টাৰ বাবে"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-az/strings.xml b/compose/material3/material3/src/androidMain/res/values-az/strings.xml
new file mode 100644
index 0000000..4d882ac
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-az/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialoq"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Genişləndirilb"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Yığcamlaşdırılıb"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Rədd edin"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Axtarış"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Təkliflər aşağıdadır"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Tarix seçin"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Seçilmiş tarix"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"İl seçiminə keçin"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"İl seçmək üçün sürüşdürün. Gün seçiminə qayıtmaq üçün toxunun"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Növbəti aya dəyişin"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Əvvəlki aya dəyişin"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Bu ilə keçin: %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Cari seçim: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Yoxdur"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Bu gün"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"İl seçicisi görünür"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Tarix seçin"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Daxil edilmiş tarix"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Tarix"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Daxil edilmiş tarix: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Yoxdur"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Tarixə icazə verilmir: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Tarix gözlənilən modelə uyğun gəlmir: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Tarix gözlənilən il aralığından kənardır: %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Təqvim daxiletmə rejiminə keçin"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Mətn daxiletmə rejiminə keçin"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Sonrakı illəri göstərmək üçün sürüşdürün"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Əvvəlki illəri göstərmək üçün sürüşdürün"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Tarixlər seçin"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Başlama tarixi"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Bitmə tarixi"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Növbəti ayı göstərmək üçün sürüşdürün"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Əvvəlki ayı göstərmək üçün sürüşdürün"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Bu aralıqda"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Tarixlər daxil edin"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Yanlış tarix aralığı daxiletməsi"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Dəstəyi çəkin"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Aşağıdakı vərəqi yığcamlaşdırın"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Aşağıdakı vərəqi rədd edin"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Aşağıdakı vərəqi genişləndirin"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Alət izahı"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Alət izahını göstərin"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM və ya PM seçin"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Saat seçin"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Dəqiqə seçin"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Saat: %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d saat"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d dəqiqə"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Dəqiqə"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Saat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"dəqiqəlik"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"saatlıq"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-b+sr+Latn/strings.xml b/compose/material3/material3/src/androidMain/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..82602ea
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dijalog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Prošireno je"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Skupljeno je"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Odbaci"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pretraga"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Predlozi su u nastavku"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Izaberite datum"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Izabrani datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Pređite na izbor godine"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Prevucite da biste izabrali godinu ili dodirnite da biste se vratili na izbor dana"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Pređite na sledeći mesec"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Pređite na prethodni mesec"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Idite na godinu: %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuelni izbor: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ništa"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Danas"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Vidljiv birač godina"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Izaberite datum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Uneti datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Uneti datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ništa"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datum nije dozvoljen: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum ne odgovara očekivanom šablonu: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum je izvan očekivanog opsega godina %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Pređite na režim unosa u Kalendaru"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Pređite na režim unosa teksta"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Skrolujte da bi se prikazale kasnije godine"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Skrolujte da bi se prikazale ranije godine"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Izaberite datume"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Datum početka"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Datum završetka"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Pomerajte da bi se prikazao sledeći mesec"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Pomerajte da bi se prikazao prethodni mesec"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"U opsegu"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Unesite datume"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Unos opsega datuma je nevažeći"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Identifikator za prevlačenje"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Skupite donju tabelu"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Odbacite donju tabelu"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Proširite donju tabelu"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Objašnjenje"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Prikažite objašnjenje"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Izaberite pre podne ili po podne"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Izaberite sat"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Izaberite minute"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d s"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d s"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d min"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Sat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"za minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"za sate"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-be/strings.xml b/compose/material3/material3/src/androidMain/res/values-be/strings.xml
new file mode 100644
index 0000000..bf493db
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-be/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Дыялогавае акно"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Разгорнута"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Згорнута"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Закрыць"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Пошук"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Прапановы ўнізе"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Выберыце дату"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Выбраная дата"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Перайсці да выбару года"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Правядзіце пальцам, каб выбраць год, або націсніце, каб вярнуцца да выбару даты"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Перайсці да наступнага месяца"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Перайсці да папярэдняга месяца"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Перайсці ў год %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Бягучы выбар: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Без абмежаванняў"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Сёння"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Бачны інструмент выбару года"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Выберыце дату"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Уведзеная дата"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Дата"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Уведзеная дата: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Без абмежаванняў"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Дата забаронена: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Дата не адпавядае ўзору: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Дата выходзіць за дазволены дыяпазон гадоў %1$s-%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Пераключыцца ў рэжым уводу \"Каляндар\""</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Пераключыцца ў рэжым уводу \"Тэкст\""</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Прагартайце экран, каб прагледзець пазнейшыя гады"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Прагартайце экран, каб прагледзець ранейшыя гады"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Выберыце даты"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Дата пачатку"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Дата заканчэння"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Прагартайце экран, каб прагледзець наступны месяц"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Прагартайце экран, каб прагледзець мінулы месяц"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"У межах дыяпазону"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Увядзіце даты"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Уведзены няправільны дыяпазон дат"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Маркер перацягвання"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Згарнуць ніжні аркуш"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Закрыць ніжні аркуш"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Разгарнуць ніжні аркуш"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Падказка"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Паказваць усплывальую падказку"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"пасля паўдня"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"да паўдня"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Выберыце AM (да паўдня) або PM (пасля паўдня)"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Выберыце гадзіны"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Выберыце хвіліны"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d гадз"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d гадз"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d хв"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Хвіліны"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Гадзіны"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"хвіліны"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"гадзіны"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-bg/strings.xml b/compose/material3/material3/src/androidMain/res/values-bg/strings.xml
new file mode 100644
index 0000000..f600a9a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-bg/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Диалогов прозорец"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Разгънато"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Свито"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Отхвърляне"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Лента за търсене"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Предложенията са по-долу"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Избиране на дата"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Избрана дата"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Превключване към избиране на година"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Прекарайте пръст, за да изберете година, или докоснете, за да се върнете към избора на ден"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Преминаване към следващия месец"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Преминаване към предишния месец"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Навигиране до %1$s година"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Текущ избор: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Няма"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Днес"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Инструментът за избор на година е видим"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Избиране на дата"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Въведена дата"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Дата"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Въведена дата: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Няма"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Датата не е разрешена: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Датата не е в очаквания формат: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Датата е извън очаквания годишен диапазон: %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Превключване към режим за въвеждане в календар"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Превключване към режим за въвеждане на текст"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Превъртете, за да се покажат следващите години"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Превъртете, за да се покажат миналите години"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Избиране на дати"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Начална дата"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Крайна дата"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Превъртете, за да се покаже следващият месец"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Превъртете, за да се покаже предишният месец"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"В диапазона"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Въвеждане на дати"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Въведен е невалиден период от време"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Манипулатор за преместване с плъзгане"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Свиване на долния лист"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Отхвърляне на долния лист"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Разгъване на долния лист"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Подсказка"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Показване на подсказка"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Изберете AM или PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Изберете час"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Изберете минути"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d часа"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d часа"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d минути"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Минута"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Час"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"за минутите"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"за часа"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-bn/strings.xml b/compose/material3/material3/src/androidMain/res/values-bn/strings.xml
new file mode 100644
index 0000000..1a04e7f
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-bn/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ডায়ালগ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"বড় করা হয়েছে"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"আড়াল করা হয়েছে"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"বাতিল করুন"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"সার্চ করুন"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"নিচে দেওয়া সাজেশন"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"তারিখ বেছে নিন"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"বেছে নেওয়া তারিখ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"কোনও একটি বছর বেছে নিতে বদল করুন"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"একটি বছর বেছে নিতে সোয়াইপ করুন অথবা দিন বেছে নেওয়ার বিকল্পে ফিরে যেতে ট্যাপ করুন"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"আগামী মাসে পরিবর্তন করুন"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"আগের মাসে পরিবর্তন করুন"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"নেভিগেট করে %1$s বছরে যান"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"বর্তমানে বেছে নেওয়া হয়েছে: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"কোনওটিই নয়"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"আজ"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"বছর বেছে নেওয়ার তালিকা দেখা যাচ্ছে"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"তারিখ বেছে নিন"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"উল্লেখ করা তারিখ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"তারিখ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"উল্লেখ করা তারিখ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"কোনওটিই নয়"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"এই তারিখ লেখা যাবে না: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"প্রত্যাশিত প্যাটার্নের সাথে তারিখ মিলছে না: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"প্রত্যাশিত বছরের রেঞ্জের বাইরের তারিখ %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ক্যালেন্ডার ইনপুট মোডে বদল করুন"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"টেক্সট ইনপুট মোডে বদল করুন"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"পরের বছরগুলি দেখতে স্ক্রল করুন"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"আগের বছরগুলি দেখতে স্ক্রল করুন"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"তারিখ বেছে নিন"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"শুরুর তারিখ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"শেষ হওয়ার তারিখ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"পরের মাস দেখতে স্ক্রল করুন"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"আগের মাস দেখতে স্ক্রল করুন"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"সীমার মধ্যে"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"তারিখ লিখুন"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"তারিখের ব্যাপ্তি সম্পর্কিত ইনপুট ভুল দেওয়া আছে"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"টেনে আনার হ্যান্ডেল"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"স্ক্রিনের নিচে অ্যাটাচ করা শিট আড়াল করুন"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"স্ক্রিনের নিচে অ্যাটাচ করা শিট বাতিল করুন"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"স্ক্রিনের নিচে অ্যাটাচ করা শিট বড় করুন"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"টুলটিপ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"টুলটিপ দেখান"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM বা PM বেছে নিন"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ঘণ্টা বেছে নিন"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"মিনিট বেছে নিন"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$dটা"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ঘণ্টা"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d মিনিট"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"মিনিট"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ঘণ্টা"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"এত মিনিটের জন্য"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"এত ঘণ্টার জন্য"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-bs/strings.xml b/compose/material3/material3/src/androidMain/res/values-bs/strings.xml
new file mode 100644
index 0000000..584bfe0
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-bs/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dijaloški okvir"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Prošireno"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Suženo"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Odbacivanje"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pretraživanje"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Prijedlozi su u nastavku"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Odabir datuma"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Odabrani datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Prebacivanje na odabir godine"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Prevucite da odaberete godinu ili dodirnite da se vratite na odabir dana"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Promjena na sljedeći mjesec"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Promjena na prethodni mjesec"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Odlazak na %1$s. godinu"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Trenutni odabir: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ništa"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Danas"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Birač godine je vidljiv"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Odabir datuma"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Unesen je datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Unesen je datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ništa"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datum nije dozvoljen: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datumi se ne podudaraju s očekivanim obrascem: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum je izvan očekivanog raspona %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Prebacivanje na način rada unosa kalendara"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Prebacivanje na način rada unosa teksta"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Kliznite da se prikažu kasnije godine"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Kliznite da se prikažu ranije godine"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Odabir datuma"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Datum početka"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Datum završetka"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Kliznite da se prikaže sljedeći mjesec"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Kliznite da se prikaže prethodni mjesec"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"U rasponu"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Unos datuma"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Nevažeći unos raspona datuma"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Ručica za prevlačenje"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Sužavanje donje tabele"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Odbacivanje donje tabele"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Proširivanje donje tabele"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Skočni opis"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Prikaz skočnog opisa"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"poslijepodne"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"prijepodne"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Odaberite prijepodne ili poslijepodne"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Odaberite sate"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Odaberite minute"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d h"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d h"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d min"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Sat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"za minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"za sat"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ca/strings.xml b/compose/material3/material3/src/androidMain/res/values-ca/strings.xml
new file mode 100644
index 0000000..982a4b0
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ca/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Quadre de diàleg"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"S\'ha desplegat"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"S\'ha replegat"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Ignora"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Cerca"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggeriments a continuació"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selecciona la data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data seleccionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Canvia a la selecció de l\'any"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Llisca per seleccionar un any o toca per tornar a seleccionar un dia"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Canvia al mes següent"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Canvia al mes anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navega fins a l\'any %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Selecció actual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Cap"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Avui"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selector d\'any visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selecciona la data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data introduïda"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data introduïda: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Cap"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data no permesa: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La data no coincideix amb el patró esperat: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"La data no es troba dins de l\'interval d\'anys esperat: %1$s-%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Canvia al mode d\'introducció de calendari"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Canvia al mode d\'introducció de text"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Desplaça\'t per mostrar els anys posteriors"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Desplaça\'t per mostrar els anys anteriors"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selecciona les dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data d\'inici"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de finalització"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Desplaça\'t per mostrar el mes següent"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Desplaça\'t per mostrar el mes anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dins de l\'interval"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Introdueix les dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"S\'ha introduït un interval de dates no vàlid"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Ansa per arrossegar"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Replega el full inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ignora el full inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Desplega el full inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Descripció emergent"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostra la descripció emergent"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecciona AM o PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecciona l\'hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecciona els minuts"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d en punt"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hores"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuts"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"per als minuts"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"per a l\'hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-cs/strings.xml b/compose/material3/material3/src/androidMain/res/values-cs/strings.xml
new file mode 100644
index 0000000..0a3c854
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-cs/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogové okno"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Rozbaleno"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Sbaleno"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Zavřít"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Vyhledávání"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Níže jsou k dispozici návrhy"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Výběr data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Vybrané datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Přepnout na výběr roku"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Přejetím prstem vyberte rok nebo se klepnutím vraťte k výběru dne"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Přejít na další měsíc"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Přejít na předchozí měsíc"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Přejít na rok %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuální výběr: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Žádné"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Dnes"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Je zobrazen výběr roku"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Vyberte datum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Zadané datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Zadané datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Žádné"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Nepovolené datum: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum neodpovídá očekávanému vzoru: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum není v očekávaném rozsahu roků %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Přepnout na režim zadávání pomocí kalendáře"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Přepnout na režim zadávání textu"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Posunutím zobrazíte pozdější roky"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Posunutím zobrazíte předchozí roky"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Vyberte data"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Datum zahájení"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Datum ukončení"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Posunutím zobrazíte další měsíc"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Posunutím zobrazíte předchozí měsíc"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"V rozsahu"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Zadejte data"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Neplatné období"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Úchyt pro přetažení"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Sbalit spodní tabulku"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Zavřít spodní tabulku"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Rozbalit spodní tabulku"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Popisek"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Zobrazit popisek"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Vyberte AM nebo PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Vybrat hodinu"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Vyberte minuty"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d hodin"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hodin"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minut"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hodina"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"pro minuty"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"pro hodinu"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-da/strings.xml b/compose/material3/material3/src/androidMain/res/values-da/strings.xml
new file mode 100644
index 0000000..1acf697
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-da/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogboks"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Udvidet"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Skjult"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Afvis"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Søg"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Forslag nedenfor"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Vælg dato"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valgt dato"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Skift til valg af år"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Stryg for at vælge et år, eller tryk for at skifte tilbage til datovælgeren"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Skift til næste måned"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Skift til forrige måned"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Gå til år %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuelt valg: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ingen"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"I dag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Årsvælgeren er synlig"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Vælg dato"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Angivet dato"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dato"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Angivet dato: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ingen"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datoen er ikke tilladt: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datoen svarer ikke til det forventede format: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datoen er uden for det forventede årsinterval: %1$s-%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Skift til input-tilstand for kalender"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Skift til input-tilstand for tekst"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Rul for at se senere år"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Rul for at se tidligere år"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Vælg datoer"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Startdato"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Slutdato"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Rul for at se næste måned"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Rul for at se forrige måned"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Inden for de valgte dage"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Angiv datoer"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Det angivne datointerval er ugyldigt"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Håndtag"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Skjul felt i bunden"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Luk felt i bunden"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Udvid felt i bunden"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Værktøjstip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Se værktøjstip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Vælg AM eller PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Vælg time"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Vælg minutter"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"kl. %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d timer"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutter"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Time"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"til minutter"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"til timer"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-de/strings.xml b/compose/material3/material3/src/androidMain/res/values-de/strings.xml
new file mode 100644
index 0000000..3cee3b1
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-de/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogfeld"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Maximiert"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Minimiert"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Schließen"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Suche"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Vorschläge unten"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Datum auswählen"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Ausgewähltes Datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Zur Jahresauswahl wechseln"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Wischen, um ein Jahr auszuwählen, oder tippen, um zur Tagesauswahl zurückzukehren"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Zum nächsten Monat wechseln"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Zum vorherigen Monat wechseln"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Zum Jahr %1$s wechseln"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuelle Auswahl: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Kein Datum"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Heute"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Jahresauswahl sichtbar"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Datum auswählen"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Eingabedatum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Eingabedatum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Kein Datum"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Unzulässiges Datum: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum entspricht nicht dem erwarteten Format: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum liegt außerhalb des erwarteten Jahresbereichs (%1$s–%2$s)"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"In den Kalendereingabemodus wechseln"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"In den Texteingabemodus wechseln"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Zum Ansehen nachfolgender Jahre scrollen"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Zum Ansehen vorheriger Jahre scrollen"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Daten auswählen"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Startdatum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Enddatum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Zum Ansehen des nächsten Monats scrollen"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Zum Ansehen des vorherigen Monats scrollen"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Im Zeitraum"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Daten eingeben"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Angegebener Zeitraum ungültig"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Ziehpunkt"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Ansicht am unteren Rand minimieren"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ansicht am unteren Rand schließen"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Ansicht am unteren Rand maximieren"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Kurzinfo"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Kurzinfo anzeigen"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"Nachmittags"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"Vormittags"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Vormittags oder nachmittags auswählen"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Stunde auswählen"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Minuten auswählen"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d Uhr"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d Std."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d Minuten"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Stunde"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"für Minuten"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"für Stunde"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-el/strings.xml b/compose/material3/material3/src/androidMain/res/values-el/strings.xml
new file mode 100644
index 0000000..bee936e
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-el/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Παράθυρο διαλόγου"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Αναπτυγμένο"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Συμπτυγμένο"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Παράβλεψη"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Αναζήτηση"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Προτάσεις παρακάτω"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Επιλογή ημερομηνίας"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Επιλεγμένη ημερομηνία"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Εναλλαγή σε επιλογή έτους"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Σύρετε για να επιλέξετε ένα έτος ή πατήστε για να επιστρέψετε στην επιλογή ημέρας."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Αλλαγή στον επόμενο μήνα"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Αλλαγή στον προηγούμενο μήνα"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Μετάβαση στο έτος %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Τρέχουσα επιλογή: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Καμία"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Σήμερα"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Το εργαλείο επιλογής έτους είναι ορατό"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Επιλογή ημερομηνίας"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Εισαγωγή ημερομηνίας"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Ημερομηνία"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Εισαγωγή ημερομηνίας: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Καμία"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Η ημερομηνία δεν επιτρέπεται: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Η ημερομηνία δεν αντιστοιχεί στο αναμενόμενο μοτίβο: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Η ημερομηνία είναι εκτός του αναμενόμενου εύρους ετών %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Εναλλαγή στη λειτουργία εισαγωγής ημερολογίου"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Εναλλαγή στη λειτουργία εισαγωγής κειμένου"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Κάντε κύλιση για εμφάνιση επόμενων ετών"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Κάντε κύλιση για εμφάνιση προηγούμενων ετών"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Επιλογή ημερομηνιών"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Ημερομηνία έναρξης"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Ημερομηνία λήξης"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Κάντε κύλιση για εμφάνιση του επόμενου μήνα"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Κάντε κύλιση για εμφάνιση του προηγούμενου μήνα"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Εντός εύρους"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Εισαγωγή ημερομηνιών"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Μη έγκυρη εισαγωγή εύρους ημερομηνιών"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Λαβή μεταφοράς"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Σύμπτυξη φύλλου κάτω μέρους"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Παράβλεψη φύλλου κάτω μέρους"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Ανάπτυξη φύλλου κάτω μέρους"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Επεξήγηση εργαλείου"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Προβολή επεξήγησης εργαλείου"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"μμ"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"πμ"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Επιλέξτε π.μ. ή μ.μ."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Επιλογή ώρας"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Επιλογή λεπτών"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d η ώρα"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"Ώρα %1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d λεπτά"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Λεπτό"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ώρα"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"για λεπτά"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"για ώρα"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-en-rAU/strings.xml b/compose/material3/material3/src/androidMain/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..f2f7017
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-en-rAU/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogue"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expanded"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Collapsed"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Search"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions below"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Select date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Selected date"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Switch to selecting a year"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe to select a year or tap to switch back to selecting a day"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Change to next month"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Change to previous month"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigate to year %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Current selection: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"None"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Today"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Year picker visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Select date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Entered date"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Entered date: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"None"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date not allowed: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Date does not match expected pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date out of expected year range %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Switch to calendar input mode"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Switch to text input mode"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll to show later years"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll to show earlier years"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Select dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Start date"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"End date"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll to show the next month"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll to show the previous month"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"In range"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Enter dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid date range input"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Drag handle"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Collapse bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dismiss bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expand bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Show tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"p.m."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"a.m."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Select a.m. or p.m."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Select hour"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Select minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hours"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hour"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for hour"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-en-rCA/strings.xml b/compose/material3/material3/src/androidMain/res/values-en-rCA/strings.xml
index e1286b7..8914bb2 100644
--- a/compose/material3/material3/src/androidMain/res/values-en-rCA/strings.xml
+++ b/compose/material3/material3/src/androidMain/res/values-en-rCA/strings.xml
@@ -17,112 +17,59 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for m3c_dialog (7617233117134790350) -->
- <skip />
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
<string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expanded"</string>
<string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Collapsed"</string>
- <!-- no translation found for m3c_snackbar_dismiss (6152755701819882931) -->
- <skip />
- <!-- no translation found for m3c_search_bar_search (6152806324422087846) -->
- <skip />
- <!-- no translation found for m3c_suggestions_available (7655536806087401899) -->
- <skip />
- <!-- no translation found for m3c_date_picker_title (7430790972741451689) -->
- <skip />
- <!-- no translation found for m3c_date_picker_headline (7605002211875882969) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_year_selection (791651718641787594) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_day_selection (395627960681594326) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_next_month (7142101321095356500) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_previous_month (228438865139394590) -->
- <skip />
- <!-- no translation found for m3c_date_picker_navigate_to_year_description (8436650776581492840) -->
- <skip />
- <!-- no translation found for m3c_date_picker_headline_description (3664277305226978227) -->
- <skip />
- <!-- no translation found for m3c_date_picker_no_selection_description (5811000998184572395) -->
- <skip />
- <!-- no translation found for m3c_date_picker_today_description (3199387177749801575) -->
- <skip />
- <!-- no translation found for m3c_date_picker_year_picker_pane_title (2068382232816991922) -->
- <skip />
- <!-- no translation found for m3c_date_input_title (7306227249789210568) -->
- <skip />
- <!-- no translation found for m3c_date_input_headline (8166741421776570875) -->
- <skip />
- <!-- no translation found for m3c_date_input_label (2895559812010326913) -->
- <skip />
- <!-- no translation found for m3c_date_input_headline_description (229313757840775812) -->
- <skip />
- <!-- no translation found for m3c_date_input_no_input_description (1237013946323089826) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_not_allowed (2521768508935305279) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_for_pattern (6116910750161463197) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_year_range (7052898923934555305) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_calendar_mode (1804346892470238807) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_input_mode (2219746470065162704) -->
- <skip />
- <!-- no translation found for m3c_date_picker_scroll_to_later_years (5727367015496556177) -->
- <skip />
- <!-- no translation found for m3c_date_picker_scroll_to_earlier_years (7813882352367152251) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_title (3134165431120340385) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_start_headline (4665981448952749820) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_end_headline (4947636797751277713) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_scroll_to_next_month (602077859540990149) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_scroll_to_previous_month (4592174524846109496) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_day_in_range (2138321128465719402) -->
- <skip />
- <!-- no translation found for m3c_date_range_input_title (3148384720560189467) -->
- <skip />
- <!-- no translation found for m3c_date_range_input_invalid_range_input (3190049423327661366) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_drag_handle_description (8403354765404029791) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_collapse_description (2988463736136100848) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_dismiss_description (1555567894577437024) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_expand_description (6670819569745899763) -->
- <skip />
- <!-- no translation found for m3c_tooltip_pane_description (5460405025248574620) -->
- <skip />
- <!-- no translation found for m3c_tooltip_long_press_label (1805687647081129904) -->
- <skip />
- <!-- no translation found for m3c_time_picker_pm (6616362054113087709) -->
- <skip />
- <!-- no translation found for m3c_time_picker_am (2786685010796619560) -->
- <skip />
- <!-- no translation found for m3c_time_picker_period_toggle_description (5865171949528594571) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_selection (8876759303332837035) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_selection (4699133535056739733) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_suffix (3458167507790628988) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_24h_suffix (9179527532316922345) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_suffix (5064177921781937179) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute (4313071914266462005) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour (2349193472625211372) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_text_field (7661234488295443182) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_text_field (6973808109666874069) -->
- <skip />
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Search"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions below"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Select date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Selected date"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Switch to selecting a year"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe to select a year, or tap to switch back to selecting a day"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Change to next month"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Change to previous month"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigate to year %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Current selection: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"None"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Today"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Year picker visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Select date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Entered date"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Entered date: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"None"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date not allowed: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Date does not match expected pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date out of expected year range %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Switch to calendar input mode"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Switch to text input mode"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll to show later years"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll to show earlier years"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Select dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Start date"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"End date"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll to show the next month"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll to show the previous month"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"In range"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Enter dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid date range input"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Drag handle"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Collapse bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dismiss bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expand bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Show tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Select AM or PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Select hour"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Select minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hours"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hour"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for hour"</string>
</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-en-rGB/strings.xml b/compose/material3/material3/src/androidMain/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..f2f7017
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-en-rGB/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogue"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expanded"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Collapsed"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Search"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions below"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Select date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Selected date"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Switch to selecting a year"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe to select a year or tap to switch back to selecting a day"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Change to next month"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Change to previous month"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigate to year %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Current selection: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"None"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Today"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Year picker visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Select date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Entered date"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Entered date: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"None"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date not allowed: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Date does not match expected pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date out of expected year range %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Switch to calendar input mode"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Switch to text input mode"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll to show later years"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll to show earlier years"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Select dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Start date"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"End date"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll to show the next month"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll to show the previous month"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"In range"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Enter dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid date range input"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Drag handle"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Collapse bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dismiss bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expand bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Show tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"p.m."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"a.m."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Select a.m. or p.m."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Select hour"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Select minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hours"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hour"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for hour"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-en-rIN/strings.xml b/compose/material3/material3/src/androidMain/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..f2f7017
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-en-rIN/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogue"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expanded"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Collapsed"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Search"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions below"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Select date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Selected date"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Switch to selecting a year"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe to select a year or tap to switch back to selecting a day"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Change to next month"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Change to previous month"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigate to year %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Current selection: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"None"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Today"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Year picker visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Select date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Entered date"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Entered date: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"None"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date not allowed: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Date does not match expected pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date out of expected year range %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Switch to calendar input mode"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Switch to text input mode"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll to show later years"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll to show earlier years"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Select dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Start date"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"End date"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll to show the next month"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll to show the previous month"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"In range"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Enter dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid date range input"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Drag handle"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Collapse bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dismiss bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expand bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Show tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"p.m."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"a.m."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Select a.m. or p.m."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Select hour"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Select minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hours"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hour"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for hour"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-en-rXC/strings.xml b/compose/material3/material3/src/androidMain/res/values-en-rXC/strings.xml
index af84efe..8713ddb 100644
--- a/compose/material3/material3/src/androidMain/res/values-en-rXC/strings.xml
+++ b/compose/material3/material3/src/androidMain/res/values-en-rXC/strings.xml
@@ -17,112 +17,59 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- no translation found for m3c_dialog (7617233117134790350) -->
- <skip />
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
<string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expanded"</string>
<string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Collapsed"</string>
- <!-- no translation found for m3c_snackbar_dismiss (6152755701819882931) -->
- <skip />
- <!-- no translation found for m3c_search_bar_search (6152806324422087846) -->
- <skip />
- <!-- no translation found for m3c_suggestions_available (7655536806087401899) -->
- <skip />
- <!-- no translation found for m3c_date_picker_title (7430790972741451689) -->
- <skip />
- <!-- no translation found for m3c_date_picker_headline (7605002211875882969) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_year_selection (791651718641787594) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_day_selection (395627960681594326) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_next_month (7142101321095356500) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_previous_month (228438865139394590) -->
- <skip />
- <!-- no translation found for m3c_date_picker_navigate_to_year_description (8436650776581492840) -->
- <skip />
- <!-- no translation found for m3c_date_picker_headline_description (3664277305226978227) -->
- <skip />
- <!-- no translation found for m3c_date_picker_no_selection_description (5811000998184572395) -->
- <skip />
- <!-- no translation found for m3c_date_picker_today_description (3199387177749801575) -->
- <skip />
- <!-- no translation found for m3c_date_picker_year_picker_pane_title (2068382232816991922) -->
- <skip />
- <!-- no translation found for m3c_date_input_title (7306227249789210568) -->
- <skip />
- <!-- no translation found for m3c_date_input_headline (8166741421776570875) -->
- <skip />
- <!-- no translation found for m3c_date_input_label (2895559812010326913) -->
- <skip />
- <!-- no translation found for m3c_date_input_headline_description (229313757840775812) -->
- <skip />
- <!-- no translation found for m3c_date_input_no_input_description (1237013946323089826) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_not_allowed (2521768508935305279) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_for_pattern (6116910750161463197) -->
- <skip />
- <!-- no translation found for m3c_date_input_invalid_year_range (7052898923934555305) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_calendar_mode (1804346892470238807) -->
- <skip />
- <!-- no translation found for m3c_date_picker_switch_to_input_mode (2219746470065162704) -->
- <skip />
- <!-- no translation found for m3c_date_picker_scroll_to_later_years (5727367015496556177) -->
- <skip />
- <!-- no translation found for m3c_date_picker_scroll_to_earlier_years (7813882352367152251) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_title (3134165431120340385) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_start_headline (4665981448952749820) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_end_headline (4947636797751277713) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_scroll_to_next_month (602077859540990149) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_scroll_to_previous_month (4592174524846109496) -->
- <skip />
- <!-- no translation found for m3c_date_range_picker_day_in_range (2138321128465719402) -->
- <skip />
- <!-- no translation found for m3c_date_range_input_title (3148384720560189467) -->
- <skip />
- <!-- no translation found for m3c_date_range_input_invalid_range_input (3190049423327661366) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_drag_handle_description (8403354765404029791) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_collapse_description (2988463736136100848) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_dismiss_description (1555567894577437024) -->
- <skip />
- <!-- no translation found for m3c_bottom_sheet_expand_description (6670819569745899763) -->
- <skip />
- <!-- no translation found for m3c_tooltip_pane_description (5460405025248574620) -->
- <skip />
- <!-- no translation found for m3c_tooltip_long_press_label (1805687647081129904) -->
- <skip />
- <!-- no translation found for m3c_time_picker_pm (6616362054113087709) -->
- <skip />
- <!-- no translation found for m3c_time_picker_am (2786685010796619560) -->
- <skip />
- <!-- no translation found for m3c_time_picker_period_toggle_description (5865171949528594571) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_selection (8876759303332837035) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_selection (4699133535056739733) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_suffix (3458167507790628988) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_24h_suffix (9179527532316922345) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_suffix (5064177921781937179) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute (4313071914266462005) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour (2349193472625211372) -->
- <skip />
- <!-- no translation found for m3c_time_picker_minute_text_field (7661234488295443182) -->
- <skip />
- <!-- no translation found for m3c_time_picker_hour_text_field (6973808109666874069) -->
- <skip />
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Search"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions below"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Select date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Selected date"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Switch to selecting a year"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe to select a year, or tap to switch back to selecting a day"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Change to next month"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Change to previous month"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigate to year %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Current selection: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"None"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Today"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Year picker visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Select date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Entered date"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Entered date: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"None"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date not allowed: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Date does not match expected pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date out of expected year range %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Switch to calendar input mode"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Switch to text input mode"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll to show later years"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll to show earlier years"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Select dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Start date"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"End date"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll to show the next month"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll to show the previous month"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"In range"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Enter dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid date range input"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Drag handle"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Collapse bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dismiss bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expand bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Show tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Select AM or PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Select hour"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Select minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d hours"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hour"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for hour"</string>
</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-es-rUS/strings.xml b/compose/material3/material3/src/androidMain/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..3ffdcf73
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-es-rUS/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expandido"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Contraído"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Descartar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Buscar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugerencias a continuación"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Seleccionar fecha"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Fecha seleccionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Cambiar a seleccionar un año"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Desliza el dedo para seleccionar un año o presiona para volver a la selección de día"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Cambiar al mes siguiente"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Cambiar al mes anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navegar al año %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Selección actual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ninguna"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoy"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selector de año visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Seleccionar fecha"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Fecha ingresada"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Fecha"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Fecha ingresada: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ninguna"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Fecha no permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La fecha no coincide con el patrón esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"La fecha está fuera del rango de años esperado: %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Cambiar al modo de entrada de calendario"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Cambiar al modo de entrada de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Desplázate para ver los últimos años"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Desplázate para ver los primeros años"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Seleccionar fechas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Fecha de inicio"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Fecha de finalización"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Desplázate para ver el próximo mes"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Desplázate para ver el mes anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"En el rango"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Ingresar fechas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Se introdujo un período no válido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Controlador de arrastre"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Contraer la hoja inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Descartar la hoja inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expandir la hoja inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Información"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar información"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecciona a.m. o p.m."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Seleccionar hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Seleccionar los minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d en punto"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"por minutos"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"por hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-es/strings.xml b/compose/material3/material3/src/androidMain/res/values-es/strings.xml
new file mode 100644
index 0000000..659ba0b
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-es/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Cuadro de diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Desplegado"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Contraído"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Cerrar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Buscar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugerencias a continuación"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Seleccionar fecha"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Fecha seleccionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Cambiar para seleccionar un año"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Desliza para seleccionar un año o toca para volver a seleccionar un día"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Cambiar al mes siguiente"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Cambiar al mes anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Ir al año %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Seleccionado: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"No hay datos"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoy"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selector de año visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Seleccionar fecha"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Fecha introducida"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Fecha"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Fecha introducida: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"No hay datos"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Fecha no permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La fecha no coincide con el patrón esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Fecha fuera del intervalo de años previsto: %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Cambiar al modo de introducción de calendario"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Cambiar al modo de introducción de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Desplázate para ver los años posteriores"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Desplázate para ver los años anteriores"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Seleccionar fechas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Fecha de inicio"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Fecha de finalización"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Desplázate para ver el mes siguiente"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Desplázate para ver el mes anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dentro del intervalo"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Introducir fechas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"El intervalo de fechas no es válido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Controlador de arrastre"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Contrae la hoja inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Cierra la hoja inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Despliega la hoja inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Descripción emergente"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar descripción emergente"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecciona AM o PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Seleccionar hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Seleccionar minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d en punto"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minutos"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"para los minutos"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"para la hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-et/strings.xml b/compose/material3/material3/src/androidMain/res/values-et/strings.xml
new file mode 100644
index 0000000..f283b3d
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-et/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialoog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Laiendatud"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Ahendatud"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Loobu"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Otsing"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Soovitused on allpool"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Valige kuupäev"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valitud kuupäev"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Lülitu aasta valimisele"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Pühkige aasta valimiseks või puudutage, et minna tagasi päeva valimise juurde"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Vaheta järgmisele kuule"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Vaheta eelmisele kuule"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Liigu aasta %1$s juurde"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Praegune valik: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Puudub"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Täna"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Aasta valija on nähtav"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Valige kuupäev"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Sisestatud kuupäev"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Kuupäev"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Sisestatud kuupäev: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Puudub"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Kuupäev pole lubatud: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Kuupäev ei ühti eeldatud mustriga: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Kuupäev on väljaspool eeldatud aastavahemikku %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Lülitu kalendrisisestusrežiimile"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Lülitu tekstisisestusrežiimile"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Hilisemate aastate kuvamiseks kerige"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Varasemate aastate kuvamiseks kerige"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Valige kuupäevad"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Alguskuupäev"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Lõppkuupäev"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Järgmise kuu kuvamiseks kerige"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Eelmise kuu kuvamiseks kerige"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Vahemikus"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Sisestage kuupäevad"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Sisestati sobimatu kuupäevavahemik"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Lohistamispide"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Alumise lehe ahendamine"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Alumisest lehest loobumine"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Alumise lehe laiendamine"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Kohtspikker"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Kuva kohtspikker"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Valige AM või PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Tunni valimine"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Minutite valimine"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d.00"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d tundi"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutit"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Tunnid"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minutite jaoks"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"tundide jaoks"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-eu/strings.xml b/compose/material3/material3/src/androidMain/res/values-eu/strings.xml
new file mode 100644
index 0000000..4a3ec21
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-eu/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Leihoa"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Zabalduta"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Tolestuta"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Baztertu"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Bilatu"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Iradokizunak daude behean"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Hautatu data bat"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Hautatutako data"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Joan urte-hautatzailera"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Pasatu hatza urte bat hautatzeko. Bestela, sakatu hau eguna hautatzeko pantailara itzultzeko."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Aldatu hurrengo hilabetera"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Aldatu aurreko hilabetera"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Joan %1$s. urtera"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Oraingo hautapena: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Bat ere ez"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Gaur"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Urte-hautatzailea ikusgai dago"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Hautatu data bat"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Idatzitako data"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Idatzitako data: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Bat ere ez"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Ez da onartzen data: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Data ez dator bat espero den ereduarekin: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Espero den urte tartetik (%1$s-%2$s) kanpo dago data"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Aldatu egutegiaren idazketa-metodora"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Aldatu testua idazteko modura"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Egin gora/behera etorkizuneko urteak erakusteko"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Egin gora/behera iraganeko urteak erakusteko"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Hautatu datak"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Hasiera-data"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Amaiera-data"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Egin gora/behera hurrengo hilabetea erakusteko"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Egin gora/behera aurreko hilabetea erakusteko"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Barrutian"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Idatzi datak"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Idatzitako data tarteak ez du balio"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Arrastatzeko kontrol-puntua"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Tolestu pantailaren behealdean ainguratutako orria"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Baztertu pantailaren behealdean ainguratutako orria"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Zabaldu pantailaren behealdean ainguratutako orria"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Aholkua"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Erakutsi aholkua"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Hautatu AM edo PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Hautatu ordua"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Hautatu minutuak"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutu"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minutua"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ordua"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minutuetarako"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ordurako"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-fa/strings.xml b/compose/material3/material3/src/androidMain/res/values-fa/strings.xml
new file mode 100644
index 0000000..0cae189
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-fa/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"کادر گفتگو"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ازهم باز شد"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"جمع شد"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"بستن"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"جستجو"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"پیشنهادهای زیر"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"انتخاب تاریخ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"تاریخ انتخابی"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"رفتن به انتخاب سال"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"برای انتخاب سال، تند بکشید یا برای برگشتن به انتخاب روز، ضربه بزنید"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"تغییر به ماه بعدی"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"تغییر به ماه قبلی"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"پیمایش به سال %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"انتخاب فعلی: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"هیچکدام"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"امروز"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"انتخابگر سال نمایان است"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"انتخاب تاریخ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"تاریخ واردشده"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"تاریخ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"تاریخ واردشده: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"هیچکدام"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"تاریخ مجاز نیست: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"تاریخ با الگوی موردانتظار مطابقت ندارد: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"تاریخ خارج از بازه زمانی %1$s تا %2$s است"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"رفتن به روش ورودی تقویم"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"رفتن به حالت ورودی نوشتاری"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"برای نمایش سالهای بعد پیمایش کنید"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"برای نمایش سالهای قبل پیمایش کنید"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"تاریخها را انتخاب کنید"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"تاریخ شروع"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"تاریخ پایان"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"برای نمایش ماه بعد پیمایش کنید"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"برای نمایش ماه قبل پیمایش کنید"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"در محدوده"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"تاریخها را وارد کنید"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"محدوده تاریخ واردشده نامعتبر است"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"دستگیره کشاندن"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"جمع کردن برگ زیرین"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"بستن برگ زیرین"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ازهم باز کردن برگ زیرین"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"نکتهابزار"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"نمایش نکتهابزار"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ب.ظ."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ق.ظ."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"انتخاب ق.ظ. یا ب.ظ."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"انتخاب ساعت"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"انتخاب دقیقه"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"ساعت %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ساعت"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d دقیقه"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"دقیقه"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ساعت"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"برای دقیقه"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"برای ساعت"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-fi/strings.xml b/compose/material3/material3/src/androidMain/res/values-fi/strings.xml
new file mode 100644
index 0000000..4936890
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-fi/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Valintaikkuna"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Laajennettu"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Tiivistetty"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Ohita"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Hae"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Ehdotuksia alla"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Valitse päivämäärä"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valittu päivämäärä"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Vaihda vuoden valintaan"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Valitse vuosi pyyhkäisemällä tai palaa päivän valintaan napauttamalla"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Vaihda seuraavaan kuukauteen"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Vaihda edelliseen kuukauteen"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Siirry vuoteen %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Nykyinen valinta: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"–"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Tänään"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Vuosivalitsin näkyvillä"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Valitse päivämäärä"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Lisätty päivämäärä"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Päivämäärä"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Lisätty päivämäärä: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"–"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Päivämäärä ei sallittu: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Päivämäärä ei vastaa odotettua mallia: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Päivämäärä ei sisälly odotettuun vuosiaikaväliin: %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Vaihda syöttötavaksi kalenteri"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Vaihda tekstinsyöttötilaan"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Vieritä nähdäksesi myöhemmät vuodet"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Vieritä nähdäksesi aiemmat vuodet"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Valitse päivämäärät"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Alkamispäivä"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Päättymispäivä"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Vieritä nähdäksesi seuraavan kuukauden"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Vieritä nähdäksesi edellisen kuukauden"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Valitulla välillä"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Lisää päivämäärät"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Virheellinen ajanjakso"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Vetokahva"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Tiivistä alapaneeli"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Hylkää alapaneeli"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Laajenna alapaneeli"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Vihjeteksti"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Näytä vihjeteksti"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"IP"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AP"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Valitse AP tai IP"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Valitse tunti"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Valitse minuutit"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Kello %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d h"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuuttia"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuutti"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Tunti"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minuuttien osalta"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"tuntien osalta"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-fr-rCA/strings.xml b/compose/material3/material3/src/androidMain/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..9f32ba2
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-fr-rCA/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogue"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Développé"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Réduit"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Fermer"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Recherche"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions ci-dessous"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Sélectionner une date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Date sélectionnée"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Passer à la sélection d\'une année"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Balayez l\'écran pour sélectionner une année, ou touchez pour revenir en arrière et sélectionner un jour"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Passer au mois suivant"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Passer au mois précédent"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Naviguez jusqu\'à l\'année %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Sélection actuelle : %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Aucune"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Aujourd\'hui"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Sélecteur d\'année visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Sélectionner une date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Date entrée"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Date entrée : %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Aucune"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date non autorisée : %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La date ne correspond pas au schéma prévu : %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date non comprise dans la fourchette prévue des années %1$s à %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Passer au mode d\'entrée de l\'agenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Passer au mode d\'entrée de texte"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Faites défiler pour afficher les années suivantes"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Faites défiler pour afficher les années précédentes"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Sélectionner les dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Date de début"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Date de fin"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Faites défiler pour afficher le mois suivant"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Faites défiler pour afficher le mois précédent"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dans la fourchette"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Entrer les dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Entrée de période incorrecte"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Poignée de déplacement"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Réduire la zone de contenu dans le bas de l\'écran"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Fermer la zone de contenu dans le bas de l\'écran"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Développer la zone de contenu dans le bas de l\'écran"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Infobulle"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Afficher une infobulle"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Sélectionner AM ou PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Sélectionner l\'heure"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Sélectionnez les minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d h"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d h"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Heure"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"pour les minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"pour l\'heure"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-fr/strings.xml b/compose/material3/material3/src/androidMain/res/values-fr/strings.xml
new file mode 100644
index 0000000..617abdc
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-fr/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Boîte de dialogue"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Développé"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Réduit"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Fermer"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Rechercher"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggestions ci-dessous"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Sélectionner une date"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Date sélectionnée"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Passer à la sélection d\'une année"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Balayez l\'écran pour sélectionner une année ou appuyez pour revenir à la sélection d\'un jour"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Passer au mois suivant"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Passer au mois précédent"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Accéder à l\'année %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Sélection actuelle : %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Aucun"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Aujourd\'hui"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Sélecteur d\'année visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Sélectionner une date"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Date saisie"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Date"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Date saisie : %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Aucun"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Date non autorisée : %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La date ne correspond pas au format attendu : %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Date hors de la plage d\'années attendue : %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Passer au mode de saisie Agenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Passer au mode de saisie Texte"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Faites défiler pour afficher les années suivantes"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Faites défiler pour afficher les années précédentes"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Sélectionner des dates"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Date de début"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Date de fin"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Faites défiler pour afficher le mois suivant"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Faites défiler pour afficher le mois précédent"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dans la plage"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Saisir des dates"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Plage de dates non valide"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Poignée de déplacement"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Réduire la bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Fermer la bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Développer la bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Info-bulle"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Afficher l\'info-bulle"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Sélectionner le format AM ou PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Sélectionner une heure"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Sélectionner des minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d heures"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d heures"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutes"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minute"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Heure"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"en minutes"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"en heures"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-gl/strings.xml b/compose/material3/material3/src/androidMain/res/values-gl/strings.xml
new file mode 100644
index 0000000..d0a13b4
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-gl/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Cadro de diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Despregado"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Contraído"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Pechar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Buscar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Hai suxestións abaixo"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selecciona a data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data seleccionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Cambiar á selección do ano"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Pasar o dedo para seleccionar un ano ou tocar a pantalla para volver á selección do día"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Cambiar ao mes seguinte"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Cambiar ao mes anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Ir ao ano %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Selección actual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ningunha"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoxe"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selector de ano visible"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selecciona a data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data indicada"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data indicada: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ningunha"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data non permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"A data non coincide co padrón esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"A data está fóra do intervalo de anos esperado (%1$s - %2$s)"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Cambiar ao modo de introdución de texto do calendario"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Cambiar ao modo de introdución de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Desprazarse para mostrar anos posteriores"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Desprazarse para mostrar anos anteriores"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selecciona as datas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data de inicio"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de finalización"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Desprazarse para mostrar o mes seguinte"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Desprazarse para mostrar o mes anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dentro do intervalo"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Indica as datas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Indicouse un intervalo de datas que non é válido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Controlador de arrastre"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Contrae o panel inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Pecha o panel inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Desprega o panel inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Cadro de información"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar o cadro de información"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecciona a.m. ou p.m."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecciona a hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecciona os minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"por minuto"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"por hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-gu/strings.xml b/compose/material3/material3/src/androidMain/res/values-gu/strings.xml
new file mode 100644
index 0000000..cacb9c4
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-gu/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"સંવાદ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"મોટી કરેલી"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"નાની કરેલી"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"છોડી દો"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"શોધો"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"સૂચનો નીચે છે"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"તારીખ પસંદ કરો"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"પસંદ કરેલી તારીખ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"વર્ષ પસંદ કરવાના વિકલ્પ પર સ્વિચ કરો"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"વર્ષ પસંદ કરવા માટે સ્વાઇપ કરો અથવા દિવસની પસંદગી પર પાછા સ્વિચ કરવા માટે ટૅપ કરો"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"બદલીને આગલો મહિનો પસંદ કરો"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"બદલીને પાછલો મહિનો પસંદ કરો"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"વર્ષ %1$s પર નૅવિગેટ કરો"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"હાલની પસંદગી: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"એકપણ નહીં"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"આજે"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"વર્ષ માટેનું પિકર દૃશ્યમાન છે"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"તારીખ પસંદ કરો"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"દાખલ કરેલી તારીખ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"તારીખ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"દાખલ કરેલી તારીખ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"એકપણ નહીં"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"આ તારીખની મંજૂરી નથી: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"તારીખ અપેક્ષિત પૅટર્ન સાથે મેળ ખાતી નથી: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"અપેક્ષિત વર્ષની શ્રેણી %1$s - %2$sની બહારની તારીખ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"કૅલેન્ડર ઇનપુટ મોડ પર સ્વિચ કરો"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ટેક્સ્ટ ઇનપુટ મોડ પર સ્વિચ કરો"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"પછીના વર્ષો બતાવવા માટે સ્ક્રોલ કરો"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"અગાઉના વર્ષો બતાવવા માટે સ્ક્રોલ કરો"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"તારીખો પસંદ કરો"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"પ્રારંભ તારીખ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"સમાપ્તિ તારીખ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"આગલો મહિનો બતાવવા માટે સ્ક્રોલ કરો"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"પાછલો મહિનો બતાવવા માટે સ્ક્રોલ કરો"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"રેન્જમાં છે"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"તારીખો દાખલ કરો"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"તારીખની શ્રેણીનું અમાન્ય ઇનપુટ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ઑબ્જેક્ટ ખેંચવાનું હૅન્ડલ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"બોટમ શીટ નાની કરો"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"બોટમ શીટ છોડી દો"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"બોટમ શીટ મોટી કરો"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ટૂલટિપ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ટૂલટિપ બતાવો"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM કે PM પસંદ કરો"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"કલાક પસંદ કરો"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"મિનિટ પસંદ કરો"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d વાગ્યે"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d કલાક"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d મિનિટ"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"મિનિટ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"કલાક"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"મિનિટ માટે"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"કલાક માટે"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-hi/strings.xml b/compose/material3/material3/src/androidMain/res/values-hi/strings.xml
new file mode 100644
index 0000000..3973f98
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-hi/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"डायलॉग"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"बड़ा किया गया"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"छोटा किया गया"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"खारिज करें"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"खोजें"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"सुझाव यहां मौजूद हैं"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"तारीख चुनें"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"चुनी गई तारीख"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"साल चुनने के लिए स्विच करें"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"किसी साल को चुनने के लिए स्वाइप करें या दिन को चुनने की सेटिंग पर वापस जाने के लिए टैप करें"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"अगले महीने पर सेट करें"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"पिछले महीने पर सेट करें"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"साल %1$s पर जाएं"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"फ़िलहाल, यह तारीख चुनी गई है: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"कोई नहीं"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"आज"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"साल चुनने का विकल्प दिख रहा है"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"तारीख चुनें"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"डाली गई तारीख"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"तारीख"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"डाली गई तारीख: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"कोई नहीं"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"यह तारीख सही नहीं है: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"तारीख सही फ़ॉर्मैट में नहीं डाली गई है: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"तारीख को साल की सही रेंज में नहीं डाला गया है %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"कैलेंडर इनपुट मोड पर स्विच करें"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"टेक्स्ट इनपुट मोड पर स्विच करें"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"बाद वाले सालों की तारीख देखने के लिए स्क्रोल करें"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"पिछले सालों की तारीख देखने के लिए स्क्रोल करें"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"तारीखें चुनें"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"शुरू होने की तारीख"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"खत्म होने की तारीख"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"अगले महीने की तारीख देखने के लिए स्क्रोल करें"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"पिछले महीने की तारीख देखने के लिए स्क्रोल करें"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"रेंज में"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"तारीखें डालें"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"तारीख की दी गई सीमा गलत है"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"खींचकर छोड़ने वाला हैंडल"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"बॉटम शीट को छोटा करें"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"बॉटम शीट को खारिज करें"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"बॉटम शीट को बड़ा करें"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"टूलटिप"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"टूलटिप देखें"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM या PM चुनें"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"घंटा चुनें"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"मिनट चुनें"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d बजे"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d घंटे"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d मिनट"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"मिनट"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"घंटा"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"मिनट के लिए"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"घंटे के लिए"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-hr/strings.xml b/compose/material3/material3/src/androidMain/res/values-hr/strings.xml
new file mode 100644
index 0000000..70dab0f
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-hr/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dijaloški okvir"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Prošireno"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Sažeto"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Odbaci"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pretraživanje"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Prijedlozi su u nastavku"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Odaberite datum"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Odabrani datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Prijelaz na odabir godine"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Pomaknite se za odabir godine ili dodirnite za povratak na odabir dana"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Pomicanje na sljedeći mjesec"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Pomicanje na prethodni mjesec"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Prelazak u godinu %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Trenutačni odabir: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ništa"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Danas"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Vidljiv je alat za odabir godine"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Odaberite datum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Datum unosa"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Datum unosa: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ništa"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datum nije dopušten: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum se ne podudara s očekivanim uzorkom: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum je izvan očekivanog raspona godine %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Prijelaz na način unosa u Kalendaru"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Prijelaz na način unosa teksta"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Pomaknite se za prikaz kasnijih godina"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Pomaknite se za prikaz ranijih godina"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Odabir datuma"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Datum početka"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Datum završetka"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Pomaknite se za prikaz sljedećeg mjeseca"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Pomaknite se za prikaz prethodnog mjeseca"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"U dometu"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Unos datuma"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Unos datumskog raspona nije važeći"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Marker za povlačenje"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Sažimanje donje tablice"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Odbacivanje donje tablice"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Proširivanje donje tablice"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Opis"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Prikaži opis"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"Poslijepodne"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"Prijepodne"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Odaberite prijepodne ili poslijepodne"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Odabir sata"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Odaberite minute"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d h"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d h"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d min"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Sat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"za minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"za sat"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-hu/strings.xml b/compose/material3/material3/src/androidMain/res/values-hu/strings.xml
new file mode 100644
index 0000000..7808ce8
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-hu/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Párbeszédpanel"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Kibontva"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Összecsukva"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Elvetés"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Keresés"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Javaslatok alább"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Dátum kiválasztása"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Kiválasztott dátum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Váltás az év kiválasztására"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Csúsztatással kiválaszthatja a kívánt évet, vagy koppintással visszaválthat a nap kiválasztásához."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Váltás a következő hónapra"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Váltás az előző hónapra"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigálás a következő évhez: %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Jelenleg kiválasztva: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nincs"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Ma"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Látható az évválasztó"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Dátum kiválasztása"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Megadott dátum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dátum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Megadott dátum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nincs"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Nem engedélyezett dátum: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"A dátum nem felel meg a várt formátumnak: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"A dátum a várt időtartományon (%1$s – %2$s) kívül esik"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Váltás naptárbeviteli módra"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Váltás szövegbeviteli módra"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Görgessen a későbbi évek megjelenítéséhez"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Görgessen a korábbi évek megjelenítéséhez"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Dátumok kiválasztása"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Kezdő dátum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Záró dátum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Görgessen a következő hónap megjelenítéséhez"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Görgessen az előző hónap megjelenítéséhez"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Tartományon belül"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Dátumok megadása"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Érvénytelen a megadott dátumtartomány"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Fogópont"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Az alsó lap összecsukása"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Az alsó lap elvetése"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Az alsó lap kibontása"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Elemleírás"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Elemleírás megjelenítése"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"du."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"de."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Napszak kiválasztása"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Óra kiválasztása"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Perc kiválasztása"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d óra"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d óra"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d perc"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Perc"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Óra"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"perc megadása"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"óra megadása"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-hy/strings.xml b/compose/material3/material3/src/androidMain/res/values-hy/strings.xml
new file mode 100644
index 0000000..f50f0f3
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-hy/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Երկխոսության պատուհան"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Ծավալված է"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Ծալված է"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Փակել"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Որոնում"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Առաջարկները հասանելի են ստորև"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Ընտրեք ամսաթիվը"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Ընտրված ամսաթիվ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Անցնել տարվա ընտրությանը"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Սահեցրեք՝ տարեթիվ ընտրելու համար, կամ հպեք՝ օրվա ընտրությանը վերադառնալու համար"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Անցնել հաջորդ ամսվան"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Անցնել նախորդ ամսվան"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Անցնել %1$s թվական"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Ընթացիկ ընտրությունը՝ %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Չկա"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Այսօր"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Տարեթվի ցուցադրվող ընտրիչ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Ընտրեք ամսաթիվը"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Մուտքագրված ամսաթիվ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Ամսաթիվ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Մուտքագրված ամսաթիվ՝ %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Չկա"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Ամսաթիվը թույլատրված չէ՝ %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Ամսաթիվը չի համընկնում թույլատրելի ձևաչափի հետ՝ %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Ամսաթիվը տարեթվերի թույլատրելի միջակայքից (%1$s – %2$s) դուրս է"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Անցնել օրացույցի մուտքագրման ռեժիմ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Անցնել տեքստի մուտքագրման ռեժիմին"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Ոլորեք՝ վերջին տարիները ցուցադրելու համար"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Ոլորեք՝ նախորդ տարիները ցուցադրելու համար"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Ընտրեք ամսաթվեր"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Սկզբի ամսաթիվ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Ավարտի ամսաթիվ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Ոլորեք՝ հաջորդ ամիսը ցուցադրելու համար"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Ոլորեք՝ նախորդ ամիսը ցուցադրելու համար"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Միջակայքում"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Մուտքագրեք ամսաթվերը"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Մուտքագրված ամսաթվերի միջակայքն անվավեր է"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Տեղափոխման նշիչ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Ծալել ներքևի էկրանը"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Փակել ներքևի էկրանը"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Ծավալել ներքևի էկրանը"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Հուշակ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Ցուցադրել հուշում"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Ընտրել AM կամ PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Ընտրեք ժամը"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Ընտրեք րոպեն"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ժամ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d րոպե"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Րոպեներ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ժամ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"րոպեներ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ժամեր"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-in/strings.xml b/compose/material3/material3/src/androidMain/res/values-in/strings.xml
new file mode 100644
index 0000000..1622117
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-in/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Diperluas"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Diciutkan"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Tutup"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Telusuri"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Saran di bawah"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Pilih tanggal"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Tanggal yang dipilih"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Beralih ke memilih tahun"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Geser untuk memilih tahun, atau ketuk untuk beralih kembali ke pemilihan tanggal"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Ubah ke bulan berikutnya"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Ubah ke bulan sebelumnya"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Pilih tahun %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Pilihan saat ini: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Tidak ada"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hari ini"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Pemilih tahun terlihat"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Pilih tanggal"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Tanggal yang dimasukkan"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Tanggal"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Tanggal yang dimasukkan: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Tidak ada"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Tanggal tidak diizinkan: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Tanggal tidak cocok dengan pola yang diharapkan: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Tanggal di luar rentang tahun yang diharapkan %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Beralih ke mode input kalender"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Beralih ke mode input teks"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll untuk menampilkan tahun berikutnya"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll untuk menampilkan tahun sebelumnya"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Pilih tanggal"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Tanggal mulai"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Tanggal akhir"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll untuk menampilkan bulan berikutnya"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll untuk menampilkan bulan sebelumnya"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dalam rentang"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Masukkan tanggal"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Input rentang tanggal tidak valid"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Handel geser"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Menciutkan sheet bawah"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Menutup sheet bawah"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Meluaskan sheet bawah"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Tampilkan tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Pilih AM atau PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Pilih jam"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Pilih menit"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Pukul %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d jam"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d menit"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Menit"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Jam"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"untuk menit"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"untuk jam"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-is/strings.xml b/compose/material3/material3/src/androidMain/res/values-is/strings.xml
new file mode 100644
index 0000000..5dcf9b3
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-is/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Gluggi"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Stækkað"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Minnkað"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Hunsa"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Leit"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Tillögur hér fyrir neðan"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Velja dagsetningu"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valin dagsetning"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Skipta yfir í val á ári"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Strjúktu til að velja ár eða ýttu til að skipta aftur yfir í að velja dag"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Breyta í næsta mánuð"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Breyta í fyrri mánuð"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Fletta til ársins %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Núverandi val: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ekkert"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Í dag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Ársval birt"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Velja dagsetningu"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Skráð dagsetning"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dagsetning"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Skráð dagsetning: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ekkert"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Dagsetning er ekki leyfileg: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Dagsetning passar ekki við áætlað mynstur: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Dagsetning er utan áætlaðra ára: %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Skipta yfir í innfærsluaðferð fyrir dagatal"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Skipta yfir í textainnslátt"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Flettu til að sjá síðari ár"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Flettu til að sjá fyrri ár"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Velja dagsetningar"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Upphafsdagur"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Lokadagur"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Flettu til að sjá næsta mánuð"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Flettu til að sjá fyrri mánuð"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Innan tímabils"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Slá inn dagsetningar"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Ógilt tímabil fært inn"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Dragkló"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Minnka blað neðst"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Hunsa blað neðst"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Stækka blað neðst"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Ábending"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Sýna ábendingu"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"eh"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"fh"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Velja f.h. eða e.h."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Velja klst."</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Velja mínútur"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Kl. %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d klst."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d mínútur"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Mínúta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Klukkustund"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"fyrir mínútur"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"fyrir klukkustund"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-it/strings.xml b/compose/material3/material3/src/androidMain/res/values-it/strings.xml
new file mode 100644
index 0000000..62375a6
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-it/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Finestra di dialogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Espanso"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Compresso"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Chiudi"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Cerca"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggerimenti sotto"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Seleziona data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data selezionata"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Passa alla selezione di un anno"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Scorri per selezionare un anno o tocca per tornare alla selezione di un giorno"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Passa al mese successivo"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Passa al mese precedente"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Vai all\'anno %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Selezione attuale: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nessuna selezione"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Oggi"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selettore dell\'anno visibile"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Seleziona data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data inserita"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data inserita: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nessuna selezione"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data non consentita: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"La data non corrisponde al pattern previsto: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"La data non rientra nell\'intervallo di anni previsto (%1$s-%2$s)"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Passa alla modalità di immissione calendario"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Passa alla modalità di immissione testo"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scorri per visualizzare gli anni successivi"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scorri per visualizzare gli anni precedenti"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Seleziona date"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data di inizio"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data di fine"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scorri per visualizzare il mese successivo"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scorri per visualizzare il mese precedente"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Nell\'intervallo"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Inserisci date"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Intervallo di date inserito non valido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Punto di trascinamento"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Comprimi il riquadro inferiore"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Chiudi il riquadro inferiore"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Espandi il riquadro inferiore"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Descrizione comando"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostra descrizione comando"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Seleziona AM o PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Seleziona l\'ora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Seleziona i minuti"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d in punto"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ore"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuti"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"per i minuti"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"per l\'ora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-iw/strings.xml b/compose/material3/material3/src/androidMain/res/values-iw/strings.xml
new file mode 100644
index 0000000..fe7d309
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-iw/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"תיבת דו-שיח"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"התפריט הנפתח מורחב"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"התפריט הנפתח מכווץ"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"סגירה"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"חיפוש"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"הצעות מופיעות למטה"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"בחירת תאריך"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"התאריך הנבחר"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"החלפה לבחירה של שנה"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"יש להחליק כדי לבחור שנה, או להקיש כדי לחזור לבחירת היום"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"מעבר לחודש הבא"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"מעבר לחודש הקודם"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"ניווט לשנת %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"הבחירה הנוכחית: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ללא"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"היום"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"בורר השנה גלוי"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"בחירת תאריך"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"התאריך שהוזן"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"תאריך"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"התאריך שהוזן: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ללא"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"תאריך לא מורשה: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"התאריך לא תואם לקו ביטול הנעילה הצפוי: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"התאריך נמצא מחוץ לטווח השנים הצפוי %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"מעבר לשיטת קלט של יומן"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"מעבר לשיטת קלט של טקסט"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"צריך לגלול כדי להציג את השנים המאוחרות"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"צריך לגלול כדי להציג את השנים הקודמות"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"בחירת תאריכים"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"תאריך התחלה"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"תאריך סיום"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"צריך לגלול כדי להציג את החודש הבא"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"צריך לגלול כדי להציג את החודש הקודם"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"בטווח"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"הזנת תאריכים"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"קלט טווח תאריכים לא חוקי"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"נקודת אחיזה לגרירה"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"כיווץ הגיליון התחתון"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"סגירת הגיליון התחתון"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"הרחבת הגיליון התחתון"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"הסבר קצר"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"הצגת הסבר קצר"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"צריך לבחור ב-AM או ב-PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"בחירת שעה"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"בחירת דקות"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d שעות"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d דקות"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"דקות"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"שעות"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"דקות"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"שעות"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ja/strings.xml b/compose/material3/material3/src/androidMain/res/values-ja/strings.xml
new file mode 100644
index 0000000..c624ebe
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ja/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ダイアログ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"開いています"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"閉じています"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"閉じる"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"検索"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"検索候補は次のとおりです"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"日付の選択"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"選択した日付"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"年の選択に切り替え"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"スワイプして年を選択するか、タップして日付の選択に戻ります"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"翌月に変更"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"前月に変更"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"年に移動 %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"現在の選択: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"なし"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"今日"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"年の選択ツールの表示"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"日付の選択"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"入力された日付"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"日付"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"入力された日付: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"なし"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"許可されない日付: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"想定パターンと一致しない日付: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"想定される年の範囲(%1$s~%2$s)から日付が外れています"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"カレンダー入力モードに切り替え"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"テキスト入力モードに切り替え"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"これより後の年を表示するにはスクロールしてください"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"これより前の年を表示するにはスクロールしてください"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"日付の選択"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"開始日"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"終了日"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"翌月を表示するにはスクロールしてください"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"前月を表示するにはスクロールしてください"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"範囲内"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"日付の入力"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"入力された期間は無効です"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ドラッグ ハンドル"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ボトムシートを折りたたみます"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ボトムシートを閉じます"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ボトムシートを開きます"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ツールチップ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ツールチップを表示"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"午前または午後を選択"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"時刻を選択"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"分を選択"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d 時"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d 時間"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d 分"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"分"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"時間"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"(分単位)"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"(時間単位)"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ka/strings.xml b/compose/material3/material3/src/androidMain/res/values-ka/strings.xml
new file mode 100644
index 0000000..132e1f9
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ka/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"დიალოგი"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"გაფართოებული"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ჩაკეცილი"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"დახურვა"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ძიება"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"შემოთავაზებები იხილეთ ქვემოთ"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"თარიღის არჩევა"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"არჩეული თარიღი"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"წლის არჩევაზე გადასვლა"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"გადაფურცლეთ წლის ასარჩევად, ან შეხებით აირჩიეთ ისევ დღის არჩევაზე გადართვა"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"შემდეგ თვეზე გადასვლა"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"წინა თვეზე გადასვლა"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s-ზე გადასვლა"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ამჟამინდელი არჩევანი: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"არცერთი"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"დღეს"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"არჩეული წელი ხილულია"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"თარიღის არჩევა"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"შეყვანილი სახელი"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"თარიღი"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"შეყვანილი თარიღი: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"არცერთი"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"თარიღი დაუშვებელია: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"თარიღი არ ემთხვევა მოსალოდნელ ნიმუშს: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"თარიღი არ არის წლების მოსალოდნელ დიაპაზონში %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"კალენდარში შეყვანის რეჟიმზე გადართვა"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ტექსტის შეყვანის რეჟიმზე გადართვა"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"გადააადგილეთ შემდგომი წლების საჩვენებლად"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"გადააადგილეთ წინა წლების საჩვენებლად"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"თარიღების არჩევა"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"დაწყების თარიღი"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"დასრულების თარიღი"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"გადააადგილეთ შემდეგი თვის საჩვენებლად"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"გადააადგილეთ წინა თვის საჩვენებლად"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"არეალშია"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"თარიღების შეყვანა"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"შეყვანილია თარიღების არასწორი დიაპაზონი"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"სახელური ჩავლებისთვის"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ქვედა ფურცლის ჩაკეცვა"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ქვედა ფურცლის უარყოფა"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ქვედა ფურცლის გაშლა"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"მინიშნება"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"მინიშნების ჩვენება"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"აირჩიეთ AM ან PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"აირჩიეთ საათი"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"აირჩიეთ წუთები"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d სთ"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d საათი"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d წთ"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"წუთი"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"საათი"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"რამდენიმე წუთით"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ერთი საათით"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-kk/strings.xml b/compose/material3/material3/src/androidMain/res/values-kk/strings.xml
new file mode 100644
index 0000000..e208383
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-kk/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Диалогтік терезе"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Жайылды"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Жиылды"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Жабу"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Іздеу"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Төмендегі ұсыныстар"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Күн таңдау"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Таңдалған күн"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Жыл таңдауға өту"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Жыл таңдау үшін сырғытыңыз. Күн таңдауға ауысу үшін түртіңіз."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Келесі айға өзгерту"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Алдыңғы айға өзгерту"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Мына жылға өту: %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Қазіргі таңдау: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ешқандай"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Бүгін"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Көрсетілген жыл таңдағышы"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Күн таңдау"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Деректер енгізілді"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Күні"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Деректер енгізілді: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ешқандай"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Деректер рұқсат етілмейді: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Деректер болжалды өрнекке сай келмейді: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Күтілетін жыл аралығы: %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Күнтізбенің енгізу режиміне ауысу"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Мәтін енгізу режиміне ауысу"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Кейінгі жылдарды көрсету үшін айналдырыңыз."</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Алдыңғы жылдарды көрсету үшін айналдырыңыз."</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Күндер таңдау"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Басталу күні"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Аяқталу күні"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Келесі айды көрсету үшін айналдырыңыз."</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Алдыңғы айды көрсету үшін айналдырыңыз."</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Күндер аралығында"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Күндерді енгізіңіз"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Жарамсыз күндер аралығы енгізілген."</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Сүйрейтін тетік"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Төменгі парақшаны жию"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Төменгі парақшаны жабу"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Төменгі парақшаны жаю"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Қалқыма көмек"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Қалқыма көмекті көрсету"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"түстен кейін"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"түске дейін"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"\"AM\" немесе \"PM\" форматын таңдау"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Сағатты таңдау"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Минут таңдау"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d сағат"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d сағат"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d минут"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Mинут"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Сағат"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"минут"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"сағат"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-km/strings.xml b/compose/material3/material3/src/androidMain/res/values-km/strings.xml
new file mode 100644
index 0000000..0e6572c
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-km/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ប្រអប់"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"បានពង្រីក"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"បានបង្រួម"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ច្រានចោល"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ស្វែងរក"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"ការណែនាំខាងក្រោម"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ជ្រើសរើសកាលបរិច្ឆេទ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"កាលបរិច្ឆេទដែលបានជ្រើសរើស"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ប្ដូរទៅការជ្រើសរើសឆ្នាំ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"អូសដើម្បីជ្រើសរើសឆ្នាំ ឬចុចដើម្បីប្ដូរត្រឡប់ទៅការជ្រើសរើសថ្ងៃវិញ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ប្ដូរទៅខែបន្ទាប់"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ប្ដូរទៅខែមុន"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"រុករកទៅកាន់ឆ្នាំ %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ការជ្រើសរើសបច្ចុប្បន្ន៖ %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"គ្មាន"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ថ្ងៃនេះ"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"អាចមើលឃើញផ្ទាំងជ្រើសរើសឆ្នាំ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ជ្រើសរើសកាលបរិច្ឆេទ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"កាលបរិច្ឆេទដែលបានបញ្ចូល"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"កាលបរិច្ឆេទ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"កាលបរិច្ឆេទដែលបានបញ្ចូល៖ %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"គ្មាន"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"កាលបរិច្ឆេទដែលមិនបានអនុញ្ញាត៖ %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"កាលបរិច្ឆេទមិនត្រូវគ្នានឹងលំនាំដែលរំពឹងទុកទេ៖ %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"កាលបរិច្ឆេទដែលស្ថិតនៅក្រៅចន្លោះឆ្នាំដែលរំពឹងទុក %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ប្ដូរទៅមុខងារបញ្ចូលប្រតិទិន"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ប្ដូរទៅមុខងារបញ្ចូលអក្សរ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"រំកិលដើម្បីបង្ហាញឆ្នាំក្រោយៗ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"រំកិលដើម្បីបង្ហាញឆ្នាំមុនៗ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ជ្រើសរើសកាលបរិច្ឆេទ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"កាលបរិច្ឆេទចាប់ផ្ដើម"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"កាលបរិច្ឆេទបញ្ចប់"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"រំកិលដើម្បីបង្ហាញខែក្រោយ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"រំកិលដើម្បីបង្ហាញខែមុន"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"ក្នុងចន្លោះ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"បញ្ចូលកាលបរិច្ឆេទ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ការបញ្ចូលចន្លោះកាលបរិច្ឆេទមិនត្រឹមត្រូវ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ដងអូស"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"បង្រួមសន្លឹកខាងក្រោម"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ច្រានចោលសន្លឹកខាងក្រោម"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ពង្រីកសន្លឹកខាងក្រោម"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"កំណត់ពន្យល់"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"បង្ហាញកំណត់ពន្យល់"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"ជ្រើសរើស AM ឬ PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ជ្រើសរើសម៉ោង"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ជ្រើសរើសនាទី"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"ម៉ោង %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ម៉ោង"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d នាទី"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"នាទី"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ម៉ោង"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"រយៈពេលប៉ុន្មាននាទី"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"រយៈពេលប៉ុន្មានម៉ោង"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-kn/strings.xml b/compose/material3/material3/src/androidMain/res/values-kn/strings.xml
new file mode 100644
index 0000000..dfb622b
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-kn/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ಡೈಲಾಗ್"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ವಿಸ್ತರಿಸಲಾಗಿದೆ"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ಕುಗ್ಗಿಸಲಾಗಿದೆ"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ಹುಡುಕಿ"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"ಸಲಹೆಗಳನ್ನು ಕೆಳಗೆ ನೀಡಲಾಗಿದೆ"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ದಿನಾಂಕ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ಆಯ್ಕೆಮಾಡಲಾದ ದಿನಾಂಕ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ವರ್ಷವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಬದಲಿಸಿ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ವರ್ಷವನ್ನು ಆಯ್ಕೆಮಾಡಲು ಸ್ವೈಪ್ ಮಾಡಿ ಅಥವಾ ದಿನವನ್ನು ಆಯ್ಕೆಮಾಡಲು ಹಿಂತಿರುಗಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ಮುಂದಿನ ತಿಂಗಳಿಗೆ ಬದಲಿಸಿ"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ಹಿಂದಿನ ತಿಂಗಳಿಗೆ ಬದಲಿಸಿ"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s ವರ್ಷಕ್ಕೆ ನ್ಯಾವಿಗೇಟ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ಪ್ರಸ್ತುತ ಆಯ್ಕೆ: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ಯಾವುದೂ ಅಲ್ಲ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ಇಂದು"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ವರ್ಷದ ಪಿಕರ್ ಗೋಚರಿಸುತ್ತದೆ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ದಿನಾಂಕ ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ನಮೂದಿಸಿದ ದಿನಾಂಕ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ದಿನಾಂಕ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ನಮೂದಿಸಿದ ದಿನಾಂಕ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ಯಾವುದೂ ಅಲ್ಲ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ದಿನಾಂಕವನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ನಿರೀಕ್ಷಿಸಿದ ಪ್ಯಾಟರ್ನ್ನೊಂದಿಗೆ ದಿನಾಂಕ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ದಿನಾಂಕವು ನಿರೀಕ್ಷಿಸಿದ ವರ್ಷದ ವ್ಯಾಪ್ತಿಯನ್ನು ಮೀರಿದೆ %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ಕ್ಯಾಲೆಂಡರ್ ಇನ್ಪುಟ್ ಮೋಡ್ಗೆ ಬದಲಿಸಿ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ಪಠ್ಯ ಇನ್ಪುಟ್ ಮೋಡ್ಗೆ ಬದಲಿಸಿ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"ನಂತರದ ವರ್ಷಗಳನ್ನು ತೋರಿಸಲು ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ಹಿಂದಿನ ವರ್ಷಗಳನ್ನು ತೋರಿಸಲು ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ದಿನಾಂಕಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ಪ್ರಾರಂಭ ದಿನಾಂಕ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ಅಂತಿಮ ದಿನಾಂಕ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ಮುಂದಿನ ತಿಂಗಳನ್ನು ತೋರಿಸಲು ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ಹಿಂದಿನ ತಿಂಗಳನ್ನು ತೋರಿಸಲು ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"ವ್ಯಾಪ್ತಿಯಲ್ಲಿದೆ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ದಿನಾಂಕಗಳನ್ನು ನಮೂದಿಸಿ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ದಿನಾಂಕ ವ್ಯಾಪ್ತಿಯ ಇನ್ಪುಟ್ ಅಮಾನ್ಯವಾಗಿದೆ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ಹ್ಯಾಂಡಲ್ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ಕೆಳಭಾಗದ ಶೀಟ್ ಅನ್ನು ಕುಗ್ಗಿಸಿ"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ಕೆಳಭಾಗದ ಶೀಟ್ ಅನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ಕೆಳಭಾಗದ ಶೀಟ್ ಅನ್ನು ವಿಸ್ತರಿಸಿ"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ಟೂಲ್ಟಿಪ್"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ಟೂಲ್ಟಿಪ್ ಅನ್ನು ತೋರಿಸಿ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM ಅಥವಾ PM ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ಸಮಯವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ನಿಮಿಷಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d ಓ ಕ್ಲಾಕ್"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ಗಂಟೆ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d ನಿಮಿಷಗಳು"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"ನಿಮಿಷ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ಗಂಟೆ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ನಿಮಿಷಗಳವರೆಗೆ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ಗಂಟೆಯವರೆಗೆ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ko/strings.xml b/compose/material3/material3/src/androidMain/res/values-ko/strings.xml
new file mode 100644
index 0000000..fb57d2d
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ko/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"대화상자"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"펼침"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"접힘"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"닫기"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"검색"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"아래의 추천 검색어"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"날짜 선택"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"선택한 날짜"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"연도 선택으로 전환"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"스와이프하여 연도를 선택하거나 탭하여 날짜 선택으로 돌아가세요."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"다음 달로 변경"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"이전 달로 변경"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s년으로 이동"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"현재 선택사항: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"없음"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"오늘"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"연도 선택 도구 표시"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"날짜 선택"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"입력한 날짜"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"날짜"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"입력한 날짜: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"없음"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"데이터 허용 안 됨: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"데이터가 예상 패턴과 일치하지 않음: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"데이터가 예상 연도 범위(%1$s~%2$s)를 벗어남"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"캘린더 입력 모드로 전환"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"텍스트 입력 모드로 전환"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"스크롤하여 이후 연도 보기"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"스크롤하여 이전 연도 보기"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"날짜 선택"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"시작일"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"종료일"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"스크롤하여 다음 달 보기"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"스크롤하여 이전 달 보기"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"범위 내"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"날짜 입력"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"잘못된 기간 입력"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"드래그 핸들"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"하단 시트 접기"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"하단 시트 닫기"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"하단 시트 펼치기"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"도움말"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"도움말 표시"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"오후"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"오전"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"오전 또는 오후를 선택하세요."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"시간 선택"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"분 선택"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d시 정각"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d시간"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d분"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"분"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"시간"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"기간(분)"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"기간(시간)"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ky/strings.xml b/compose/material3/material3/src/androidMain/res/values-ky/strings.xml
new file mode 100644
index 0000000..849a323
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ky/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Диалог"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Жайылып көрсөтүлдү"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Жыйыштырылды"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Жабуу"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Издөө"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Сунуштар төмөндө келтирилди"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Күндү тандоо"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Тандалган күн"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Жыл тандоого которулуу"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Жылды тандоо үчүн экранды сүрүңүз же күндү тандоого кайтуу үчүн таптап коюңуз"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Кийинки айга өзгөртүү"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Мурунку айга өзгөртүү"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s-жылга өтүү"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Учурда %1$s тандалды"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Жок"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Бүгүн"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Көрсөтүлгөн жыл тандагыч"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Күндү тандоо"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Киргизилген күн"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Күнү"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Киргизилген күн: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Жок"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Күндүн мындай форматын колдонууга болбойт: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Күндүн форматы үлгүгө дал келген жок: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Күн %1$s — %2$s деп белгиленген жылдар диапазонуна кирбей калды"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Жылнаамага киргизүү режимине которулуу"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Текст киргизүү режимине которулуу"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Кийинки жылдарды көрүү үчүн сыдырыңыз"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Мурунку жылдарды көрүү үчүн сыдырыңыз"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Күндөрдү тандоо"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Башталуу күнү"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Аяктоо күнү"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Кийинки айды көрүү үчүн сыдырыңыз"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Мурунку айды көрүү үчүн сыдырыңыз"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Төмөнкү убакыт аралыгындагы күн"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Күндөрдү киргизүү"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Даталар диапазону туура эмес тандалды"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Сүйрөө маркери"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Ылдыйкы экранды жыйыштыруу"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ылдыйкы экранды жабуу"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Ылдыйкы экранды жайып көрсөтүү"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Калкып чыгуучу кеңеш"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Калкып чыгуучу кеңешти көрсөтүү"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"түштөн кийин"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"түшкө чейин"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Түшкө чейинки же түштөн кийинки убакытты тандоо"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Саат тандоо"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Мүнөттөрдү тандаңыз"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d саат"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d саат"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d мүнөт"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Мүнөт"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Саат"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"мүнөткө"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"саатка"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-lo/strings.xml b/compose/material3/material3/src/androidMain/res/values-lo/strings.xml
new file mode 100644
index 0000000..f4f11a3
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-lo/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ກ່ອງໂຕ້ຕອບ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ຂະຫຍາຍແລ້ວ"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ຫຍໍ້ລົງແລ້ວ"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ປິດໄວ້"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ຊອກຫາ"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"ມີຄຳແນະນຳຢູ່ຂ້າງລຸ່ມ"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ເລືອກວັນທີ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ວັນທີທີ່ເລືອກໄວ້"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ປ່ຽນໄປເລືອກປີ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ປັດເພື່ອເລືອກປີ ຫຼື ແຕະເພື່ອປ່ຽນກັບໄປຫາການເລືອກວັນ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ປ່ຽນເປັນເດືອນຕໍ່ໄປ"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ປ່ຽນເປັນເດືອນກ່ອນໜ້າ"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"ນຳທາງໄປຫາປີ %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ການເລືອກປັດຈຸບັນ: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ບໍ່ມີ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ມື້ນີ້"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ສະແດງຕົວເລືອກປີ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ເລືອກວັນທີ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ລະບຸວັນທີແລ້ວ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ວັນທີ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ລະບຸວັນທີແລ້ວ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ບໍ່ມີ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ບໍ່ອະນຸຍາດໃຫ້ໃຊ້ວັນທີ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ວັນທີບໍ່ກົງກັບຮູບແບບທີ່ຄາດໄວ້: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ວັນທີຢູ່ນອກໄລຍະປີທີ່ຄາດໄວ້ %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ສະຫຼັບໄປໃຊ້ໂໝດປ້ອນຂໍ້ມູນປະຕິທິນ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ສະຫຼັບໄປໃຊ້ໂໝດປ້ອນຂໍ້ຄວາມ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"ເລື່ອນເພື່ອສະແດງປີຫຼັງຈາກນີ້"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ເລື່ອນເພື່ອສະແດງປີກ່ອນໜ້ານີ້"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ເລືອກວັນທີ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ວັນທີເລີ່ມຕົ້ນ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ວັນທີສິ້ນສຸດ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ເລື່ອນເພື່ອສະແດງເດືອນຕໍ່ໄປ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ເລື່ອນເພື່ອສະແດງເດືອນກ່ອນໜ້າ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"ຢູ່ໃນໄລຍະວັນທີທີ່ເລືອກ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ໃສ່ວັນທີ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ອິນພຸດໄລຍະວັນທີບໍ່ຖືກຕ້ອງ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ບ່ອນຈັບລາກ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ຫຍໍ້ຊີດລຸ່ມສຸດລົງ"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ປິດຊີດລຸ່ມສຸດໄວ້"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ຂະຫຍາຍຊີດລຸ່ມສຸດ"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ຄຳແນະນຳ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ສະແດງຄຳແນະນຳ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ຫຼັງທ່ຽງ"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ກ່ອນທ່ຽງ"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"ເລືອກກ່ອນທ່ຽງ ຫຼື ຫຼັງທ່ຽງ"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ເລືອກຊົ່ວໂມງ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ເລືອກນາທີ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d ໂມງ"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ຊົ່ວໂມງ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d ນາທີ"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"ນາທີ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ຊົ່ວໂມງ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ສຳລັບນາທີ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ສຳລັບຊົ່ວໂມງ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-lt/strings.xml b/compose/material3/material3/src/androidMain/res/values-lt/strings.xml
new file mode 100644
index 0000000..a24fa91
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-lt/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogo langas"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Išskleista"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Sutraukta"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Atsisakyti"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Paieška"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Pasiūlymai pateikti toliau"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Pasirinkite datą"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Pasirinkta data"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Perjungti į metų pasirinkimą"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Perbraukite, kad pasirinktumėte metus, arba palieskite, kad grįžtumėte ir vėl pasirinktumėte dieną"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Pakeisti į kitą mėnesį"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Pakeisti į ankstesnį mėnesį"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Eiti į %1$s m."</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Dabartinis pasirinkimas: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nėra"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Šiandien"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Rodomas metų parinkiklis"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Pasirinkite datą"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Įvesta data"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Įvesta data: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nėra"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data neleidžiama: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Data neatitinka numatyto šablono: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Data nepatenka į numatytų metų diapazoną: %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Perjungti į kalendoriaus įvesties režimą"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Perjungti į teksto įvesties režimą"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Slinkite, kol bus rodomi vėlesni metai"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Slinkite, kol bus rodomi ankstesni metai"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Pasirinkite datas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Pradžios data"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Pabaigos data"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Slinkite, kol bus rodomas kitas mėnuo"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Slinkite, kol bus rodomas ankstesnis mėnuo"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Diapazone"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Įvesti datas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Netinkama dienų sekos įvestis"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Vilkimo rankenėlė"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Sutraukti apatinį lapą"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Atsisakyti apatinio lapo"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Išskleisti apatinį lapą"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Patarimas"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Rodyti patarimą"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"popiet"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Pasirinkite „priešpiet“ arba „popiet“"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Pasirinkite valandą"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Pasirinkite minutes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d val."</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d val."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%d min."</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minutė"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Valanda"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minutės"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"valandos"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-lv/strings.xml b/compose/material3/material3/src/androidMain/res/values-lv/strings.xml
new file mode 100644
index 0000000..508be30
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-lv/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialoglodziņš"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Izvērsta"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Sakļauta"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Nerādīt"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Meklēšana"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Tālāk ir sniegti ieteikumi"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Atlasīt datumu"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Atlasītais datums"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Pāriet uz gada atlasi"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Velciet, lai atlasītu gadu, vai pieskarieties, lai pārietu atpakaļ pie dienas atlases"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Mainīt uz nākamo mēnesi"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Mainīt uz iepriekšējo mēnesi"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Pāriet uz %1$s. gadu"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Pašreizējā atlase: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nav"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Šodien"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Redzams gada atlasītājs"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Atlasīt datumu"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Ievadītais datums"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datums"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Ievadītais datums: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nav"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datums nav atļauts: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datums neatbilst paredzētajam formātam: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datums nav paredzētajā gadu diapazonā (%1$s.–%2$s. g.)"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Pārslēgties uz kalendāra ievades režīmu"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Pārslēgties uz teksta ievades režīmu"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Lai rādītu nākamos gadus, ritiniet"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Lai rādītu iepriekšējos gadus, ritiniet"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Atlasiet datumus"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Sākuma datums"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Beigu datums"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Lai rādītu nākamo mēnesi, ritiniet"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Lai rādītu iepriekšējo mēnesi, ritiniet"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Atlasītajā diapazonā"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Ievadiet datumus"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Ievadīts nederīgs datumu diapazons."</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Vilkšanas turis"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Sakļaut ekrāna apakšdaļas lapu"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Noraidīt ekrāna apakšdaļas lapu"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Izvērst ekrāna apakšdaļas lapu"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Rīka padoms"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Rādīt rīka padomu"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Atlasīt “AM” (priekšpusdienā) vai “PM” (pēcpusdienā)"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Atlasīt stundu"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Atlasīt minūtes"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"Minūtes: %1$d"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minūtes"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Stunda"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minūtēm"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"stundām"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-mk/strings.xml b/compose/material3/material3/src/androidMain/res/values-mk/strings.xml
new file mode 100644
index 0000000..f137b45
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-mk/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Дијалог"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Проширено"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Собрано"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Отфрли"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Пребарување"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Предлозите се наведени подолу"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Изберете датум"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Избран датум"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Префрли на избирање година"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Повлечете за да изберете година или допрете за да се вратите на избирање ден"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Промени на следниот месец"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Промени на претходниот месец"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Одете на %1$s година"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Тековен избор: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Нема"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Денес"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Избирачот на година е видлив"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Изберете датум"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Внесен датум"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Датум"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Внесен датум: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Нема"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Датумот не е дозволен: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Не се совпаѓа со очекуваната шема: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Датумот не е во очекуваниот опсег на години %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Префрли на режим за внесување во календарот"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Префрли на режим за внесување текст"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Лизгајте за да ги прикажете подоцнежните години"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Лизгајте за да ги прикажете претходните години"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Изберете датуми"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Датум на започнување"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Датум на завршување"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Лизгајте за да се прикаже следниот месец"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Лизгајте за да се прикаже претходниот месец"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Во опсег"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Внесете датуми"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Внесовте неважечки временски период"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Рачка за влечење"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Собери го долниот лист"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Отфрли го долниот лист"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Прошири го долниот лист"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Совет за алатка"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Прикажи совет за алатка"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"попл."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"прет."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Изберете претпладне или попладне"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Изберете час"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Изберете минути"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d часот"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d часа"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d минути"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Минута"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Час"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"за минути"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"за час"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ml/strings.xml b/compose/material3/material3/src/androidMain/res/values-ml/strings.xml
new file mode 100644
index 0000000..a800a5a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ml/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ഡയലോഗ്"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"വിപുലീകരിച്ചത്"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ചുരുക്കിയത്"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ഡിസ്മിസ് ചെയ്യുക"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"തിരയുക"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"നിദ്ദേശങ്ങൾ ചുവടെയുണ്ട്"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"തീയതി തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"തിരഞ്ഞെടുത്ത തീയതി"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"വർഷം തിരഞ്ഞെടുക്കുന്നതിലേക്ക് മാറുക"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"വർഷം തിരഞ്ഞെടുക്കാൻ സ്വൈപ്പ് ചെയ്യുക അല്ലെങ്കിൽ ദിവസം തിരഞ്ഞെടുക്കുന്നതിലേക്ക് തിരികെ പോകാൻ ടാപ്പ് ചെയ്യുക"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"അടുത്ത മാസത്തിലേക്ക് മാറ്റുക"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"മുമ്പത്തെ മാസത്തിലേക്ക് മാറ്റുക"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s എന്ന വർഷത്തിലേക്ക് പോകുക"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"നിലവിലെ തിരഞ്ഞെടുപ്പ്: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ഒന്നുമില്ല"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ഇന്ന്"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"വർഷ പിക്കർ ദൃശ്യമാണ്"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"തീയതി തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"നൽകിയ തീയതി"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"തീയതി"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"നൽകിയ തീയതി: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ഒന്നുമില്ല"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"തീയതി അനുവദനീയമല്ല: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"പ്രതീക്ഷിച്ച പാറ്റേണുമായി തീയതി പൊരുത്തപ്പെടുന്നില്ല: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"പ്രതീക്ഷിക്കുന്ന കാലയളവിലെ വർഷമല്ല നൽകിയ തീയതിയുടേത് %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"കലണ്ടർ ഇൻപുട്ട് മോഡിലേക്ക് മാറുക"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ടെക്സ്റ്റ് ഇൻപുട്ട് മോഡിലേക്ക് മാറുക"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"പിന്നീടുള്ള വർഷങ്ങൾ കാണിക്കാൻ സ്ക്രോൾ ചെയ്യുക"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"മുൻ വർഷങ്ങൾ കാണിക്കാൻ സ്ക്രോൾ ചെയ്യുക"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"തീയതികൾ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ആരംഭിക്കുന്ന തീയതി"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"അവസാനിക്കുന്ന തീയതി"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"അടുത്ത മാസം കാണിക്കാൻ സ്ക്രോൾ ചെയ്യുക"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"മുമ്പത്തെ മാസം കാണിക്കാൻ സ്ക്രോൾ ചെയ്യുക"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"പരിധിയിൽ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"തീയതികൾ നൽകുക"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"തീയതി ശ്രേണി ഇൻപുട്ട് അസാധുവാണ്"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"വലിച്ചിടുന്നതിനുള്ള ഹാൻഡിൽ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ബോട്ടം ഷീറ്റ് ചുരുക്കുക"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ബോട്ടം ഷീറ്റ് ഡിസ്മിസ് ചെയ്യുക"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ബോട്ടം ഷീറ്റ് വികസിപ്പിക്കുക"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ടൂൾടിപ്പ്"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ടൂൾടിപ്പ് കാണിക്കുക"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM അല്ലെങ്കിൽ PM തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"മണിക്കൂർ തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"മിനിറ്റ് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d മണി"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d മ."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d മിനിറ്റ്"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"മിനിറ്റ്"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"മണിക്കൂർ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"മിനിറ്റ് നേരത്തേക്ക്"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"മണിക്കൂർ നേരത്തേക്ക്"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-mn/strings.xml b/compose/material3/material3/src/androidMain/res/values-mn/strings.xml
new file mode 100644
index 0000000..485667d
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-mn/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Харилцах цонх"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Дэлгэсэн"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Хураасан"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Хаах"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Хайх"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Доорх зөвлөмжүүд"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Огноо сонгох"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Сонгосон огноо"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Он сонгох руу сэлгэх"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Он сонгохын тулд шудрах эсвэл өдөр сонгох руу буцааж сэлгэхийн тулд товшино уу"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Дараагийн сар луу өөрчлөх"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Өмнөх сар луу өөрчлөх"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s он руу шилжих"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Одоогийн сонголт: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Байхгүй"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Өнөөдөр"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Он сонгогч харагдаж байна"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Огноо сонгох"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Оруулсан огноо"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Огноо"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Оруулсан огноо: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Байхгүй"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Зөвшөөрөөгүй огноо: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Огноо нь тооцоолсон хээтэй таарахгүй байна: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Тооцоолсон оны %1$s - %2$s мужаас гарсан огноо"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Календарийн орох горим руу сэлгэх"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Текст оруулах горим руу сэлгэх"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Дараагийн жилүүдийг харуулахын тулд гүйлгэнэ үү"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Өмнөх жилүүдийг харуулахын тулд гүйлгэнэ үү"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Огноо сонгох"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Эхлэх огноо"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Дуусах огноо"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Дараагийн сарыг харуулахын тулд гүйлгэнэ үү"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Өмнөх сарыг харуулахын тулд гүйлгэнэ үү"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Мужид байгаа"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Огноо оруулах"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Хугацааны интервалын оролт буруу байна"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Чирэх бариул"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Доод хүснэгтийг хураах"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Доод хүснэгтийг хаах"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Доод хүснэгтийг дэлгэх"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Зөвлөмж"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Зөвлөмж харуулах"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ҮХ"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ҮӨ"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"ҮӨ эсвэл ҮХ эсэхийг сонгоно уу"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Цаг сонгох"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Минут сонгох"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d цаг"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d цаг"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d минут"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Минут"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Цаг"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"минутын турш"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"цагийн турш"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-mr/strings.xml b/compose/material3/material3/src/androidMain/res/values-mr/strings.xml
new file mode 100644
index 0000000..f5231f06
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-mr/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"डायलॉग"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"विस्तारित केला आहे"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"कोलॅप्स केला आहे"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"डिसमिस करा"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"शोधा"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"सूचना खाली आहेत"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"तारीख निवडा"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"निवडलेली तारीख"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"वर्ष निवडणे यावर स्विच करा"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"वर्ष निवडण्यासाठी स्वाइप करा किंवा दिवस निवडण्यावर परत स्विच करण्यासाठी टॅप करा"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"पुढील महिन्यावर बदला"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"मागील महिन्यावर बदला"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s वर्षावर नेव्हिगेट करा"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"सध्याची निवड: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"काहीही नाही"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"आज"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"वर्ष पिकर दृश्यमान आहे"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"तारीख निवडा"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"एंटर केलेली तारीख"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"तारीख"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"एंटर केली तारीख: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"काहीही नाही"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"अशा तारखेला अनुमती नाही: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"तारीख ही अपेक्षित पॅटर्नशी जुळत नाही: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"तारीख ही %1$s - %2$s या अपेक्षित रेंजच्या बाहेरची आहे"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"कॅलेंडर इनपुट मोडवर स्विच करा"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"टेक्स्ट इनपुट मोडवर स्विच करा"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"नंतरची वर्षे दाखवण्यासाठी स्क्रोल करा"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"मागील वर्षे दाखवण्यासाठी स्क्रोल करा"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"तारखा निवडा"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"सुरू होण्याची तारीख"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"संपण्याची तारीख"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"पुढील महिना दाखवण्यासाठी स्क्रोल करा"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"मागील महिना दाखवण्यासाठी स्क्रोल करा"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"रेंजमध्ये"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"तारखा एंटर करा"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"तारीख रेंजचे इनपुट चुकीचे आहे"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ड्रॅग हॅंडल"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"तळाशी असलेली शीट कोलॅप्स करा"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"तळाशी असलेली शीट डिसमिस करा"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"तळाशी असलेली शीट विस्तारीत करा"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"टूलटिप"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"टूलटिप दाखवा"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM किंवा PM निवडा"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"तास निवडा"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"मिनिटे निवडा"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d वाजता"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d तास"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d मिनिटे"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"मिनिट"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"तास"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"मिनिटांसाठी"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"तासासाठी"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ms/strings.xml b/compose/material3/material3/src/androidMain/res/values-ms/strings.xml
new file mode 100644
index 0000000..e6c51cd
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ms/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Dikembangkan"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Dikuncupkan"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Ketepikan"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Carian"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Cadangan di bawah"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Pilih tarikh"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Tarikh dipilih"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Beralih kepada pemilihan tahun"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Leret untuk memilih tahun atau ketik untuk bertukar kembali kepada pemilihan hari"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Tukar kepada bulan seterusnya"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Tukar kepada bulan sebelumnya"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigasi ke tahun %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Pilihan semasa: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Tiada"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hari ini"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Pemilih tahun kelihatan"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Pilih tarikh"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Tarikh yang dimasukkan"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Tarikh"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Tarikh yang dimasukkan: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Tiada"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Tarikh yang tidak dibenarkan: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Tarikh tidak sepadan dengan corak yang dijangkakan: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Tarikh di luar julat tahun yang dijangkakan %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Beralih kepada mod input kalendar"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Beralih kepada mod input teks"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Tatal untuk menunjukkan tahun kemudian"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Tatal untuk menunjukkan tahun terdahulu"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Pilih tarikh"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Tarikh mula"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Tarikh tamat"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Tatal untuk menunjukkan bulan seterusnya"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Tatal untuk menunjukkan bulan sebelumnya"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dalam liputan"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Masukkan tarikh"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Input julat tarikh tidak sah"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Pemegang seret"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Kuncupkan helaian bawah"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ketepikan helaian bawah"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Kembangkan helaian bawah"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tip alat"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Tunjukkan tip alat"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"P/M"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"PG"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Pilih PG atau PTG/MLM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Pilih jam"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Pilih minit"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Pukul %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d jam"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minit"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minit"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Jam"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"selama # minit"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"selama # jam"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-my/strings.xml b/compose/material3/material3/src/androidMain/res/values-my/strings.xml
new file mode 100644
index 0000000..9d1ec09
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-my/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ဒိုင်ယာလော့"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ချဲ့ထားသည်"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ချုံ့ထားသည်"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ပယ်ရန်"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ရှာရန်"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"အကြံပြုချက်များသည် အောက်တွင်ရှိသည်"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ရက်စွဲရွေးရန်"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ရွေးထားသည့် ရက်စွဲ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"နှစ်ရွေးခြင်းသို့ ပြောင်းရန်"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ခုနှစ်ရွေးချယ်ရန် ပွတ်ဆွဲပါ (သို့) ရက်ရွေးချယ်ခြင်းသို့ ပြန်ရန် တို့ပါ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"နောက်လသို့ ပြောင်းရန်"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ယခင်လသို့ ပြောင်းရန်"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s ခုနှစ်သို့ သွားရန်"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"လက်ရှိ ရွေးချယ်မှု- %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"မရှိ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ယနေ့"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ခုနှစ်ရွေးချယ်ရေးစနစ်ကို မြင်ရသည်"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ရက်စွဲရွေးရန်"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ထည့်ထားသော ရက်စွဲ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ရက်စွဲ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ထည့်ထားသော ရက်စွဲ- %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"မရှိ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ရက်စွဲကို ခွင့်ပြုမထားပါ- %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ရက်စွဲသည် မျှော်မှန်းထားသော ပုံစံနှင့် မကိုက်ညီပါ- %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ရက်စွဲသည် မျှော်မှန်းထားသော နှစ်အပိုင်းအခြား %1$s - %2$s တွင် မပါဝင်ပါ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ပြက္ခဒိန် လက်ကွက်ထည့်သွင်းနည်းသို့ ပြောင်းရန်"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"စာရိုက်နည်းသို့ ပြောင်းရန်"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"နောက်ပိုင်းနှစ်များ ပြရန် လှိမ့်ပါ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ယခင်နှစ်များ ပြရန် လှိမ့်ပါ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ရက်စွဲများရွေးပါ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"စတင်ရက်"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ပြီးဆုံးရက်"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"လာမည့်လကို ပြရန် လှိမ့်ပါ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ယခင်လကို ပြရန် လှိမ့်ပါ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"အပိုင်းအခြားအတွင်း"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ရက်စွဲများထည့်ပါ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ဒေတာအပိုင်းအခြား ထည့်သွင်းမှု မမှန်ပါ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ဖိဆွဲအထိန်း"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"အောက်ခြေအပိုဆောင်း စာမျက်နှာကို ချုံ့သည်"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"အောက်ခြေအပိုဆောင်း စာမျက်နှာကို ပယ်သည်"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"အောက်ခြေအပိုဆောင်း စာမျက်နှာကို ချဲ့သည်"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"အကြံပြုချက်ပြ ပေါ့အပ် ဝင်းဒိုး"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"အကြံပြုချက်ပြ ပေါ့အပ်ဝင်းဒိုး ပြရန်"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM (သို့) PM ရွေးရန်"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"နာရီ ရွေးရန်"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"မိနစ်များရွေးပါ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d နာရီ"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d နာရီ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d မိနစ်"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"မိနစ်"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"နာရီ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"မိနစ်ကြာ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"နာရီကြာ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-nb/strings.xml b/compose/material3/material3/src/androidMain/res/values-nb/strings.xml
new file mode 100644
index 0000000..04edceb
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-nb/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogboks"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Vises"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Skjules"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Lukk"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Søk"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Du finner forslag nedenfor"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Velg dato"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valgt dato"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Bytt til å velge et år"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Sveip for å velge år, eller trykk for å bytte tilbake til valg av dag"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Bytt til neste måned"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Bytt til forrige måned"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Gå til år %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Valgt: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ingen"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"I dag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Årsvelgeren er synlig"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Velg dato"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Angitt dato"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dato"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Angitt dato: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ingen"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datoen er ikke tillatt: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datoen matcher ikke det forventede mønsteret: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datoen er utenfor det forventede årsintervallet %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Bytt til kalendermodus for inndata"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Bytt til tekstmodus for inndata"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Rull for å vise senere år"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Rull for å vise tidligere år"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Velg datoer"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Startdato"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Sluttdato"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Rull for å vise den neste måneden"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Rull for å vise den forrige måneden"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Innenfor området"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Legg inn datoer"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"En ugyldig datoperiode er valgt"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Håndtak"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Skjul feltet nederst"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Lukk feltet nederst"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Vis feltet nederst"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Verktøytips"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Vis verktøytips"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Velg AM eller PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Velg time"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Velg minutter"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d timer"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutter"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minutt"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Time"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"for minutter"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"for timer"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ne/strings.xml b/compose/material3/material3/src/androidMain/res/values-ne/strings.xml
new file mode 100644
index 0000000..5079393
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ne/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"डायलग"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"एक्स्पान्ड गरिएको छ"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"कोल्याप्स गरिएको छ"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"खारेज गर्नुहोस्"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"खोज्नुहोस्"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"सुझावहरू तल दिइएका छन्"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"मिति चयन गर्नुहोस्"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"चयन गरिएको मिति"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"साल चयन गर्ने फिल्डमा जानुहोस्"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"कुनै साल छनौट गर्न स्वाइप गर्नुहोस् वा दिन चयन गर्न ट्याप गर्नुहोस्"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"हाल चयन गरिएको महिना परिवर्तन गरी आगामी महिना बनाउनुहोस्"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"हाल चयन गरिएको महिना परिवर्तन गरी अघिल्लो महिना बनाउनुहोस्"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"साल %1$s मा जानुहोस्"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"हालको छनौट: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"कुनै पनि होइन"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"आज"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"डेट पिकर देखिएको छ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"मिति चयन गर्नुहोस्"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"हालिएको मिति"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"मिति"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"हालिएको मिति: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"कुनै पनि होइन"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"यो मिति हाल्न पाइँदैन: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"हालिएको मितिको प्याटर्न अपेक्षित प्याटर्नसँग मिल्दैन: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"हालिएको मिति सालको अपेक्षित दायरा (%1$s - %2$s) भित्र पर्दैन"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"पात्रोको इनपुट मोड प्रयोग गर्नुहोस्"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"टेक्स्ट इनपुट मोड प्रयोग गर्नुहोस्"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"आगामी सालहरूको जानकारी हेर्न स्क्रोल गर्नुहोस्"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"विगतका सालहरूको जानकारी हेर्न स्क्रोल गर्नुहोस्"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"मितिहरू चयन गर्नुहोस्"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"सुरु हुने मिति"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"अन्त्य हुने मिति"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"अर्को महिनाको जानकारी हेर्न स्क्रोल गर्नुहोस्"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"गत महिनाको जानकारी हेर्न स्क्रोल गर्नुहोस्"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"चयन गरिएका दिनभित्र पर्ने"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"मितिहरू हाल्नुहोस्"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"मितिको अवैध दायरा हालियो"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ड्र्याग ह्यान्डल"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"पुछारको पाना कोल्याप्स गर्नुहोस्"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"पुछारको पाना हटाउनुहोस्"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"पुछारको पाना एक्स्पान्ड गर्नुहोस्"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"टुलटिप"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"टुलटिप देखाइयोस्"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"अपराह्न"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"पूर्वाह्न"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"पूर्वाह्न वा अपराह्न चयन गर्नुहोस्"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"घण्टा चयन गर्नुहोस्"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"मिनेट चयन गर्नुहोस्"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d बजे"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d घण्टा"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d मिनेट"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"मिनेट"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"घण्टा"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"मिनेटका लागि"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"घण्टाका लागि"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-nl/strings.xml b/compose/material3/material3/src/androidMain/res/values-nl/strings.xml
new file mode 100644
index 0000000..0fd598d
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-nl/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialoogvenster"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Uitgevouwen"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Samengevouwen"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Sluiten"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Zoeken"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Suggesties hieronder"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Datum selecteren"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Geselecteerde datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Schakelaar om een jaar te selecteren"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swipe om een jaar te selecteren of tik om terug te gaan en een dag te selecteren"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Naar volgende maand gaan"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Naar vorige maand gaan"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Ga naar jaar %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Huidige selectie: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Geen"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Vandaag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Jaarselectie zichtbaar"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Datum selecteren"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Ingevulde datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Ingevulde datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Geen"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datum niet toegestaan: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"De datum komt niet overeen met het verwachte patroon: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum buiten het verwachte jaarbereik %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Overschakelen naar agenda-invoermodus"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Overschakelen naar tekstinvoermodus"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scroll om latere jaren te tonen"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scroll om eerdere jaren te tonen"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Datums selecteren"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Startdatum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Einddatum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scroll om de volgende maand te tonen"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scroll om de vorige maand te tonen"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Binnen bereik"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Datums opgeven"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Ongeldige invoer voor periode"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Handgreep voor slepen"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Blad onderaan samenvouwen"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Blad onderaan sluiten"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Blad onderaan uitvouwen"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Tooltip tonen"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM of PM selecteren"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Uur selecteren"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Minuten selecteren"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d uur"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d uur"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuten"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Uur"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"voor minuten"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"voor uur"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-or/strings.xml b/compose/material3/material3/src/androidMain/res/values-or/strings.xml
new file mode 100644
index 0000000..9babec3
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-or/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ଡାଏଲଗ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ବିସ୍ତାର କରାଯାଇଛି"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ସଙ୍କୁଚିତ କରାଯାଇଛି"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"ପରାମର୍ଶ ତଳେ ଦିଆଯାଇଛି"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ତାରିଖ ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ଚୟନିତ ତାରିଖ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ଏକ ବର୍ଷ ଚୟନ କରିବାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ଏକ ବର୍ଷ ଚୟନ କରିବା ପାଇଁ ସ୍ୱାଇପ କରନ୍ତୁ କିମ୍ବା ଏକ ଦିନ ଚୟନ କରିବା ପାଇଁ ପୁଣି ସୁଇଚ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ପରବର୍ତ୍ତୀ ମାସକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ପୂର୍ବବର୍ତ୍ତୀ ମାସକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s ବର୍ଷକୁ ନାଭିଗେଟ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ବର୍ତ୍ତମାନର ଚୟନ: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"କିଛି ନାହିଁ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ଆଜି"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ବର୍ଷ ପିକର ଦେଖାଯାଉଛି"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ତାରିଖ ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ଲେଖାଯାଇଥିବା ତାରିଖ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ତାରିଖ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ଲେଖାଯାଇଥିବା ତାରିଖ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"କିଛି ନାହିଁ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ତାରିଖକୁ ଅନୁମତି ଦିଆଯାଇନାହିଁ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ଆଶା କରାଯାଉଥିବା ପାଟର୍ନ ସହ ତାରିଖ ମେଳ ହେଉନାହିଁ: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ତାରିଖଟି ଆଶା କରାଯାଉଥିବା ବର୍ଷ ରେଞ୍ଜ %1$s - %2$sରୁ ବାହାରେ ଅଛି"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"କେଲେଣ୍ଡର ଇନପୁଟ ମୋଡକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ଟେକ୍ସଟ ଇନପୁଟ ମୋଡକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"ପର ବର୍ଷଗୁଡ଼ିକ ଦେଖାଇବା ପାଇଁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ପୂର୍ବ ବର୍ଷଗୁଡ଼ିକ ଦେଖାଇବା ପାଇଁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ତାରିଖଗୁଡ଼ିକ ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ଆରମ୍ଭ ତାରିଖ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ଶେଷ ତାରିଖ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ପରବର୍ତ୍ତୀ ମାସ ଦେଖାଇବା ପାଇଁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ପୂର୍ବବର୍ତ୍ତୀ ମାସ ଦେଖାଇବା ପାଇଁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"ରେଞ୍ଜରେ ଅଛି"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ତାରିଖଗୁଡ଼ିକ ଲେଖନ୍ତୁ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ଅବୈଧ ତାରିଖ ରେଞ୍ଜ ଇନପୁଟ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ଡ୍ରାଗ ହେଣ୍ଡେଲ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ବଟମ ସିଟକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ବଟମ ସିଟକୁ ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ବଟମ ସିଟକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ଟୁଲଟିପ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ଟୁଲଟିପ ଦେଖାନ୍ତୁ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM କିମ୍ବା PM ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ଘଣ୍ଟା ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ମିନିଟ ଚୟନ କରନ୍ତୁ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$dଟା"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ଘଣ୍ଟା"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d ମିନିଟ"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"ମିନିଟ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ଘଣ୍ଟା"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ମିନିଟ ପାଇଁ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ଘଣ୍ଟା ପାଇଁ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-pa/strings.xml b/compose/material3/material3/src/androidMain/res/values-pa/strings.xml
new file mode 100644
index 0000000..ccb24f9
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-pa/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ਡਾਇਲੌਗ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ਵਿਸਤਾਰ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ਸਮੇਟਿਆ ਗਿਆ"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ਖਾਰਜ ਕਰੋ"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ਖੋਜੋ"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"ਸੁਝਾਅ ਹੇਠਾਂ ਹਨ"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"ਤਾਰੀਖ ਚੁਣੋ"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ਚੁਣੀ ਗਈ ਤਾਰੀਖ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ਸਾਲ ਚੁਣਨ ਲਈ ਸਵਿੱਚ ਕਰੋ"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ਕੋਈ ਸਾਲ ਚੁਣਨ ਲਈ ਸਵਾਈਪ ਕਰੋ ਜਾਂ ਕੋਈ ਦਿਨ ਚੁਣਨ ਲਈ ਵਾਪਸ ਜਾਣ ਵਾਸਤੇ ਟੈਪ ਕਰੋ"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ਅਗਲੇ ਮਹੀਨੇ \'ਤੇ ਜਾਓ"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"ਪਿਛਲੇ ਮਹੀਨੇ \'ਤੇ ਜਾਓ"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"ਸਾਲ %1$s \'ਤੇ ਜਾਓ"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ਮੌਜੂਦਾ ਚੋਣ: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ਕੋਈ ਨਹੀਂ"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"ਅੱਜ"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ਸਾਲ ਚੋਣਕਾਰ ਦਿਖਣਯੋਗ ਹੈ"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"ਤਾਰੀਖ ਚੁਣੋ"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ਦਾਖਲ ਕੀਤੀ ਗਈ ਤਾਰੀਖ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"ਤਾਰੀਖ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ਦਾਖਲ ਕੀਤੀ ਗਈ ਤਾਰੀਖ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ਕੋਈ ਨਹੀਂ"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ਇਸ ਤਾਰੀਖ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"ਤਾਰੀਖ ਸੰਭਾਵਿਤ ਪੈਟਰਨ ਨਾਲ ਮੇਲ ਨਹੀਂ ਖਾਂਦੀ: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ਤਾਰੀਖ ਸੰਭਾਵਿਤ ਸਾਲ ਦੀ ਰੇਂਜ, %1$s - %2$s ਤੋਂ ਬਾਹਰ ਹੈ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"ਕੈਲੰਡਰ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ਲਿਖਤ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"ਬਾਅਦ ਵਾਲੇ ਸਾਲਾਂ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"ਪਿਛਲੇ ਸਾਲਾਂ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"ਤਾਰੀਖਾਂ ਚੁਣੋ"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ਸ਼ੁੁਰੂਆਤੀ ਤਾਰੀਖ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ਸਮਾਪਤੀ ਤਾਰੀਖ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ਅਗਲਾ ਮਹੀਨਾ ਦਿਖਾਉਣ ਲਈ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"ਪਿਛਲਾ ਮਹੀਨਾ ਦਿਖਾਉਣ ਲਈ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"ਰੇਂਜ ਵਿੱਚ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ਤਾਰੀਖਾਂ ਦਾਖਲ ਕਰੋ"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"ਇਨਪੁੱਟ ਕੀਤੀ ਗਈ ਤਾਰੀਖ ਦੀ ਰੇਂਜ ਅਵੈਧ ਹੈ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ਘਸੀਟਣ ਵਾਲਾ ਹੈਂਡਲ"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ਹੇਠਲੀ ਸ਼ੀਟ ਨੂੰ ਸਮੇਟੋ"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ਹੇਠਲੀ ਸ਼ੀਟ ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ਹੇਠਲੀ ਸ਼ੀਟ ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ਟੂਲ-ਟਿੱਪ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ਟੂਲ-ਟਿੱਪ ਦਿਖਾਓ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM ਜਾਂ PM ਚੁਣੋ"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"ਘੰਟਾ ਚੁਣੋ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"ਮਿੰਟ ਚੁਣੋ"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d ਵਜੇ"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ਘੰਟੇ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d ਮਿੰਟ"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"ਮਿੰਟ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ਘੰਟਾ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ਮਿੰਟਾਂ ਲਈ"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ਘੰਟੇ ਲਈ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-pl/strings.xml b/compose/material3/material3/src/androidMain/res/values-pl/strings.xml
new file mode 100644
index 0000000..69066e2
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-pl/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Okno"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Rozwinięte"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Zwinięte"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Zamknij"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Szukaj"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugestie znajdziesz poniżej"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Wybierz datę"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Wybrana data"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Przełącz na wybór roku"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Przesuń, aby wybrać rok, lub kliknij, aby wrócić do wyboru dnia"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Zmień na następny miesiąc"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Zmień na poprzedni miesiąc"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Przejdź do roku %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Obecnie wybrane: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Brak"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Dzisiaj"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Widoczny selektor roku"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Wybierz datę"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Wprowadzono datę"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Wprowadzono datę: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Brak"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data jest niedozwolona: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Data nie pasuje do oczekiwanego wzorca: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Data jest poza oczekiwanym zakresem lat %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Włącz tryb wprowadzania danych kalendarzowych"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Przełącz na tryb wprowadzania tekstu"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Przewiń, aby wyświetlić późniejsze lata"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Przewiń, aby wyświetlić wcześniejsze lata"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Wybierz daty"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data początkowa"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data końcowa"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Przewiń, aby wyświetlić następny miesiąc"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Przewiń, aby wyświetlić poprzedni miesiąc"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"W zakresie"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Wprowadź daty"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Nieprawidłowy zakres dat"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Uchwyt do przeciągania"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Zwiń planszę dolną"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Zamknij planszę dolną"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Rozwiń planszę dolną"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Etykietka"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Pokaż etykietkę"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Wybierz AM lub PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Wybierz godzinę"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Wybierz minuty"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"Minuty: %1$d"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Godzina"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"aby wpisać minuty"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"aby wpisać godzinę"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-pt-rBR/strings.xml b/compose/material3/material3/src/androidMain/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..c281759
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-pt-rBR/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Caixa de diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Aberto"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Fechado"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dispensar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pesquisar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugestões abaixo"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selecionar data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data selecionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Usar a seleção de ano"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Deslize para selecionar um ano ou toque para voltar à seleção de dia"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Mudar para o próximo mês"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Mudar para o mês anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navegar para o ano de %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Seleção atual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nenhum"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoje"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Seletor de ano visível"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selecionar data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data informada"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data informada: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nenhum"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data não permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"A data não está no padrão esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"A data está fora do intervalo de anos esperado: %1$s a %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Usar o modo de entrada na agenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Usar o modo de entrada de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Role a tela para mostrar anos seguintes"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Role a tela para mostrar anos anteriores"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selecionar datas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data de início"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de término"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Role a tela para mostrar o mês seguinte"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Role a tela para mostrar o mês anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dentro do período"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Informar datas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Período inválido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Alça de arrastar"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Fechar página inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dispensar página inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Abrir página inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Dica"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar dica"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecione AM ou PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecione a hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecione os minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$dh"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"por minutos"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"por hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-pt-rPT/strings.xml b/compose/material3/material3/src/androidMain/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..2a4eb3b
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-pt-rPT/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Caixa de diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Expandido"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Reduzido"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Ignorar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pesquisar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugestões abaixo"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selecione uma data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data selecionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Mudar para a seleção do ano"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Deslize rapidamente para selecionar um ano ou toque para mudar novamente para a seleção do dia"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Mudar para o mês seguinte"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Mudar para o mês anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navegar para o ano %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Seleção atual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nenhuma"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoje"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selecionador de ano visível"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selecione uma data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data introduzida"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data introduzida: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nenhuma"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data não permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"A data não corresponde ao padrão esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Data fora do intervalo de anos esperado: %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Mudar para o método de introdução de calendário"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Mudar para o método de introdução de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Desloque a página para mostrar anos posteriores"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Desloque a página para mostrar anos anteriores"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selecione as datas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data de início"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de fim"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Desloque a página para mostrar o mês seguinte"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Desloque a página para mostrar o mês anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dentro do intervalo"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Introduza as datas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Entrada do intervalo de datas inválida"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Indicador para arrastar"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Reduza a secção inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ignore a secção inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Expanda a secção inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Sugestão"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar sugestão"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecione AM ou PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecionar hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecionar minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d h"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"para minutos"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"para hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-pt/strings.xml b/compose/material3/material3/src/androidMain/res/values-pt/strings.xml
new file mode 100644
index 0000000..c281759
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-pt/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Caixa de diálogo"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Aberto"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Fechado"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Dispensar"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Pesquisar"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugestões abaixo"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selecionar data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data selecionada"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Usar a seleção de ano"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Deslize para selecionar um ano ou toque para voltar à seleção de dia"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Mudar para o próximo mês"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Mudar para o mês anterior"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navegar para o ano de %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Seleção atual: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Nenhum"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hoje"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Seletor de ano visível"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selecionar data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data informada"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data informada: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Nenhum"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data não permitida: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"A data não está no padrão esperado: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"A data está fora do intervalo de anos esperado: %1$s a %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Usar o modo de entrada na agenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Usar o modo de entrada de texto"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Role a tela para mostrar anos seguintes"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Role a tela para mostrar anos anteriores"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selecionar datas"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data de início"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de término"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Role a tela para mostrar o mês seguinte"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Role a tela para mostrar o mês anterior"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Dentro do período"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Informar datas"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Período inválido"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Alça de arrastar"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Fechar página inferior"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Dispensar página inferior"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Abrir página inferior"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Dica"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Mostrar dica"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selecione AM ou PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selecione a hora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selecione os minutos"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$dh"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d horas"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minutos"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"por minutos"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"por hora"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ro/strings.xml b/compose/material3/material3/src/androidMain/res/values-ro/strings.xml
new file mode 100644
index 0000000..0b357c8
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ro/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Extins"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Restrâns"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Închide"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Caută"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugestii mai jos"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Selectează data"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data selectată"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Comută la selectarea anului"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Glisează pentru a selecta un an sau atinge pentru a reveni la selectarea zilei"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Treci la luna următoare"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Treci la luna anterioară"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navighează la anul %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Opțiunea selectată: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Niciuna"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Azi"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Selectorul de an este vizibil"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Selectează data"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data introdusă"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dată"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data introdusă: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Niciuna"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data nu este permisă: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Data nu corespunde modelului așteptat: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Data este în afara intervalului de ani %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Comută la modul de introducere în calendar"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Comută la modul de introducere a textului"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Derulează pentru a afișa anii ulteriori"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Derulează pentru a afișa anii anteriori"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Selectează datele"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data de începere"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data de încheiere"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Derulează pentru a afișa luna următoare"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Derulează pentru a afișa luna anterioară"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"În interval"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Introdu datele"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Intervalul de date introdus nu este valid"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Ghidaj de tragere"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Restrânge foaia din partea de jos"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Închide foaia din partea de jos"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Extinde foaia din partea de jos"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Balon explicativ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Afișează balonul explicativ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Selectează AM sau PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Selectează ora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Selectează minutele"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Ora %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"Ora %1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minute"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Oră"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"pentru minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"pentru oră"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ru/strings.xml b/compose/material3/material3/src/androidMain/res/values-ru/strings.xml
new file mode 100644
index 0000000..2443c51
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ru/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Диалоговое окно"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Развернуто"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Свернуто"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Закрыть"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Строка поиска"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Подсказки показаны ниже"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Выберите дату"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Выбранная дата"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Перейти к выбору года"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Проведите по экрану, чтобы выбрать год, или нажмите, чтобы вернуться к выбору дня."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Перейти к следующему месяцу"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Перейти к предыдущему месяцу"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Переход к %1$s году"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Текущий выбор: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Нет"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Сегодня"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Отображаемый выбор года"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Выберите дату"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Введенная дата"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Дата"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Введенная дата: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Нет"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Недопустимая дата: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Дата не соответствует допустимому шаблону: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Дата не входит в допустимый диапазон: %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Перейти в режим выбора даты"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Перейти в режим ввода текста"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Прокрутите до более поздних лет"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Прокрутите до более ранних лет"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Выберите даты"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Начальная дата"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Конечная дата"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Прокрутите до следующего месяца"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Прокрутите до предыдущего месяца"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"День в диапазоне дат"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Введите даты"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Указан недопустимый диапазон дат."</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Маркер перемещения"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Свернуть нижний экран"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Закрыть нижний экран"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Развернуть нижний экран"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Подсказка"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Показать подсказку"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Выбрать AM (до полудня) или PM (после полудня)"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Выбрать час"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Выберите минуты"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d ч."</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ч."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d мин."</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Минуты"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Часы"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"минуты"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"часы"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-si/strings.xml b/compose/material3/material3/src/androidMain/res/values-si/strings.xml
new file mode 100644
index 0000000..461c6bf
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-si/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"සංවාදය"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"දිග හරින ලදි"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"හකුළන ලදි"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"අස් කරන්න"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"සෙවීම"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"පහත යෝජනා"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"දිනය තෝරන්න"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"තෝරා ගත් දිනය"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"වසරක් තේරීමට මාරු වන්න"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"වසරක් තේරීමට ස්වයිප් කරන්න, නැතහොත් දිනක් තේරීමට ආපසු මාරු වීමට තට්ටු කරන්න"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"ඊළඟ මාසයට වෙනස් කරන්න"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"පෙර මාසයට වෙනස් කරන්න"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s වසර වෙත සංචලන කරන්න"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"වත්මන් තේරීම: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"කිසිවක් නැත"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"අද"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"වසර තෝරකය දෘශ්යමානයි"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"දිනය තෝරන්න"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ඇතුළත් කළ දිනය"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"දිනය"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ඇතුළත් කළ දිනය: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"කිසිවක් නැත"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"දිනයට ඉඩ දෙනු නොලැබේ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"දිනය අපේක්ෂිත රටාවට නොගැළපෙයි: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"දිනය %1$s - %2$s අපේක්ෂිත වසර පරාසයෙන් පිටත වේ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"දිනදර්ශන ආදාන ප්රකාරයට මාරු වන්න"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"පාඨ ආදාන ප්රකාරයට මාරු වන්න"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"පසු වසර පෙන්වීමට අනුචලන කරන්න"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"පෙර වසර පෙන්වීමට අනුචලන කරන්න"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"දින තෝරන්න"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ආරම්භක දිනය"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"අවසාන දිනය"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"ඊළඟ මාසය පෙන්වීමට අනුචලන කරන්න"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"පෙර මාසය පෙන්වීමට අනුචලන කරන්න"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"පරාසය තුළ"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"දින ඇතුළු කරන්න"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"අවලංගු දින පරාස ආදානය"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"ඇදීම් හැඬලය"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"පහළම පත්රය හකුළන්න"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"පහළම පත්රය අස් කරන්න"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"පහළම පත්රය දිග හරින්න"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"මෙවලම් ඉඟිය"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"මෙවලම් ඉඟිය පෙන්වන්න"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ප.ව."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"පෙ.ව."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"පෙ.ව. හෝ ප.ව. තෝරන්න"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"පැය තෝරන්න"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"මිනිත්තු ගණන තෝරන්න"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$dට"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"පැය %1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"මිනිත්තු %1$d"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"විනාඩි"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"පැය"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"මිනිත්තු ගණනක් සඳහා"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"පැයක් සඳහා"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sk/strings.xml b/compose/material3/material3/src/androidMain/res/values-sk/strings.xml
new file mode 100644
index 0000000..744b6eb
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sk/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialógové okno"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Rozbalené"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Zbalené"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Zavrieť"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Hľadať"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Návrhy sú nižšie"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Vybrať dátum"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Vybraný dátum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Prepnúť na výber roka"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Potiahnutím vyberte rok alebo klepnutím prepnite späť na výber dňa"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Zmeniť na nasledujúci mesiac"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Zmeniť na predchádzajúci mesiac"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Prejsť na rok %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuálny výber: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Žiadne"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Dnes"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Výber roka je viditeľný"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Vybrať dátum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Zadaný dátum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Dátum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Zadaný dátum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Žiadne"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Nepovolený dátum: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Dátum nezodpovedá očakávanému vzoru: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Dátum sa nenachádza v očakávanom rozsahu rokov: %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Prepnúť na kalendárový režim vstupu"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Prepnúť na režim zadávania textu"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Posunutím si zobrazte neskoršie roky"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Posunutím si zobrazte skoršie roky"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Vybrať dátumy"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Dátum začatia"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Dátum ukončenia"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Posunutím si zobrazte nasledujúci mesiac"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Posunutím si zobrazte predchádzajúci mesiac"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"V rozsahu"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Zadať dátumy"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Neplatné zadané obdobie"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Presúvadlo"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Zbaliť dolný hárok"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Zavrieť dolný hárok"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Rozbaliť dolný hárok"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Popis"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Zobraziť popis"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Vyberte AM alebo PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Vybrať hodinu"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Vybrať minúty"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d h"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d h"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d min"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minúty"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Hodina"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"minúty"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"hodiny"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sl/strings.xml b/compose/material3/material3/src/androidMain/res/values-sl/strings.xml
new file mode 100644
index 0000000..3d9543a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sl/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Pogovorno okno"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Razširjeno"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Strnjeno"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Opusti"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Iskanje"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Predlogi so spodaj"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Izbira datuma"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Izbrani datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Preklopi na izbiro leta"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Povlecite, da izberete leto, ali se dotaknite, da preklopite nazaj na izbiranje dneva."</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Spremeni na naslednji mesec"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Spremeni na prejšnji mesec"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Pomik na leto %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Trenutna izbira: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Brez"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Danes"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Izbirnik leta je viden"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Izbira datuma"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Vneseni datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Vneseni datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Brez"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Oblika datuma ni dovoljena: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datum se ne ujema s pričakovanim vzorcem: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datum je zunaj pričakovanega razpona let %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Preklop na način vnosa v koledar"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Preklop na način vnosa besedila"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Pomaknite se za prikaz poznejših let."</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Pomaknite se za prikaz zgodnejših let."</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Izberite datume"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Začetni datum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Končni datum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Pomaknite se za prikaz naslednjega meseca."</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Pomaknite se za prikaz prejšnjega meseca."</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Znotraj obdobja"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Vnesite datume"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Neveljaven vnos obdobja."</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Ročica za vlečenje"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Strnitev razdelka na dnu zaslona"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Opustitev razdelka na dnu zaslona"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Razširitev razdelka na dnu zaslona"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Opis orodja"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Pokaži opis orodja"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"pop."</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"dop."</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Izberite dopoldanski ali popoldanski čas."</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Izbira ure"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Izbira minut"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d min"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ura"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"za minute"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"za uro"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sq/strings.xml b/compose/material3/material3/src/androidMain/res/values-sq/strings.xml
new file mode 100644
index 0000000..781881a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sq/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogu"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Zgjeruar"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Palosur"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Hiq"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Kërkimi"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Sugjerimet më poshtë"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Zgjidh datën"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Data e zgjedhur"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Kalo te zgjedhja e një viti"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Rrëshqit shpejt për të zgjedhur një vit ose trokit për të kaluar sërish te zgjedhja e ditës"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Ndrysho te muaji i ardhshëm"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Ndrysho te muaji i kaluar"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigo në vitin %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Zgjedhja aktuale: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Asnjë"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Sot"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Zgjedhësi i vitit i dukshëm"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Zgjidh datën"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Data e futur"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Data"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Data e futur: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Asnjë"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Data nuk lejohet: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Data nuk përputhet me motivin e pritur: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Data jashtë diapazonit të pritur të vitit %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Kalo te modaliteti i \"Hyrjes së kalendarit\""</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Kalo te modaliteti i \"Hyrjes së tekstit\""</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Lëviz për të shfaqur vitet e ardhshme"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Lëviz për të shfaqur vitet e mëparshme"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Zgjidh datat"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Data e fillimit"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Data e mbarimit"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Lëviz për të shfaqur muajin e ardhshëm"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Lëviz për të shfaqur muajin e mëparshëm"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Brenda intervalit"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Fut datat"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Hyrje e pavlefshme e diapazonit të datave"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Doreza e zvarritjes"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Palos fletën e poshtme"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Hiq fletën e poshtme"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Zgjero fletën e poshtme"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Këshilla për veglën"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Shfaq këshillat për veglën"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"pasdite"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"paradite"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Zgjidh paradite ose pasdite"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Zgjidh orën"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Zgjidh minutat"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"ora %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d orë"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuta"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuta"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"për minuta"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"për orë"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sr/strings.xml b/compose/material3/material3/src/androidMain/res/values-sr/strings.xml
new file mode 100644
index 0000000..030fc23
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sr/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Дијалог"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Проширено је"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Скупљено је"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Одбаци"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Претрага"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Предлози су у наставку"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Изаберите датум"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Изабрани датум"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Пређите на избор године"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Превуците да бисте изабрали годину или додирните да бисте се вратили на избор дана"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Пређите на следећи месец"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Пређите на претходни месец"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Идите на годину: %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Актуелни избор: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Ништа"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Данас"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Видљив бирач година"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Изаберите датум"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Унети датум"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Датум"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Унети датум: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Ништа"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Датум није дозвољен: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Датум не одговара очекиваном шаблону: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Датум је изван очекиваног опсега година %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Пређите на режим уноса у Календару"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Пређите на режим уноса текста"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Скролујте да би се приказале касније године"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Скролујте да би се приказале раније године"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Изаберите датуме"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Датум почетка"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Датум завршетка"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Померајте да би се приказао следећи месец"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Померајте да би се приказао претходни месец"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"У опсегу"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Унесите датуме"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Унос опсега датума је неважећи"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Идентификатор за превлачење"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Скупите доњу табелу"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Одбаците доњу табелу"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Проширите доњу табелу"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Објашњење"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Прикажите објашњење"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Изаберите пре подне или по подне"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Изаберите сат"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Изаберите минуте"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d с"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d с"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d мин"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Минут"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Сат"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"за минуте"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"за сате"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sv/strings.xml b/compose/material3/material3/src/androidMain/res/values-sv/strings.xml
new file mode 100644
index 0000000..b5a62cc
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sv/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialogruta"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Utökad"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Komprimerad"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Stäng"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Sök"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Se förslag nedan"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Välj datum"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Valt datum"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Byt till att välja år"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Svep för att välja ett år eller tryck för att återgå till att välja en dag"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Ändra till nästa månad"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Ändra till föregående månad"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Navigera till %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Aktuellt val: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Inga"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"I dag"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Årväljaren är synlig"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Välj datum"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Angivet datum"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Datum"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Angivet datum: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Inga"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Datumet är inte tillåtet: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Datumet matchar inte det förväntade formatet: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Datumet faller utanför det förväntade årsintervallet %1$s–%2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Byt till kalender som inmatningsläge"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Byt till text som inmatningsläge"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Scrolla för att visa senare år"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Scrolla för att visa föregående år"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Välj datum"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Startdatum"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Slutdatum"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Scrolla för att visa nästa månad"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Scrolla för att visa föregående månad"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Inom intervall"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Ange datum"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Ett ogiltigt datumintervall har angetts"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Handtag"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Komprimera arket på nedre delen av skärmen"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Stäng arket på nedre delen av skärmen"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Utöka arket på nedre delen av skärmen"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Beskrivning"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Visa beskrivning"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"EM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"FM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Välj mellan FM och EM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Ange timme"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Välj minuter"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Kl. %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d tim"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d minuter"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minut"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Timme"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"för minuter"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"för timme"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-sw/strings.xml b/compose/material3/material3/src/androidMain/res/values-sw/strings.xml
new file mode 100644
index 0000000..cc4d5a6
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-sw/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Kidirisha"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Imepanuliwa"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Imekunjwa"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Ondoa"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Tafuta"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Mapendekezo yaliyo hapa chini"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Chagua tarehe"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Tarehe uliyochagua"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Teua mwaka"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Telezesha kidole ili uchague mwaka au gusa ili urejee kuchagua siku"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Nenda kwenye mwezi unaofuata"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Rudi kwenye mwezi uliotangulia"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Nenda kwenye mwaka %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Ambayo umechagua: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Hamna"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Leo"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Kiteua mwaka kimeonyeshwa"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Chagua tarehe"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Tarehe uliyoweka"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Tarehe"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Tarehe uliyoweka: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Hamna"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Tarehe si sahihi: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Tarehe hailingani na mpangilio unaotumika: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Tarehe uliyoweka haiambatani na kipindi husika %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Badilisha uteue tarehe kwenye kalenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Badilisha uandike tarehe mwenyewe"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Sogeza ili uone miaka ya baadaye"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Sogeza ili uone miaka iliyopita"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Chagua tarehe"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Tarehe ya kuanza"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Tarehe ya mwisho"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Sogeza ili kuonyesha mwezi ujao"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Sogeza ili kuonyesha mwezi uliopita"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Ipo katika kipindi"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Weka tarehe"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Kipindi ulichoweka si sahihi"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Aikoni ya buruta"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Kunja safu ya chini"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Ondoa safu ya chini"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Panua safu ya chini"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Kidirisha cha vidokezo"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Onyesha kidirisha cha vidokezo"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Chagua AM au PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Chagua saa"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Chagua dakika"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Saa %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"Saa %1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"Dakika %1$d"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Dakika"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Saa"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"cha dakika"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"cha moja"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ta/strings.xml b/compose/material3/material3/src/androidMain/res/values-ta/strings.xml
new file mode 100644
index 0000000..12c420a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ta/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"உரையாடல்"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"விரிவாக்கப்பட்டது"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"சுருக்கப்பட்டது"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"நிராகரிக்கும்"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"தேடல்"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"பரிந்துரைகள் கீழே கிடைக்கும்"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"தேதியைத் தேர்வுசெய்க"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"தேர்ந்தெடுக்கப்பட்ட தேதி"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ஆண்டைத் தேர்ந்தெடுக்கும் விருப்பத்திற்கு மாற்று"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ஆண்டைத் தேர்வுசெய்ய ஸ்வைப் செய்யுங்கள் அல்லது தேதியைத் தேர்வுசெய்யும் பக்கத்திற்கு மீண்டும் செல்ல தட்டுங்கள்"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"அடுத்த மாதத்திற்கு மாற்று"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"முந்தைய மாதத்திற்கு மாற்று"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$sக்குச் செல்லும்"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"தற்போதைய தேர்வு: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ஏதுமில்லை"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"இன்று"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"ஆண்டைத் தேர்வுசெய்யும் விருப்பம் காட்டப்படுகிறது"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"தேதியைத் தேர்வுசெய்க"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"உள்ளிட்ட தேதி"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"தேதி"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"உள்ளிட்ட தேதி: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ஏதுமில்லை"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"இந்தத் தேதி அனுமதிக்கப்படவில்லை: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"எதிர்பார்க்கப்படும் பேட்டர்னுடன் தேதி பொருந்தவில்லை: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"இந்தத் தேதி %1$s - %2$s ஆண்டு வரம்பிற்குள் இல்லை"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"கேலெண்டர் உள்ளீட்டு முறைக்கு மாற்று"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"எழுத்து உள்ளீட்டு முறைக்கு மாற்று"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"பிந்தைய ஆண்டுகளைப் பார்க்க ஸ்க்ரோல் செய்யுங்கள்"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"முந்தைய ஆண்டுகளைப் பார்க்க ஸ்க்ரோல் செய்யுங்கள்"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"தேதிகளைத் தேர்ந்தெடுங்கள்"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"தொடக்கத் தேதி"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"முடிவுத் தேதி"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"அடுத்த மாதத்தைப் பார்க்க ஸ்க்ரோல் செய்யுங்கள்"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"முந்தைய மாதத்தைப் பார்க்க ஸ்க்ரோல் செய்யுங்கள்"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"வரம்பிற்குள் உள்ளது"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"தேதிகளை உள்ளிடுங்கள்"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"தவறான தேதி வரம்பை உள்ளிட்டுள்ளீர்கள்"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"இழுப்பதற்கான ஹேண்டில்"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"கீழ்ப்புற ஷீட்டைச் சுருக்கும்"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"கீழ்ப்புற ஷீட்டை நிராகரிக்கும்"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"கீழ்ப்புற ஷீட்டை விரிவாக்கும்"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"உதவிக்குறிப்பு"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"உதவிக்குறிப்பைக் காட்டு"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM/PM என்பதைத் தேர்ந்தெடுக்கலாம்"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"மணிநேரத்தைத் தேர்ந்தெடுக்கலாம்"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"நிமிடங்களைத் தேர்ந்தெடுக்கலாம்"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d மணி"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d மணி"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d நிமிடங்கள்"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"நிமிடம்"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"மணிநேரம்"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"நிமிடங்களுக்கு"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"மணிநேரத்திற்கு"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-te/strings.xml b/compose/material3/material3/src/androidMain/res/values-te/strings.xml
new file mode 100644
index 0000000..29a5642
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-te/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"డైలాగ్"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"విస్తరించబడింది"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"కుదించబడింది"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"విస్మరించండి"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"సెర్చ్ చేయండి"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"సూచనలు దిగువున ఉన్నాయి"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"తేదీని ఎంచుకోండి"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"ఎంచుకున్న తేదీ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"సంవత్సరాన్ని ఎంచుకునే ఆప్షన్కు మారండి"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"సంవత్సరాన్ని ఎంచుకోవడానికి స్వైప్ చేయండి, లేదా తిరిగి రోజును ఎంచుకునేందుకు మారడానికి ట్యాప్ చేయండి"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"వచ్చే నెలకు మార్చండి"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"మునుపటి నెలకు మార్చండి"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s సంవత్సరానికి వెళ్లండి"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"ప్రస్తుత ఎంపిక: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ఏదీ లేదు"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"నేడు"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"సంవత్సరం పికర్ కనిపిస్తుంది"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"తేదీని ఎంచుకోండి"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"ఎంటర్ చేసిన తేదీ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"తేదీ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"ఎంటర్ చేసిన తేదీ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ఏదీ లేదు"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"చెల్లని తేదీ: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"తేదీ, ఉండాల్సిన ఫార్మాట్తో మ్యాచ్ కాలేదు: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"ఉండాల్సిన సంవత్సరాల పరిధి %1$s - %2$sలో తేదీ లేదు"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"క్యాలెండర్ ఇన్పుట్ మోడ్కు మారండి"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"టెక్స్ట్ ఇన్పుట్ మోడ్కు మారండి"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"తర్వాతి సంవత్సరాల డేటాను చూడటానికి స్క్రోల్ చేయండి"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"మునుపటి సంవత్సరాల డేటాను చూడటానికి స్క్రోల్ చేయండి"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"తేదీలను ఎంచుకోండి"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"ప్రారంభ తేదీ"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"ముగింపు తేదీ"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"వచ్చే నెల డేటాను చూడటానికి స్క్రోల్ చేయండి"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"మునుపటి నెల డేటాను చూడటానికి స్క్రోల్ చేయండి"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"పరిధిలో ఉంది"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"తేదీలను ఎంటర్ చేయండి"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"తేదీల పరిధి ఇన్పుట్ చెల్లదు"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"లాగే హ్యాండిల్"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"దిగువున ఉన్న షీట్ను కుదిస్తుంది"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"దిగువున ఉన్న షీట్ను విస్మరిస్తుంది"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"దిగువున ఉన్న షీట్ను విస్తరిస్తుంది"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"టూల్టిప్"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"టూల్టిప్ను చూడండి"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM లేదా PMను ఎంచుకోండి"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"గంటలను ఎంచుకోవడానికి వీలు కల్పిస్తుంది"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"నిమిషాలను ఎంచుకోండి"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d గం"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d గంటలు"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d నిమిషాలు"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"నిమిషం"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"గంట"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"నిమిషాలను ఎంచుకోవడం కోసం"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"గంటలను ఎంచుకోవడం కోసం"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-th/strings.xml b/compose/material3/material3/src/androidMain/res/values-th/strings.xml
new file mode 100644
index 0000000..e591400
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-th/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"กล่องโต้ตอบ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"ขยายแล้ว"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"ยุบแล้ว"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"ปิด"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"ค้นหา"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"มีคำแนะนำที่ด้านล่าง"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"เลือกวันที่"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"วันที่ที่เลือก"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"เปลี่ยนไปที่การเลือกปี"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ปัดเพื่อเลือกปีหรือแตะเพื่อเปลี่ยนกลับไปยังการเลือกวัน"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"เปลี่ยนไปที่เดือนถัดไป"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"เปลี่ยนไปที่เดือนก่อนหน้า"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"ไปยังปี %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"การเลือกปัจจุบัน: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"ไม่มี"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"วันนี้"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"แสดงตัวเลือกปี"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"เลือกวันที่"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"วันที่ป้อน"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"วันที่"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"วันที่ป้อน: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"ไม่มี"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"ไม่อนุญาตให้ใช้วันที่นี้: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"วันที่ไม่ตรงกับรูปแบบที่คาดไว้: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"วันที่อยู่นอกเหนือจากช่วงปีที่คาดไว้ %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"สลับไปใช้โหมดป้อนข้อมูลปฏิทิน"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"สลับไปใช้โหมดการป้อนข้อความ"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"เลื่อนเพื่อแสดงปีหลังจากนี้"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"เลื่อนเพื่อแสดงปีก่อนหน้านี้"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"เลือกวันที่"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"วันที่เริ่มต้น"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"วันที่สิ้นสุด"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"เลื่อนเพื่อแสดงเดือนถัดไป"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"เลื่อนเพื่อแสดงเดือนก่อนหน้า"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"อยู่ในช่วงวันที่ที่เลือก"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"ป้อนวันที่"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"การป้อนข้อมูลช่วงวันที่ไม่ถูกต้อง"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"แฮนเดิลการลาก"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"ยุบ Bottom Sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"ปิด Bottom Sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"ขยาย Bottom Sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"เคล็ดลับเครื่องมือ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"แสดงเคล็ดลับเครื่องมือ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"เลือก AM หรือ PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"เลือกชั่วโมง"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"เลือกนาที"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d น."</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d ชม."</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d นาที"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"นาที"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"ชั่วโมง"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"สำหรับนาที"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"สำหรับชั่วโมง"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-tl/strings.xml b/compose/material3/material3/src/androidMain/res/values-tl/strings.xml
new file mode 100644
index 0000000..6eee833
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-tl/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Naka-expand"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Naka-collapse"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"I-dismiss"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Maghanap"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Mga suhestyon sa ibaba"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Pumili ng petsa"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Piniling petsa"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Lumipat sa pagpili ng taon"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Mag-swipe para pumili ng taon, o mag-tap para bumalik sa pagpili ng araw"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Lumipat sa susunod na buwan"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Lumipat sa nakaraang buwan"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Mag-navigate papunta sa taong %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Kasalukuyang napili: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Wala"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Ngayon"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Nakikita ang picker ng taon"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Pumili ng petsa"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Inilagay na petsa"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Petsa"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Inilagay na petsa: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Wala"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Hindi pinapayagan ang petsa: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Hindi tumutugma ang petsa sa inaasahang pattern: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Wala ang petsa sa inaasahang hanay ng taon na %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Lumipat sa pamamaraan ng pag-input ng kalendaryo"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Lumipat sa pamamaraan ng pag-input ng text"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Mag-scroll para makita ang mga mas kamakailang taon"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Mag-scroll para ipakita ang mga mas naunang taon"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Pumili ng mga petsa"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Petsa ng pagsisimula"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Petsa ng pagtatapos"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Mag-scroll para ipakita ang susunod na buwan"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Mag-scroll para ipakita ang nakaraang buwan"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"May signal"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Maglagay ng mga petsa"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Invalid ang input na hanay ng petsa"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Handle sa pag-drag"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"I-collapse ang bottom sheet"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"I-dismiss ang bottom sheet"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Palawakin ang bottom sheet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Tooltip"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Ipakita ang tooltip"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Piliin ang AM o PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Pumili ng oras"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Pumili ng mga minuto"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d oras"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d (na) minuto"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Minuto"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Oras"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"nang ilang minuto"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"nang ilang oras"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-tr/strings.xml b/compose/material3/material3/src/androidMain/res/values-tr/strings.xml
new file mode 100644
index 0000000..a1bb70e
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-tr/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Dialog"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Genişletildi"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Daraltıldı"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Kapat"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Arama"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Önerileri aşağıda bulabilirsiniz"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Tarih seç"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Seçilen tarih"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Yıl seçimine geç"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Kaydırarak bir yıl seçin veya gün seçme bölümüne geri dönmek için dokunun"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Sonraki aya değiştir"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Önceki aya değiştir"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s yılına gidin"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Geçerli seçim: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Yok"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Bugün"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Yıl seçici görünür durumda"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Tarih seç"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Girilen tarih"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Tarih"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Girilen tarih: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Yok"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Tarihe izin verilmiyor: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Tarih, istenen biçimle eşleşmiyor: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Tarih, istenen %1$s-%2$s yıl aralığının dışında"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Takvim giriş moduna geç"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Metin giriş moduna geç"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Sonraki yılları göstermek için kaydırın"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Önceki yılları göstermek için kaydırın"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Tarihleri seçin"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Başlangıç tarihi"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Bitiş tarihi"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Sonraki ayı göstermek için kaydırın"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Önceki ayı göstermek için kaydırın"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Aralıkta"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Tarihleri girin"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Geçersiz tarih aralığı girişi"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Sürükleme tutamacı"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Alt sayfayı daralt"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Alt sayfayı kapat"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Alt sayfayı genişlet"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"İpucu"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Araç ipucunu göster"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ÖS"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ÖÖ"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"ÖÖ veya ÖS\'yi seçin"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Saat seçin"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Dakikayı seçin"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Saat %1$d"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d saat"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d dakika"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Dakika"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Saat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"dakika"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"saat"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-uk/strings.xml b/compose/material3/material3/src/androidMain/res/values-uk/strings.xml
new file mode 100644
index 0000000..5c563cf
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-uk/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Вікно"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Розгорнуто"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Згорнуто"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Закрити"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Пошук"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Підказки внизу"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Виберіть дату"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Вибрана дата"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Перейти до вибору року"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Проведіть пальцем по екрану, щоб вибрати рік, або торкніться, щоб повернутися до вибору дня"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Перейти до наступного місяця"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Перейти до попереднього місяця"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Перейти до %1$s року"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Поточний вибір: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Немає"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Сьогодні"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Показувати засіб вибору року"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Виберіть дату"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Введена дата"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Дата"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Введена дата: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Немає"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Недопустима дата: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Дата не відповідає очікуваному шаблону: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Дата за межами очікуваного діапазону років %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Перейти в режим введення в календарі"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Перейти в режим введення тексту"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Прокрутіть, щоб відобразити пізніші роки"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Прокрутіть, щоб відобразити попередні роки"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Виберіть дати"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Дата початку"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Дата завершення"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Прокрутіть, щоб відобразити наступний місяць"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Прокрутіть, щоб відобразити попередній місяць"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"У діапазоні"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Введіть дати"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Указано недійсний діапазон дат"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Маркер переміщення"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Згорнути нижній екран"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Закрити нижній екран"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Розгорнути нижній екран"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Спливаюча підказка"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Показати спливаючу підказку"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"ПП"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"ДП"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Виберіть ДП чи ПП"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Вибрати годину"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Вибрати хвилини"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d год"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d год"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d хв"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Хвилина"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Година"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"для хвилин"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"для годин"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-ur/strings.xml b/compose/material3/material3/src/androidMain/res/values-ur/strings.xml
new file mode 100644
index 0000000..90a6720
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-ur/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"ڈائلاگ"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"پھیلایا گیا"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"سکیڑا گیا"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"برخاست کریں"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"تلاش کریں"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"تلاش کی تجاویز نیچے دستیاب ہیں"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"تاریخ منتخب کریں"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"منتخب کردہ تاریخ"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"ایک سال کا انتخاب کرنے کے لیے سوئچ کریں"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"ایک سال منتخب کرنے کے لیے سوائپ کریں یا ایک دن منتخب کرنے کی خاطر دوبارہ سوئچ کرنے کے لیے تھپتھپائیں"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"اگلے ماہ میں تبدیل کریں"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"گزشتہ ماہ میں تبدیل کریں"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"سال %1$s پر نیویگیٹ کریں"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"موجودہ انتخاب: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"کوئی نہیں"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"آج"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"سال کا منتخب کنندہ مرئی ہے"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"تاریخ منتخب کریں"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"درج کردہ تاریخ"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"تاریخ"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"درج کردہ تاریخ: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"کوئی نہیں"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"تاریخ کی اجازت نہیں ہے: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"تاریخ متوقع پیٹرن سے مماثل نہیں ہے: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"متوقع سال کی حد %1$s - %2$s سے باہر کی تاریخ"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"کیلنڈر اِن پٹ موڈ پر سوئچ کریں"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"ٹیکسٹ اِن پٹ موڈ پر سوئچ کریں"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"بعد کے سالوں کا ڈیٹا دکھانے کے لیے اسکرول کریں"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"پچھلے سالوں کا ڈیٹا دکھانے کے لیے اسکرول کریں"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"تواریخ منتخب کریں"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"تاریخ آغاز"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"تاریخ اختتام"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"اگلے ماہ کا ڈیٹا دکھانے کے لیے اسکرول کریں"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"پچھلے ماہ کا ڈیٹا دکھانے کے لیے اسکرول کریں"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"رینج میں ہے"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"تواریخ درج کریں"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"تاریخ کی حد کا غلط ان پٹ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"گھسیٹنے کا ہینڈل"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"نیچے کی شیٹ کو سکیڑیں"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"نیچے کی شیٹ کو برخاست کریں"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"نیچے کی شیٹ کو پھیلائیں"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"ٹول ٹپ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"ٹول ٹپ دکھائیں"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"AM یا PM منتخب کریں"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"گھنٹہ منتخب کریں"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"منٹ منتخب کریں"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d بجے"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d گھنٹے"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d منٹس"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"منٹ"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"گھنٹہ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"منٹ کے لیے"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"گھنٹے کے لیے"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-uz/strings.xml b/compose/material3/material3/src/androidMain/res/values-uz/strings.xml
new file mode 100644
index 0000000..cc90175
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-uz/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Muloqot oynasi"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Yoyilgan"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Yigʻilgan"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Yopish"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Qidiruv"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Takliflar quyida"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Sanani tanlang"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Tanlangan sana"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Tanlangan yilga oʻtish"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Yilni tanlash uchun suring yoki kunni tanlashga qaytish uchun tegining"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Keyingi oyga oʻzgartirish"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Avvalgi oyga oʻzgartirish"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"%1$s-yilga oʻtish"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Joriy tanlov: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Hech biri"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Bugun"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Yil tanlagich ochiq"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Sanani tanlang"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Kiritilgan sana"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Sana"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Kiritilgan sana: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Hech biri"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Sana xato: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Sana mavjud namunaga mos kelmaydi: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Sana kutilgan yillar oraligʻida emas: %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Taqvim kiritish rejimiga oʻtish"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Matn kiritish rejimiga oʻtish"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Keyingi yillarga varaqlang"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Avvalgi yillarga varaqlang"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Sanalarni tanlang"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Boshlanish sanasi"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Tugash sanasi"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Keyingi oyga varaqlang"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Avvalgi oyga varaqlang"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Xizmat doirasida"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Sanalarni kiriting"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Kiritilgan muddat yaroqsiz"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Surish dastagi"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Quyi ekranni yigʻish"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Quyi ekranni yopish"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Quyi ekranni yoyish"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Maslahat oynasi"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Maslahat oynasini koʻrsatish"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"TK"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"TO"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Tushdan oldin yoki keyinligini tanlang"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Soatni tanlang"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Daqiqani tanlang"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d soat"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d soat"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d daqiqa"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Daqiqa"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Soat"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"bir daqiqa"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"bir soat"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-vi/strings.xml b/compose/material3/material3/src/androidMain/res/values-vi/strings.xml
new file mode 100644
index 0000000..211355e
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-vi/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Hộp thoại"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Đã mở rộng"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Đã thu gọn"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Đóng"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Tìm kiếm"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Các đề xuất ở bên dưới"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Chọn ngày"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Ngày đã chọn"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Chuyển sang chọn năm"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Vuốt để chọn một năm hoặc nhấn để chuyển lại về chọn một ngày"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Chuyển sang tháng tiếp theo"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Chuyển về tháng trước"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Chuyển đến năm %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Lựa chọn hiện tại: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Không có"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Hôm nay"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Bộ chọn năm hiển thị"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Chọn ngày"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Ngày đã nhập"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Ngày"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Ngày đã nhập: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Không có"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Ngày không được phép: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Ngày không khớp với định dạng dự kiến: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Ngày không thuộc phạm vi năm dự kiến %1$s – %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Chuyển sang chế độ nhập lịch"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Chuyển sang chế độ nhập văn bản"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Cuộn để hiện những năm sau"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Cuộn để hiện những năm trước"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Chọn ngày"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Ngày bắt đầu"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Ngày kết thúc"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Cuộn để hiện tháng sau"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Cuộn để hiện tháng trước"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Trong khoảng"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Nhập ngày"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Phạm vi ngày đã nhập không hợp lệ"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Nút kéo"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Thu gọn bảng dưới cùng"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Đóng bảng dưới cùng"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Mở rộng bảng dưới cùng"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Chú giải công cụ"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Hiện chú giải công cụ"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"CH"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"SA"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Chọn SA hoặc CH"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Chọn giờ"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Chọn phút"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d giờ"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d giờ"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d phút"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Phút"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Giờ"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"nhập phút"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"nhập giờ"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-zh-rCN/strings.xml b/compose/material3/material3/src/androidMain/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..bcb313d
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-zh-rCN/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"对话框"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"已展开"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"已收起"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"关闭"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"搜索"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"以下是搜索建议"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"选择日期"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"选定的日期"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"切换为选择年份"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"滑动可选择年份,点按可切换回选择日期"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"转到下个月"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"转到上个月"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"切换到年份:%1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"当前的选择:%1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"无"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"今天"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"年份选择器可见"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"选择日期"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"输入的日期"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"日期"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"输入的日期:%1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"无"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"日期无效:%1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"日期不符合格式要求:%1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"日期超出预期年份范围 %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"切换到日历输入模式"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"切换到文本字段输入模式"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"滚动即可显示之后的年份"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"滚动即可显示之前的年份"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"选择日期"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"开始日期"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"结束日期"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"滚动即可显示下个月"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"滚动即可显示上个月"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"在范围内"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"输入日期"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"输入的日期范围无效"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"拖动手柄"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"收起底部动作条"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"关闭底部动作条"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"展开底部动作条"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"提示"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"显示提示"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"下午"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"上午"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"选择上午或下午"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"选择小时"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"选择分钟"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d 点"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d 小时"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d 分钟"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"分钟"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"小时"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"输入分钟"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"输入小时"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-zh-rHK/strings.xml b/compose/material3/material3/src/androidMain/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..c87746f
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-zh-rHK/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"對話框"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"已展開"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"已收合"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"關閉"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"搜尋"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"建議如下"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"選取日期"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"所選日期"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"切換為選取年份"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"滑動可選取年分,或可輕按返回選取日期"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"變更至下個月"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"變更至上個月"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"前往 %1$s 年"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"目前選項:%1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"無"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"今天"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"顯示年分挑選器"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"選取日期"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"已輸入的日期"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"日期"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"已輸入的日期:%1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"無"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"不允許的日期:%1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"日期格式不符:%1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"日期超出預期的年份範圍:%1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"切換至日曆輸入模式"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"切換至文字輸入模式"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"碌去顯示新啲嘅年份"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"碌去顯示舊啲嘅年份"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"選取日期"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"開始日期"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"結束日期"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"碌去顯示下一個月"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"碌去顯示上一個月"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"喺指定日期範圍內"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"輸入日期"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"輸入的日期範圍無效"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"拖曳控點"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"收合頁底面板"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"關閉頁底面板"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"展開頁底面板"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"提示"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"顯示提示"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"下午"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"上午"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"選取上午或下午"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"選取小時"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"選取分鐘"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d 點"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d 點"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d 分鐘"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"分鐘"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"小時"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"分鐘"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"小時"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-zh-rTW/strings.xml b/compose/material3/material3/src/androidMain/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..c24a29a
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-zh-rTW/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"對話方塊"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"已展開"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"已收合"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"關閉"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"搜尋"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"建議如下"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"選取日期"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"所選日期"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"改為選取年份"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"滑動即可選取年分,也可輕觸返回選取日期"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"改成下個月"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"改成上個月"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"前往 %1$s 年"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"目前選項:%1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"無"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"今天"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"顯示年份挑選器"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"選取日期"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"輸入的日期"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"日期"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"輸入的日期:%1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"無"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"不允許的日期:%1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"日期格式不符:%1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"日期超出預期的年份範圍:%1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"切換至日曆輸入模式"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"切換至文字輸入模式"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"捲動即可顯示之後年分"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"捲動即可顯示先前年分"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"選取日期"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"開始日期"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"結束日期"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"捲動即可顯示下一個月"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"捲動即可顯示上一個月"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"在有效範圍內"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"輸入日期"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"輸入的日期範圍無效"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"拖曳控點"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"收合底部功能表"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"關閉底部功能表"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"展開底部功能表"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"工具提示"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"顯示工具提示"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"下午"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"上午"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"選取上午或下午"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"選取小時"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"選取分鐘數"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"%1$d 點"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"%1$d 時"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"%1$d 分鐘"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"分鐘"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"小時"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"分鐘"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"小時"</string>
+</resources>
diff --git a/compose/material3/material3/src/androidMain/res/values-zu/strings.xml b/compose/material3/material3/src/androidMain/res/values-zu/strings.xml
new file mode 100644
index 0000000..f123626
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/res/values-zu/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="m3c_dialog" msgid="7617233117134790350">"Ibhokisi"</string>
+ <string name="m3c_dropdown_menu_expanded" msgid="2360841780724299882">"Kunwetshiwe"</string>
+ <string name="m3c_dropdown_menu_collapsed" msgid="3177828188723359358">"Kugoqiwe"</string>
+ <string name="m3c_snackbar_dismiss" msgid="6152755701819882931">"Chitha"</string>
+ <string name="m3c_search_bar_search" msgid="6152806324422087846">"Sesha"</string>
+ <string name="m3c_suggestions_available" msgid="7655536806087401899">"Iziphakamiso ngezansi"</string>
+ <string name="m3c_date_picker_title" msgid="7430790972741451689">"Khetha usuku"</string>
+ <string name="m3c_date_picker_headline" msgid="7605002211875882969">"Usuku olukhethiwe"</string>
+ <string name="m3c_date_picker_switch_to_year_selection" msgid="791651718641787594">"Shintshela ekukhetheni unyaka"</string>
+ <string name="m3c_date_picker_switch_to_day_selection" msgid="395627960681594326">"Swayipha ukuze ukhethe unyaka, noma thepha ukuze ubuyele ekukhetheni usuku"</string>
+ <string name="m3c_date_picker_switch_to_next_month" msgid="7142101321095356500">"Shintshela kunyanga elandelayo"</string>
+ <string name="m3c_date_picker_switch_to_previous_month" msgid="228438865139394590">"Shintshela kunyanga edlule"</string>
+ <string name="m3c_date_picker_navigate_to_year_description" msgid="8436650776581492840">"Funa onyakeni %1$s"</string>
+ <string name="m3c_date_picker_headline_description" msgid="3664277305226978227">"Ukukhetha kwamanje: %1$s"</string>
+ <string name="m3c_date_picker_no_selection_description" msgid="5811000998184572395">"Lutho"</string>
+ <string name="m3c_date_picker_today_description" msgid="3199387177749801575">"Namuhla"</string>
+ <string name="m3c_date_picker_year_picker_pane_title" msgid="2068382232816991922">"Isikhethi sonyaka siyabonakala"</string>
+ <string name="m3c_date_input_title" msgid="7306227249789210568">"Khetha usuku"</string>
+ <string name="m3c_date_input_headline" msgid="8166741421776570875">"Usuku olufakiwe"</string>
+ <string name="m3c_date_input_label" msgid="2895559812010326913">"Usuku"</string>
+ <string name="m3c_date_input_headline_description" msgid="229313757840775812">"Usuku olufakiwe: %1$s"</string>
+ <string name="m3c_date_input_no_input_description" msgid="1237013946323089826">"Lutho"</string>
+ <string name="m3c_date_input_invalid_not_allowed" msgid="2521768508935305279">"Usuku aluvunyelwe: %1$s"</string>
+ <string name="m3c_date_input_invalid_for_pattern" msgid="6116910750161463197">"Usuku alufani nephethini elindelekile: %1$s"</string>
+ <string name="m3c_date_input_invalid_year_range" msgid="7052898923934555305">"Usuku lungaphandle kwebanga lonyaka elilindelekile %1$s - %2$s"</string>
+ <string name="m3c_date_picker_switch_to_calendar_mode" msgid="1804346892470238807">"Shintshela kwimodi yokufaka yekhalenda"</string>
+ <string name="m3c_date_picker_switch_to_input_mode" msgid="2219746470065162704">"Shintshela kwimodi yokufaka yombhalo"</string>
+ <string name="m3c_date_picker_scroll_to_later_years" msgid="5727367015496556177">"Skrola ukuze ubonise iminyaka yakamuva"</string>
+ <string name="m3c_date_picker_scroll_to_earlier_years" msgid="7813882352367152251">"Skrola ukuze ubonise iminyaka yangaphambilini"</string>
+ <string name="m3c_date_range_picker_title" msgid="3134165431120340385">"Khetha izinsuku"</string>
+ <string name="m3c_date_range_picker_start_headline" msgid="4665981448952749820">"Usuku lokuqala"</string>
+ <string name="m3c_date_range_picker_end_headline" msgid="4947636797751277713">"Usuku lokuphela"</string>
+ <string name="m3c_date_range_picker_scroll_to_next_month" msgid="602077859540990149">"Skrola ukuze ubonise inyanga elandelayo"</string>
+ <string name="m3c_date_range_picker_scroll_to_previous_month" msgid="4592174524846109496">"Skrola ukuze ubonise inyanga edlule"</string>
+ <string name="m3c_date_range_picker_day_in_range" msgid="2138321128465719402">"Ebangeni"</string>
+ <string name="m3c_date_range_input_title" msgid="3148384720560189467">"Faka izinsuku"</string>
+ <string name="m3c_date_range_input_invalid_range_input" msgid="3190049423327661366">"Okokufaka kwebanga losuku okungavumelekile"</string>
+ <string name="m3c_bottom_sheet_drag_handle_description" msgid="8403354765404029791">"Hudula isibambi"</string>
+ <string name="m3c_bottom_sheet_collapse_description" msgid="2988463736136100848">"Goqa ishidi eliphansi"</string>
+ <string name="m3c_bottom_sheet_dismiss_description" msgid="1555567894577437024">"Chitha ishidi eliphansi"</string>
+ <string name="m3c_bottom_sheet_expand_description" msgid="6670819569745899763">"Nweba ishidi eliphansi"</string>
+ <string name="m3c_tooltip_pane_description" msgid="5460405025248574620">"Ithulithiphu"</string>
+ <string name="m3c_tooltip_long_press_label" msgid="1805687647081129904">"Bonisa ithulithiphu"</string>
+ <string name="m3c_time_picker_pm" msgid="6616362054113087709">"PM"</string>
+ <string name="m3c_time_picker_am" msgid="2786685010796619560">"AM"</string>
+ <string name="m3c_time_picker_period_toggle_description" msgid="5865171949528594571">"Khetha u-AM noma u-PM"</string>
+ <string name="m3c_time_picker_hour_selection" msgid="8876759303332837035">"Khetha ihora"</string>
+ <string name="m3c_time_picker_minute_selection" msgid="4699133535056739733">"Khetha imizuzu"</string>
+ <string name="m3c_time_picker_hour_suffix" msgid="3458167507790628988">"Ngu-%1$d o\'clock"</string>
+ <string name="m3c_time_picker_hour_24h_suffix" msgid="9179527532316922345">"Amahora angu-%1$d"</string>
+ <string name="m3c_time_picker_minute_suffix" msgid="5064177921781937179">"Imizuzu engu-%1$d"</string>
+ <string name="m3c_time_picker_minute" msgid="4313071914266462005">"Umzuzu"</string>
+ <string name="m3c_time_picker_hour" msgid="2349193472625211372">"Ihora"</string>
+ <string name="m3c_time_picker_minute_text_field" msgid="7661234488295443182">"ngemizuzu"</string>
+ <string name="m3c_time_picker_hour_text_field" msgid="6973808109666874069">"ngehora"</string>
+</resources>
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
index 36bd57b..d85d841 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt
@@ -56,7 +56,7 @@
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
@@ -830,7 +830,7 @@
*
* Use this limit to coerce the [heightOffset] value when it's updated.
*/
- var heightOffsetLimit by mutableStateOf(initialHeightOffsetLimit)
+ var heightOffsetLimit by mutableFloatStateOf(initialHeightOffsetLimit)
/**
* The top app bar's current height offset in pixels. This height offset is applied to the fixed
@@ -857,7 +857,7 @@
* consumes scroll events. A common implementation would update the value to be the sum of all
* [NestedScrollConnection.onPostScroll] `consumed.y` values.
*/
- var contentOffset by mutableStateOf(initialContentOffset)
+ var contentOffset by mutableFloatStateOf(initialContentOffset)
/**
* A value that represents the collapsed height percentage of the app bar.
@@ -905,7 +905,7 @@
)
}
- private var _heightOffset = mutableStateOf(initialHeightOffset)
+ private var _heightOffset = mutableFloatStateOf(initialHeightOffset)
}
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
index d0379dd..d81502f7 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt
@@ -24,9 +24,9 @@
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.layout.widthIn
-import androidx.compose.material3.SheetValue.PartiallyExpanded
import androidx.compose.material3.SheetValue.Expanded
import androidx.compose.material3.SheetValue.Hidden
+import androidx.compose.material3.SheetValue.PartiallyExpanded
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Divider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Divider.kt
index 73e47de..5da509f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Divider.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Divider.kt
@@ -16,8 +16,8 @@
package androidx.compose.material3
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material3.tokens.DividerTokens
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
index 318985d..6356636 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt
@@ -61,7 +61,6 @@
import kotlin.math.max
import kotlin.math.min
-@Suppress("ModifierParameter")
@Composable
internal fun DropdownMenuContent(
expandedStates: MutableTransitionState<Boolean>,
@@ -305,7 +304,7 @@
internal data class DropdownMenuPositionProvider(
val contentOffset: DpOffset,
val density: Density,
- val onPositionCalculated: (IntRect, IntRect) -> Unit = { _, _ -> }
+ val onPositionCalculated: (anchorBounds: IntRect, menuBounds: IntRect) -> Unit = { _, _ -> }
) : PopupPositionProvider {
override fun calculatePosition(
anchorBounds: IntRect,
@@ -319,40 +318,45 @@
val contentOffsetX = with(density) { contentOffset.x.roundToPx() }
val contentOffsetY = with(density) { contentOffset.y.roundToPx() }
- // Compute horizontal position.
- val toRight = anchorBounds.left + contentOffsetX
- val toLeft = anchorBounds.right - contentOffsetX - popupContentSize.width
- val toDisplayRight = windowSize.width - popupContentSize.width
- val toDisplayLeft = 0
+ // Compute menu horizontal position.
+ val leftToAnchorLeft = anchorBounds.left + contentOffsetX
+ val rightToAnchorRight = anchorBounds.right - contentOffsetX - popupContentSize.width
+ val leftToWindowLeft = 0
+ val rightToWindowRight = windowSize.width - popupContentSize.width
val x = if (layoutDirection == LayoutDirection.Ltr) {
sequenceOf(
- toRight,
- toLeft,
+ leftToAnchorLeft,
+ rightToAnchorRight,
// If the anchor gets outside of the window on the left, we want to position
- // toDisplayLeft for proximity to the anchor. Otherwise, toDisplayRight.
- if (anchorBounds.left >= 0) toDisplayRight else toDisplayLeft
+ // `leftToWindowLeft` for proximity to the anchor. Otherwise, `rightToWindowRight`.
+ if (anchorBounds.left < 0) leftToWindowLeft else rightToWindowRight
)
} else {
sequenceOf(
- toLeft,
- toRight,
+ rightToAnchorRight,
+ leftToAnchorLeft,
// If the anchor gets outside of the window on the right, we want to position
- // toDisplayRight for proximity to the anchor. Otherwise, toDisplayLeft.
- if (anchorBounds.right <= windowSize.width) toDisplayLeft else toDisplayRight
+ // `rightToWindowRight` for proximity to the anchor. Otherwise, `leftToWindowLeft`.
+ if (anchorBounds.right > windowSize.width) rightToWindowRight else leftToWindowLeft
)
}.firstOrNull {
it >= 0 && it + popupContentSize.width <= windowSize.width
- } ?: toLeft
+ } ?: rightToAnchorRight
- // Compute vertical position.
- val toBottom = maxOf(anchorBounds.bottom + contentOffsetY, verticalMargin)
- val toTop = anchorBounds.top - contentOffsetY - popupContentSize.height
- val toCenter = anchorBounds.top - popupContentSize.height / 2
- val toDisplayBottom = windowSize.height - popupContentSize.height - verticalMargin
- val y = sequenceOf(toBottom, toTop, toCenter, toDisplayBottom).firstOrNull {
+ // Compute menu vertical position.
+ val topToAnchorBottom = maxOf(anchorBounds.bottom + contentOffsetY, verticalMargin)
+ val bottomToAnchorTop = anchorBounds.top - contentOffsetY - popupContentSize.height
+ val centerToAnchorTop = anchorBounds.top - popupContentSize.height / 2
+ val bottomToWindowBottom = windowSize.height - popupContentSize.height - verticalMargin
+ val y = sequenceOf(
+ topToAnchorBottom,
+ bottomToAnchorTop,
+ centerToAnchorTop,
+ bottomToWindowBottom
+ ).firstOrNull {
it >= verticalMargin &&
it + popupContentSize.height <= windowSize.height - verticalMargin
- } ?: toTop
+ } ?: bottomToAnchorTop
onPositionCalculated(
anchorBounds,
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
index 2746436..989ceba 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt
@@ -43,7 +43,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -187,7 +187,7 @@
}
}
- var itemWidth by remember { mutableStateOf(0) }
+ var itemWidth by remember { mutableIntStateOf(0) }
Box(
modifier
@@ -535,8 +535,8 @@
* [animationProgress].
*
* When [alwaysShowLabel] is true, the positions do not move. The [iconPlaceable] will be placed
- * near the top of the item and the [labelPlaceable] will be placed near the bottom, according to
- * the spec.
+ * near the top of the item and the [labelPlaceable] will be placed beneath it with padding,
+ * according to the spec.
*
* When [animationProgress] is 1 (representing the selected state), the positions will be the same
* as above.
@@ -573,11 +573,13 @@
): MeasureResult {
val height = constraints.maxHeight
- // Label should be `ItemVerticalPadding` from the bottom
- val labelY = height - labelPlaceable.height - NavigationBarItemVerticalPadding.roundToPx()
+ val contentTotalHeight = iconPlaceable.height + IndicatorVerticalPadding.roundToPx() +
+ NavigationBarIndicatorToLabelPadding.roundToPx() + labelPlaceable.height
+ val contentVerticalPadding = ((height - contentTotalHeight) / 2)
+ .coerceAtLeast(IndicatorVerticalPadding.roundToPx())
- // Icon (when selected) should be `ItemVerticalPadding` from the top
- val selectedIconY = NavigationBarItemVerticalPadding.roundToPx()
+ // Icon (when selected) should be `contentVerticalPadding` from top
+ val selectedIconY = contentVerticalPadding
val unselectedIconY =
if (alwaysShowLabel) selectedIconY else (height - iconPlaceable.height) / 2
@@ -588,6 +590,10 @@
// animationProgress.
val offset = (iconDistance * (1 - animationProgress)).roundToInt()
+ // Label should be fixed padding below icon
+ val labelY = selectedIconY + iconPlaceable.height + IndicatorVerticalPadding.roundToPx() +
+ NavigationBarIndicatorToLabelPadding.roundToPx()
+
val containerWidth = constraints.maxWidth
val labelX = (containerWidth - labelPlaceable.width) / 2
@@ -626,12 +632,13 @@
internal val NavigationBarItemHorizontalPadding: Dp = 8.dp
/*@VisibleForTesting*/
-internal val NavigationBarItemVerticalPadding: Dp = 16.dp
+internal val NavigationBarIndicatorToLabelPadding: Dp = 4.dp
private val IndicatorHorizontalPadding: Dp =
(NavigationBarTokens.ActiveIndicatorWidth - NavigationBarTokens.IconSize) / 2
-private val IndicatorVerticalPadding: Dp =
+/*@VisibleForTesting*/
+internal val IndicatorVerticalPadding: Dp =
(NavigationBarTokens.ActiveIndicatorHeight - NavigationBarTokens.IconSize) / 2
private val IndicatorVerticalOffset: Dp = 12.dp
\ No newline at end of file
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
index 4feea7b..630f24b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt
@@ -671,16 +671,15 @@
occupiedSpaceVertically = max(occupiedSpaceVertically, heightOrZero(suffixPlaceable))
// measure label
- val isLabelInMiddleSection = animationProgress < 1f
val labelHorizontalPaddingOffset =
paddingValues.calculateLeftPadding(layoutDirection).roundToPx() +
paddingValues.calculateRightPadding(layoutDirection).roundToPx()
val labelConstraints = relaxedConstraints.offset(
- horizontal = if (isLabelInMiddleSection) {
- -occupiedSpaceHorizontally - labelHorizontalPaddingOffset
- } else {
- -labelHorizontalPaddingOffset
- },
+ horizontal = lerp(
+ -occupiedSpaceHorizontally - labelHorizontalPaddingOffset, // label in middle
+ -labelHorizontalPaddingOffset, // label at top
+ animationProgress,
+ ),
vertical = -bottomPadding
)
val labelPlaceable =
@@ -689,17 +688,20 @@
onLabelMeasured(Size(it.width.toFloat(), it.height.toFloat()))
}
+ // supporting text must be measured after other elements, but we
+ // reserve space for it using its intrinsic height as a heuristic
+ val supportingMeasurable = measurables.find { it.layoutId == SupportingId }
+ val supportingIntrinsicHeight =
+ supportingMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0
+
// measure text field
- // On top, we offset either by default padding or by label's half height if its too big.
- // On bottom, we offset to make room for supporting text.
- // minHeight must not be set to 0 due to how foundation TextField treats zero minHeight.
val topPadding = max(
heightOrZero(labelPlaceable) / 2,
paddingValues.calculateTopPadding().roundToPx()
)
val textConstraints = constraints.offset(
horizontal = -occupiedSpaceHorizontally,
- vertical = -bottomPadding - topPadding
+ vertical = -bottomPadding - topPadding - supportingIntrinsicHeight
).copy(minHeight = 0)
val textFieldPlaceable =
measurables.first { it.layoutId == TextFieldId }.measure(textConstraints)
@@ -715,14 +717,6 @@
topPadding + bottomPadding
)
- // measure supporting text
- val supportingConstraints = relaxedConstraints.offset(
- vertical = -occupiedSpaceVertically
- ).copy(minHeight = 0)
- val supportingPlaceable =
- measurables.find { it.layoutId == SupportingId }?.measure(supportingConstraints)
- val supportingHeight = heightOrZero(supportingPlaceable)
-
val width =
calculateWidth(
leadingPlaceableWidth = widthOrZero(leadingPlaceable),
@@ -732,21 +726,30 @@
textFieldPlaceableWidth = textFieldPlaceable.width,
labelPlaceableWidth = widthOrZero(labelPlaceable),
placeholderPlaceableWidth = widthOrZero(placeholderPlaceable),
- isLabelInMiddleSection = isLabelInMiddleSection,
+ animationProgress = animationProgress,
constraints = constraints,
density = density,
paddingValues = paddingValues,
)
+
+ // measure supporting text
+ val supportingConstraints = relaxedConstraints.offset(
+ vertical = -occupiedSpaceVertically
+ ).copy(minHeight = 0, maxWidth = width)
+ val supportingPlaceable = supportingMeasurable?.measure(supportingConstraints)
+ val supportingHeight = heightOrZero(supportingPlaceable)
+
val totalHeight =
calculateHeight(
- leadingPlaceableHeight = heightOrZero(leadingPlaceable),
- trailingPlaceableHeight = heightOrZero(trailingPlaceable),
- prefixPlaceableHeight = heightOrZero(prefixPlaceable),
- suffixPlaceableHeight = heightOrZero(suffixPlaceable),
- textFieldPlaceableHeight = textFieldPlaceable.height,
- labelPlaceableHeight = heightOrZero(labelPlaceable),
- placeholderPlaceableHeight = heightOrZero(placeholderPlaceable),
- supportingPlaceableHeight = heightOrZero(supportingPlaceable),
+ leadingHeight = heightOrZero(leadingPlaceable),
+ trailingHeight = heightOrZero(trailingPlaceable),
+ prefixHeight = heightOrZero(prefixPlaceable),
+ suffixHeight = heightOrZero(suffixPlaceable),
+ textFieldHeight = textFieldPlaceable.height,
+ labelHeight = heightOrZero(labelPlaceable),
+ placeholderHeight = heightOrZero(placeholderPlaceable),
+ supportingHeight = heightOrZero(supportingPlaceable),
+ animationProgress = animationProgress,
constraints = constraints,
density = density,
paddingValues = paddingValues,
@@ -852,7 +855,7 @@
textFieldPlaceableWidth = textFieldWidth,
labelPlaceableWidth = labelWidth,
placeholderPlaceableWidth = placeholderWidth,
- isLabelInMiddleSection = animationProgress < 1f,
+ animationProgress = animationProgress,
constraints = ZeroConstraints,
density = density,
paddingValues = paddingValues,
@@ -888,14 +891,15 @@
intrinsicMeasurer(it, width)
} ?: 0
return calculateHeight(
- leadingPlaceableHeight = leadingHeight,
- trailingPlaceableHeight = trailingHeight,
- prefixPlaceableHeight = prefixHeight,
- suffixPlaceableHeight = suffixHeight,
- textFieldPlaceableHeight = textFieldHeight,
- labelPlaceableHeight = labelHeight,
- placeholderPlaceableHeight = placeholderHeight,
- supportingPlaceableHeight = supportingHeight,
+ leadingHeight = leadingHeight,
+ trailingHeight = trailingHeight,
+ prefixHeight = prefixHeight,
+ suffixHeight = suffixHeight,
+ textFieldHeight = textFieldHeight,
+ labelHeight = labelHeight,
+ placeholderHeight = placeholderHeight,
+ supportingHeight = supportingHeight,
+ animationProgress = animationProgress,
constraints = ZeroConstraints,
density = density,
paddingValues = paddingValues
@@ -914,7 +918,7 @@
textFieldPlaceableWidth: Int,
labelPlaceableWidth: Int,
placeholderPlaceableWidth: Int,
- isLabelInMiddleSection: Boolean,
+ animationProgress: Float,
constraints: Constraints,
density: Float,
paddingValues: PaddingValues,
@@ -924,19 +928,16 @@
textFieldPlaceableWidth + affixTotalWidth,
placeholderPlaceableWidth + affixTotalWidth,
// Prefix/suffix does not get applied to label
- if (isLabelInMiddleSection) labelPlaceableWidth else 0,
+ lerp(labelPlaceableWidth, 0, animationProgress),
)
val wrappedWidth =
leadingPlaceableWidth + middleSection + trailingPlaceableWidth
+
+ // Actual LayoutDirection doesn't matter; we only need the sum
+ val labelHorizontalPadding = (paddingValues.calculateLeftPadding(LayoutDirection.Ltr) +
+ paddingValues.calculateRightPadding(LayoutDirection.Ltr)).value * density
val focusedLabelWidth =
- if (!isLabelInMiddleSection) {
- // Actual LayoutDirection doesn't matter; we only need the sum
- val labelHorizontalPadding = (paddingValues.calculateLeftPadding(LayoutDirection.Ltr) +
- paddingValues.calculateRightPadding(LayoutDirection.Ltr)).value * density
- labelPlaceableWidth + labelHorizontalPadding.roundToInt()
- } else {
- 0
- }
+ ((labelPlaceableWidth + labelHorizontalPadding) * animationProgress).roundToInt()
return maxOf(wrappedWidth, focusedLabelWidth, constraints.minWidth)
}
@@ -946,40 +947,38 @@
* inside the text field.
*/
private fun calculateHeight(
- leadingPlaceableHeight: Int,
- trailingPlaceableHeight: Int,
- prefixPlaceableHeight: Int,
- suffixPlaceableHeight: Int,
- textFieldPlaceableHeight: Int,
- labelPlaceableHeight: Int,
- placeholderPlaceableHeight: Int,
- supportingPlaceableHeight: Int,
+ leadingHeight: Int,
+ trailingHeight: Int,
+ prefixHeight: Int,
+ suffixHeight: Int,
+ textFieldHeight: Int,
+ labelHeight: Int,
+ placeholderHeight: Int,
+ supportingHeight: Int,
+ animationProgress: Float,
constraints: Constraints,
density: Float,
paddingValues: PaddingValues
): Int {
- // middle section is defined as a height of the text field or placeholder (whichever is
- // taller) plus 16.dp or half height of the label if it is taller, given that the label
- // is vertically centered to the top edge of the resulting text field's container
- val inputFieldHeight = max(
- textFieldPlaceableHeight,
- placeholderPlaceableHeight
+ val inputFieldHeight = maxOf(
+ textFieldHeight,
+ placeholderHeight,
+ lerp(labelHeight, 0, animationProgress)
)
val topPadding = paddingValues.calculateTopPadding().value * density
+ val actualTopPadding = lerp(topPadding, max(topPadding, labelHeight / 2f), animationProgress)
val bottomPadding = paddingValues.calculateBottomPadding().value * density
- val middleSectionHeight = inputFieldHeight + bottomPadding + max(
- topPadding,
- labelPlaceableHeight / 2f
- )
+ val middleSectionHeight = actualTopPadding + inputFieldHeight + bottomPadding
+
return max(
constraints.minHeight,
maxOf(
- leadingPlaceableHeight,
- trailingPlaceableHeight,
- prefixPlaceableHeight,
- suffixPlaceableHeight,
+ leadingHeight,
+ trailingHeight,
+ prefixHeight,
+ suffixHeight,
middleSectionHeight.roundToInt()
- ) + supportingPlaceableHeight
+ ) + supportingHeight
)
}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt
index c0fcd04..2fed380 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt
@@ -25,8 +25,8 @@
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.staticCompositionLocalOf
-import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.dp
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
index 71dd117..bc8acd2 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SheetDefaults.kt
@@ -20,9 +20,9 @@
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
-import androidx.compose.material3.SheetValue.PartiallyExpanded
-import androidx.compose.material3.SheetValue.Hidden
import androidx.compose.material3.SheetValue.Expanded
+import androidx.compose.material3.SheetValue.Hidden
+import androidx.compose.material3.SheetValue.PartiallyExpanded
import androidx.compose.material3.tokens.ScrimTokens
import androidx.compose.material3.tokens.SheetBottomTokens
import androidx.compose.runtime.Composable
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
index 69c0d59..1bce0b5 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Slider.kt
@@ -27,10 +27,10 @@
import androidx.compose.foundation.gestures.GestureCancellationException
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.PressGestureScope
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.draggable
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.horizontalDrag
import androidx.compose.foundation.hoverable
import androidx.compose.foundation.indication
@@ -55,6 +55,8 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -680,9 +682,9 @@
stepsToTickFractions(steps)
}
- var startThumbWidth by remember { mutableStateOf(ThumbWidth.value) }
- var endThumbWidth by remember { mutableStateOf(ThumbWidth.value) }
- var totalWidth by remember { mutableStateOf(0) }
+ var startThumbWidth by remember { mutableFloatStateOf(ThumbWidth.value) }
+ var endThumbWidth by remember { mutableFloatStateOf(ThumbWidth.value) }
+ var totalWidth by remember { mutableIntStateOf(0) }
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
@@ -695,8 +697,8 @@
scale(valueRange.start, valueRange.endInclusive, userValue, minPx, maxPx)
var obtainedMeasurements = remember { mutableStateOf(false) }
- val rawOffsetStart = remember { mutableStateOf(0f) }
- val rawOffsetEnd = remember { mutableStateOf(0f) }
+ val rawOffsetStart = remember { mutableFloatStateOf(0f) }
+ val rawOffsetEnd = remember { mutableFloatStateOf(0f) }
val gestureEndAction = rememberUpdatedState<(Boolean) -> Unit> {
onValueChangeFinished?.invoke()
@@ -706,17 +708,17 @@
val maxPx = max(totalWidth - endThumbWidth / 2, 0f)
val minPx = min(startThumbWidth / 2, maxPx)
val offsetRange = if (isStart) {
- rawOffsetStart.value = (rawOffsetStart.value + offset)
- rawOffsetEnd.value = scaleToOffset(minPx, maxPx, value.endInclusive)
- val offsetEnd = rawOffsetEnd.value
- var offsetStart = rawOffsetStart.value.coerceIn(minPx, offsetEnd)
+ rawOffsetStart.floatValue = (rawOffsetStart.floatValue + offset)
+ rawOffsetEnd.floatValue = scaleToOffset(minPx, maxPx, value.endInclusive)
+ val offsetEnd = rawOffsetEnd.floatValue
+ var offsetStart = rawOffsetStart.floatValue.coerceIn(minPx, offsetEnd)
offsetStart = snapValueToTick(offsetStart, tickFractions, minPx, maxPx)
offsetStart..offsetEnd
} else {
- rawOffsetEnd.value = (rawOffsetEnd.value + offset)
- rawOffsetStart.value = scaleToOffset(minPx, maxPx, value.start)
- val offsetStart = rawOffsetStart.value
- var offsetEnd = rawOffsetEnd.value.coerceIn(offsetStart, maxPx)
+ rawOffsetEnd.floatValue = (rawOffsetEnd.floatValue + offset)
+ rawOffsetStart.floatValue = scaleToOffset(minPx, maxPx, value.start)
+ val offsetStart = rawOffsetStart.floatValue
+ var offsetEnd = rawOffsetEnd.floatValue.coerceIn(offsetStart, maxPx)
offsetEnd = snapValueToTick(offsetEnd, tickFractions, minPx, maxPx)
offsetStart..offsetEnd
}
@@ -847,12 +849,12 @@
if (!obtainedMeasurements.value) {
val finalizedMaxPx = max(totalWidth - endThumbWidth / 2, 0f)
val finalizedMinPx = min(startThumbWidth / 2, finalizedMaxPx)
- rawOffsetStart.value = scaleToOffset(
+ rawOffsetStart.floatValue = scaleToOffset(
finalizedMinPx,
finalizedMaxPx,
value.start
)
- rawOffsetEnd.value = scaleToOffset(
+ rawOffsetEnd.floatValue = scaleToOffset(
finalizedMinPx,
finalizedMaxPx,
value.endInclusive
@@ -1679,7 +1681,7 @@
val valueRange: ClosedFloatingPointRange<Float> = 0f..1f,
var onValueChangeFinished: (() -> Unit)? = null
) {
- private var valueState by mutableStateOf(initialValue)
+ private var valueState by mutableFloatStateOf(initialValue)
/**
* [Float] that indicates the current value that the thumb
@@ -1709,11 +1711,11 @@
internal val tickFractions = stepsToTickFractions(steps)
- private var thumbWidth by mutableStateOf(ThumbWidth.value)
- internal var totalWidth by mutableStateOf(0)
+ private var thumbWidth by mutableFloatStateOf(ThumbWidth.value)
+ internal var totalWidth by mutableIntStateOf(0)
- internal var rawOffset by mutableStateOf(scaleToOffset(0f, 0f, value))
- internal var pressOffset by mutableStateOf(0f)
+ internal var rawOffset by mutableFloatStateOf(scaleToOffset(0f, 0f, value))
+ internal var pressOffset by mutableFloatStateOf(0f)
internal var isRtl = false
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SnackbarHost.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SnackbarHost.kt
index 3e072a2..dce3b38 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SnackbarHost.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SnackbarHost.kt
@@ -41,12 +41,12 @@
import androidx.compose.ui.semantics.dismiss
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
+import kotlin.coroutines.resume
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.delay
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
-import kotlin.coroutines.resume
/**
* State of the [SnackbarHost], which controls the queue and the current [Snackbar] being shown
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
index 271d0cf..dfd656f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismiss.kt
@@ -27,8 +27,8 @@
import androidx.compose.material3.DismissValue.DismissedToEnd
import androidx.compose.material3.DismissValue.DismissedToStart
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLayoutDirection
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
index 1090fd0..3155cfd 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Swipeable.kt
@@ -29,11 +29,12 @@
import androidx.compose.material3.SwipeableDefaults.resistanceConfig
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.FloatState
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
@@ -52,16 +53,16 @@
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
+import kotlin.math.PI
+import kotlin.math.abs
+import kotlin.math.sign
+import kotlin.math.sin
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.launch
-import kotlin.math.PI
-import kotlin.math.abs
-import kotlin.math.sign
-import kotlin.math.sin
/**
* State of the [swipeable] modifier.
@@ -103,20 +104,20 @@
* You should use this state to offset your content accordingly. The recommended way is to
* use `Modifier.offsetPx`. This includes the resistance by default, if resistance is enabled.
*/
- val offset: State<Float> get() = offsetState
+ val offset: FloatState get() = offsetState
/**
* The amount by which the [swipeable] has been swiped past its bounds.
*/
- val overflow: State<Float> get() = overflowState
+ val overflow: FloatState get() = overflowState
// Use `Float.NaN` as a placeholder while the state is uninitialised.
- private val offsetState = mutableStateOf(0f)
- private val overflowState = mutableStateOf(0f)
+ private val offsetState = mutableFloatStateOf(0f)
+ private val overflowState = mutableFloatStateOf(0f)
// the source of truth for the "real"(non ui) position
// basically position in bounds + overflow
- private val absoluteOffset = mutableStateOf(0f)
+ private val absoluteOffset = mutableFloatStateOf(0f)
// current animation target, if animating, otherwise null
private val animationTarget = mutableStateOf<Float?>(null)
@@ -138,8 +139,8 @@
requireNotNull(initialOffset) {
"The initial value must have an associated anchor."
}
- offsetState.value = initialOffset
- absoluteOffset.value = initialOffset
+ offsetState.floatValue = initialOffset
+ absoluteOffset.floatValue = initialOffset
}
}
@@ -174,10 +175,10 @@
newState ?: newAnchors.keys.minByOrNull { abs(it - animationTargetValue) }!!
} else {
// we're not animating, proceed by finding the new anchors for an old value
- val actualOldValue = oldAnchors[offset.value]
+ val actualOldValue = oldAnchors[offset.floatValue]
val value = if (actualOldValue == currentValue) currentValue else actualOldValue
newAnchors.getOffset(value) ?: newAnchors
- .keys.minByOrNull { abs(it - offset.value) }!!
+ .keys.minByOrNull { abs(it - offset.floatValue) }!!
}
try {
animateInternalToOffset(targetOffset, animationSpec)
@@ -194,18 +195,18 @@
internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
- internal var velocityThreshold by mutableStateOf(0f)
+ internal var velocityThreshold by mutableFloatStateOf(0f)
internal var resistance: ResistanceConfig? by mutableStateOf(null)
internal val draggableState = DraggableState {
- val newAbsolute = absoluteOffset.value + it
+ val newAbsolute = absoluteOffset.floatValue + it
val clamped = newAbsolute.coerceIn(minBound, maxBound)
val overflow = newAbsolute - clamped
val resistanceDelta = resistance?.computeResistance(overflow) ?: 0f
- offsetState.value = clamped + resistanceDelta
- overflowState.value = overflow
- absoluteOffset.value = newAbsolute
+ offsetState.floatValue = clamped + resistanceDelta
+ overflowState.floatValue = overflow
+ absoluteOffset.floatValue = newAbsolute
}
private suspend fun snapInternalToOffset(target: Float) {
@@ -216,7 +217,7 @@
private suspend fun animateInternalToOffset(target: Float, spec: AnimationSpec<Float>) {
draggableState.drag {
- var prevValue = absoluteOffset.value
+ var prevValue = absoluteOffset.floatValue
animationTarget.value = target
isAnimationRunning = true
try {
@@ -261,7 +262,7 @@
@ExperimentalMaterial3Api
internal val progress: SwipeProgress<T>
get() {
- val bounds = findBounds(offset.value, anchors.keys)
+ val bounds = findBounds(offset.floatValue, anchors.keys)
val from: T
val to: T
val fraction: Float
@@ -285,7 +286,7 @@
}
from = anchors.getValue(a)
to = anchors.getValue(b)
- fraction = (offset.value - a) / (b - a)
+ fraction = (offset.floatValue - a) / (b - a)
}
}
return SwipeProgress(from, to, fraction)
@@ -299,7 +300,7 @@
*/
@ExperimentalMaterial3Api
internal val direction: Float
- get() = anchors.getOffset(currentValue)?.let { sign(offset.value - it) } ?: 0f
+ get() = anchors.getOffset(currentValue)?.let { sign(offset.floatValue - it) } ?: 0f
/**
* Set the state without any animation and suspend until it's set
@@ -334,7 +335,7 @@
}
animateInternalToOffset(targetOffset, anim)
} finally {
- val endOffset = absoluteOffset.value
+ val endOffset = absoluteOffset.floatValue
val endValue = anchors
// fighting rounding error once again, anchor should be as close as 0.5 pixels
.filterKeys { anchorOffset -> abs(anchorOffset - endOffset) < 0.5f }
@@ -392,9 +393,9 @@
* @return the amount of [delta] consumed
*/
internal fun performDrag(delta: Float): Float {
- val potentiallyConsumed = absoluteOffset.value + delta
+ val potentiallyConsumed = absoluteOffset.floatValue + delta
val clamped = potentiallyConsumed.coerceIn(minBound, maxBound)
- val deltaToConsume = clamped - absoluteOffset.value
+ val deltaToConsume = clamped - absoluteOffset.floatValue
if (abs(deltaToConsume) > 0) {
draggableState.dispatchRawDelta(deltaToConsume)
}
@@ -865,7 +866,7 @@
override suspend fun onPreFling(available: Velocity): Velocity {
val toFling = Offset(available.x, available.y).toFloat()
- return if (toFling < 0 && offset.value > minBound) {
+ return if (toFling < 0 && offset.floatValue > minBound) {
performFling(velocity = toFling)
// since we go to the anchor with tween settling, consume all for the best UX
available
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
index 77bdf92..8db36b9 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeableV2.kt
@@ -32,6 +32,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
@@ -267,7 +268,7 @@
* You can use this value to provide smooth reconciliation behavior when re-targeting an
* animation.
*/
- var lastVelocity: Float by mutableStateOf(0f)
+ var lastVelocity: Float by mutableFloatStateOf(0f)
private set
/**
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
index d726302..b1cbd6f 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt
@@ -52,7 +52,6 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-
import kotlin.math.max
/**
@@ -315,7 +314,11 @@
) { text() }
}
if (icon != null) {
- Box(Modifier.layoutId("icon")) { icon() }
+ Box(
+ Modifier
+ .layoutId("icon")
+ .padding(horizontal = HorizontalTextPadding)
+ ) { icon() }
}
}
) { measurables, constraints ->
@@ -430,7 +433,7 @@
private const val TabFadeOutAnimationDuration = 100
// The horizontal padding on the left and right of text
-private val HorizontalTextPadding = 16.dp
+internal val HorizontalTextPadding = 16.dp
// Distance from the top of the indicator to the text baseline when there is one line of text and an
// icon
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
index 6480116..82d1d85 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt
@@ -24,9 +24,11 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
@@ -43,6 +45,8 @@
import androidx.compose.ui.composed
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.layout.SubcomposeLayout
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Constraints
@@ -52,8 +56,9 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
-// TODO: Provide M3 tab row asset and docs when available.
/**
+ * <a href="https://m3.material.io/components/tabs/overview" class="external" target="_blank">Material Design tabs</a>
+ *
* Material Design fixed tabs.
*
* Fixed tabs display all tabs in a set simultaneously. They are best for switching between related
@@ -113,7 +118,7 @@
* matching content color for [containerColor], or to the current [LocalContentColor] if
* [containerColor] is not a color from the theme.
* @param indicator the indicator that represents which tab is currently selected. By default this
- * will be a [TabRowDefaults.Indicator], using a [TabRowDefaults.tabIndicatorOffset] modifier to
+ * will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset] modifier to
* animate its position. Note that this indicator will be forced to fill up the entire tab row, so
* you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual drawn
* indicator inside this space, and provide an offset from the start.
@@ -130,7 +135,7 @@
contentColor: Color = TabRowDefaults.contentColor,
indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
if (selectedTabIndex < tabPositions.size) {
- TabRowDefaults.Indicator(
+ TabRowDefaults.SecondaryIndicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
}
@@ -140,6 +145,18 @@
},
tabs: @Composable () -> Unit
) {
+ TabRowImpl(modifier, containerColor, contentColor, indicator, divider, tabs)
+}
+
+@Composable
+private fun TabRowImpl(
+ modifier: Modifier,
+ containerColor: Color,
+ contentColor: Color,
+ indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,
+ divider: @Composable () -> Unit,
+ tabs: @Composable () -> Unit
+) {
Surface(
modifier = modifier.selectableGroup(),
color = containerColor,
@@ -169,7 +186,10 @@
}
val tabPositions = List(tabCount) { index ->
- TabPosition(tabWidth.toDp() * index, tabWidth.toDp())
+ var contentWidth =
+ minOf(tabMeasurables[index].maxIntrinsicWidth(tabRowHeight), tabWidth).toDp()
+ contentWidth -= HorizontalTextPadding * 2
+ TabPosition(tabWidth.toDp() * index, tabWidth.toDp(), contentWidth)
}
layout(tabRowWidth, tabRowHeight) {
@@ -192,8 +212,9 @@
}
}
-// TODO: Provide M3 tab row asset and docs when available.
/**
+ * <a href="https://m3.material.io/components/tabs/overview" class="external" target="_blank">Material Design tabs</a>
+ *
* Material Design scrollable tabs.
*
* When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use longer text
@@ -215,7 +236,7 @@
* and the tabs inside the row. This padding helps inform the user that this tab row can be
* scrolled, unlike a [TabRow].
* @param indicator the indicator that represents which tab is currently selected. By default this
- * will be a [TabRowDefaults.Indicator], using a [TabRowDefaults.tabIndicatorOffset] modifier to
+ * will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset] modifier to
* animate its position. Note that this indicator will be forced to fill up the entire tab row, so
* you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual drawn
* indicator inside this space, and provide an offset from the start.
@@ -232,7 +253,7 @@
contentColor: Color = TabRowDefaults.contentColor,
edgePadding: Dp = ScrollableTabRowPadding,
indicator: @Composable (tabPositions: List<TabPosition>) -> Unit = @Composable { tabPositions ->
- TabRowDefaults.Indicator(
+ TabRowDefaults.SecondaryIndicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
},
@@ -276,8 +297,20 @@
minHeight = layoutHeight,
maxHeight = layoutHeight,
)
- val tabPlaceables = tabMeasurables
- .map { it.measure(tabConstraints) }
+
+ val tabPlaceables = mutableListOf<Placeable>()
+ val tabContentWidths = mutableListOf<Dp>()
+ tabMeasurables.forEach {
+ val placeable = it.measure(tabConstraints)
+ var contentWidth =
+ minOf(
+ it.maxIntrinsicWidth(placeable.height),
+ placeable.width
+ ).toDp()
+ contentWidth -= HorizontalTextPadding * 2
+ tabPlaceables.add(placeable)
+ tabContentWidths.add(contentWidth)
+ }
val layoutWidth = tabPlaceables.fold(initial = padding * 2) { curr, measurable ->
curr + measurable.width
@@ -288,10 +321,16 @@
// Place the tabs
val tabPositions = mutableListOf<TabPosition>()
var left = padding
- tabPlaceables.forEach {
- it.placeRelative(left, 0)
- tabPositions.add(TabPosition(left = left.toDp(), width = it.width.toDp()))
- left += it.width
+ tabPlaceables.forEachIndexed { index, placeable ->
+ placeable.placeRelative(left, 0)
+ tabPositions.add(
+ TabPosition(
+ left = left.toDp(),
+ width = placeable.width.toDp(),
+ contentWidth = tabContentWidths[index]
+ )
+ )
+ left += placeable.width
}
// The divider is measured with its own height, and width equal to the total width
@@ -333,9 +372,11 @@
* @property left the left edge's x position from the start of the [TabRow]
* @property right the right edge's x position from the start of the [TabRow]
* @property width the width of this tab
+ * @property contentWidth the content width of this tab
*/
@Immutable
-class TabPosition internal constructor(val left: Dp, val width: Dp) {
+class TabPosition internal constructor(val left: Dp, val width: Dp, val contentWidth: Dp) {
+
val right: Dp get() = left + width
override fun equals(other: Any?): Boolean {
@@ -344,6 +385,7 @@
if (left != other.left) return false
if (width != other.width) return false
+ if (contentWidth != other.contentWidth) return false
return true
}
@@ -351,11 +393,12 @@
override fun hashCode(): Int {
var result = left.hashCode()
result = 31 * result + width.hashCode()
+ result = 31 * result + contentWidth.hashCode()
return result
}
override fun toString(): String {
- return "TabPosition(left=$left, right=$right, width=$width)"
+ return "TabPosition(left=$left, right=$right, width=$width, contentWidth=$contentWidth)"
}
}
@@ -364,12 +407,14 @@
*/
object TabRowDefaults {
/** Default container color of a tab row. */
- val containerColor: Color @Composable get() =
- PrimaryNavigationTabTokens.ContainerColor.toColor()
+ val containerColor: Color
+ @Composable get() =
+ PrimaryNavigationTabTokens.ContainerColor.toColor()
/** Default content color of a tab row. */
- val contentColor: Color @Composable get() =
- PrimaryNavigationTabTokens.ActiveLabelTextColor.toColor()
+ val contentColor: Color
+ @Composable get() =
+ PrimaryNavigationTabTokens.ActiveLabelTextColor.toColor()
/**
* Default indicator, which will be positioned at the bottom of the [TabRow], on top of the
@@ -380,6 +425,12 @@
* @param color color of the indicator
*/
@Composable
+ @Deprecated(
+ message = "Use SecondaryIndicator instead.",
+ replaceWith = ReplaceWith(
+ "SecondaryIndicator(modifier, height, color)"
+ )
+ )
fun Indicator(
modifier: Modifier = Modifier,
height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,
@@ -395,6 +446,54 @@
}
/**
+ * Primary indicator, which will be positioned at the bottom of the [TabRow], on top of the
+ * divider.
+ *
+ * @param modifier modifier for the indicator's layout
+ * @param width width of the indicator
+ * @param height height of the indicator
+ * @param color color of the indicator
+ * @param shape shape of the indicator
+ */
+ @Composable
+ fun PrimaryIndicator(
+ modifier: Modifier = Modifier,
+ width: Dp = 0.dp,
+ height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,
+ color: Color = PrimaryNavigationTabTokens.ActiveIndicatorColor.toColor(),
+ shape: Shape = PrimaryNavigationTabTokens.ActiveIndicatorShape
+ ) {
+ Spacer(
+ modifier
+ .requiredSize(width, height)
+ .background(color = color, shape = shape)
+ )
+ }
+
+ /**
+ * Secondary indicator, which will be positioned at the bottom of the [TabRow], on top of the
+ * divider.
+ *
+ * @param modifier modifier for the indicator's layout
+ * @param height height of the indicator
+ * @param color color of the indicator
+ */
+ @Composable
+ fun SecondaryIndicator(
+ modifier: Modifier = Modifier,
+ height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,
+ color: Color =
+ MaterialTheme.colorScheme.fromToken(PrimaryNavigationTabTokens.ActiveIndicatorColor)
+ ) {
+ Box(
+ modifier
+ .fillMaxWidth()
+ .height(height)
+ .background(color = color)
+ )
+ }
+
+ /**
* [Modifier] that takes up all the available width inside the [TabRow], and then animates
* the offset of the indicator it is applied to, depending on the [currentTabPosition].
*
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
index d13a240..cd786c6 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
@@ -676,13 +676,18 @@
val labelPlaceable =
measurables.find { it.layoutId == LabelId }?.measure(labelConstraints)
+ // supporting text must be measured after other elements, but we
+ // reserve space for it using its intrinsic height as a heuristic
+ val supportingMeasurable = measurables.find { it.layoutId == SupportingId }
+ val supportingIntrinsicHeight =
+ supportingMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0
+
// measure input field
val effectiveTopOffset = topPaddingValue + heightOrZero(labelPlaceable)
- val verticalConstraintOffset = -effectiveTopOffset - bottomPaddingValue
val textFieldConstraints = constraints
.copy(minHeight = 0)
.offset(
- vertical = verticalConstraintOffset,
+ vertical = -effectiveTopOffset - bottomPaddingValue - supportingIntrinsicHeight,
horizontal = -occupiedSpaceHorizontally
)
val textFieldPlaceable = measurables
@@ -700,15 +705,6 @@
max(heightOrZero(textFieldPlaceable), heightOrZero(placeholderPlaceable)) +
effectiveTopOffset + bottomPaddingValue
)
-
- // measure supporting text
- val supportingConstraints = looseConstraints.offset(
- vertical = -occupiedSpaceVertically
- ).copy(minHeight = 0)
- val supportingPlaceable =
- measurables.find { it.layoutId == SupportingId }?.measure(supportingConstraints)
- val supportingHeight = heightOrZero(supportingPlaceable)
-
val width = calculateWidth(
leadingWidth = widthOrZero(leadingPlaceable),
trailingWidth = widthOrZero(trailingPlaceable),
@@ -719,6 +715,14 @@
placeholderWidth = widthOrZero(placeholderPlaceable),
constraints = constraints,
)
+
+ // measure supporting text
+ val supportingConstraints = looseConstraints.offset(
+ vertical = -occupiedSpaceVertically
+ ).copy(minHeight = 0, maxWidth = width)
+ val supportingPlaceable = supportingMeasurable?.measure(supportingConstraints)
+ val supportingHeight = heightOrZero(supportingPlaceable)
+
val totalHeight = calculateHeight(
textFieldHeight = textFieldPlaceable.height,
labelHeight = heightOrZero(labelPlaceable),
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
index 6dae869..3764c75 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TimePicker.kt
@@ -91,6 +91,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -527,8 +528,12 @@
internal var isAfternoonToggle by mutableStateOf(initialHour > 12 && !is24Hour)
internal var isInnerCircle by mutableStateOf(initialHour >= 12)
- internal var hourAngle by mutableStateOf(RadiansPerHour * initialHour % 12 - FullCircle / 4)
- internal var minuteAngle by mutableStateOf(RadiansPerMinute * initialMinute - FullCircle / 4)
+ internal var hourAngle by mutableFloatStateOf(
+ RadiansPerHour * initialHour % 12 - FullCircle / 4
+ )
+ internal var minuteAngle by mutableFloatStateOf(
+ RadiansPerMinute * initialMinute - FullCircle / 4
+ )
private val mutex = MutatorMutex()
private val isAfternoon by derivedStateOf { is24hour && isInnerCircle || isAfternoonToggle }
@@ -1245,8 +1250,8 @@
name = "clockDial"
properties["state"] = state
}) {
- var offsetX by remember { mutableStateOf(0f) }
- var offsetY by remember { mutableStateOf(0f) }
+ var offsetX by remember { mutableFloatStateOf(0f) }
+ var offsetY by remember { mutableFloatStateOf(0f) }
val center by remember { mutableStateOf(IntOffset.Zero) }
val scope = rememberCoroutineScope()
val maxDist = with(LocalDensity.current) { MaxDistance.toPx() }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Typography.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Typography.kt
index fe45135..7b6273b 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Typography.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Typography.kt
@@ -17,10 +17,10 @@
package androidx.compose.material3
import androidx.compose.material3.tokens.TypographyKeyTokens
+import androidx.compose.material3.tokens.TypographyTokens
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.text.TextStyle
-import androidx.compose.material3.tokens.TypographyTokens
/**
* The Material Design type scale includes a range of contrasting styles that support the needs of
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/PrimaryNavigationTabTokens.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/PrimaryNavigationTabTokens.kt
index 3fd0e91..4622e75 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/PrimaryNavigationTabTokens.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/PrimaryNavigationTabTokens.kt
@@ -13,7 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// VERSION: v0_103
+
+// VERSION: v0_162
// GENERATED CODE - DO NOT MODIFY BY HAND
package androidx.compose.material3.tokens
@@ -29,8 +30,6 @@
val ContainerElevation = ElevationTokens.Level0
val ContainerHeight = 48.0.dp
val ContainerShape = ShapeKeyTokens.CornerNone
- val DividerColor = ColorSchemeKeyTokens.SurfaceVariant
- val DividerHeight = 1.0.dp
val ActiveFocusIconColor = ColorSchemeKeyTokens.Primary
val ActiveHoverIconColor = ColorSchemeKeyTokens.Primary
val ActiveIconColor = ColorSchemeKeyTokens.Primary
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/SecondaryNavigationTabTokens.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/SecondaryNavigationTabTokens.kt
new file mode 100644
index 0000000..6d34a48
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/SecondaryNavigationTabTokens.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+// VERSION: v0_162
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.compose.material3.tokens
+
+import androidx.compose.ui.unit.dp
+
+internal object SecondaryNavigationTabTokens {
+ val ActiveLabelTextColor = ColorSchemeKeyTokens.OnSurface
+ val ContainerColor = ColorSchemeKeyTokens.Surface
+ val ContainerElevation = ElevationTokens.Level0
+ val ContainerHeight = 48.0.dp
+ val ContainerShape = ShapeKeyTokens.CornerNone
+ val DividerColor = ColorSchemeKeyTokens.SurfaceVariant
+ val DividerHeight = 1.0.dp
+ val FocusLabelTextColor = ColorSchemeKeyTokens.OnSurface
+ val HoverLabelTextColor = ColorSchemeKeyTokens.OnSurface
+ val InactiveLabelTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+ val LabelTextFont = TypographyKeyTokens.TitleSmall
+ val PressedLabelTextColor = ColorSchemeKeyTokens.OnSurface
+ val ActiveIconColor = ColorSchemeKeyTokens.OnSurface
+ val FocusIconColor = ColorSchemeKeyTokens.OnSurface
+ val HoverIconColor = ColorSchemeKeyTokens.OnSurface
+ val IconSize = 24.0.dp
+ val InactiveIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+ val PressedIconColor = ColorSchemeKeyTokens.OnSurface
+}
\ No newline at end of file
diff --git a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Strings.desktop.kt b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Strings.desktop.kt
index 2de7b31..ed3cf456 100644
--- a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Strings.desktop.kt
+++ b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Strings.desktop.kt
@@ -18,7 +18,6 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
-
import java.util.Locale
@Composable
diff --git a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/SystemBarsDefaultInsets.desktop.kt b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/SystemBarsDefaultInsets.desktop.kt
index fe5ca33..c48c446 100644
--- a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/SystemBarsDefaultInsets.desktop.kt
+++ b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/SystemBarsDefaultInsets.desktop.kt
@@ -17,8 +17,8 @@
package androidx.compose.material3
import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.ui.unit.dp
import androidx.compose.runtime.Composable
+import androidx.compose.ui.unit.dp
internal actual val WindowInsets.Companion.systemBarsForVisualComponents: WindowInsets
@Composable
diff --git a/compose/runtime/OWNERS b/compose/runtime/OWNERS
index a9c5fa6..1d23419 100644
--- a/compose/runtime/OWNERS
+++ b/compose/runtime/OWNERS
@@ -3,6 +3,7 @@
chuckj@google.com
lelandr@google.com
anbailey@google.com
+ashikov@google.com
# Per-file for Playground infra
per-file settings.gradle = yboyar@google.com, dustinlam@google.com, rahulrav@google.com
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
new file mode 100644
index 0000000..b013276
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:Suppress("UnstableApiUsage")
+
+package androidx.compose.runtime.lint
+
+import androidx.compose.lint.Name
+import androidx.compose.lint.Names
+import androidx.compose.lint.isInPackageName
+import androidx.compose.lint.resolveCall
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
+import org.jetbrains.kotlin.psi.KtTypeArgumentList
+import org.jetbrains.kotlin.psi.KtValueArgumentList
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
+import org.jetbrains.uast.skipParenthesizedExprDown
+
+/**
+ * Suggests alternative functions to mutableStateOf<T>() if all of the following are true:
+ * - a snapshot mutation policy argument is not specified (or it is structural equivalent policy)
+ * - `T` is in the [replacements] map
+ * - `T` is a non-nullable type
+ */
+class AutoboxingStateCreationDetector : Detector(), SourceCodeScanner {
+
+ /**
+ * Map of canonical PSI types to the fully-qualified function that should be used to
+ * create MutableState instances of said type.
+ */
+ private val replacements = mapOf(
+ "kotlin.Int" to Names.Runtime.MutableIntStateOf,
+ "kotlin.Long" to Names.Runtime.MutableLongStateOf,
+ "kotlin.Float" to Names.Runtime.MutableFloatStateOf,
+ "kotlin.Double" to Names.Runtime.MutableDoubleStateOf,
+ )
+
+ override fun getApplicableMethodNames() = listOf(Names.Runtime.MutableStateOf.shortName)
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ if (!method.isInPackageName(Names.Runtime.PackageName)) return
+
+ val replacement = getSuggestedReplacementName(node as KotlinUFunctionCallExpression)
+ ?: return
+
+ context.report(
+ issue = AutoboxingStateCreation,
+ scope = node,
+ location = context.getNameLocation(node),
+ message = "Prefer `${replacement.shortName}` instead of `${method.name}`",
+ quickfixData = createLintFix(context, node, replacement)
+ )
+ }
+
+ private fun createLintFix(
+ context: JavaContext,
+ node: UCallExpression,
+ replacementFunction: Name
+ ): LintFix {
+ val fixes = listOfNotNull(
+ // Replace the function name
+ LintFix.create()
+ .replace()
+ .range(context.getNameLocation(node))
+ .with(replacementFunction.javaFqn)
+ .shortenNames(true)
+ .build(),
+
+ // Remove the type arguments list (if present)
+ context.getLocationOfTypeArguments(node)
+ ?.let { LintFix.create().replace().range(it).with("").build() },
+
+ // Remove the SnapshotMutationPolicy argument (if present)
+ context.getLocationOfArgumentsList(node)
+ ?.takeIf { node.getArgumentForParameter(MUTATION_POLICY_PARAM_IDX) != null }
+ ?.let { argsListLocation ->
+ node.getArgumentForParameter(VALUE_PARAM_IDX)?.sourcePsi?.text
+ ?.let { valueArg ->
+ LintFix.create()
+ .replace()
+ .range(argsListLocation)
+ .with("($valueArg)")
+ .build()
+ }
+ }
+ )
+
+ return LintFix.create()
+ .name("Replace with ${replacementFunction.shortName}")
+ .composite(*fixes.toTypedArray())
+ }
+
+ private fun JavaContext.getLocationOfTypeArguments(node: UCallExpression): Location? {
+ val typeArgsList = node.sourcePsi?.children?.firstIsInstanceOrNull<KtTypeArgumentList>()
+ ?: return null
+ return getLocation(typeArgsList)
+ }
+
+ private fun JavaContext.getLocationOfArgumentsList(node: UCallExpression): Location? {
+ val argsList = node.sourcePsi?.children?.firstIsInstanceOrNull<KtValueArgumentList>()
+ ?: return null
+ return getLocation(argsList)
+ }
+
+ private fun getSuggestedReplacementName(
+ invocation: KotlinUFunctionCallExpression
+ ): Name? {
+ if (!usesStructuralEqualityPolicy(invocation)) return null
+
+ val resolvedCall = invocation.resolveCall() ?: return null
+ val stateType = resolvedCall.typeArguments.asIterable().single().value
+ return when {
+ stateType.isMarkedNullable -> null
+ else -> replacements[stateType.getJetTypeFqName(true)]
+ }
+ }
+
+ private fun usesStructuralEqualityPolicy(
+ invocation: KotlinUFunctionCallExpression
+ ): Boolean {
+ val policyExpr = invocation.valueArguments.getOrNull(MUTATION_POLICY_PARAM_IDX)
+ ?.skipParenthesizedExprDown()
+ ?: return true // No argument passed; we're using the default policy
+
+ val policyMethod = (policyExpr as? KotlinUFunctionCallExpression)?.resolve()
+ ?: return false // Argument isn't a direct function call. Assume it's a more complex
+ // policy, or isn't always the structural equality policy.
+
+ return policyMethod.isInPackageName(Names.Runtime.PackageName) &&
+ policyMethod.name == Names.Runtime.StructuralEqualityPolicy.shortName
+ }
+
+ companion object {
+ private const val VALUE_PARAM_IDX = 0
+ private const val MUTATION_POLICY_PARAM_IDX = 1
+
+ val AutoboxingStateCreation = Issue.create(
+ id = "AutoboxingStateCreation",
+ briefDescription = "`State<T>` will autobox values assigned to this state. " +
+ "Use a specialized state type instead.",
+ explanation = "Calling `mutableStateOf<T>()` when `T` is either backed by a " +
+ "primitive type on the JVM or is a value class results in a state implementation " +
+ "that requires all state values to be boxed. This usually causes an additional " +
+ "allocation for each state write, and adds some additional work to auto-unbox " +
+ "values when reading the value of the state. Instead, prefer to use a " +
+ "specialized primitive state implementation for `Int`, `Long`, `Float`, and " +
+ "`Double` when the state does not need to track null values and does not " +
+ "override the default `SnapshotMutationPolicy`.",
+ category = Category.PERFORMANCE, priority = 3, severity = Severity.WARNING,
+ implementation = Implementation(
+ AutoboxingStateCreationDetector::class.java,
+ EnumSet.of(Scope.JAVA_FILE)
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetector.kt
index 8f8df7f..373c6f1 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableCoroutineCreationDetector.kt
@@ -31,8 +31,8 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
/**
* [Detector] that checks `async` and `launch` calls to make sure they don't happen inside the
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetector.kt
index 7688c4f..024e954 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableFlowOperatorDetector.kt
@@ -33,6 +33,7 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.impl.compiled.ClsMethodImpl
+import java.util.EnumSet
import kotlinx.metadata.KmClassifier
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.uast.UCallExpression
@@ -40,7 +41,6 @@
import org.jetbrains.uast.UTypeReferenceExpression
import org.jetbrains.uast.resolveToUElement
import org.jetbrains.uast.toUElement
-import java.util.EnumSet
/**
* [Detector] that checks calls to Flow operator functions (such as map) to make sure they don't
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt
index 1ed4cd9..5993c93 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableLambdaParameterDetector.kt
@@ -30,13 +30,13 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
+import java.util.EnumSet
import org.jetbrains.kotlin.psi.KtFunctionType
import org.jetbrains.kotlin.psi.KtNullableType
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMethod
import org.jetbrains.uast.UParameter
-import java.util.EnumSet
/**
* [Detector] that checks composable lambda parameters inside composable functions for
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableNamingDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableNamingDetector.kt
index 1bbfff0..c7be5bf 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableNamingDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableNamingDetector.kt
@@ -30,9 +30,9 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
-import org.jetbrains.uast.UMethod
import java.util.EnumSet
import java.util.Locale
+import org.jetbrains.uast.UMethod
/**
* [Detector] that checks the naming of @Composable functions for consistency with guidelines.
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetector.kt
index 8673429..ce42adb 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ComposableStateFlowValueDetector.kt
@@ -32,9 +32,9 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.USimpleNameReferenceExpression
import org.jetbrains.uast.tryResolve
-import java.util.EnumSet
/**
* [Detector] that checks calls to StateFlow.value to make sure they don't happen inside the body
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/CompositionLocalNamingDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/CompositionLocalNamingDetector.kt
index ef2fca4..dee4098 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/CompositionLocalNamingDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/CompositionLocalNamingDetector.kt
@@ -29,12 +29,12 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
+import java.util.EnumSet
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UParameter
import org.jetbrains.uast.UVariable
-import java.util.EnumSet
/**
* [Detector] that checks the naming of CompositionLocal properties for consistency with guidelines.
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetector.kt
index 896c7bf..4285eca 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/MutableCollectionMutableStateDetector.kt
@@ -29,13 +29,13 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.kotlin.descriptors.containingPackage
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
-import java.util.EnumSet
/**
* [Detector] that checks `mutableStateOf` calls to warn if the type is a mutable collection, as
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetector.kt
new file mode 100644
index 0000000..70fd1cd
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetector.kt
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:Suppress("UnstableApiUsage")
+
+package androidx.compose.runtime.lint
+
+import androidx.compose.lint.Names
+import androidx.compose.lint.isInPackageName
+import androidx.compose.lint.isVoidOrUnit
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.android.tools.lint.detector.api.UastLintUtils.Companion.tryResolveUDeclaration
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiParameter
+import java.util.EnumSet
+import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
+import org.jetbrains.uast.UBlockExpression
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UClass
+import org.jetbrains.uast.UDeclarationsExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.UExpressionList
+import org.jetbrains.uast.UParameter
+import org.jetbrains.uast.USimpleNameReferenceExpression
+import org.jetbrains.uast.UVariable
+import org.jetbrains.uast.skipParenthesizedExprDown
+import org.jetbrains.uast.toUElement
+
+/**
+ * Detector to warn when [Unit] is being passed "opaquely" as an argument to any of the methods in
+ * [getApplicableMethodNames]. An argument is defined as an opaque unit key if all the following
+ * are true:
+ * - The argument is an expression of type `Unit`
+ * - The argument is being passed to a parameter of type `Any?`
+ * - The argument is not the `Unit` literal
+ * - The argument is not a trivial variable or property read expression
+ */
+class OpaqueUnitKeyDetector : Detector(), SourceCodeScanner {
+
+ override fun getApplicableMethodNames(): List<String> = listOf(
+ Names.Runtime.Remember.shortName,
+ Names.Runtime.RememberSaveable.shortName,
+ Names.Runtime.DisposableEffect.shortName,
+ Names.Runtime.LaunchedEffect.shortName,
+ Names.Runtime.ProduceState.shortName,
+ Names.Runtime.ReusableContent.shortName,
+ Names.Runtime.Key.shortName,
+ )
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ if (!method.isInPackageName(Names.Runtime.PackageName)) return
+
+ method.parameterList.parameters.forEach { parameter ->
+ val arg = node.getArgumentForParameter(parameter.parameterIndex())
+ if (parameter.isNullableAny()) {
+ if (arg?.isOpaqueUnitExpression() == true) {
+ reportOpaqueUnitArgKey(
+ context = context,
+ method = method,
+ methodInvocation = node,
+ parameter = parameter,
+ argument = arg
+ )
+ }
+ } else if (parameter.isPotentiallyVarArgs() && arg is UExpressionList) {
+ arg.expressions.forEach { varArg ->
+ if (varArg.isOpaqueUnitExpression()) {
+ reportOpaqueUnitArgKey(
+ context = context,
+ method = method,
+ methodInvocation = node,
+ parameter = parameter,
+ argument = varArg
+ )
+ }
+ }
+ }
+ }
+ }
+
+ private fun reportOpaqueUnitArgKey(
+ context: JavaContext,
+ method: PsiMethod,
+ methodInvocation: UCallExpression,
+ parameter: PsiParameter,
+ argument: UExpression
+ ) {
+ val rootExpression = methodInvocation.resolveRootExpression()
+ val rootExpressionLocation = context.getLocation(rootExpression)
+
+ context.report(
+ OpaqueUnitKey,
+ argument,
+ context.getLocation(argument),
+ "Implicitly passing `Unit` as argument to ${parameter.name}",
+ fix()
+ .name(
+ "Move expression outside of `${method.name}`'s arguments " +
+ "and pass `Unit` explicitly"
+ )
+ .composite(
+ if (rootExpression.isInPhysicalBlock()) {
+ // If we're in a block where we can add an expression without breaking any
+ // syntax rules, promote the argument's expression to a sibling.
+ fix()
+ .replace()
+ .range(rootExpressionLocation)
+ .beginning()
+ .with("${argument.asSourceString()}\n")
+ .reformat(true)
+ .build()
+ } else {
+ // If we're not in a block, then introduce one for cheap by wrapping the
+ // call with Kotlin's `run` function to a format that appears as follows:
+ //
+ // ```
+ // run {
+ // theArgument()
+ // theMethod(...)
+ // }
+ // ```
+ fix()
+ .composite(
+ fix()
+ .replace()
+ .range(rootExpressionLocation)
+ .beginning()
+ .with("kotlin.run {\n${argument.asSourceString()}\n")
+ .reformat(true)
+ .shortenNames()
+ .build(),
+ fix()
+ .replace()
+ .range(rootExpressionLocation)
+ .end()
+ .with("\n}")
+ .reformat(true)
+ .build()
+ )
+ },
+
+ // Replace the old parameter with the Unit literal
+ fix()
+ .replace()
+ .range(context.getLocation(argument))
+ .with(FqUnitName)
+ .shortenNames()
+ .build(),
+ )
+ )
+ }
+
+ private fun UCallExpression.resolveRootExpression(): UExpression {
+ var root: UExpression = this
+ var parent: UExpression? = root.getParentExpression()
+ while (parent != null && parent !is UBlockExpression) {
+ if (!parent.isVirtual) { root = parent }
+ parent = parent.getParentExpression()
+ }
+ return root
+ }
+
+ private fun UExpression.isInPhysicalBlock(): Boolean {
+ var parent: UElement? = this
+ while (parent != null) {
+ if (parent is UBlockExpression) {
+ return !parent.isVirtual
+ }
+ parent = parent.uastParent
+ }
+ return false
+ }
+
+ private val UElement.isVirtual get() = sourcePsi == null
+
+ private fun UExpression.getParentExpression(): UExpression? {
+ return when (val parent = uastParent) {
+ is UVariable -> parent.uastParent as UDeclarationsExpression
+ is UExpression -> parent
+ else -> null
+ }
+ }
+
+ private fun PsiParameter.isNullableAny(): Boolean {
+ val element = toUElement() as UParameter
+ return element.type.canonicalText == FqJavaObjectName &&
+ element.getAnnotations().any { it.qualifiedName == FqKotlinNullableAnnotation }
+ }
+
+ private fun PsiParameter.isPotentiallyVarArgs(): Boolean {
+ return type.canonicalText == "$FqJavaObjectName[]"
+ }
+
+ private fun UExpression.isOpaqueUnitExpression(): Boolean {
+ return getExpressionType().isVoidOrUnit && !isUnitLiteral()
+ }
+
+ private fun UExpression.isUnitLiteral(): Boolean {
+ val expr = skipParenthesizedExprDown() ?: this
+ if (expr !is USimpleNameReferenceExpression) return false
+
+ return (expr.tryResolveUDeclaration() as? UClass)?.qualifiedName == FqUnitName
+ }
+
+ companion object {
+ private const val FqJavaObjectName = "java.lang.Object"
+ private const val FqUnitName = "kotlin.Unit"
+ private const val FqKotlinNullableAnnotation = "org.jetbrains.annotations.Nullable"
+
+ val OpaqueUnitKey = Issue.create(
+ "OpaqueUnitKey",
+ "Passing an expression which always returns `Unit` as a key argument",
+ "Certain Compose functions including `remember`, `LaunchedEffect`, and " +
+ "`DisposableEffect` declare (and sometimes require) one or more key parameters. " +
+ "When a key parameter changes, it is a signal that the previous invocation is " +
+ "now invalid. In certain cases, it may be required to pass `Unit` as a key to " +
+ "one of these functions, indicating that the invocation never becomes invalid. " +
+ "Using `Unit` as a key should be done infrequently, and should always be done " +
+ "explicitly by passing the `Unit` literal. This inspection checks for " +
+ "invocations where `Unit` is being passed as a key argument in any form other " +
+ "than the `Unit` literal. This is usually done by mistake, and can harm " +
+ "readability. If a Unit expression is being passed as a key, it is always " +
+ "equivalent to move the expression before the function invocation and pass the " +
+ "`Unit` literal instead.",
+ Category.CORRECTNESS, 3, Severity.WARNING,
+ Implementation(
+ OpaqueUnitKeyDetector::class.java,
+ EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ProduceStateDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ProduceStateDetector.kt
index a18642d..2afb1ab 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ProduceStateDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/ProduceStateDetector.kt
@@ -31,12 +31,12 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.USimpleNameReferenceExpression
import org.jetbrains.uast.getParameterForArgument
import org.jetbrains.uast.tryResolve
import org.jetbrains.uast.visitor.AbstractUastVisitor
-import java.util.EnumSet
/**
* [Detector] that checks calls to produceState, to make sure that the producer lambda writes to
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
index 559d08c..354a305 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RememberDetector.kt
@@ -30,10 +30,10 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtLambdaExpression
+import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.toUElementOfType
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
index bc749d0..1ead6c8 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
@@ -31,6 +31,7 @@
override val minApi = CURRENT_API
override val issues get() = listOf(
AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty,
+ AutoboxingStateCreationDetector.AutoboxingStateCreation,
ComposableCoroutineCreationDetector.CoroutineCreationDuringComposition,
ComposableFlowOperatorDetector.FlowOperatorInvokedInComposition,
ComposableLambdaParameterDetector.ComposableLambdaParameterNaming,
@@ -41,6 +42,7 @@
MutableCollectionMutableStateDetector.MutableCollectionMutableState,
ProduceStateDetector.ProduceStateDoesNotAssignValue,
RememberDetector.RememberReturnType,
+ OpaqueUnitKeyDetector.OpaqueUnitKey,
UnrememberedStateDetector.UnrememberedState
)
override val vendor = Vendor(
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/UnrememberedStateDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/UnrememberedStateDetector.kt
index 4eaa5a9..70ff3eb 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/UnrememberedStateDetector.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/UnrememberedStateDetector.kt
@@ -18,9 +18,8 @@
package androidx.compose.runtime.lint
-import androidx.compose.lint.Names
-import androidx.compose.lint.isInPackageName
import androidx.compose.lint.isNotRemembered
+import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Implementation
@@ -29,9 +28,9 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
/**
* [Detector] that checks `derivedStateOf`, `mutableStateOf`, `mutableStateListOf`,
@@ -39,27 +38,32 @@
* they are `remember`ed.
*/
class UnrememberedStateDetector : Detector(), SourceCodeScanner {
- override fun getApplicableMethodNames(): List<String> = listOf(
- Names.Runtime.DerivedStateOf.shortName,
- Names.Runtime.MutableStateOf.shortName,
- Names.Runtime.MutableStateListOf.shortName,
- Names.Runtime.MutableStateMapOf.shortName
- )
+ override fun getApplicableUastTypes(): List<Class<out UElement>> {
+ return listOf(UCallExpression::class.java)
+ }
- override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
- if (!method.isInPackageName(Names.Runtime.PackageName)) return
-
- if (node.isNotRemembered()) {
- context.report(
- UnrememberedState,
- node,
- context.getNameLocation(node),
- "Creating a state object during composition without using `remember`"
- )
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ return object : UElementHandler() {
+ override fun visitCallExpression(node: UCallExpression) {
+ if (node.isStateFactoryInvocation() && node.isNotRemembered()) {
+ context.report(
+ UnrememberedState,
+ node,
+ context.getNameLocation(node),
+ "Creating a state object during composition without using `remember`"
+ )
+ }
+ }
}
}
+ private fun UCallExpression.isStateFactoryInvocation(): Boolean =
+ resolve()?.annotations?.any { it.hasQualifiedName(FqStateFactoryAnnotationName) } ?: false
+
companion object {
+ private const val FqStateFactoryAnnotationName =
+ "androidx.compose.runtime.snapshots.StateFactoryMarker"
+
val UnrememberedState = Issue.create(
"UnrememberedMutableState", // Left as previous id for backwards compatibility
"Creating a state object during composition without using `remember`",
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
new file mode 100644
index 0000000..06eb0d1
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
@@ -0,0 +1,505 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.runtime.lint
+
+import androidx.compose.lint.test.Stubs
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/* ktlint-disable max-line-length */
+@RunWith(Parameterized::class)
+class AutoboxingStateCreationDetectorTest(
+ typeUnderTest: TypeUnderTest
+) : LintDetectorTest() {
+
+ private val fqType = typeUnderTest.fqName
+ private val type = typeUnderTest.typeName
+ private val stateValue = typeUnderTest.sampleValue
+
+ private val primitiveStateStub = kotlin(
+ """
+ package androidx.compose.runtime
+
+ import kotlin.reflect.KProperty
+ import $fqType
+
+ fun mutable${type}StateOf(value: $type): Mutable${type}State {
+ TODO("Not implemented in lint stubs.")
+ }
+
+ interface Mutable${type}State : State<$type> {
+ override var value: $type
+ var ${type.toLowerCaseAsciiOnly()}Value: $type
+ }
+
+ @Suppress("NOTHING_TO_INLINE")
+ inline operator fun Mutable${type}State.getValue(
+ thisObj: Any?,
+ property: KProperty<*>
+ ): $type = ${type.toLowerCaseAsciiOnly()}Value
+
+ @Suppress("NOTHING_TO_INLINE")
+ inline operator fun Mutable${type}State.setValue(
+ thisObj: Any?,
+ property: KProperty<*>,
+ value: $type
+ ) {
+ ${type.toLowerCaseAsciiOnly()}Value = value
+ }
+ """
+ )
+
+ override fun getDetector(): Detector = AutoboxingStateCreationDetector()
+
+ override fun getIssues(): MutableList<Issue> =
+ mutableListOf(AutoboxingStateCreationDetector.AutoboxingStateCreation)
+
+ @Test
+ fun testTrivialMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf<$type>($stateValue)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ val state = mutableStateOf<$type>($stateValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- val state = mutableStateOf<$type>($stateValue)
++ val state = mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testInferredMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf($stateValue)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ val state = mutableStateOf($stateValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- val state = mutableStateOf($stateValue)
++ val state = mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testFqMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf<$fqType>($stateValue)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ val state = mutableStateOf<$fqType>($stateValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- val state = mutableStateOf<$fqType>($stateValue)
++ val state = mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testStateDelegate_withExplicitType_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun propertyDelegation() {
+ var state by mutableStateOf<$type>($stateValue)
+ state = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ var state by mutableStateOf<$type>($stateValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- var state by mutableStateOf<$type>($stateValue)
++ var state by mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testStateDelegate_withInferredType_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun propertyDelegation() {
+ var state by mutableStateOf($stateValue)
+ state = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ var state by mutableStateOf($stateValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- var state by mutableStateOf($stateValue)
++ var state by mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testStateDelegate_withInferredType_andInternalSetter_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ class Test(initialValue: $type = $stateValue) {
+ var state by mutableStateOf(initialValue)
+ private set
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/Test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ var state by mutableStateOf(initialValue)
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/Test.kt line 7: Replace with mutable${type}StateOf:
+@@ -8 +8
+- var state by mutableStateOf(initialValue)
++ var state by mutable${type}StateOf(initialValue)
+ """
+ )
+ }
+
+ @Test
+ fun testStateDelegate_withTypeInferredFromProperty_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun propertyDelegation() {
+ var state: $type by mutableStateOf($stateValue)
+ state = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ var state: $type by mutableStateOf($stateValue)
+ ${" ".repeat(type.length)} ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- var state: $type by mutableStateOf($stateValue)
++ var state: $type by mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testStateDelegate_withNullableInferredType_cannotBeReplacedWithMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun propertyDelegation() {
+ var state: $type? by mutableStateOf($stateValue)
+ state = $stateValue
+ }
+ """
+ )
+ ).run().expectClean()
+ }
+
+ @Test
+ fun testInferredMutableStateOf_withExplicitEqualityPolicy_thatCouldBeMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf($stateValue, structuralEqualityPolicy())
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expect(
+ """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+ val state = mutableStateOf($stateValue, structuralEqualityPolicy())
+ ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ ).expectFixDiffs(
+ """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+- val state = mutableStateOf($stateValue, structuralEqualityPolicy())
++ val state = mutable${type}StateOf($stateValue)
+ """
+ )
+ }
+
+ @Test
+ fun testNonStructuralEqualityPolicy_cannotBeReplacedWithMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf($stateValue, neverEqualPolicy())
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expectClean()
+ }
+
+ @Test
+ fun testNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf<$type?>($stateValue)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expectClean()
+ }
+
+ @Test
+ fun testInferredNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state: MutableState<$type?> = mutableStateOf($stateValue)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expectClean()
+ }
+
+ @Test
+ fun testInferredByCastNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+ lint().files(
+ primitiveStateStub,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package androidx.compose.runtime.lint.test
+
+ import androidx.compose.runtime.*
+ import $fqType
+
+ fun valueAssignment() {
+ val state = mutableStateOf($stateValue as $type?)
+ state.value = $stateValue
+ }
+ """
+ )
+ ).run().expectClean()
+ }
+
+ companion object {
+ @JvmStatic
+ @Parameterized.Parameters(name = "{0}")
+ fun initParameters() = listOf(
+ testCase("kotlin.Int", "42"),
+ testCase("kotlin.Long", "0xABCDEF1234"),
+ testCase("kotlin.Float", "1.5f"),
+ testCase("kotlin.Double", "1.024")
+ )
+
+ private fun testCase(fqName: String, value: String): TypeUnderTest {
+ val parts = fqName.split('.')
+ return TypeUnderTest(
+ fqName = fqName,
+ typeName = parts.last(),
+ packageName = parts.dropLast(1).joinToString(separator = "."),
+ sampleValue = value
+ )
+ }
+ }
+
+ data class TypeUnderTest(
+ val fqName: String,
+ val typeName: String,
+ val packageName: String,
+ val sampleValue: String,
+ ) {
+ // Formatting for test parameter list.
+ override fun toString() = "type = $fqName"
+ }
+}
+/* ktlint-enable max-line-length */
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetectorTest.kt
new file mode 100644
index 0000000..597189a
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/OpaqueUnitKeyDetectorTest.kt
@@ -0,0 +1,1744 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.runtime.lint
+
+import androidx.compose.lint.test.Stubs
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/* ktlint-disable max-line-length */
+@RunWith(JUnit4::class)
+class OpaqueUnitKeyDetectorTest : LintDetectorTest() {
+ override fun getDetector(): Detector = OpaqueUnitKeyDetector()
+
+ override fun getIssues() = listOf(OpaqueUnitKeyDetector.OpaqueUnitKey)
+
+ // region remember test cases
+
+ @Test
+ fun remember_withUnitLiteralKey_doesNotError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x = remember(Unit) { listOf(1, 2, 3) }
+ }
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun remember_withUnitPropertyRead_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ val unitProperty = Unit
+
+ @Composable
+ fun Test() {
+ val x = remember(unitProperty) { listOf(1, 2, 3) }
+ }
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x = remember(unitProperty) { listOf(1, 2, 3) }
+ ~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -10 +10
+- val x = remember(unitProperty) { listOf(1, 2, 3) }
++ unitProperty
++ val x = remember(kotlin.Unit) { listOf(1, 2, 3) }
+ """
+ )
+ }
+
+ @Test
+ fun remember_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x = remember(produceUnit()) { listOf(1, 2, 3) }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x = remember(produceUnit()) { listOf(1, 2, 3) }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x = remember(produceUnit()) { listOf(1, 2, 3) }
++ produceUnit()
++ val x = remember(kotlin.Unit) { listOf(1, 2, 3) }
+ """
+ )
+ }
+
+ @Test
+ fun remember_withUnitComposableInvocation_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x = remember(AnotherComposable()) { listOf(1, 2, 3) }
+ }
+
+ @Composable
+ fun AnotherComposable() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x = remember(AnotherComposable()) { listOf(1, 2, 3) }
+ ~~~~~~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x = remember(AnotherComposable()) { listOf(1, 2, 3) }
++ AnotherComposable()
++ val x = remember(kotlin.Unit) { listOf(1, 2, 3) }
+ """
+ )
+ }
+
+ @Test
+ fun remember_withUnitComposableInvocation_reportsError_withFixInSingleExpressionFun() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun test() = remember(produceUnit()) { listOf(1, 2, 3) }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:7: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ fun test() = remember(produceUnit()) { listOf(1, 2, 3) }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 7: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -7 +7
+- fun test() = remember(produceUnit()) { listOf(1, 2, 3) }
++ fun test() = kotlin.run {
++ produceUnit()
++ remember(kotlin.Unit) { listOf(1, 2, 3) }
++ }
+ """
+ )
+ }
+
+ @Test
+ fun remember_withIfStatementThatReturnsUnit_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ val x = remember(
+ if (condition) {
+ doSomething()
+ } else {
+ doSomethingElse()
+ }
+ ) { listOf(1, 2, 3) }
+ }
+
+ fun doSomething() {}
+ fun doSomethingElse() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:9: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ if (condition) {
+ ^
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x = remember(
+- if (condition) {
+- doSomething()
+- } else {
+- doSomethingElse()
+- }
++ if (condition) {
++ doSomething()
++ }else {
++ doSomethingElse()
++ }
++ val x = remember(
++ kotlin.Unit
+ """
+ )
+ }
+
+ @Test
+ fun remember_withIfStatementCoercedToAny_doesNotReportError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ val x = remember(
+ if (condition) {
+ doSomething()
+ } else {
+ 42
+ }
+ ) { listOf(1, 2, 3) }
+ }
+
+ fun doSomething() {}
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun remember_twoKeys_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x = remember(42, produceUnit()) { listOf(1, 2, 3) }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key2 [OpaqueUnitKey]
+ val x = remember(42, produceUnit()) { listOf(1, 2, 3) }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `remember`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x = remember(42, produceUnit()) { listOf(1, 2, 3) }
++ produceUnit()
++ val x = remember(42, kotlin.Unit) { listOf(1, 2, 3) }
+ """
+ )
+ }
+
+ // endregion remember test cases
+
+ // region produceState test cases
+
+ @Test
+ fun produceState_withUnitLiteralKey_doesNotError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x by produceState("123", Unit) { /* Do nothing. */ }
+ }
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun produceState_withUnitPropertyRead_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ val unitProperty = Unit
+
+ @Composable
+ fun Test() {
+ val x by produceState("123", unitProperty) { /* Do nothing. */ }
+ }
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x by produceState("123", unitProperty) { /* Do nothing. */ }
+ ~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -10 +10
+- val x by produceState("123", unitProperty) { /* Do nothing. */ }
++ unitProperty
++ val x by produceState("123", kotlin.Unit) { /* Do nothing. */ }
+ """
+ )
+ }
+
+ @Test
+ fun produceState_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x by produceState("123", produceUnit()) { /* Do nothing. */ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x by produceState("123", produceUnit()) { /* Do nothing. */ }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x by produceState("123", produceUnit()) { /* Do nothing. */ }
++ produceUnit()
++ val x by produceState("123", kotlin.Unit) { /* Do nothing. */ }
+ """
+ )
+ }
+
+ @Test
+ fun produceState_withUnitComposableInvocation_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x by produceState("123", AnotherComposable()) { /* Do nothing. */ }
+ }
+
+ @Composable
+ fun AnotherComposable() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x by produceState("123", AnotherComposable()) { /* Do nothing. */ }
+ ~~~~~~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x by produceState("123", AnotherComposable()) { /* Do nothing. */ }
++ AnotherComposable()
++ val x by produceState("123", kotlin.Unit) { /* Do nothing. */ }
+ """
+ )
+ }
+
+ @Test
+ fun produceState_withUnitComposableInvocation_reportsError_withFixInSingleExpressionFun() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun test() = produceState("123", produceUnit()) { /* Do nothing. */ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:7: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ fun test() = produceState("123", produceUnit()) { /* Do nothing. */ }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 7: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -7 +7
+- fun test() = produceState("123", produceUnit()) { /* Do nothing. */ }
++ fun test() = kotlin.run {
++ produceUnit()
++ produceState("123", kotlin.Unit) { /* Do nothing. */ }
++ }
+ """
+ )
+ }
+
+ @Test
+ fun produceState_withIfStatementThatReturnsUnit_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ val x by produceState(
+ initialValue = "123",
+ if (condition) {
+ doSomething()
+ } else {
+ doSomethingElse()
+ }
+ ) { /* Do nothing. */ }
+ }
+
+ fun doSomething() {}
+ fun doSomethingElse() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ if (condition) {
+ ^
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x by produceState(
++ if (condition) {
++ doSomething()
++ }else {
++ doSomethingElse()
++ }
++ val x by produceState(
+- if (condition) {
+- doSomething()
+- } else {
+- doSomethingElse()
+- }
++ kotlin.Unit
+ """
+ )
+ }
+
+ @Test
+ fun produceState_withIfStatementCoercedToAny_doesNotReportError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ val x by produceState(
+ initialValue = "123",
+ if (condition) {
+ doSomething()
+ } else {
+ 42
+ }
+ ) { /* Do nothing */ }
+ }
+
+ fun doSomething() {}
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun produceState_twoKeys_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ val x by produceState("123", produceUnit()) { /* Do nothing */ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ val x by produceState("123", produceUnit()) { /* Do nothing */ }
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `produceState`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- val x by produceState("123", produceUnit()) { /* Do nothing */ }
++ produceUnit()
++ val x by produceState("123", kotlin.Unit) { /* Do nothing */ }
+ """
+ )
+ }
+
+ // endregion produceState test cases
+
+ // region DisposableEffect test cases
+
+ @Test
+ fun disposableEffect_withUnitLiteralKey_doesNotError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ DisposableEffect(Unit) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun disposableEffect_withUnitPropertyRead_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ val unitProperty = Unit
+
+ @Composable
+ fun Test() {
+ DisposableEffect(unitProperty) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ DisposableEffect(unitProperty) {
+ ~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -10 +10
+- DisposableEffect(unitProperty) {
++ unitProperty
++ DisposableEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun disposableEffect_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ DisposableEffect(produceUnit()) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ DisposableEffect(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- DisposableEffect(produceUnit()) {
++ produceUnit()
++ DisposableEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun disposableEffect_withUnitComposableInvocation_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ DisposableEffect(AnotherComposable()) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+
+ @Composable
+ fun AnotherComposable() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ DisposableEffect(AnotherComposable()) {
+ ~~~~~~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- DisposableEffect(AnotherComposable()) {
++ AnotherComposable()
++ DisposableEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun disposableEffect_withUnitComposableInvocation_reportsError_withFixInSingleExpressionFun() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun test() = DisposableEffect(produceUnit()) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:7: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ fun test() = DisposableEffect(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 7: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -7 +7
+- fun test() = DisposableEffect(produceUnit()) {
++ fun test() = kotlin.run {
++ produceUnit()
++ DisposableEffect(kotlin.Unit) {
+@@ -12 +14
++ }
+ """
+ )
+ }
+
+ @Test
+ fun disposableEffect_withIfStatementThatReturnsUnit_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ DisposableEffect(
+ if (condition) {
+ doSomething()
+ } else {
+ doSomethingElse()
+ }
+ ) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+
+ fun doSomething() {}
+ fun doSomethingElse() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:9: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ if (condition) {
+ ^
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 9: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- DisposableEffect(
+- if (condition) {
+- doSomething()
+- } else {
+- doSomethingElse()
+- }
++ if (condition) {
++ doSomething()
++ }else {
++ doSomethingElse()
++ }
++ DisposableEffect(
++ kotlin.Unit
+ """
+ )
+ }
+
+ @Test
+ fun disposableEffect_withIfStatementCoercedToAny_doesNotReportError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ DisposableEffect(
+ if (condition) {
+ doSomething()
+ } else {
+ 42
+ }
+ ) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+
+ fun doSomething() {}
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun disposableEffect_twoKeys_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ DisposableEffect(42, produceUnit()) {
+ onDispose {
+ // Do nothing.
+ }
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key2 [OpaqueUnitKey]
+ DisposableEffect(42, produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `DisposableEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- DisposableEffect(42, produceUnit()) {
++ produceUnit()
++ DisposableEffect(42, kotlin.Unit) {
+ """
+ )
+ }
+
+ // endregion DisposableEffect test cases
+
+ // region LaunchedEffect test cases
+
+ @Test
+ fun launchedEffect_withUnitLiteralKey_doesNotError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ LaunchedEffect(Unit) {
+ // Do nothing.
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun launchedEffect_withUnitPropertyRead_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ val unitProperty = Unit
+
+ @Composable
+ fun Test() {
+ LaunchedEffect(unitProperty) {
+ // Do nothing.
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ LaunchedEffect(unitProperty) {
+ ~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -10 +10
+- LaunchedEffect(unitProperty) {
++ unitProperty
++ LaunchedEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun launchedEffect_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ LaunchedEffect(produceUnit()) {
+ // Do nothing.
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ LaunchedEffect(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- LaunchedEffect(produceUnit()) {
++ produceUnit()
++ LaunchedEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun launchedEffect_withUnitComposableInvocation_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ LaunchedEffect(AnotherComposable()) {
+ // Do nothing.
+ }
+ }
+
+ @Composable
+ fun AnotherComposable() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ LaunchedEffect(AnotherComposable()) {
+ ~~~~~~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- LaunchedEffect(AnotherComposable()) {
++ AnotherComposable()
++ LaunchedEffect(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun launchedEffect_withUnitComposableInvocation_reportsError_withFixInSingleExpressionFun() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun test() = LaunchedEffect(produceUnit()) {
+ // Do nothing.
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:7: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ fun test() = LaunchedEffect(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 7: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -7 +7
+- fun test() = LaunchedEffect(produceUnit()) {
++ fun test() = kotlin.run {
++ produceUnit()
++ LaunchedEffect(kotlin.Unit) {
+@@ -10 +12
++ }
+ """
+ )
+ }
+
+ @Test
+ fun launchedEffect_withIfStatementThatReturnsUnit_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ LaunchedEffect(
+ if (condition) {
+ doSomething()
+ } else {
+ doSomethingElse()
+ }
+ ) {
+ // Do nothing.
+ }
+ }
+
+ fun doSomething() {}
+ fun doSomethingElse() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:9: Warning: Implicitly passing Unit as argument to key1 [OpaqueUnitKey]
+ if (condition) {
+ ^
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 9: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- LaunchedEffect(
+- if (condition) {
+- doSomething()
+- } else {
+- doSomethingElse()
+- }
++ if (condition) {
++ doSomething()
++ }else {
++ doSomethingElse()
++ }
++ LaunchedEffect(
++ kotlin.Unit
+ """
+ )
+ }
+
+ @Test
+ fun launchedEffect_withIfStatementCoercedToAny_doesNotReportError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ LaunchedEffect(
+ if (condition) {
+ doSomething()
+ } else {
+ 42
+ }
+ ) {
+ // Do nothing.
+ }
+ }
+
+ fun doSomething() {}
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun launchedEffect_twoKeys_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Effects,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ LaunchedEffect(42, produceUnit()) {
+ // Do nothing.
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to key2 [OpaqueUnitKey]
+ LaunchedEffect(42, produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `LaunchedEffect`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- LaunchedEffect(42, produceUnit()) {
++ produceUnit()
++ LaunchedEffect(42, kotlin.Unit) {
+ """
+ )
+ }
+
+ // endregion LaunchedEffect test cases
+
+ // region key() test cases
+
+ @Test
+ fun key_withUnitLiteralKey_doesNotError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ key(Unit) {
+ // Do nothing.
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun key_withUnitPropertyRead_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ val unitProperty = Unit
+
+ @Composable
+ fun Test() {
+ key(unitProperty) {
+ // Do nothing.
+ }
+ }
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:10: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ key(unitProperty) {
+ ~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 10: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -10 +10
+- key(unitProperty) {
++ unitProperty
++ key(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun key_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ key(produceUnit()) {
+ // Do nothing.
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ key(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- key(produceUnit()) {
++ produceUnit()
++ key(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun key_withUnitComposableInvocation_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ key(AnotherComposable()) {
+ // Do nothing.
+ }
+ }
+
+ @Composable
+ fun AnotherComposable() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ key(AnotherComposable()) {
+ ~~~~~~~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- key(AnotherComposable()) {
++ AnotherComposable()
++ key(kotlin.Unit) {
+ """
+ )
+ }
+
+ @Test
+ fun key_withUnitComposableInvocation_reportsError_withFixInSingleExpressionFun() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun test() = key(produceUnit()) {
+ // Do nothing.
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:7: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ fun test() = key(produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 7: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -7 +7
+- fun test() = key(produceUnit()) {
++ fun test() = kotlin.run {
++ produceUnit()
++ key(kotlin.Unit) {
+@@ -10 +12
++ }
+ """
+ )
+ }
+
+ @Test
+ fun key_withIfStatementThatReturnsUnit_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ key(
+ if (condition) {
+ doSomething()
+ } else {
+ doSomethingElse()
+ }
+ ) {
+ // Do nothing.
+ }
+ }
+
+ fun doSomething() {}
+ fun doSomethingElse() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:9: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ if (condition) {
+ ^
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 9: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- key(
+- if (condition) {
+- doSomething()
+- } else {
+- doSomethingElse()
+- }
++ if (condition) {
++ doSomething()
++ }else {
++ doSomethingElse()
++ }
++ key(
++ kotlin.Unit
+ """
+ )
+ }
+
+ @Test
+ fun key_withIfStatementCoercedToAny_doesNotReportError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test(condition: Boolean) {
+ key(
+ if (condition) {
+ doSomething()
+ } else {
+ 42
+ }
+ ) {
+ // Do nothing.
+ }
+ }
+
+ fun doSomething() {}
+ """
+ )
+ )
+ .run()
+ .expectClean()
+ }
+
+ @Test
+ fun key_twoKeys_withUnitFunctionCall_reportsError() {
+ lint()
+ .files(
+ Stubs.Remember,
+ Stubs.Composable,
+ Stubs.Composables,
+ kotlin(
+ """
+ package test
+
+ import androidx.compose.runtime.*
+
+ @Composable
+ fun Test() {
+ key(42, produceUnit()) {
+ // Do nothing.
+ }
+ }
+
+ fun produceUnit() {}
+ """
+ )
+ )
+ .run()
+ .expect(
+ """
+src/test/test.kt:8: Warning: Implicitly passing Unit as argument to keys [OpaqueUnitKey]
+ key(42, produceUnit()) {
+ ~~~~~~~~~~~~~
+0 errors, 1 warnings
+ """
+ )
+ .expectFixDiffs(
+ """
+Fix for src/test/test.kt line 8: Move expression outside of `key`'s arguments and pass `Unit` explicitly:
+@@ -8 +8
+- key(42, produceUnit()) {
++ produceUnit()
++ key(42, kotlin.Unit) {
+ """
+ )
+ }
+
+ // endregion key() test cases
+}
+/* ktlint-enable max-line-length */
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/UnrememberedStateDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/UnrememberedStateDetectorTest.kt
index 77863fd..a10571f 100644
--- a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/UnrememberedStateDetectorTest.kt
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/UnrememberedStateDetectorTest.kt
@@ -118,6 +118,7 @@
),
Stubs.Composable,
Stubs.SnapshotState,
+ Stubs.StateFactoryMarker,
Stubs.Remember
)
.skipTestModes(TestMode.TYPE_ALIAS)
@@ -315,6 +316,7 @@
),
Stubs.Composable,
Stubs.SnapshotState,
+ Stubs.StateFactoryMarker,
Stubs.Remember
)
.run()
@@ -418,5 +420,107 @@
.run()
.expectClean()
}
+
+ @Test
+ fun arbitraryStateFactoryAnnotated() {
+ lint().files(
+ kotlin(
+ """
+ package androidx.compose.runtime.foo
+
+ import androidx.compose.runtime.*
+ import androidx.compose.runtime.snapshots.StateFactoryMarker
+
+ @StateFactoryMarker
+ fun makeMyState(): State<Nothing> = TODO()
+
+ @Composable
+ fun Test() {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+
+ val lambda = @Composable {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+
+ val lambda2: @Composable () -> Unit = {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+
+ @Composable
+ fun LambdaParameter(content: @Composable () -> Unit) {}
+
+ @Composable
+ fun Test2() {
+ LambdaParameter(content = {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ })
+ LambdaParameter {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+ }
+
+ fun test3() {
+ val localLambda1 = @Composable {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+
+ val localLambda2: @Composable () -> Unit = {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+ }
+
+ @Composable
+ fun Test4() {
+ val localObject = object {
+ val foo = makeMyState()
+ val bar = remember { makeMyState() }
+ }
+ }
+ """
+ ),
+ Stubs.Composable,
+ Stubs.SnapshotState,
+ Stubs.StateFactoryMarker,
+ Stubs.Remember
+ )
+ .skipTestModes(TestMode.TYPE_ALIAS)
+ .run()
+ .expect("""
+src/androidx/compose/runtime/foo/{.kt:12: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:17: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:22: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:32: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:36: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:43: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:48: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+src/androidx/compose/runtime/foo/{.kt:56: Error: Creating a state object during composition without using remember [UnrememberedMutableState]
+ val foo = makeMyState()
+ ~~~~~~~~~~~
+8 errors, 0 warnings
+ """
+ )
+ }
}
/* ktlint-enable max-line-length */
diff --git a/compose/runtime/runtime-livedata/samples/build.gradle b/compose/runtime/runtime-livedata/samples/build.gradle
index 78130f2..436d6e9 100644
--- a/compose/runtime/runtime-livedata/samples/build.gradle
+++ b/compose/runtime/runtime-livedata/samples/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Compose UI Livedata Interop Samples"
+ name = "Compose UI Livedata Interop Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Livedata Interop System"
diff --git a/compose/runtime/runtime-livedata/samples/src/main/AndroidManifest.xml b/compose/runtime/runtime-livedata/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/runtime/runtime-livedata/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-livedata/src/androidTest/AndroidManifest.xml b/compose/runtime/runtime-livedata/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-livedata/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-livedata/src/main/AndroidManifest.xml b/compose/runtime/runtime-livedata/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-livedata/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava2/samples/build.gradle b/compose/runtime/runtime-rxjava2/samples/build.gradle
index d73b254..5c9082f4 100644
--- a/compose/runtime/runtime-rxjava2/samples/build.gradle
+++ b/compose/runtime/runtime-rxjava2/samples/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Compose RxJava 2 Integration Samples"
+ name = "Compose RxJava 2 Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose RxJava 2 Integration System"
diff --git a/compose/runtime/runtime-rxjava2/samples/src/main/AndroidManifest.xml b/compose/runtime/runtime-rxjava2/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/runtime/runtime-rxjava2/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava2/src/androidTest/AndroidManifest.xml b/compose/runtime/runtime-rxjava2/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-rxjava2/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava2/src/main/AndroidManifest.xml b/compose/runtime/runtime-rxjava2/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-rxjava2/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava3/samples/build.gradle b/compose/runtime/runtime-rxjava3/samples/build.gradle
index aa111a0..9da055d 100644
--- a/compose/runtime/runtime-rxjava3/samples/build.gradle
+++ b/compose/runtime/runtime-rxjava3/samples/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Compose RxJava 3 Integration Samples"
+ name = "Compose RxJava 3 Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2020"
description = "Contains the sample code for the Androidx Compose RxJava 3 Integration System"
diff --git a/compose/runtime/runtime-rxjava3/samples/src/main/AndroidManifest.xml b/compose/runtime/runtime-rxjava3/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/runtime/runtime-rxjava3/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava3/src/androidTest/AndroidManifest.xml b/compose/runtime/runtime-rxjava3/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-rxjava3/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-rxjava3/src/main/AndroidManifest.xml b/compose/runtime/runtime-rxjava3/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-rxjava3/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetector.kt b/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetector.kt
index 146c33a..c96aa91 100644
--- a/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetector.kt
+++ b/compose/runtime/runtime-saveable-lint/src/main/java/androidx/compose/runtime/saveable/lint/RememberSaveableDetector.kt
@@ -34,8 +34,8 @@
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiArrayType
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
/**
* [Detector] that checks `rememberSaveable` calls to make sure that a `Saver` is not passed to
diff --git a/compose/runtime/runtime-saveable/build.gradle b/compose/runtime/runtime-saveable/build.gradle
index b4d8073..d23376d 100644
--- a/compose/runtime/runtime-saveable/build.gradle
+++ b/compose/runtime/runtime-saveable/build.gradle
@@ -15,9 +15,8 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,77 +24,54 @@
id("com.android.library")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /* When updating dependencies, make sure to make the an an analogous update in the
- corresponding block below */
- api project(":compose:runtime:runtime")
- api "androidx.annotation:annotation:1.1.0"
-
- implementation(libs.kotlinStdlib)
-
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.testCore)
- testImplementation(libs.testRules)
-
- androidTestImplementation projectOrArtifact(':compose:ui:ui')
- androidTestImplementation projectOrArtifact(":compose:ui:ui-test-junit4")
- androidTestImplementation projectOrArtifact(":compose:test-utils")
- androidTestImplementation "androidx.fragment:fragment:1.3.0"
- androidTestImplementation projectOrArtifact(":activity:activity-compose")
- androidTestImplementation(libs.testUiautomator)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoCore)
-
- lintPublish(project(":compose:runtime:runtime-saveable-lint"))
-
- samples(projectOrArtifact(":compose:runtime:runtime-saveable:runtime-saveable-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /* When updating dependencies, make sure to make the an an analogous update in the
- corresponding block above */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api project(":compose:runtime:runtime")
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
implementation(libs.kotlinStdlib)
api "androidx.annotation:annotation:1.1.0"
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
}
+ }
- androidAndroidTest.dependencies {
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation project(':compose:ui:ui')
implementation project(":compose:ui:ui-test-junit4")
implementation project(":compose:test-utils")
@@ -112,10 +88,32 @@
implementation(libs.mockitoCore)
}
}
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
- dependencies {
- samples(projectOrArtifact(":compose:runtime:runtime-saveable:runtime-saveable-samples"))
- }
+}
+
+dependencies {
+ samples(projectOrArtifact(":compose:runtime:runtime-saveable:runtime-saveable-samples"))
+ lintPublish(project(":compose:runtime:runtime-saveable-lint"))
}
androidx {
diff --git a/compose/runtime/runtime-saveable/samples/build.gradle b/compose/runtime/runtime-saveable/samples/build.gradle
index 8483522..c69d961 100644
--- a/compose/runtime/runtime-saveable/samples/build.gradle
+++ b/compose/runtime/runtime-saveable/samples/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Compose Saved Instance State System Samples"
+ name = "Compose Saved Instance State System Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose Saved Instance State System"
diff --git a/compose/runtime/runtime-saveable/samples/src/main/AndroidManifest.xml b/compose/runtime/runtime-saveable/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/runtime/runtime-saveable/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
index aaec57b..ab8811c 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/ActivityRecreationTest.kt
@@ -37,9 +37,9 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.random.Random
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.random.Random
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableTest.kt b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableTest.kt
index 1d15b6c..ceffeeb 100644
--- a/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableTest.kt
+++ b/compose/runtime/runtime-saveable/src/androidAndroidTest/kotlin/androidx/compose/runtime/saveable/RememberSaveableTest.kt
@@ -26,13 +26,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/runtime/runtime-saveable/src/androidMain/AndroidManifest.xml b/compose/runtime/runtime-saveable/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime-saveable/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 0fee604..2ba2092 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -385,7 +385,7 @@
public final class PrimitiveSnapshotStateKt {
method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<?> property, float value);
}
@@ -483,19 +483,19 @@
public final class SnapshotDoubleStateKt {
method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property, double value);
}
public final class SnapshotIntStateKt {
method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<?> property, int value);
}
public final class SnapshotLongStateKt {
method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<?> property, long value);
}
@@ -514,14 +514,14 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
@@ -765,6 +765,7 @@
public static final class Snapshot.Companion {
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public boolean isApplyObserverNotificationPending();
method public void notifyObjectsInitialized();
method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
@@ -775,6 +776,7 @@
method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
+ property public final boolean isApplyObserverNotificationPending;
}
public final class SnapshotApplyConflictException extends java.lang.Exception {
@@ -885,6 +887,9 @@
method @Deprecated public void withNoObservations(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface StateFactoryMarker {
+ }
+
@kotlin.jvm.JvmDefaultWithCompatibility public interface StateObject {
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public default androidx.compose.runtime.snapshots.StateRecord? mergeRecords(androidx.compose.runtime.snapshots.StateRecord previous, androidx.compose.runtime.snapshots.StateRecord current, androidx.compose.runtime.snapshots.StateRecord applied);
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index 1fa82d6..6edfaf4 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -433,7 +433,7 @@
public final class PrimitiveSnapshotStateKt {
method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<?> property, float value);
}
@@ -532,19 +532,19 @@
public final class SnapshotDoubleStateKt {
method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property, double value);
}
public final class SnapshotIntStateKt {
method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<?> property, int value);
}
public final class SnapshotLongStateKt {
method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<?> property, long value);
}
@@ -563,14 +563,14 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
@@ -833,6 +833,7 @@
public static final class Snapshot.Companion {
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public boolean isApplyObserverNotificationPending();
method public void notifyObjectsInitialized();
method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method @androidx.compose.runtime.InternalComposeApi public int openSnapshotCount();
@@ -844,6 +845,7 @@
method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
+ property public final boolean isApplyObserverNotificationPending;
}
public final class SnapshotApplyConflictException extends java.lang.Exception {
@@ -965,6 +967,9 @@
method @Deprecated public void withNoObservations(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface StateFactoryMarker {
+ }
+
@kotlin.jvm.JvmDefaultWithCompatibility public interface StateObject {
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public default androidx.compose.runtime.snapshots.StateRecord? mergeRecords(androidx.compose.runtime.snapshots.StateRecord previous, androidx.compose.runtime.snapshots.StateRecord current, androidx.compose.runtime.snapshots.StateRecord applied);
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 5ce4dbc..fae054f 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -417,7 +417,7 @@
public final class PrimitiveSnapshotStateKt {
method public static inline operator float getValue(androidx.compose.runtime.FloatState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableFloatState mutableFloatStateOf(float value);
method public static inline operator void setValue(androidx.compose.runtime.MutableFloatState, Object? thisObj, kotlin.reflect.KProperty<?> property, float value);
}
@@ -519,19 +519,19 @@
public final class SnapshotDoubleStateKt {
method public static inline operator double getValue(androidx.compose.runtime.DoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableDoubleState mutableDoubleStateOf(double value);
method public static inline operator void setValue(androidx.compose.runtime.MutableDoubleState, Object? thisObj, kotlin.reflect.KProperty<?> property, double value);
}
public final class SnapshotIntStateKt {
method public static inline operator int getValue(androidx.compose.runtime.IntState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableIntState mutableIntStateOf(int value);
method public static inline operator void setValue(androidx.compose.runtime.MutableIntState, Object? thisObj, kotlin.reflect.KProperty<?> property, int value);
}
public final class SnapshotLongStateKt {
method public static inline operator long getValue(androidx.compose.runtime.LongState, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static androidx.compose.runtime.MutableLongState mutableLongStateOf(long value);
method public static inline operator void setValue(androidx.compose.runtime.MutableLongState, Object? thisObj, kotlin.reflect.KProperty<?> property, long value);
}
@@ -550,14 +550,14 @@
public final class SnapshotStateKt {
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> collectAsState(kotlinx.coroutines.flow.StateFlow<? extends T>, optional kotlin.coroutines.CoroutineContext context);
method @androidx.compose.runtime.Composable public static <T extends R, R> androidx.compose.runtime.State<R> collectAsState(kotlinx.coroutines.flow.Flow<? extends T>, R initial, optional kotlin.coroutines.CoroutineContext context);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
- method public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(kotlin.jvm.functions.Function0<? extends T> calculation);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.State<T> derivedStateOf(androidx.compose.runtime.SnapshotMutationPolicy<T> policy, kotlin.jvm.functions.Function0<? extends T> calculation);
method public static inline operator <T> T getValue(androidx.compose.runtime.State<? extends T>, Object? thisObj, kotlin.reflect.KProperty<?> property);
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
- method public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
- method public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
- method public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.snapshots.SnapshotStateList<T> mutableStateListOf(T?... elements);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf();
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <K, V> androidx.compose.runtime.snapshots.SnapshotStateMap<K,V> mutableStateMapOf(kotlin.Pair<? extends K,? extends V>... pairs);
+ method @androidx.compose.runtime.snapshots.StateFactoryMarker public static <T> androidx.compose.runtime.MutableState<T> mutableStateOf(T value, optional androidx.compose.runtime.SnapshotMutationPolicy<T> policy);
method public static <T> androidx.compose.runtime.SnapshotMutationPolicy<T> neverEqualPolicy();
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
method @androidx.compose.runtime.Composable public static <T> androidx.compose.runtime.State<T> produceState(T initialValue, Object? key1, kotlin.jvm.functions.Function2<? super androidx.compose.runtime.ProduceStateScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> producer);
@@ -806,6 +806,7 @@
method @kotlin.PublishedApi internal androidx.compose.runtime.snapshots.Snapshot createNonObservableSnapshot();
method public androidx.compose.runtime.snapshots.Snapshot getCurrent();
method public inline <T> T global(kotlin.jvm.functions.Function0<? extends T> block);
+ method public boolean isApplyObserverNotificationPending();
method public void notifyObjectsInitialized();
method public <T> T observe(optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? readObserver, optional kotlin.jvm.functions.Function1<java.lang.Object,kotlin.Unit>? writeObserver, kotlin.jvm.functions.Function0<? extends T> block);
method public androidx.compose.runtime.snapshots.ObserverHandle registerApplyObserver(kotlin.jvm.functions.Function2<? super java.util.Set<?>,? super androidx.compose.runtime.snapshots.Snapshot,kotlin.Unit> observer);
@@ -818,6 +819,7 @@
method public inline <R> R withMutableSnapshot(kotlin.jvm.functions.Function0<? extends R> block);
method public inline <T> T withoutReadObservation(kotlin.jvm.functions.Function0<? extends T> block);
property public final androidx.compose.runtime.snapshots.Snapshot current;
+ property public final boolean isApplyObserverNotificationPending;
}
public final class SnapshotApplyConflictException extends java.lang.Exception {
@@ -935,6 +937,9 @@
method @Deprecated public void withNoObservations(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=kotlin.annotation.AnnotationTarget.FUNCTION) public @interface StateFactoryMarker {
+ }
+
@kotlin.jvm.JvmDefaultWithCompatibility public interface StateObject {
method public androidx.compose.runtime.snapshots.StateRecord getFirstStateRecord();
method public default androidx.compose.runtime.snapshots.StateRecord? mergeRecords(androidx.compose.runtime.snapshots.StateRecord previous, androidx.compose.runtime.snapshots.StateRecord current, androidx.compose.runtime.snapshots.StateRecord applied);
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/ComposeBenchmark.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/ComposeBenchmark.kt
index 56ef072..147cc7b 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/ComposeBenchmark.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/ComposeBenchmark.kt
@@ -21,9 +21,9 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/DbMonsterBenchmark.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/DbMonsterBenchmark.kt
index 5f134b7..ad91d96 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/DbMonsterBenchmark.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/DbMonsterBenchmark.kt
@@ -25,12 +25,12 @@
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import kotlin.random.Random
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
-import kotlin.random.Random
/**
* This is an implementation of a classic web perf benchmark "dbmonster". This can provide insight into apps with
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SiblingBenchmark.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SiblingBenchmark.kt
index 391d120..da437421 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SiblingBenchmark.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SiblingBenchmark.kt
@@ -25,11 +25,11 @@
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.test.annotation.UiThreadTest
import androidx.test.filters.LargeTest
+import kotlin.random.Random
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.random.Random
/**
* Managing “lists” of components that are siblings in Compose and other declarative reactive frameworks ends up
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SnapshotStateObserverBenchmark.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SnapshotStateObserverBenchmark.kt
index 4fe328d..055b6f9 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SnapshotStateObserverBenchmark.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/SnapshotStateObserverBenchmark.kt
@@ -21,8 +21,8 @@
import android.os.Looper
import androidx.benchmark.junit4.measureRepeated
import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotStateObserver
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/deeptree/DeepTree.kt b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/deeptree/DeepTree.kt
index 45e8e80..c481a56 100644
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/deeptree/DeepTree.kt
+++ b/compose/runtime/runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/runtime/benchmark/deeptree/DeepTree.kt
@@ -16,8 +16,8 @@
package androidx.compose.runtime.benchmark.deeptree
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
diff --git a/compose/runtime/runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml b/compose/runtime/runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index df93a1a..0000000
--- a/compose/runtime/runtime/compose-runtime-benchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- Copyright 2019 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 />
\ No newline at end of file
diff --git a/compose/runtime/runtime/integration-tests/build.gradle b/compose/runtime/runtime/integration-tests/build.gradle
index b9b65e5..f62e6ba 100644
--- a/compose/runtime/runtime/integration-tests/build.gradle
+++ b/compose/runtime/runtime/integration-tests/build.gradle
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
@@ -24,69 +23,63 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidTestImplementation(projectOrArtifact(":compose:ui:ui"))
- androidTestImplementation(projectOrArtifact(":compose:material:material"))
- androidTestImplementation(projectOrArtifact(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":compose:runtime:runtime"))
- androidTestImplementation(projectOrArtifact(":compose:test-utils"))
- androidTestImplementation(projectOrArtifact(":activity:activity-compose"))
-
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.kotlinTestJunit)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.kotlinStdlib)
- androidTestImplementation(libs.kotlinReflect)
- androidTestImplementation(libs.truth)
- }
-}
-
-android {
- namespace "androidx.compose.runtime.integrationtests"
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
implementation(libs.kotlinCoroutinesCore)
implementation(projectOrArtifact(":compose:ui:ui"))
}
- jvmMain.dependencies {
+ }
+
+ commonTest {
+ dependencies {
+ implementation(kotlin("test-junit"))
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
implementation(libs.kotlinStdlib)
api(libs.kotlinCoroutinesCore)
}
- androidMain.dependencies {
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api(libs.kotlinCoroutinesAndroid)
api("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core-ktx:1.1.0")
}
- desktopMain.dependencies {
- api(libs.kotlinCoroutinesSwing)
- }
+ }
- commonTest.dependencies {
- implementation(kotlin("test-junit"))
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api(libs.kotlinCoroutinesSwing)
+ }
}
- androidAndroidTest.dependencies {
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(projectOrArtifact(":compose:ui:ui"))
implementation(projectOrArtifact(":compose:material:material"))
implementation(projectOrArtifact(":compose:ui:ui-test-junit4"))
@@ -98,9 +91,23 @@
implementation(libs.truth)
}
}
+
+ androidTest {
+ dependsOn(jvmTest)
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
}
+android {
+ namespace "androidx.compose.runtime.integrationtests"
+}
+
tasks.withType(KotlinCompile).configureEach {
kotlinOptions {
incremental = false
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ComposeIntoTests.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ComposeIntoTests.kt
index e22971c..79df8bd 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ComposeIntoTests.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ComposeIntoTests.kt
@@ -21,10 +21,6 @@
import androidx.core.os.HandlerCompat
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import org.junit.Assert.assertEquals
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.lang.ref.PhantomReference
import java.lang.ref.ReferenceQueue
import java.util.concurrent.CountDownLatch
@@ -32,6 +28,10 @@
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ComposeIntoTests : BaseComposeTest() {
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
index f34d918..1ab873f 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/EmittableComposer.kt
@@ -17,8 +17,8 @@
import android.view.View
import android.widget.Button
-import android.widget.TextView
import android.widget.LinearLayout
+import android.widget.TextView
import androidx.compose.ui.viewinterop.AndroidView
@Suppress("UNUSED_PARAMETER")
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/FlowAdapterTest.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/FlowAdapterTest.kt
index fdb2a56..7d7a083 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/FlowAdapterTest.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/FlowAdapterTest.kt
@@ -20,6 +20,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.CoroutineContext
+import kotlin.test.assertNotNull
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -27,8 +29,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.coroutines.CoroutineContext
-import kotlin.test.assertNotNull
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ProduceStateTests.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ProduceStateTests.kt
index a550adb..ad0091f 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ProduceStateTests.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/ProduceStateTests.kt
@@ -16,14 +16,14 @@
package androidx.compose.runtime
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import kotlin.test.assertEquals
import kotlinx.coroutines.channels.Channel
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import kotlin.test.assertEquals
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SideEffectTests.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SideEffectTests.kt
index f156f72..da25ff8 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SideEffectTests.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SideEffectTests.kt
@@ -19,18 +19,18 @@
import android.view.Choreographer
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.ReceiveChannel
-import kotlinx.coroutines.channels.SendChannel
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull
import kotlin.test.assertSame
import kotlin.test.assertTrue
import kotlin.test.fail
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.ReceiveChannel
+import kotlinx.coroutines.channels.SendChannel
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
@Suppress("UNUSED_VARIABLE")
@MediumTest
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SuspendingEffectsTests.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SuspendingEffectsTests.kt
index 09cdb86..243e11a 100644
--- a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SuspendingEffectsTests.kt
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/SuspendingEffectsTests.kt
@@ -19,6 +19,12 @@
import android.view.Choreographer
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertSame
+import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
@@ -26,12 +32,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertNotEquals
-import kotlin.test.assertNotNull
-import kotlin.test.assertSame
-import kotlin.test.assertTrue
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/runtime/runtime/integration-tests/src/androidMain/AndroidManifest.xml b/compose/runtime/runtime/integration-tests/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/runtime/runtime/integration-tests/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/runtime/runtime/samples/build.gradle b/compose/runtime/runtime/samples/build.gradle
index 376b851..a8c279f 100644
--- a/compose/runtime/runtime/samples/build.gradle
+++ b/compose/runtime/runtime/samples/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "AndroidX Compose Runtime Samples"
+ name = "Compose Runtime Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Compose runtime"
diff --git a/compose/runtime/runtime/samples/src/main/AndroidManifest.xml b/compose/runtime/runtime/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 67aa632..0000000
--- a/compose/runtime/runtime/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/CustomTreeCompositionSamples.kt b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/CustomTreeCompositionSamples.kt
index 688760c..28d0089 100644
--- a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/CustomTreeCompositionSamples.kt
+++ b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/CustomTreeCompositionSamples.kt
@@ -19,9 +19,9 @@
import androidx.annotation.Sampled
import androidx.compose.runtime.AbstractApplier
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.CompositionContext
-import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
diff --git a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/ModelSamples.kt b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/ModelSamples.kt
index d1c516f..7080f39 100644
--- a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/ModelSamples.kt
+++ b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/ModelSamples.kt
@@ -18,9 +18,9 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
-import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateListSamples.kt b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateListSamples.kt
index db5044c..24f0b6f 100644
--- a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateListSamples.kt
+++ b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateListSamples.kt
@@ -20,9 +20,9 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
-import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
diff --git a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateMapSample.kt b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateMapSample.kt
index 9d8b1ec3..8a6f4df 100644
--- a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateMapSample.kt
+++ b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/MutableStateMapSample.kt
@@ -20,9 +20,9 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
-import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
diff --git a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/SnapshotSamples.kt b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/SnapshotSamples.kt
index c6b6ac0..937674e 100644
--- a/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/SnapshotSamples.kt
+++ b/compose/runtime/runtime/samples/src/main/java/androidx/compose/runtime/samples/SnapshotSamples.kt
@@ -21,8 +21,8 @@
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
-import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshotFlow
+import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.asContextElement
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
diff --git a/compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/snapshots/ParcelableMutableStateTests.kt b/compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/snapshots/ParcelableMutableStateTests.kt
index dbb8932..42e45c5 100644
--- a/compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/snapshots/ParcelableMutableStateTests.kt
+++ b/compose/runtime/runtime/src/androidAndroidTest/kotlin/androidx/compose/runtime/snapshots/ParcelableMutableStateTests.kt
@@ -23,10 +23,10 @@
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.referentialEqualityPolicy
import androidx.compose.runtime.structuralEqualityPolicy
+import kotlin.test.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.test.assertEquals
@RunWith(Parameterized::class)
class ParcelableMutableStateTests(
diff --git a/compose/runtime/runtime/src/androidMain/AndroidManifest.xml b/compose/runtime/runtime/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index b47339d..0000000
--- a/compose/runtime/runtime/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
index cec11b2..1718d92 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/BroadcastFrameClock.kt
@@ -17,10 +17,10 @@
package androidx.compose.runtime
import androidx.compose.runtime.snapshots.fastForEach
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.Continuation
import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* A simple frame clock.
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
index 7aade6c..06356b3 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt
@@ -673,35 +673,39 @@
override fun prepareCompose(block: () -> Unit) = composer.prepareCompose(block)
- private fun addPendingInvalidationsLocked(values: Set<Any>, forgetConditionalScopes: Boolean) {
- var invalidated: HashSet<RecomposeScopeImpl>? = null
-
- fun invalidate(value: Any) {
- observations.forEachScopeOf(value) { scope ->
- if (
- !observationsProcessed.remove(value, scope) &&
- scope.invalidateForResult(value) != InvalidationResult.IGNORED
- ) {
- if (scope.isConditional && !forgetConditionalScopes) {
- conditionallyInvalidatedScopes.add(scope)
- } else {
- val set = invalidated
- ?: HashSet<RecomposeScopeImpl>().also {
- invalidated = it
- }
- set.add(scope)
- }
+ private fun HashSet<RecomposeScopeImpl>?.addPendingInvalidationsLocked(
+ value: Any,
+ forgetConditionalScopes: Boolean
+ ): HashSet<RecomposeScopeImpl>? {
+ var set = this
+ observations.forEachScopeOf(value) { scope ->
+ if (
+ !observationsProcessed.remove(value, scope) &&
+ scope.invalidateForResult(value) != InvalidationResult.IGNORED
+ ) {
+ if (scope.isConditional && !forgetConditionalScopes) {
+ conditionallyInvalidatedScopes.add(scope)
+ } else {
+ if (set == null) set = HashSet()
+ set?.add(scope)
}
}
}
+ return set
+ }
+
+ private fun addPendingInvalidationsLocked(values: Set<Any>, forgetConditionalScopes: Boolean) {
+ var invalidated: HashSet<RecomposeScopeImpl>? = null
values.fastForEach { value ->
if (value is RecomposeScopeImpl) {
value.invalidateForResult(null)
} else {
- invalidate(value)
+ invalidated =
+ invalidated.addPendingInvalidationsLocked(value, forgetConditionalScopes)
derivedStates.forEachScopeOf(value) {
- invalidate(it)
+ invalidated =
+ invalidated.addPendingInvalidationsLocked(it, forgetConditionalScopes)
}
}
}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/DerivedState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/DerivedState.kt
index 4fa3504..a131262 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/DerivedState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/DerivedState.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.collection.IdentityArrayMap
import androidx.compose.runtime.collection.MutableVector
import androidx.compose.runtime.snapshots.Snapshot
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.current
@@ -279,6 +280,7 @@
*
* @param calculation the calculation to create the value this state object represents.
*/
+@StateFactoryMarker
fun <T> derivedStateOf(
calculation: () -> T,
): State<T> = DerivedSnapshotState(calculation, null)
@@ -296,6 +298,7 @@
* @param policy mutation policy to control when changes to the [calculation] result trigger update.
* @param calculation the calculation to create the value this state object represents.
*/
+@StateFactoryMarker
fun <T> derivedStateOf(
policy: SnapshotMutationPolicy<T>,
calculation: () -> T,
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
index 1254875..183f5fe 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt
@@ -17,11 +17,12 @@
package androidx.compose.runtime
import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
-import kotlin.coroutines.EmptyCoroutineContext
/**
* Schedule [effect] to run when the current composition completes successfully and applies
@@ -284,17 +285,18 @@
private var job: Job? = null
override fun onRemembered() {
+ // This should never happen but is left here for safety
job?.cancel("Old job was still running!")
job = scope.launch(block = task)
}
override fun onForgotten() {
- job?.cancel()
+ job?.cancel(LeftCompositionCancellationException())
job = null
}
override fun onAbandoned() {
- job?.cancel()
+ job?.cancel(LeftCompositionCancellationException())
job = null
}
}
@@ -384,6 +386,12 @@
remember(key1, key2, key3) { LaunchedEffectImpl(applyContext, block) }
}
+private class LeftCompositionCancellationException : CancellationException(
+ "The coroutine scope left the composition"
+) {
+ override fun fillInStackTrace(): Throwable = this
+}
+
/**
* When [LaunchedEffect] enters the composition it will launch [block] into the composition's
* [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when
@@ -416,11 +424,11 @@
}
override fun onForgotten() {
- coroutineScope.cancel()
+ coroutineScope.cancel(LeftCompositionCancellationException())
}
override fun onAbandoned() {
- coroutineScope.cancel()
+ coroutineScope.cancel(LeftCompositionCancellationException())
}
}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Latch.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Latch.kt
index 6be6d1a..8bb366f 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Latch.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Latch.kt
@@ -16,9 +16,9 @@
package androidx.compose.runtime
-import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* A boolean open or closed latch for awaiting a single repeating event, like pending
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
index 9fa259d..c6227a5 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/MonotonicFrameClock.kt
@@ -16,9 +16,9 @@
package androidx.compose.runtime
+import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
-import androidx.compose.runtime.internal.JvmDefaultWithCompatibility
/**
* Provides a time source for display frames and the ability to perform an action on the next frame.
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
index cc4584c..faf8739 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt
@@ -612,7 +612,12 @@
// Perform apply changes
try {
- toComplete += toApply
+ // We could do toComplete += toApply but doing it like below
+ // avoids unncessary allocations since toApply is a mutable list
+ // toComplete += toApply
+ toApply.fastForEach { composition ->
+ toComplete.add(composition)
+ }
toApply.fastForEach { composition ->
composition.applyChanges()
}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
index f4fb14b..8521c5a 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotDoubleState.kt
@@ -22,6 +22,7 @@
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.overwritable
@@ -46,6 +47,7 @@
* @see mutableLongStateOf
* @see mutableFloatStateOf
*/
+@StateFactoryMarker
fun mutableDoubleStateOf(
value: Double
): MutableDoubleState = createSnapshotMutableDoubleState(value)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
index df4a2f7..fa6bfe5 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotFloatState.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.overwritable
@@ -45,6 +46,7 @@
* @see mutableLongStateOf
* @see mutableDoubleStateOf
*/
+@StateFactoryMarker
fun mutableFloatStateOf(
value: Float
): MutableFloatState = createSnapshotMutableFloatState(value)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
index ec700ee..e43f884 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotIntState.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.overwritable
@@ -45,6 +46,7 @@
* @see mutableFloatStateOf
* @see mutableDoubleStateOf
*/
+@StateFactoryMarker
fun mutableIntStateOf(
value: Int
): MutableIntState = createSnapshotMutableIntState(value)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
index a95ae2e..a22c5c4 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotLongState.kt
@@ -22,6 +22,7 @@
import androidx.compose.runtime.snapshots.AutoboxingStateValueProperty
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotMutableState
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.overwritable
@@ -46,6 +47,7 @@
* @see mutableFloatStateOf
* @see mutableDoubleStateOf
*/
+@StateFactoryMarker
fun mutableLongStateOf(
value: Long
): MutableLongState = createSnapshotMutableLongState(value)
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
index d408eb3..60e2885 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt
@@ -22,6 +22,7 @@
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.runtime.snapshots.SnapshotStateMap
+import androidx.compose.runtime.snapshots.StateFactoryMarker
import androidx.compose.runtime.snapshots.StateObject
import androidx.compose.runtime.snapshots.StateRecord
import androidx.compose.runtime.snapshots.overwritable
@@ -53,6 +54,7 @@
* @see mutableFloatStateOf
* @see mutableDoubleStateOf
*/
+@StateFactoryMarker
fun <T> mutableStateOf(
value: T,
policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
@@ -223,6 +225,7 @@
* @see MutableList
* @see Snapshot.takeSnapshot
*/
+@StateFactoryMarker
fun <T> mutableStateListOf() = SnapshotStateList<T>()
/**
@@ -233,6 +236,7 @@
* @see MutableList
* @see Snapshot.takeSnapshot
*/
+@StateFactoryMarker
fun <T> mutableStateListOf(vararg elements: T) =
SnapshotStateList<T>().also { it.addAll(elements.toList()) }
@@ -252,6 +256,7 @@
* @see MutableMap
* @see Snapshot.takeSnapshot
*/
+@StateFactoryMarker
fun <K, V> mutableStateMapOf() = SnapshotStateMap<K, V>()
/**
@@ -262,6 +267,7 @@
* @see MutableMap
* @see Snapshot.takeSnapshot
*/
+@StateFactoryMarker
fun <K, V> mutableStateMapOf(vararg pairs: Pair<K, V>) =
SnapshotStateMap<K, V>().apply { putAll(pairs.toMap()) }
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
index 06d1f47..d5d312b 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt
@@ -16,6 +16,7 @@
package androidx.compose.runtime.snapshots
+import androidx.compose.runtime.AtomicInt
import androidx.compose.runtime.AtomicReference
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisallowComposableCalls
@@ -280,6 +281,13 @@
val current get() = currentSnapshot()
/**
+ * Returns whether any threads are currently in the process of notifying observers about
+ * changes to the global snapshot.
+ */
+ val isApplyObserverNotificationPending: Boolean
+ get() = pendingApplyObserverCount.get() > 0
+
+ /**
* Take a snapshot of the current value of all state objects. The values are preserved until
* [Snapshot.dispose] is called on the result.
*
@@ -1767,20 +1775,36 @@
return result
}
+/**
+ * Counts the number of threads currently inside `advanceGlobalSnapshot`, notifying observers of
+ * changes to the global snapshot.
+ */
+private var pendingApplyObserverCount = AtomicInt(0)
+
private fun <T> advanceGlobalSnapshot(block: (invalid: SnapshotIdSet) -> T): T {
var previousGlobalSnapshot = snapshotInitializer as GlobalSnapshot
+
+ var modified: IdentityArraySet<StateObject>? = null // Effectively val; can be with contracts
val result = sync {
previousGlobalSnapshot = currentGlobalSnapshot.get()
+ modified = previousGlobalSnapshot.modified
+ if (modified != null) {
+ pendingApplyObserverCount.add(1)
+ }
takeNewGlobalSnapshot(previousGlobalSnapshot, block)
}
// If the previous global snapshot had any modified states then notify the registered apply
// observers.
- val modified = previousGlobalSnapshot.modified
- if (modified != null) {
- val observers: List<(Set<Any>, Snapshot) -> Unit> = sync { applyObservers.toMutableList() }
- observers.fastForEach { observer ->
- observer(modified, previousGlobalSnapshot)
+ modified?.let {
+ try {
+ val observers: List<(Set<Any>, Snapshot) -> Unit> =
+ sync { applyObservers.toMutableList() }
+ observers.fastForEach { observer ->
+ observer(it, previousGlobalSnapshot)
+ }
+ } finally {
+ pendingApplyObserverCount.add(-1)
}
}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/StateFactoryMarker.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/StateFactoryMarker.kt
new file mode 100644
index 0000000..7555423
--- /dev/null
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/StateFactoryMarker.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.runtime.snapshots
+
+/**
+ * Designates a function as a factory function that produces a State object. Since State factory
+ * functions create and initialize a state, they should usually only be called once per state value
+ * initialization. This annotation causes all invocations of marked state factory functions to be
+ * checked to ensure that they are not called directly inside the body of a [Composable] function
+ * and are instead wrapped with an appropriate [remember] call.
+ */
+@MustBeDocumented
+@Target(AnnotationTarget.FUNCTION)
+@Retention(AnnotationRetention.BINARY)
+annotation class StateFactoryMarker
\ No newline at end of file
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/BroadcastFrameClockTest.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/BroadcastFrameClockTest.kt
index 21e14a5..a0f493d 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/BroadcastFrameClockTest.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/BroadcastFrameClockTest.kt
@@ -16,15 +16,15 @@
package androidx.compose.runtime.dispatch
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import kotlin.test.Test
-import kotlin.test.assertEquals
-import kotlin.test.assertTrue
@ExperimentalCoroutinesApi
class BroadcastFrameClockTest {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
index 468fd71..2dc9e36 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/CompositionLocalTests.kt
@@ -26,12 +26,12 @@
import androidx.compose.runtime.mock.expectNoChanges
import androidx.compose.runtime.mock.revalidate
import androidx.compose.runtime.mock.validate
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
// Create a normal (dynamic) CompositionLocal with a string value
val LocalSomeTextComposition = compositionLocalOf { "Default" }
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt
index 04c5b531..edfbac3 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt
@@ -19,11 +19,10 @@
package androidx.compose.runtime
import androidx.compose.runtime.mock.CompositionTestScope
+import androidx.compose.runtime.mock.View
import androidx.compose.runtime.mock.compositionTest
import androidx.compose.runtime.tooling.CompositionData
import androidx.compose.runtime.tooling.CompositionGroup
-import androidx.compose.runtime.mock.View
-
import kotlin.test.Test
class GroupSizeValidationTests {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/LatchTest.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/LatchTest.kt
index 3367da5..041d795 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/LatchTest.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/LatchTest.kt
@@ -16,13 +16,13 @@
package androidx.compose.runtime
+import kotlin.test.Test
+import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withTimeout
-import kotlin.test.Test
-import kotlin.test.assertTrue
@ExperimentalCoroutinesApi
class LatchTest {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/SnapshotFlowTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/SnapshotFlowTests.kt
index 8e7e8fc..13b1ba4 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/SnapshotFlowTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/SnapshotFlowTests.kt
@@ -17,6 +17,8 @@
package androidx.compose.runtime
import androidx.compose.runtime.snapshots.Snapshot
+import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.launchIn
@@ -24,8 +26,6 @@
import kotlinx.coroutines.plus
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
-import kotlin.test.Test
-import kotlin.test.assertEquals
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("RemoveExplicitTypeArguments")
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/CompositionTest.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/CompositionTest.kt
index 15e98c8..4a3d14b 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/CompositionTest.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/CompositionTest.kt
@@ -22,14 +22,14 @@
import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.Recomposer
import androidx.compose.runtime.snapshots.Snapshot
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-import kotlinx.coroutines.test.TestCoroutineScheduler
@OptIn(InternalComposeApi::class, ExperimentalCoroutinesApi::class)
fun compositionTest(block: suspend CompositionTestScope.() -> Unit) = runTest {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/Views.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/Views.kt
index a5617c9..8babf4b 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/Views.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/mock/Views.kt
@@ -18,9 +18,9 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ComposeNode
-import androidx.compose.runtime.ReusableComposeNode
-import androidx.compose.runtime.NonRestartableComposable
import androidx.compose.runtime.ComposeNodeLifecycleCallback
+import androidx.compose.runtime.NonRestartableComposable
+import androidx.compose.runtime.ReusableComposeNode
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.rememberUpdatedState
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/DerivedSnapshotStateTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/DerivedSnapshotStateTests.kt
index 3457ab2..0100bb8 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/DerivedSnapshotStateTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/DerivedSnapshotStateTests.kt
@@ -24,9 +24,9 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot.Companion.openSnapshotCount
-import kotlin.test.Ignore
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
+import kotlin.test.Ignore
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotContextElementTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotContextElementTests.kt
index 762d20c..58cdedd 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotContextElementTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotContextElementTests.kt
@@ -19,12 +19,12 @@
import androidx.compose.runtime.ExperimentalComposeApi
import kotlin.test.Test
import kotlin.test.assertSame
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.withContext
@OptIn(ExperimentalComposeApi::class, ExperimentalCoroutinesApi::class)
class SnapshotContextElementTests {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
index 886b51c..d788ffe 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateListTests.kt
@@ -17,18 +17,18 @@
package androidx.compose.runtime.snapshots
import androidx.compose.runtime.mutableStateListOf
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.runTest
import kotlinx.test.IgnoreJsTarget
class SnapshotStateListTests {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
index be1db36..dab7a74 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMapTests.kt
@@ -19,18 +19,18 @@
package androidx.compose.runtime.snapshots
import androidx.compose.runtime.mutableStateMapOf
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.runTest
import kotlinx.test.IgnoreJsTarget
class SnapshotStateMapTests {
diff --git a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
index 8efc203..3ec3fb7 100644
--- a/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorCommonTest/kotlin/androidx/compose/runtime/snapshots/SnapshotTests.kt
@@ -269,6 +269,33 @@
}
@Test
+ fun applyObserverNotificationIsPendingWhileSendingApplyNotifications() {
+ val state = mutableStateOf(0)
+
+ var notificationsPendingWhileObserving = false
+ val unregister = Snapshot.registerApplyObserver { _, _ ->
+ notificationsPendingWhileObserving = Snapshot.isApplyObserverNotificationPending
+ }
+
+ try {
+ // Normally not pending
+ assertFalse(Snapshot.isApplyObserverNotificationPending)
+
+ state.value = 1
+
+ Snapshot.sendApplyNotifications()
+
+ // Was pending while sending apply notifications
+ assertTrue(notificationsPendingWhileObserving)
+
+ // Not pending afterwards
+ assertFalse(Snapshot.isApplyObserverNotificationPending)
+ } finally {
+ unregister.dispose()
+ }
+ }
+
+ @Test
fun aNestedSnapshotCanBeTaken() {
val state = mutableStateOf<Int>(0)
diff --git a/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/JvmCompositionTests.kt b/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/JvmCompositionTests.kt
index 6e5c2d70..d6b657f 100644
--- a/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/JvmCompositionTests.kt
+++ b/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/JvmCompositionTests.kt
@@ -18,22 +18,22 @@
package androidx.compose.runtime
import androidx.compose.runtime.mock.EmptyApplier
-import androidx.compose.runtime.mock.compositionTest
import androidx.compose.runtime.mock.Text
import androidx.compose.runtime.mock.View
import androidx.compose.runtime.mock.ViewApplier
+import androidx.compose.runtime.mock.compositionTest
import androidx.compose.runtime.mock.expectChanges
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.runtime.snapshots.SnapshotStateObserver
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
import kotlin.concurrent.thread
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
-import kotlinx.coroutines.delay
import kotlin.test.Test
import kotlin.test.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
@Stable
@OptIn(InternalComposeApi::class)
diff --git a/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/MonotonicFrameClockTest.kt b/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/MonotonicFrameClockTest.kt
index b555bea..a9b8eba 100644
--- a/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/MonotonicFrameClockTest.kt
+++ b/compose/runtime/runtime/src/nonEmulatorJvmTest/kotlin/androidx/compose/runtime/MonotonicFrameClockTest.kt
@@ -16,11 +16,11 @@
package androidx.compose.runtime
-import kotlinx.coroutines.runBlocking
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertSame
+import kotlinx.coroutines.runBlocking
class MonotonicFrameClockTest {
@ExperimentalComposeApi
diff --git a/compose/test-utils/build.gradle b/compose/test-utils/build.gradle
index 5b5d26c..46eecc3 100644
--- a/compose/test-utils/build.gradle
+++ b/compose/test-utils/build.gradle
@@ -14,10 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
import androidx.build.LibraryType
import androidx.build.Publish
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,89 +23,93 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = false // b/276387374 TODO: KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
-
- api("androidx.activity:activity:1.2.0")
- api(projectOrArtifact(":compose:ui:ui-test-junit4"))
- api(project(":test:screenshot:screenshot"))
-
- implementation(libs.kotlinStdlibCommon)
- implementation(projectOrArtifact(":compose:runtime:runtime"))
- implementation(projectOrArtifact(":compose:ui:ui-unit"))
- implementation(projectOrArtifact(":compose:ui:ui-graphics"))
- implementation("androidx.activity:activity-compose:1.3.1")
- // old version of common-java8 conflicts with newer version, because both have
- // DefaultLifecycleEventObserver.
- // Outside of androidx this is resolved via constraint added to lifecycle-common,
- // but it doesn't work in androidx.
- // See aosp/1804059
- implementation("androidx.lifecycle:lifecycle-common-java8:2.5.1")
- implementation(libs.testCore)
- implementation(libs.testRules)
-
- // This has stub APIs for access to legacy Android APIs, so we don't want
- // any dependency on this module.
- compileOnly(projectOrArtifact(":compose:ui:ui-android-stubs"))
-
- testImplementation(libs.truth)
-
- androidTestImplementation(libs.truth)
- androidTestImplementation(projectOrArtifact(":compose:material:material"))
- }
-}
-
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
implementation(projectOrArtifact(":compose:runtime:runtime"))
implementation(projectOrArtifact(":compose:ui:ui-unit"))
implementation(projectOrArtifact(":compose:ui:ui-graphics"))
implementation(projectOrArtifact(":compose:ui:ui-test-junit4"))
}
+ }
+ androidMain.dependencies {
+ api("androidx.activity:activity:1.2.0")
+ implementation "androidx.activity:activity-compose:1.3.1"
+ api(projectOrArtifact(":compose:ui:ui-test-junit4"))
+ api(project(":test:screenshot:screenshot"))
+ // This has stub APIs for access to legacy Android APIs, so we don't want
+ // any dependency on this module.
+ compileOnly(projectOrArtifact(":compose:ui:ui-android-stubs"))
+ implementation(libs.testCore)
+ implementation(libs.testRules)
+ }
- androidMain.dependencies {
- api("androidx.activity:activity:1.2.0")
- implementation "androidx.activity:activity-compose:1.3.1"
- api(projectOrArtifact(":compose:ui:ui-test-junit4"))
- api(project(":test:screenshot:screenshot"))
- // This has stub APIs for access to legacy Android APIs, so we don't want
- // any dependency on this module.
- compileOnly(projectOrArtifact(":compose:ui:ui-android-stubs"))
- implementation(libs.testCore)
- implementation(libs.testRules)
+ commonTest {
+ dependencies {
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.truth)
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
}
+ }
- androidAndroidTest.dependencies {
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.truth)
implementation(projectOrArtifact(":compose:material:material"))
}
}
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
+ }
+ }
}
}
diff --git a/compose/ui/ui-android-stubs/src/main/AndroidManifest.xml b/compose/ui/ui-android-stubs/src/main/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/compose/ui/ui-android-stubs/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/compose/ui/ui-geometry/build.gradle b/compose/ui/ui-geometry/build.gradle
index 1a05daf..15e6e16 100644
--- a/compose/ui/ui-geometry/build.gradle
+++ b/compose/ui/ui-geometry/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,53 +23,69 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.annotation:annotation:1.1.0")
-
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation(project(":compose:ui:ui-util"))
- implementation(libs.kotlinStdlib)
-
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.kotlinTest)
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
- implementation(project(":compose:runtime:runtime"))
+ implementation("androidx.compose.runtime:runtime:1.2.1")
implementation(project(":compose:ui:ui-util"))
}
- jvmMain.dependencies {
+ }
+
+ commonTest {
+ dependencies {
+ implementation(kotlin("test-junit"))
+ }
+ }
+
+ jvmMain {
+ dependencies {
implementation(libs.kotlinStdlib)
}
- androidMain.dependencies {
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
}
- commonTest.dependencies {
- implementation(kotlin("test-junit"))
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(project(":compose:runtime:runtime"))
+ }
+ }
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ androidTest {
+ dependsOn(jvmTest)
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
}
}
}
diff --git a/compose/ui/ui-geometry/src/androidMain/AndroidManifest.xml b/compose/ui/ui-geometry/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/compose/ui/ui-geometry/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/compose/ui/ui-geometry/src/test/kotlin/androidx/compose/ui/geometry/RectTest.kt b/compose/ui/ui-geometry/src/test/kotlin/androidx/compose/ui/geometry/RectTest.kt
index 927b408..a911875 100644
--- a/compose/ui/ui-geometry/src/test/kotlin/androidx/compose/ui/geometry/RectTest.kt
+++ b/compose/ui/ui-geometry/src/test/kotlin/androidx/compose/ui/geometry/RectTest.kt
@@ -16,12 +16,12 @@
package androidx.compose.ui.geometry
+import kotlin.test.assertTrue
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class RectTest {
diff --git a/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/ColorDetector.kt b/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/ColorDetector.kt
index 16a8216..8e5e6e3 100644
--- a/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/ColorDetector.kt
+++ b/compose/ui/ui-graphics-lint/src/main/java/androidx/compose/ui/graphics/lint/ColorDetector.kt
@@ -30,9 +30,9 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.kotlin.KotlinULiteralExpression
-import java.util.EnumSet
/**
* [Detector] that checks hex Color definitions to ensure that they provide values for all four
diff --git a/compose/ui/ui-graphics/api/current.txt b/compose/ui/ui-graphics/api/current.txt
index ae86521..55136ac 100644
--- a/compose/ui/ui-graphics/api/current.txt
+++ b/compose/ui/ui-graphics/api/current.txt
@@ -401,7 +401,7 @@
}
public fun interface ColorProducer {
- method public long invoke();
+ method public operator long invoke();
}
@androidx.compose.runtime.Immutable @kotlin.jvm.JvmInline public final value class FilterQuality {
diff --git a/compose/ui/ui-graphics/api/public_plus_experimental_current.txt b/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
index d6fde28..6ee1568 100644
--- a/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-graphics/api/public_plus_experimental_current.txt
@@ -401,7 +401,7 @@
}
public fun interface ColorProducer {
- method public long invoke();
+ method public operator long invoke();
}
@kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGraphicsApi {
diff --git a/compose/ui/ui-graphics/api/restricted_current.txt b/compose/ui/ui-graphics/api/restricted_current.txt
index 17269b9..785b8d7 100644
--- a/compose/ui/ui-graphics/api/restricted_current.txt
+++ b/compose/ui/ui-graphics/api/restricted_current.txt
@@ -432,7 +432,7 @@
}
public fun interface ColorProducer {
- method public long invoke();
+ method public operator long invoke();
}
public final class DegreesKt {
diff --git a/compose/ui/ui-graphics/benchmark/src/main/java/androidx/compose/ui/graphics/benchmark/ImageVectorTestCase.kt b/compose/ui/ui-graphics/benchmark/src/main/java/androidx/compose/ui/graphics/benchmark/ImageVectorTestCase.kt
index 294542e..f635bf3 100644
--- a/compose/ui/ui-graphics/benchmark/src/main/java/androidx/compose/ui/graphics/benchmark/ImageVectorTestCase.kt
+++ b/compose/ui/ui-graphics/benchmark/src/main/java/androidx/compose/ui/graphics/benchmark/ImageVectorTestCase.kt
@@ -16,21 +16,21 @@
package androidx.compose.ui.graphics.benchmark
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.draw.paint
import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.paint
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.graphics.vector.PathData
import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.foundation.layout.size
-import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.ui.graphics.vector.PathData
import androidx.compose.ui.graphics.vector.rememberVectorPainter
+import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
diff --git a/compose/ui/ui-graphics/benchmark/test/src/androidTest/AndroidManifest.xml b/compose/ui/ui-graphics/benchmark/test/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e865f27..0000000
--- a/compose/ui/ui-graphics/benchmark/test/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
- -->
-<manifest />
diff --git a/compose/ui/ui-graphics/benchmark/test/src/androidTest/java/androidx/compose/ui/graphics/benchmark/test/ImageVectorTest.kt b/compose/ui/ui-graphics/benchmark/test/src/androidTest/java/androidx/compose/ui/graphics/benchmark/test/ImageVectorTest.kt
index e7ef620..331886e 100644
--- a/compose/ui/ui-graphics/benchmark/test/src/androidTest/java/androidx/compose/ui/graphics/benchmark/test/ImageVectorTest.kt
+++ b/compose/ui/ui-graphics/benchmark/test/src/androidTest/java/androidx/compose/ui/graphics/benchmark/test/ImageVectorTest.kt
@@ -39,12 +39,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
+import kotlin.math.roundToInt
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
/**
* Test to ensure that [XmlVectorTestCase] and [ProgrammaticVectorTestCase] have an identical pixel
diff --git a/compose/ui/ui-graphics/build.gradle b/compose/ui/ui-graphics/build.gradle
index 815c1df..cb9f0da 100644
--- a/compose/ui/ui-graphics/build.gradle
+++ b/compose/ui/ui-graphics/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,102 +23,72 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api("androidx.annotation:annotation:1.2.0")
- api(project(":compose:ui:ui-unit"))
-
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation(project(":compose:ui:ui-util"))
- implementation(libs.kotlinStdlibCommon)
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.kotlinTestJunit)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(project(":compose:ui:ui-graphics:ui-graphics-samples"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
-
- lintPublish(project(":compose:ui:ui-graphics-lint"))
-
- samples(projectOrArtifact(":compose:ui:ui-graphics:ui-graphics-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
-
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
-
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:ui:ui-unit"))
implementation(project(":compose:runtime:runtime"))
implementation(project(":compose:ui:ui-util"))
}
+ }
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.2.0")
+ commonTest {
+ dependencies {
+ implementation(kotlin("test"))
}
+ }
+ if (desktopEnabled) {
skikoMain {
dependsOn(commonMain)
dependencies {
api(libs.skikoCommon)
+ implementation(project(":compose:runtime:runtime"))
}
}
+ }
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.2.0")
+ }
+ }
+
+ if (desktopEnabled) {
desktopMain {
- dependsOn skikoMain
+ dependsOn(jvmMain)
+ dependsOn(skikoMain)
dependencies {
implementation(libs.kotlinStdlib)
implementation(libs.kotlinStdlibJdk8)
}
}
+ }
- commonTest {
- dependencies {
- implementation(kotlin("test"))
- }
+ jvmTest {
+ dependencies {
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
- }
-
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:ui:ui-graphics:ui-graphics-samples"))
implementation(project(":compose:ui:ui-test-junit4"))
implementation(project(":compose:test-utils"))
@@ -128,9 +97,26 @@
implementation(libs.espressoCore)
implementation(libs.junit)
}
+ }
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
desktopTest {
resources.srcDirs += "src/desktopTest/res"
+ dependsOn(jvmTest)
dependencies {
implementation(project(":compose:ui:ui-test-junit4"))
implementation(libs.junit)
@@ -140,9 +126,10 @@
}
}
}
- dependencies {
- samples(projectOrArtifact(":compose:ui:ui-graphics:ui-graphics-samples"))
- }
+}
+
+dependencies {
+ lintPublish(project(":compose:ui:ui-graphics-lint"))
}
androidx {
@@ -161,7 +148,7 @@
namespace "androidx.compose.ui.graphics"
}
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
+if (desktopEnabled) {
tasks.findByName("desktopTest").configure {
systemProperties["GOLDEN_PATH"] = project.rootDir.absolutePath + "/../../golden"
}
diff --git a/compose/ui/ui-graphics/samples/build.gradle b/compose/ui/ui-graphics/samples/build.gradle
index b255806..15643a9 100644
--- a/compose/ui/ui-graphics/samples/build.gradle
+++ b/compose/ui/ui-graphics/samples/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "AndroidX Compose UI Graphics Components Samples"
+ name = "Compose UI Graphics Components Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Graphics Components"
diff --git a/compose/ui/ui-graphics/samples/src/main/AndroidManifest.xml b/compose/ui/ui-graphics/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/ui/ui-graphics/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidBlendModeTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidBlendModeTest.kt
index e5f71d0..25472a9 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidBlendModeTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidBlendModeTest.kt
@@ -18,6 +18,7 @@
import android.graphics.PorterDuff
import android.os.Build
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
@@ -25,7 +26,6 @@
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidCanvasTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidCanvasTest.kt
index c8fcfa2..d849eb1 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidCanvasTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidCanvasTest.kt
@@ -36,14 +36,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import org.junit.Assert.assertTrue
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidMatrixTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidMatrixTest.kt
index a99ffed..d83241e 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidMatrixTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidMatrixTest.kt
@@ -16,13 +16,13 @@
package androidx.compose.ui.graphics
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import org.junit.Assert.assertTrue
private const val delta = 0.01f
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidTileModeTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidTileModeTest.kt
index 9bf63e5..a08d3dd 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidTileModeTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/AndroidTileModeTest.kt
@@ -17,14 +17,14 @@
package androidx.compose.ui.graphics
import android.os.Build
-import androidx.test.filters.SmallTest
-import org.junit.Test
-import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
index ab73407..0d59a3f 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ImageBitmapTest.kt
@@ -17,12 +17,12 @@
package androidx.compose.ui.graphics
import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PaintTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PaintTest.kt
index 659b84e..2c61d09 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PaintTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PaintTest.kt
@@ -16,14 +16,14 @@
package androidx.compose.ui.graphics
-import androidx.test.filters.SmallTest
-import org.junit.Assert.assertTrue
-import org.junit.Test
-import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
+import org.junit.Assert.assertTrue
import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PathTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PathTest.kt
index def70c3..a51bfb3 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PathTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PathTest.kt
@@ -19,14 +19,14 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
-import androidx.test.filters.SmallTest
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
import kotlin.math.PI
+import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PixelMapTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PixelMapTest.kt
index a733508..f7cb47c 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PixelMapTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/PixelMapTest.kt
@@ -17,11 +17,11 @@
package androidx.compose.ui.graphics
import androidx.compose.ui.geometry.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectHelperTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectHelperTest.kt
index 8c20469..51f9188 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectHelperTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectHelperTest.kt
@@ -18,11 +18,11 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.unit.IntRect
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectangleShapeTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectangleShapeTest.kt
index bc7919f..7ed3e90 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectangleShapeTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/RectangleShapeTest.kt
@@ -20,11 +20,11 @@
import androidx.compose.ui.geometry.toRect
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ShaderTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ShaderTest.kt
index a1c9071..1386ef1 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ShaderTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/ShaderTest.kt
@@ -24,12 +24,12 @@
import androidx.compose.ui.unit.LayoutDirection
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
import kotlin.math.roundToInt
+import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeTest.kt
index 658f78c..213e383 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/drawscope/DrawScopeTest.kt
@@ -44,12 +44,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SmallTest
+import kotlin.math.roundToInt
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/BitmapPainterTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/BitmapPainterTest.kt
index 489d888..ca0a142 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/BitmapPainterTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/BitmapPainterTest.kt
@@ -30,13 +30,13 @@
import androidx.compose.ui.graphics.toPixelMap
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/PainterTest.kt b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/PainterTest.kt
index 36e7215..ebd4c8e 100644
--- a/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/PainterTest.kt
+++ b/compose/ui/ui-graphics/src/androidAndroidTest/kotlin/androidx/compose/ui/graphics/painter/PainterTest.kt
@@ -29,13 +29,13 @@
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.toPixelMap
import androidx.compose.ui.unit.LayoutDirection
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-graphics/src/androidMain/AndroidManifest.xml b/compose/ui/ui-graphics/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/compose/ui/ui-graphics/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt
index 9dd8132..64d8783 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Canvas.kt
@@ -18,9 +18,9 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.graphics.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.graphics.internal.JvmDefaultWithCompatibility
/**
* Create a new Canvas instance that targets its drawing commands
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
index ca53498..bf442bc 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/Color.kt
@@ -668,5 +668,5 @@
/**
* Return the color
*/
- fun invoke(): Color
+ operator fun invoke(): Color
}
\ No newline at end of file
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
index 5751016..15f30fe 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawScope.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.graphics.drawscope
-import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.center
import androidx.compose.ui.graphics.BlendMode
@@ -35,12 +35,12 @@
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.degrees
+import androidx.compose.ui.graphics.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.center
-import androidx.compose.ui.graphics.internal.JvmDefaultWithCompatibility
/**
* Simultaneously translate the [DrawScope] coordinate space by [left] and [top] as well as modify
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt
index 1cfd4d9..0aedc6ff 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/DrawTransform.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ClipOp
-import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Matrix
+import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.degrees
import androidx.compose.ui.graphics.internal.JvmDefaultWithCompatibility
diff --git a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt
index e09df38..a22662d 100644
--- a/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt
+++ b/compose/ui/ui-graphics/src/commonMain/kotlin/androidx/compose/ui/graphics/drawscope/EmptyCanvas.kt
@@ -22,11 +22,11 @@
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.ClipOp
import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PointMode
import androidx.compose.ui.graphics.Vertices
-import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/BlendModeTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/BlendModeTest.kt
index 08f8bb8..38790bd 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/BlendModeTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/BlendModeTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.graphics
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
class BlendModeTest {
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ClipOpTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ClipOpTest.kt
index 3377989..da54628 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ClipOpTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ClipOpTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.graphics
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
class ClipOpTest {
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorMatrixTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorMatrixTest.kt
index 9c0338c..1a2e8fa 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorMatrixTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/ColorMatrixTest.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.graphics
import kotlin.test.BeforeTest
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ColorMatrixTest {
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/MatrixTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/MatrixTest.kt
index f4b7e7b..957d351 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/MatrixTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/MatrixTest.kt
@@ -19,12 +19,12 @@
import androidx.compose.ui.geometry.MutableRect
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
+import kotlin.math.abs
+import kotlin.math.sqrt
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
-import kotlin.math.abs
-import kotlin.math.sqrt
class MatrixTest {
@Test
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/colorspace/ColorModelTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/colorspace/ColorModelTest.kt
index 337146b..914c15f 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/colorspace/ColorModelTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/colorspace/ColorModelTest.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.graphics.colorspace
import androidx.compose.ui.util.packInts
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
class ColorModelTest {
diff --git a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/vector/PathParserTest.kt b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/vector/PathParserTest.kt
index 31ff184..fc55c77 100644
--- a/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/vector/PathParserTest.kt
+++ b/compose/ui/ui-graphics/src/commonTest/kotlin/androidx/compose/ui/graphics/vector/PathParserTest.kt
@@ -23,8 +23,8 @@
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.PathOperation
-import kotlin.test.assertEquals
import kotlin.test.Test
+import kotlin.test.assertEquals
class PathParserTest {
@Test
diff --git a/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt b/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt
index fd0bd46..96e7808 100644
--- a/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt
+++ b/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageAsset.desktop.kt
@@ -16,10 +16,10 @@
package androidx.compose.ui.graphics
-import org.jetbrains.skia.Bitmap
-import org.jetbrains.skia.Image
import java.nio.ByteBuffer
import java.nio.ByteOrder
+import org.jetbrains.skia.Bitmap
+import org.jetbrains.skia.Image
/**
* Create an [ImageBitmap] from the given [Bitmap]. Note this does
diff --git a/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt b/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt
index b03678a6..8ead9ef 100644
--- a/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt
+++ b/compose/ui/ui-graphics/src/desktopMain/kotlin/androidx/compose/ui/graphics/DesktopImageConverters.desktop.kt
@@ -25,9 +25,6 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
-import org.jetbrains.skia.Bitmap
-import org.jetbrains.skia.ColorAlphaType
-import org.jetbrains.skia.ImageInfo
import java.awt.Graphics
import java.awt.Image
import java.awt.Point
@@ -42,6 +39,9 @@
import java.awt.image.Raster
import java.awt.image.SinglePixelPackedSampleModel
import kotlin.math.roundToInt
+import org.jetbrains.skia.Bitmap
+import org.jetbrains.skia.ColorAlphaType
+import org.jetbrains.skia.ImageInfo
/**
* Convert AWT [BufferedImage] to Compose [Painter], so it would be possible to pass it to Compose
diff --git a/compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/DesktopPathTest.kt b/compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/DesktopPathTest.kt
index 4dc92b9..564e422 100644
--- a/compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/DesktopPathTest.kt
+++ b/compose/ui/ui-graphics/src/desktopTest/kotlin/androidx/compose/ui/graphics/DesktopPathTest.kt
@@ -20,8 +20,8 @@
import androidx.compose.ui.geometry.RoundRect
import androidx.compose.ui.test.InternalTestApi
import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
import org.junit.Test
@OptIn(InternalTestApi::class)
diff --git a/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt b/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
index 0e0f06e..9ea4923 100644
--- a/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
+++ b/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaBackedCanvas.skiko.kt
@@ -22,16 +22,16 @@
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach
+import org.jetbrains.skia.ClipMode as SkClipMode
import org.jetbrains.skia.CubicResampler
import org.jetbrains.skia.FilterMipmap
import org.jetbrains.skia.FilterMode
import org.jetbrains.skia.Image
import org.jetbrains.skia.Matrix44
import org.jetbrains.skia.MipmapMode
-import org.jetbrains.skia.SamplingMode
-import org.jetbrains.skia.ClipMode as SkClipMode
import org.jetbrains.skia.RRect as SkRRect
import org.jetbrains.skia.Rect as SkRect
+import org.jetbrains.skia.SamplingMode
import org.jetbrains.skia.impl.use
actual typealias NativeCanvas = org.jetbrains.skia.Canvas
diff --git a/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt b/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
index fa11fe8f..3c3b207 100644
--- a/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
+++ b/compose/ui/ui-graphics/src/skikoMain/kotlin/androidx/compose/ui/graphics/SkiaImageAsset.skiko.kt
@@ -18,13 +18,13 @@
import androidx.compose.ui.graphics.colorspace.ColorSpace
import androidx.compose.ui.graphics.colorspace.ColorSpaces
+import kotlin.math.abs
import org.jetbrains.skia.Bitmap
import org.jetbrains.skia.ColorAlphaType
import org.jetbrains.skia.ColorInfo
import org.jetbrains.skia.ColorType
import org.jetbrains.skia.Image
import org.jetbrains.skia.ImageInfo
-import kotlin.math.abs
/**
* Create an [ImageBitmap] from the given [Bitmap]. Note this does
diff --git a/compose/ui/ui-inspection/build.gradle b/compose/ui/ui-inspection/build.gradle
index d7db14f..9ee96cd9 100644
--- a/compose/ui/ui-inspection/build.gradle
+++ b/compose/ui/ui-inspection/build.gradle
@@ -62,7 +62,7 @@
}
androidx {
- name = "Android Compose Layout Inspector"
+ name = "Compose Layout Inspector"
type = LibraryType.IDE_PLUGIN
inceptionYear = "2021"
description = "Compose layout inspector. Exposes information to our tools for better IDE support."
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/ParametersTest.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/ParametersTest.kt
index 4e4932e..bc87381 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/ParametersTest.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/ParametersTest.kt
@@ -22,8 +22,8 @@
import androidx.compose.ui.inspection.util.GetComposablesCommand
import androidx.compose.ui.inspection.util.GetParameterDetailsCommand
import androidx.compose.ui.inspection.util.GetParametersByAnchorIdCommand
-import androidx.compose.ui.inspection.util.GetParametersCommand
import androidx.compose.ui.inspection.util.GetParametersByIdCommand
+import androidx.compose.ui.inspection.util.GetParametersCommand
import androidx.compose.ui.inspection.util.GetUpdateSettingsCommand
import androidx.compose.ui.inspection.util.flatten
import androidx.compose.ui.inspection.util.toMap
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/ComposeInspectionRule.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/ComposeInspectionRule.kt
index 933ee399..7e66fc6 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/ComposeInspectionRule.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/ComposeInspectionRule.kt
@@ -30,15 +30,15 @@
import androidx.compose.ui.platform.ViewRootForTest
import androidx.inspection.testing.InspectorTester
import androidx.test.core.app.ActivityScenario
-import kotlinx.coroutines.runBlocking
-import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.Command
-import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.Response
-import org.junit.rules.ExternalResource
import java.util.Collections
import java.util.WeakHashMap
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.reflect.KClass
+import kotlinx.coroutines.runBlocking
+import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.Command
+import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.Response
+import org.junit.rules.ExternalResource
/**
* Test rule with common setup for compose inspector's tests:
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/JvmtiRule.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/JvmtiRule.kt
index f9bf89d..21982eb 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/JvmtiRule.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/rules/JvmtiRule.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.inspection.rules
import android.os.Debug
-import org.junit.rules.ExternalResource
import java.io.IOException
+import org.junit.rules.ExternalResource
class JvmtiRule : ExternalResource() {
companion object {
diff --git a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/util/ProtoExtensions.kt b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/util/ProtoExtensions.kt
index 528b4c1..feba40c 100644
--- a/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/util/ProtoExtensions.kt
+++ b/compose/ui/ui-inspection/src/androidTest/java/androidx/compose/ui/inspection/util/ProtoExtensions.kt
@@ -21,8 +21,8 @@
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.ComposableNode
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.GetAllParametersCommand
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.GetComposablesCommand
-import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.GetParametersCommand
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.GetParameterDetailsCommand
+import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.GetParametersCommand
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.ParameterReference
import layoutinspector.compose.inspection.LayoutInspectorComposeProtocol.UpdateSettingsCommand
diff --git a/compose/ui/ui-inspection/src/main/AndroidManifest.xml b/compose/ui/ui-inspection/src/main/AndroidManifest.xml
deleted file mode 100644
index f3ba9c7..0000000
--- a/compose/ui/ui-inspection/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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.
--->
-<manifest />
\ No newline at end of file
diff --git a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
index 0ee0076..4e7077f 100644
--- a/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
+++ b/compose/ui/ui-inspection/src/main/java/androidx/compose/ui/inspection/inspector/ParameterFactory.kt
@@ -16,7 +16,6 @@
package androidx.compose.ui.inspection.inspector
-import java.lang.reflect.Modifier as JavaModifier
import android.util.Log
import android.view.View
import androidx.compose.runtime.internal.ComposableLambda
@@ -46,6 +45,7 @@
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import java.lang.reflect.Field
+import java.lang.reflect.Modifier as JavaModifier
import java.util.IdentityHashMap
import kotlin.jvm.internal.FunctionReference
import kotlin.jvm.internal.Lambda
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ComposedModifierDetector.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ComposedModifierDetector.kt
index 557404e..1652ea2 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ComposedModifierDetector.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ComposedModifierDetector.kt
@@ -30,12 +30,12 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.USimpleNameReferenceExpression
import org.jetbrains.uast.getParameterForArgument
import org.jetbrains.uast.tryResolve
import org.jetbrains.uast.visitor.AbstractUastVisitor
-import java.util.EnumSet
/**
* [Detector] that checks calls to Modifier.composed to make sure they actually reference a
diff --git a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
index bcc5884..3577db2 100644
--- a/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
+++ b/compose/ui/ui-lint/src/main/java/androidx/compose/ui/lint/ModifierParameterDetector.kt
@@ -32,12 +32,12 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
+import java.util.EnumSet
+import java.util.Locale
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UMethod
-import java.util.EnumSet
-import java.util.Locale
/**
* [Detector] that checks Composable functions with Modifiers parameters for consistency with
diff --git a/compose/ui/ui-test-junit4/build.gradle b/compose/ui/ui-test-junit4/build.gradle
index 5e4501d..5db2d70 100644
--- a/compose/ui/ui-test-junit4/build.gradle
+++ b/compose/ui/ui-test-junit4/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,81 +23,42 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-android {
- lintOptions {
- disable("InvalidPackage")
- }
- namespace "androidx.compose.ui.test.junit4"
-}
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
-dependencies {
-
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- api(project(":compose:ui:ui-test"))
- api("androidx.activity:activity:1.2.1")
- api(libs.junit)
- api(libs.kotlinStdlib)
- api(libs.kotlinStdlibCommon)
- api(libs.testExtJunit)
-
- implementation("androidx.compose.runtime:runtime-saveable:1.2.1")
- implementation("androidx.activity:activity-compose:1.3.0")
- implementation("androidx.annotation:annotation:1.1.0")
- implementation("androidx.lifecycle:lifecycle-common:2.5.1")
- implementation("androidx.lifecycle:lifecycle-runtime:2.5.1")
- implementation("androidx.test:core:1.5.0")
- implementation("androidx.test:monitor:1.6.0")
- implementation("androidx.test.espresso:espresso-core:3.5.0")
- implementation("androidx.test.espresso:espresso-idling-resource:3.5.0")
- implementation(libs.kotlinCoroutinesCore)
- implementation(libs.kotlinCoroutinesTest)
-
- testImplementation(project(":compose:animation:animation-core"))
- testImplementation(project(":compose:material:material"))
- testImplementation(project(":compose:test-utils"))
- testImplementation(libs.truth)
- testImplementation(libs.robolectric)
-
- androidTestImplementation(project(":compose:animation:animation"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":compose:material:material"))
- androidTestImplementation("androidx.fragment:fragment-testing:1.4.1")
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoKotlin)
- }
-}
-
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
api(project(":compose:ui:ui-test"))
implementation(libs.kotlinStdlib)
implementation(libs.kotlinCoroutinesCore)
implementation(libs.kotlinCoroutinesTest)
}
+ }
- jvmMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
api(libs.junit)
api(libs.kotlinStdlib)
api(libs.kotlinStdlibCommon)
compileOnly("androidx.annotation:annotation:1.1.0")
}
+ }
- androidMain.dependencies {
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.activity:activity:1.2.1")
implementation "androidx.activity:activity-compose:1.3.0"
api(libs.testExtJunit)
@@ -107,24 +67,31 @@
implementation(project(":compose:runtime:runtime-saveable"))
implementation("androidx.lifecycle:lifecycle-common:2.5.1")
implementation("androidx.lifecycle:lifecycle-runtime:2.5.1")
- implementation("androidx.test:core:1.4.0")
+ implementation("androidx.test:core:1.5.0")
implementation(libs.testMonitor)
implementation("androidx.test.espresso:espresso-core:3.3.0")
- implementation("androidx.test.espresso:espresso-idling-resource:3.3.0")
+ implementation("androidx.test.espresso:espresso-idling-resource:3.5.0")
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(project(":compose:animation:animation-core"))
- implementation(project(":compose:material:material"))
- implementation(project(":compose:test-utils"))
- implementation(libs.truth)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.truth)
+ implementation(libs.skiko)
+ }
}
+ }
- androidAndroidTest.dependencies {
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:animation:animation"))
implementation(project(":compose:test-utils"))
implementation(project(":compose:material:material"))
@@ -136,28 +103,50 @@
implementation(libs.dexmakerMockito)
implementation(libs.mockitoKotlin)
}
+ }
- desktopMain.dependencies {
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(project(":compose:animation:animation-core"))
+ implementation(project(":compose:material:material"))
+ implementation(project(":compose:test-utils"))
implementation(libs.truth)
- implementation(libs.skiko)
}
+ }
- desktopTest.dependencies {
- implementation(libs.truth)
- implementation(libs.junit)
- implementation(libs.kotlinTest)
- implementation(libs.skikoCurrentOs)
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:ui:ui-test-junit4"))
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.kotlinTest)
+ implementation(libs.skikoCurrentOs)
+ implementation(project(":compose:foundation:foundation"))
+ implementation(project(":compose:ui:ui-test-junit4"))
+ }
}
}
}
+}
- dependencies {
- // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
- // leaks into instrumented tests (b/214407011)
- testImplementation(libs.robolectric)
+
+android {
+ lintOptions {
+ disable("InvalidPackage")
}
+ namespace "androidx.compose.ui.test.junit4"
+}
+
+dependencies {
+ // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
+ // leaks into instrumented tests (b/214407011)
+ testImplementation(libs.robolectric)
}
androidx {
diff --git a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
index cfce9a0..ca74cd1 100644
--- a/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
+++ b/compose/ui/ui-test-junit4/src/androidAndroidTest/kotlin/androidx/compose/ui/test/junit4/SynchronizationMethodsTest.kt
@@ -25,15 +25,15 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runner.RunWith
import org.junit.runners.model.Statement
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test-junit4/src/androidMain/AndroidManifest.xml b/compose/ui/ui-test-junit4/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/compose/ui/ui-test-junit4/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/ComposeUiTest.desktop.kt b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/ComposeUiTest.desktop.kt
index 8af350a..6977ddf 100644
--- a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/ComposeUiTest.desktop.kt
+++ b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/ComposeUiTest.desktop.kt
@@ -182,6 +182,10 @@
}
}
+ /**
+ * @param matcher
+ * @param useUnmergedTree
+ */
override fun onNode(
matcher: SemanticsMatcher,
useUnmergedTree: Boolean
@@ -189,6 +193,10 @@
return SemanticsNodeInteraction(testContext, useUnmergedTree, matcher)
}
+ /**
+ * @param matcher
+ * @param useUnmergedTree
+ */
override fun onAllNodes(
matcher: SemanticsMatcher,
useUnmergedTree: Boolean
diff --git a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/SkiaTest.desktop.kt b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/SkiaTest.desktop.kt
index bc82a1a..2e6a994 100644
--- a/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/SkiaTest.desktop.kt
+++ b/compose/ui/ui-test-junit4/src/desktopMain/kotlin/androidx/compose/ui/test/junit4/SkiaTest.desktop.kt
@@ -15,15 +15,15 @@
*/
package androidx.compose.ui.test.junit4
-import org.jetbrains.skia.Image
import androidx.compose.ui.test.InternalTestApi
+import java.io.File
+import java.security.MessageDigest
+import java.util.LinkedList
+import org.jetbrains.skia.Image
import org.jetbrains.skia.Surface
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
-import java.io.File
-import java.security.MessageDigest
-import java.util.LinkedList
// TODO(https://github.com/JetBrains/compose-jb/issues/1041): refactor API
diff --git a/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt
index 3a8dda1..9efd549 100644
--- a/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt
+++ b/compose/ui/ui-test-junit4/src/jvmMain/kotlin/androidx/compose/ui/test/junit4/UncaughtExceptionHandler.jvm.kt
@@ -16,9 +16,9 @@
package androidx.compose.ui.test.junit4
-import kotlinx.coroutines.CoroutineExceptionHandler
import kotlin.coroutines.AbstractCoroutineContextElement
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineExceptionHandler
/**
* Similar to [TestCoroutineExceptionHandler], but with clearing all thrown exceptions
diff --git a/compose/ui/ui-test-junit4/src/test/kotlin/androidx/compose/ui/test/junit4/InfiniteAnimationPolicyTest.kt b/compose/ui/ui-test-junit4/src/test/kotlin/androidx/compose/ui/test/junit4/InfiniteAnimationPolicyTest.kt
index c505e085..310bfa7 100644
--- a/compose/ui/ui-test-junit4/src/test/kotlin/androidx/compose/ui/test/junit4/InfiniteAnimationPolicyTest.kt
+++ b/compose/ui/ui-test-junit4/src/test/kotlin/androidx/compose/ui/test/junit4/InfiniteAnimationPolicyTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.test.junit4
-import androidx.compose.animation.core.withInfiniteAnimationFrameNanos
import androidx.compose.animation.core.withInfiniteAnimationFrameMillis
+import androidx.compose.animation.core.withInfiniteAnimationFrameNanos
import androidx.compose.ui.platform.InfiniteAnimationPolicy
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CancellationException
diff --git a/compose/ui/ui-test/build.gradle b/compose/ui/ui-test/build.gradle
index 097486a..ead9fac 100644
--- a/compose/ui/ui-test/build.gradle
+++ b/compose/ui/ui-test/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,14 +23,115 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
+
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
+
+ sourceSets {
+ commonMain {
+ dependencies {
+ api(project(":compose:ui:ui"))
+ api(project(":compose:ui:ui-text"))
+ api(project(":compose:ui:ui-unit"))
+ api(project(":compose:runtime:runtime"))
+ api(libs.kotlinStdlib)
+
+ implementation(project(":compose:ui:ui-util"))
+ }
+ }
+
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(libs.kotlinCoroutinesCore)
+ api(libs.kotlinCoroutinesTest)
+ api(libs.kotlinStdlibCommon)
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api(project(":compose:ui:ui-graphics"))
+
+ implementation("androidx.annotation:annotation:1.1.0")
+ implementation("androidx.core:core-ktx:1.2.0")
+ implementation("androidx.test.espresso:espresso-core:3.5.0")
+ implementation(libs.testMonitor)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.junit)
+ implementation(libs.truth)
+ implementation(libs.skiko)
+ }
+ }
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidCommonTest {
+ dependsOn(commonTest)
+ dependencies {
+ implementation(project(":compose:test-utils"))
+ implementation(libs.truth)
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependsOn(androidCommonTest)
+ dependencies {
+ implementation(project(":compose:material:material"))
+ implementation(project(":compose:ui:ui-test-junit4"))
+ implementation("androidx.activity:activity-compose:1.3.1")
+ implementation(libs.mockitoCore)
+ implementation(libs.mockitoKotlin)
+ implementation(libs.dexmakerMockito)
+ implementation(libs.kotlinTest)
+ }
+ }
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependsOn(androidCommonTest)
+ dependencies {
+ implementation(libs.mockitoCore4)
+ implementation(libs.mockitoKotlin4)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
+ }
+}
android {
- if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- sourceSets {
- test.java.srcDirs += "src/androidCommonTest/kotlin"
- androidTest.java.srcDirs += "src/androidCommonTest/kotlin"
- }
+ sourceSets {
+ test.java.srcDirs += "src/androidCommonTest/kotlin"
+ androidTest.java.srcDirs += "src/androidCommonTest/kotlin"
}
lintOptions {
@@ -41,121 +141,9 @@
}
dependencies {
-
- if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- api("androidx.compose.runtime:runtime:1.2.1")
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-graphics"))
- api(project(":compose:ui:ui-text"))
- api(project(":compose:ui:ui-unit"))
- api(libs.kotlinCoroutinesCore)
- api(libs.kotlinCoroutinesTest)
- api(libs.kotlinStdlib)
- api(libs.kotlinStdlibCommon)
-
- implementation(project(":compose:ui:ui-util"))
- implementation("androidx.annotation:annotation:1.1.0")
- implementation("androidx.core:core-ktx:1.1.0")
- implementation("androidx.test.espresso:espresso-core:3.5.0")
- implementation("androidx.test:monitor:1.6.0")
-
- testImplementation(project(":compose:test-utils"))
- testImplementation(libs.truth)
- testImplementation(libs.robolectric)
- testImplementation(libs.mockitoCore4)
- testImplementation(libs.mockitoKotlin4)
-
- androidTestImplementation("androidx.activity:activity-compose:1.3.1")
- androidTestImplementation(project(":compose:material:material"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoKotlin)
- androidTestImplementation(libs.kotlinTest)
-
- samples(project(":compose:ui:ui-test:ui-test-samples"))
- }
-}
-
-
-if (AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- sourceSets {
- commonMain.dependencies {
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-text"))
- api(project(":compose:ui:ui-unit"))
- api(libs.kotlinStdlib)
-
- implementation(project(":compose:ui:ui-util"))
- }
-
- jvmMain.dependencies {
- api(project(":compose:runtime:runtime"))
- api(libs.kotlinCoroutinesCore)
- api(libs.kotlinCoroutinesTest)
- api(libs.kotlinStdlibCommon)
- }
-
- androidMain.dependencies {
- api(project(":compose:ui:ui-graphics"))
-
- implementation("androidx.annotation:annotation:1.1.0")
- implementation("androidx.core:core-ktx:1.2.0")
- implementation("androidx.test.espresso:espresso-core:3.3.0")
- implementation(libs.testMonitor)
- }
-
- androidCommonTest.dependencies {
- implementation(project(":compose:test-utils"))
- implementation(libs.truth)
- }
-
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.mockitoCore4)
- implementation(libs.mockitoKotlin4)
- }
-
- androidAndroidTest.dependencies {
- implementation(project(":compose:material:material"))
- implementation(project(":compose:ui:ui-test-junit4"))
- implementation("androidx.activity:activity-compose:1.3.1")
- implementation(libs.mockitoCore)
- implementation(libs.mockitoKotlin)
- implementation(libs.dexmakerMockito)
- implementation(libs.kotlinTest)
- }
-
- desktopMain.dependencies {
- implementation(libs.junit)
- implementation(libs.truth)
- implementation(libs.skiko)
- }
-
- androidCommonTest.dependsOn(commonTest)
- androidTest.dependsOn(androidCommonTest)
- androidAndroidTest.dependsOn(androidCommonTest)
- }
- }
-
- dependencies {
- // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
- // leaks into instrumented tests (b/214407011)
- testImplementation(libs.robolectric)
-
- samples(project(":compose:ui:ui-test:ui-test-samples"))
- }
+ // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
+ // leaks into instrumented tests (b/214407011)
+ testImplementation(libs.robolectric)
}
androidx {
diff --git a/compose/ui/ui-test/samples/build.gradle b/compose/ui/ui-test/samples/build.gradle
index 668bb91..0845c78 100644
--- a/compose/ui/ui-test/samples/build.gradle
+++ b/compose/ui/ui-test/samples/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "AndroidX Compose Testing Samples"
+ name = "Compose Testing Samples"
type = LibraryType.SAMPLES
inceptionYear = "2022"
description = "Contains samples for AndroidX Compose Testing."
diff --git a/compose/ui/ui-test/samples/src/main/AndroidManifest.xml b/compose/ui/ui-test/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index a7cd314..0000000
--- a/compose/ui/ui-test/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ 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 />
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/CallSemanticsActionTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/CallSemanticsActionTest.kt
index a354f96..a380a02 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/CallSemanticsActionTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/CallSemanticsActionTest.kt
@@ -27,11 +27,11 @@
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindAllTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindAllTest.kt
index 0cedb3f..2479e17 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindAllTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindAllTest.kt
@@ -23,11 +23,11 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindInPopupTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindInPopupTest.kt
index 835d945..0ce4aaa 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindInPopupTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindInPopupTest.kt
@@ -22,11 +22,11 @@
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.window.Popup
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
private const val contentTag = "content"
private const val popupTag = "popup"
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindersTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindersTest.kt
index 5b58bec..0a19723 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindersTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/FindersTest.kt
@@ -20,21 +20,21 @@
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.testutils.expectError
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.editableText
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.semantics.text
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.text.AnnotatedString
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import androidx.compose.testutils.expectError
-import androidx.compose.ui.semantics.contentDescription
-import androidx.compose.ui.semantics.editableText
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAllTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAllTest.kt
index 3ee7a82..8b5f6d9 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAllTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAllTest.kt
@@ -18,17 +18,17 @@
import androidx.compose.ui.test.assertAll
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithTag
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAnyTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAnyTest.kt
index 2d6f01c..50a9ca0 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAnyTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertAnyTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.assertions
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assertAny
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertContentDescription.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertContentDescription.kt
index 3076fa0..876c983 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertContentDescription.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertContentDescription.kt
@@ -26,11 +26,11 @@
import androidx.compose.ui.test.assertContentDescriptionEquals
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertText.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertText.kt
index 01ee757..2649649 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertText.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/assertions/AssertText.kt
@@ -31,11 +31,11 @@
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.text.AnnotatedString
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
index ec61d21..e55845f 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeTest.kt
@@ -64,10 +64,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeVelocityTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeVelocityTest.kt
index a23987f..42b4dcd 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeVelocityTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/gesturescope/SendSwipeVelocityTest.kt
@@ -37,11 +37,11 @@
import androidx.compose.ui.test.util.recordedDurationMillis
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.max
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.max
/**
* Tests if we can generate gestures that end with a specific velocity
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/LongClickTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/LongClickTest.kt
index 6ba723d..9a3f36c 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/LongClickTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/LongClickTest.kt
@@ -44,13 +44,13 @@
import androidx.compose.ui.test.util.verify
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.max
+import kotlin.math.roundToInt
+import kotlin.math.roundToLong
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.max
-import kotlin.math.roundToInt
-import kotlin.math.roundToLong
/**
* Tests [TouchInjectionScope.longClick] with arguments. Verifies that the click is in the middle
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/MoveWithHistoryTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/MoveWithHistoryTest.kt
index 9e60740..ca75c82 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/MoveWithHistoryTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/MoveWithHistoryTest.kt
@@ -39,10 +39,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithTouchSlopTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithTouchSlopTest.kt
index 4c447ad..c1cdadc 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithTouchSlopTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithTouchSlopTest.kt
@@ -32,10 +32,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
/**
* Test to see if we can achieve precise scroll motion when injecting touch events in the
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithVelocityTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithVelocityTest.kt
index 6bf7069..5925354 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithVelocityTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/SwipeWithVelocityTest.kt
@@ -40,11 +40,11 @@
import androidx.compose.ui.test.util.recordedDurationMillis
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.max
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.max
/**
* Test for [TouchInjectionScope.swipeWithVelocity] to see if we can generate gestures that end
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderCalculateDurationTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderCalculateDurationTest.kt
index aa7c8fd..c6bc9a6 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderCalculateDurationTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderCalculateDurationTest.kt
@@ -26,14 +26,14 @@
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.util.lerp
import com.google.common.truth.Truth.assertThat
-import org.junit.Assert.fail
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.lang.IllegalArgumentException
import kotlin.math.max
import kotlin.math.roundToInt
import kotlin.math.sqrt
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
/**
* Test to check if [VelocityPathFinder.calculateDefaultDuration] calculates a duration for
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderTest.kt
index 87832cc..f213055 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/injectionscope/touch/VelocityPathFinderTest.kt
@@ -26,14 +26,14 @@
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.util.lerp
import com.google.common.truth.Truth.assertThat
-import org.junit.Assert.fail
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import kotlin.math.floor
import kotlin.math.max
import kotlin.math.roundToInt
import kotlin.math.sqrt
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
/**
* Tests of [VelocityPathFinder] creates paths that will lead to the desired velocity.
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/partialgesturescope/Common.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/partialgesturescope/Common.kt
index e32a432..924b49d 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/partialgesturescope/Common.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/partialgesturescope/Common.kt
@@ -19,8 +19,8 @@
package androidx.compose.ui.test.partialgesturescope
-import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.GestureScope
+import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performGesture
import androidx.compose.ui.test.util.ClickableTestBox.defaultTag
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyAncestorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyAncestorTest.kt
index 40549c6..df67328 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyAncestorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyAncestorTest.kt
@@ -16,17 +16,17 @@
package androidx.compose.ui.test.predicates
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasAnyAncestor
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyChildTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyChildTest.kt
index eaab244..b6c1c80 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyChildTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyChildTest.kt
@@ -16,17 +16,17 @@
package androidx.compose.ui.test.predicates
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasAnyChild
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyDescendantTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyDescendantTest.kt
index 6e5483f..c98ec7f 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyDescendantTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnyDescendantTest.kt
@@ -16,17 +16,17 @@
package androidx.compose.ui.test.predicates
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasAnyDescendant
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnySiblingTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnySiblingTest.kt
index 9f760a7..5178fee 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnySiblingTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasAnySiblingTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.predicates
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasAnySibling
import androidx.compose.ui.test.hasParent
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasParentTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasParentTest.kt
index 3c3a2ae..0ecda22 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasParentTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/predicates/HasParentTest.kt
@@ -16,17 +16,17 @@
package androidx.compose.ui.test.predicates
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasParent
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AddIndexSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AddIndexSelectorTest.kt
index f7f6aba..faef8f6 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AddIndexSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AddIndexSelectorTest.kt
@@ -16,20 +16,20 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildAt
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AncestorsSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AncestorsSelectorTest.kt
index cb28f4c..8b35a6e 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AncestorsSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/AncestorsSelectorTest.kt
@@ -16,20 +16,20 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onAncestors
import androidx.compose.ui.test.onFirst
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onParent
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildSelectorTest.kt
index b1ca854..22e9c6a 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildSelectorTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChild
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildrenSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildrenSelectorTest.kt
index 1c10a00..0403487 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildrenSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ChildrenSelectorTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterSelectorTest.kt
index e934f88..4a78db7 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterSelectorTest.kt
@@ -16,19 +16,19 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.filter
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterToOneSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterToOneSelectorTest.kt
index a5f8fa1..129c653 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterToOneSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/FilterToOneSelectorTest.kt
@@ -16,19 +16,19 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.filterToOne
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/LastNodeSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/LastNodeSelectorTest.kt
index 61f4fb0..a78777d 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/LastNodeSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/LastNodeSelectorTest.kt
@@ -16,19 +16,19 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onLast
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ParentSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ParentSelectorTest.kt
index b110fae..1733f78 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ParentSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/ParentSelectorTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onParent
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessage
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingSelectorTest.kt
index e88d44a..aeefb12 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingSelectorTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onSibling
import androidx.compose.ui.test.util.BoundaryNode
import androidx.compose.ui.test.util.expectErrorMessageStartsWith
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingsSelectorTest.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingsSelectorTest.kt
index f054b8f..7332ead 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingsSelectorTest.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/selectors/SiblingsSelectorTest.kt
@@ -16,18 +16,18 @@
package androidx.compose.ui.test.selectors
-import androidx.test.filters.MediumTest
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
-import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.hasTestTag
+import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onSiblings
import androidx.compose.ui.test.util.BoundaryNode
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/ClickableTestBox.kt b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/ClickableTestBox.kt
index 8c40101..69d84dc 100644
--- a/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/ClickableTestBox.kt
+++ b/compose/ui/ui-test/src/androidAndroidTest/kotlin/androidx/compose/ui/test/util/ClickableTestBox.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.test.util
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/compose/ui/ui-test/src/androidMain/AndroidManifest.xml b/compose/ui/ui-test/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/compose/ui/ui-test/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
index 2f13281..d354263 100644
--- a/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
+++ b/compose/ui/ui-test/src/androidMain/kotlin/androidx/compose/ui/test/AndroidAssertions.android.kt
@@ -16,12 +16,12 @@
package androidx.compose.ui.test
-import androidx.test.espresso.matcher.ViewMatchers
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.layout.LayoutInfo
import androidx.compose.ui.platform.ViewRootForTest
import androidx.compose.ui.semantics.SemanticsNode
+import androidx.test.espresso.matcher.ViewMatchers
internal actual fun SemanticsNodeInteraction.checkIsDisplayed(): Boolean {
// hierarchy check - check layout nodes are visible
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/InjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/InjectionScope.kt
index fb0f6a7..86b9c7c 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/InjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/InjectionScope.kt
@@ -18,9 +18,9 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.ViewConfiguration
+import androidx.compose.ui.test.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.test.internal.JvmDefaultWithCompatibility
/**
* The receiver scope of all input injection lambdas offered in `ui-test`, such as
diff --git a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
index 3bcf792..d1f5822 100644
--- a/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
+++ b/compose/ui/ui-test/src/commonMain/kotlin/androidx/compose/ui/test/TouchInjectionScope.kt
@@ -19,12 +19,12 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.lerp
import androidx.compose.ui.platform.ViewConfiguration
+import androidx.compose.ui.test.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.util.lerp
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.roundToInt
import kotlin.math.roundToLong
-import androidx.compose.ui.test.internal.JvmDefaultWithCompatibility
/**
* The receiver scope of the touch input injection lambda from [performTouchInput].
diff --git a/compose/ui/ui-test/src/desktopMain/kotlin/androidx/compose/ui/test/DesktopInputDispatcher.desktop.kt b/compose/ui/ui-test/src/desktopMain/kotlin/androidx/compose/ui/test/DesktopInputDispatcher.desktop.kt
index 80c5334..1d82eff 100644
--- a/compose/ui/ui-test/src/desktopMain/kotlin/androidx/compose/ui/test/DesktopInputDispatcher.desktop.kt
+++ b/compose/ui/ui-test/src/desktopMain/kotlin/androidx/compose/ui/test/DesktopInputDispatcher.desktop.kt
@@ -19,10 +19,10 @@
package androidx.compose.ui.test
import androidx.compose.ui.InternalComposeUiApi
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.pointer.PointerId
import androidx.compose.ui.input.pointer.TestPointerInputEventData
-import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.node.RootForTest
import androidx.compose.ui.platform.SkiaRootForTest
diff --git a/compose/ui/ui-test/src/test/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt b/compose/ui/ui-test/src/test/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
index a86efdb..30174dd 100644
--- a/compose/ui/ui-test/src/test/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
+++ b/compose/ui/ui-test/src/test/kotlin/androidx/compose/ui/test/inputdispatcher/InputDispatcherTest.kt
@@ -31,10 +31,10 @@
import androidx.compose.ui.test.util.InputEventRecorder
import androidx.compose.ui.test.util.assertNoTouchGestureInProgress
import com.google.common.truth.Truth.assertThat
+import org.junit.After
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
-import org.junit.After
@OptIn(InternalTestApi::class)
open class InputDispatcherTest {
diff --git a/compose/ui/ui-text-google-fonts/build.gradle b/compose/ui/ui-text-google-fonts/build.gradle
index d8c49be..f557000 100644
--- a/compose/ui/ui-text-google-fonts/build.gradle
+++ b/compose/ui/ui-text-google-fonts/build.gradle
@@ -42,7 +42,7 @@
}
androidx {
- name = "AndroidX Compose Google Fonts integration"
+ name = "Compose Google Fonts integration"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Compose Downloadable Fonts integration for Google Fonts"
diff --git a/compose/ui/ui-text-google-fonts/src/androidTest/AndroidManifest.xml b/compose/ui/ui-text-google-fonts/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e865f27..0000000
--- a/compose/ui/ui-text-google-fonts/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
- -->
-<manifest />
diff --git a/compose/ui/ui-text-google-fonts/src/main/AndroidManifest.xml b/compose/ui/ui-text-google-fonts/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a69672..0000000
--- a/compose/ui/ui-text-google-fonts/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
diff --git a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/FrameworkTextLayoutBenchmark.kt b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/FrameworkTextLayoutBenchmark.kt
index 2872b3d..2765fb0 100644
--- a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/FrameworkTextLayoutBenchmark.kt
+++ b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/FrameworkTextLayoutBenchmark.kt
@@ -29,12 +29,12 @@
import androidx.benchmark.junit4.measureRepeated
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
+import kotlin.math.roundToInt
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.roundToInt
@LargeTest
@RunWith(Parameterized::class)
diff --git a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/ParagraphBenchmark.kt b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/ParagraphBenchmark.kt
index 7c217b8..02c2151 100644
--- a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/ParagraphBenchmark.kt
+++ b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/ParagraphBenchmark.kt
@@ -34,12 +34,12 @@
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import kotlin.math.ceil
+import kotlin.math.roundToInt
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.math.roundToInt
@LargeTest
@RunWith(Parameterized::class)
diff --git a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/input/EditProcessorBenchmark.kt b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/input/EditProcessorBenchmark.kt
index d9549db..da8dcd1 100644
--- a/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/input/EditProcessorBenchmark.kt
+++ b/compose/ui/ui-text/benchmark/src/androidTest/java/androidx/compose/ui/text/benchmark/input/EditProcessorBenchmark.kt
@@ -18,8 +18,8 @@
import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
-import androidx.compose.ui.text.benchmark.RandomTextGenerator
import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.text.benchmark.RandomTextGenerator
import androidx.compose.ui.text.benchmark.cartesian
import androidx.compose.ui.text.input.BackspaceCommand
import androidx.compose.ui.text.input.CommitTextCommand
diff --git a/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkHelper.kt b/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkHelper.kt
index c83992d0..707ffb3 100644
--- a/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkHelper.kt
+++ b/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkHelper.kt
@@ -21,9 +21,9 @@
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.style.BaselineShift
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextGeometricTransform
diff --git a/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkTestRule.kt b/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkTestRule.kt
index d8ac939..6f7f876 100644
--- a/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkTestRule.kt
+++ b/compose/ui/ui-text/benchmark/src/main/java/androidx/compose/ui/text/benchmark/TextBenchmarkTestRule.kt
@@ -17,11 +17,11 @@
import android.graphics.Canvas
import android.util.Log
+import kotlin.random.Random
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
-import kotlin.random.Random
/**
* Collection of text benchmark utilities. It tries to
diff --git a/compose/ui/ui-text/build.gradle b/compose/ui/ui-text/build.gradle
index c20c781..2903ae2 100644
--- a/compose/ui/ui-text/build.gradle
+++ b/compose/ui/ui-text/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,77 +23,15 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
- implementation(libs.kotlinCoroutinesCore)
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api(project(":compose:ui:ui-graphics"))
- api(project(":compose:ui:ui-unit"))
- api("androidx.annotation:annotation:1.1.0")
-
- // when updating the runtime version please also update the runtime-saveable version
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation("androidx.compose.runtime:runtime-saveable:1.2.1")
-
- implementation(project(":compose:ui:ui-util"))
- implementation(libs.kotlinStdlib)
- implementation("androidx.core:core:1.7.0")
- implementation('androidx.collection:collection:1.0.0')
- implementation("androidx.emoji2:emoji2:1.2.0")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.mockitoCore4)
- testImplementation(libs.truth)
- testImplementation(libs.kotlinReflect)
- testImplementation(libs.kotlinTest)
- testImplementation(libs.mockitoKotlin4)
-
- androidTestImplementation(project(":internal-testutils-fonts"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.mockitoKotlin)
-
- samples(projectOrArtifact(":compose:ui:ui-text:ui-text-samples"))
- }
-
- android {
- sourceSets {
- main {
- java.srcDirs += "${supportRootFolder}/text/text/src/main/java"
- }
- }
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
implementation(libs.kotlinCoroutinesCore)
@@ -107,53 +44,58 @@
implementation(project(":compose:ui:ui-util"))
}
+ }
- jvmMain.dependencies {
- implementation(libs.kotlinStdlib)
+ commonTest {
+ dependencies {
}
+ }
+ if (desktopEnabled) {
skikoMain {
dependsOn(commonMain)
dependencies {
api(libs.skikoCommon)
+ implementation(project(":compose:runtime:runtime"))
+ implementation(project(":compose:runtime:runtime-saveable"))
}
}
+ }
- desktopMain {
- dependsOn(skikoMain)
- dependsOn(jvmMain)
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
}
+ }
- androidMain {
- dependsOn(commonMain)
- }
- androidMain.dependencies {
+ androidMain {
+ dependsOn(commonMain)
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core:1.7.0")
implementation("androidx.emoji2:emoji2:1.2.0")
implementation('androidx.collection:collection:1.0.0')
}
+ }
- androidMain.kotlin.srcDirs("${supportRootFolder}/text/text/src/main/java")
-
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(project(":internal-testutils-fonts"))
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.mockitoCore4)
- implementation(libs.truth)
- implementation(libs.kotlinReflect)
- implementation(libs.kotlinTest)
- implementation(libs.mockitoKotlin4)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
}
+ }
- androidAndroidTest.dependencies {
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:ui:ui-test-junit4"))
implementation(project(":internal-testutils-fonts"))
implementation(libs.testRules)
@@ -165,20 +107,50 @@
implementation(libs.truth)
implementation(libs.mockitoKotlin)
}
+ }
- desktopTest.dependencies {
- implementation(libs.truth)
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(project(":internal-testutils-fonts"))
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
implementation(libs.junit)
+ implementation(libs.truth)
+ implementation(libs.kotlinReflect)
implementation(libs.kotlinTest)
- implementation(libs.skikoCurrentOs)
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:ui:ui-test-junit4"))
}
}
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.kotlinTest)
+ implementation(libs.skikoCurrentOs)
+ implementation(project(":compose:foundation:foundation"))
+ implementation(project(":compose:ui:ui-test-junit4"))
+ implementation(project(":internal-testutils-fonts"))
+ }
+ }
+ }
+
+ androidMain.kotlin.srcDirs("${supportRootFolder}/text/text/src/main/java")
}
- dependencies {
- samples(projectOrArtifact(":compose:ui:ui-text:ui-text-samples"))
- }
+}
+
+dependencies {
+ // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
+ // leaks into instrumented tests (b/214407011)
+ testImplementation(libs.mockitoCore4)
+ testImplementation(libs.mockitoKotlin4)
}
androidx {
diff --git a/compose/ui/ui-text/samples/build.gradle b/compose/ui/ui-text/samples/build.gradle
index 507a2ddb..a6d5aa4 100644
--- a/compose/ui/ui-text/samples/build.gradle
+++ b/compose/ui/ui-text/samples/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Compose UI Text Core Samples"
+ name = "Compose UI Text Core Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains sample code for the Androidx Compose UI Text Core APIs and Utilities"
diff --git a/compose/ui/ui-text/samples/src/main/AndroidManifest.xml b/compose/ui/ui-text/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a69672..0000000
--- a/compose/ui/ui-text/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
diff --git a/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/DrawTextSamples.kt b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/DrawTextSamples.kt
index 2a7f037..231274c 100644
--- a/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/DrawTextSamples.kt
+++ b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/DrawTextSamples.kt
@@ -17,42 +17,116 @@
package androidx.compose.ui.text.samples
import androidx.annotation.Sampled
+import androidx.compose.animation.animateColor
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.rememberInfiniteTransition
+import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.LocalTextStyle
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.draw.CacheDrawScope
+import androidx.compose.ui.draw.drawWithCache
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layout
-import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.drawText
+import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.rememberTextMeasurer
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.sp
+import kotlin.math.roundToInt
@Sampled
@Composable
-fun DrawTextLayoutResultSample() {
+fun DrawTextSample() {
+ val textMeasurer = rememberTextMeasurer()
+
+ Canvas(Modifier.fillMaxSize()) {
+ drawText(textMeasurer, "Hello, World!")
+ }
+}
+
+@Sampled
+@Composable
+fun DrawTextStyledSample() {
+ val textMeasurer = rememberTextMeasurer()
+
+ Canvas(Modifier.fillMaxSize()) {
+ drawText(
+ textMeasurer = textMeasurer,
+ text = "Hello, World!",
+ style = TextStyle(
+ fontSize = 24.sp,
+ fontWeight = FontWeight.Bold,
+ textDecoration = TextDecoration.Underline
+ )
+ )
+ }
+}
+
+@Sampled
+@Composable
+fun DrawTextAnnotatedStringSample() {
+ val textMeasurer = rememberTextMeasurer()
+
+ Canvas(Modifier.fillMaxSize()) {
+ drawText(
+ textMeasurer = textMeasurer,
+ text = buildAnnotatedString {
+ withStyle(ParagraphStyle(textAlign = TextAlign.Start)) {
+ append("Hello")
+ }
+ withStyle(ParagraphStyle(textAlign = TextAlign.End)) {
+ append("World")
+ }
+ }
+ )
+ }
+}
+
+/**
+ * This sample demonstrates how to use layout phase to improve performance when drawing text on
+ * DrawScope. We can use [layout] Modifier or [Layout] composable to calculate the text layout
+ * during layout phase and then cache the result in a Snapshot aware state to draw it during draw
+ * phase.
+ */
+@Sampled
+@Composable
+fun DrawTextMeasureInLayoutSample() {
val textMeasurer = rememberTextMeasurer()
var textLayoutResult by remember {
mutableStateOf<TextLayoutResult?>(null)
}
Canvas(
- Modifier.fillMaxSize()
+ Modifier
+ .fillMaxSize()
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
// TextLayout can be done any time prior to its use in draw, including in a
// background thread.
- // In this sample, text layout is done in compose layout. This way the layout call
- // can be restarted when async font loading completes due to the fact that
+ // In this sample, text layout is measured in layout modifier. This way the layout
+ // call can be restarted when async font loading completes due to the fact that
// `.measure` call is executed in `.layout`.
textLayoutResult = textMeasurer.measure(
- text = AnnotatedString("Hello ".repeat(2)),
- style = TextStyle(fontSize = 35.sp)
+ text = "Hello, World!",
+ style = TextStyle(fontSize = 24.sp)
)
layout(placeable.width, placeable.height) {
placeable.placeRelative(0, 0)
@@ -62,3 +136,57 @@
textLayoutResult?.let { drawText(it) }
}
}
+
+/**
+ * This sample demonstrates how to use [drawWithCache] modifier to improve performance when drawing
+ * text on DrawScope. We can use [drawWithCache] to calculate the text layout once in
+ * [CacheDrawScope] and then repeatedly use the same [TextLayoutResult] in the draw phase.
+ *
+ * This approach improves performance when the text itself does not change but its draw attributes
+ * do change over time, such as during a color animation.
+ */
+@Sampled
+@Composable
+fun DrawTextDrawWithCacheSample() {
+ // We can disable implicit caching since we will cache in DrawWithCache
+ val textMeasurer = rememberTextMeasurer(cacheSize = 0)
+ // Apply the current text style from theme, otherwise TextStyle.Default will be used.
+ val materialTextStyle = LocalTextStyle.current
+
+ // Animate color repeatedly
+ val infiniteTransition = rememberInfiniteTransition()
+ val color by infiniteTransition.animateColor(
+ initialValue = Color.Red,
+ targetValue = Color.Blue,
+ animationSpec = infiniteRepeatable(tween(1000))
+ )
+
+ Box(
+ Modifier
+ .fillMaxSize()
+ .drawWithCache {
+ // Text layout will be measured just once until the size of the drawing area or
+ // materialTextStyle changes.
+ val textLayoutResult = textMeasurer.measure(
+ text = "Hello, World!",
+ style = materialTextStyle,
+ constraints = Constraints.fixed(
+ width = (size.width / 2).roundToInt(),
+ height = (size.height / 2).roundToInt()
+ ),
+ overflow = TextOverflow.Ellipsis
+ )
+ // color changes will only invalidate draw phase
+ onDrawWithContent {
+ drawContent()
+ drawText(
+ textLayoutResult,
+ color = color,
+ topLeft = Offset(
+ (size.width - textLayoutResult.size.width) / 2,
+ (size.height - textLayoutResult.size.height) / 2,
+ )
+ )
+ }
+ })
+}
diff --git a/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMeasurerSamples.kt b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMeasurerSamples.kt
new file mode 100644
index 0000000..9cbe75f
--- /dev/null
+++ b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMeasurerSamples.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.ui.text.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextMeasurer
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.sp
+
+/**
+ * Sample showing how to use TextMeasurer in a non-composable function with a plain String for text.
+ */
+@Sampled
+fun measureTextStringWithConstraints(textMeasurer: TextMeasurer) {
+ textMeasurer.measure(
+ text = "Hello, World",
+ style = TextStyle(
+ color = Color.Red,
+ fontSize = 16.sp,
+ fontFamily = FontFamily.Cursive
+ ),
+ constraints = Constraints(
+ minWidth = 400,
+ maxWidth = 400,
+ minHeight = 200,
+ maxHeight = 400
+ )
+ )
+}
+
+/**
+ * Sample showing how to use TextMeasurer in a non-composable function with an AnnotatedString
+ * for text.
+ */
+@Sampled
+fun measureTextAnnotatedString(textMeasurer: TextMeasurer) {
+ textMeasurer.measure(
+ text = buildAnnotatedString {
+ append("Hello, ")
+ withStyle(SpanStyle(color = Color.Blue)) {
+ append("World!")
+ }
+ },
+ style = TextStyle(
+ fontSize = 16.sp,
+ fontFamily = FontFamily.Monospace
+ )
+ )
+}
diff --git a/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMotionSamples.kt b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMotionSamples.kt
new file mode 100644
index 0000000..7fbf0de
--- /dev/null
+++ b/compose/ui/ui-text/samples/src/main/java/androidx/compose/ui/text/samples/TextMotionSamples.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.compose.ui.text.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.animation.core.RepeatMode
+import androidx.compose.animation.core.animateFloat
+import androidx.compose.animation.core.infiniteRepeatable
+import androidx.compose.animation.core.rememberInfiniteTransition
+import androidx.compose.animation.core.tween
+import androidx.compose.material.LocalTextStyle
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.text.style.TextMotion
+
+/**
+ * This sample demonstrates how to define TextMotion on a Text composable that scales up and down
+ * repeatedly.
+ */
+@Sampled
+@Composable
+fun TextMotionSample() {
+ val infiniteTransition = rememberInfiniteTransition()
+ val scale by infiniteTransition.animateFloat(
+ initialValue = 1f,
+ targetValue = 8f,
+ animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse)
+ )
+
+ Text(
+ text = "Hello",
+ modifier = Modifier
+ .graphicsLayer {
+ scaleX = scale
+ scaleY = scale
+ transformOrigin = TransformOrigin.Center
+ },
+ // Text composable does not take TextMotion as a parameter.
+ // Provide it via style argument but make sure that we are copying from current theme
+ style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
+ )
+}
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/androidAndroidTest/AndroidManifest.xml b/compose/ui/ui-text/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/compose/ui/ui-text/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTextDirectionTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTextDirectionTest.kt
index c9dcbb7..1268ee3 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTextDirectionTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTextDirectionTest.kt
@@ -21,14 +21,14 @@
import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.platform.resolveTextDirectionHeuristics
import androidx.compose.ui.text.style.TextDirection
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTextDirectionTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTextDirectionTest.kt
index f86a193..fd2538f 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTextDirectionTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTextDirectionTest.kt
@@ -24,15 +24,15 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphFillBoundingBoxesTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphFillBoundingBoxesTest.kt
index 94f081a..d802b37 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphFillBoundingBoxesTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphFillBoundingBoxesTest.kt
@@ -19,11 +19,16 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.text.font.toFontFamily
+import androidx.compose.ui.text.matchers.assertThat
import androidx.compose.ui.text.style.BaselineShift
+import androidx.compose.ui.text.style.LineHeightStyle
+import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.style.TextIndent
+import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
@@ -32,11 +37,6 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import androidx.compose.ui.text.matchers.assertThat
-import androidx.compose.ui.text.style.LineHeightStyle
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
-import androidx.compose.ui.text.style.LineHeightStyle.Alignment
-import androidx.compose.ui.unit.Constraints
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationIndentationFixTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationIndentationFixTest.kt
index 20fe4e3..91547fd 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationIndentationFixTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationIndentationFixTest.kt
@@ -25,13 +25,13 @@
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationLineHeightStyleTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationLineHeightStyleTest.kt
index d68bd57..61ce517 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationLineHeightStyleTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationLineHeightStyleTest.kt
@@ -20,19 +20,19 @@
import androidx.compose.ui.text.android.style.lineHeight
import androidx.compose.ui.text.font.toFontFamily
import androidx.compose.ui.text.style.LineHeightStyle
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlin.math.abs
import kotlin.math.ceil
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTextDirectionTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTextDirectionTest.kt
index c41aea5..6416362 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTextDirectionTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntegrationTextDirectionTest.kt
@@ -20,15 +20,15 @@
import androidx.compose.ui.text.style.ResolvedTextDirection
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
index 322fee0..aa8e859 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/ParagraphIntrinsicIntegrationTest.kt
@@ -21,12 +21,12 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/StringTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/StringTest.kt
index d151b1e..87f155b 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/StringTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/StringTest.kt
@@ -17,12 +17,12 @@
package androidx.compose.ui.text
import androidx.compose.ui.text.intl.LocaleList
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/AndroidFontTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/AndroidFontTest.kt
index 21b13dd..d5390c5 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/AndroidFontTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/AndroidFontTest.kt
@@ -25,11 +25,11 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.io.File
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
index 8d69e3a..d42258b 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/DelegatingFontLoaderForDeprecatedUsageTest.kt
@@ -25,9 +25,9 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverFileTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverFileTest.kt
index d0c931e..daf1c07 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverFileTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontFamilyResolverFileTest.kt
@@ -26,11 +26,11 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
+import java.io.File
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt
index b6168c47..e5de0d1 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapterTest.kt
@@ -29,6 +29,9 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.coroutines.coroutineContext
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineExceptionHandler
@@ -39,19 +42,16 @@
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runBlockingTest
+import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.withTimeout
import kotlinx.coroutines.yield
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.coroutines.coroutineContext
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runCurrent
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/BackspaceCommandTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/BackspaceCommandTest.kt
index abce9eb..9d05c2b 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/BackspaceCommandTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/BackspaceCommandTest.kt
@@ -16,12 +16,12 @@
package androidx.compose.ui.text.input
import androidx.compose.ui.text.TextRange
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/MoveCursorCommandTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/MoveCursorCommandTest.kt
index fa563af..849d7f8 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/MoveCursorCommandTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/input/MoveCursorCommandTest.kt
@@ -17,12 +17,12 @@
package androidx.compose.ui.text.input
import androidx.compose.ui.text.TextRange
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleListTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleListTest.kt
index f7e356c..d43cf4e 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleListTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleListTest.kt
@@ -16,11 +16,11 @@
package androidx.compose.ui.text.intl
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleTest.kt
index a054588..44ecab1 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/intl/LocaleTest.kt
@@ -16,11 +16,11 @@
package androidx.compose.ui.text.intl
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/ComposeMatchers.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/ComposeMatchers.kt
index c377578..90b4e7c 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/ComposeMatchers.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/ComposeMatchers.kt
@@ -18,8 +18,8 @@
import android.graphics.Bitmap
import android.graphics.Typeface
-import androidx.compose.ui.text.font.TypefaceResult
import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.text.font.TypefaceResult
import com.google.common.truth.IntegerSubject
import com.google.common.truth.Truth.assertAbout
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/RectSubject.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/RectSubject.kt
index 4275a98..d253cae 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/RectSubject.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/matchers/RectSubject.kt
@@ -17,11 +17,11 @@
package androidx.compose.ui.text.matchers
import androidx.compose.ui.geometry.Rect
-import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Fact.simpleFact
import com.google.common.truth.FailureMetadata
import com.google.common.truth.Subject
import com.google.common.truth.Subject.Factory
+import com.google.common.truth.Truth.assertThat
internal class RectSubject private constructor(
failureMetadata: FailureMetadata?,
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceCacheTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceCacheTest.kt
index 2f01f2f..162b8b0 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceCacheTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceCacheTest.kt
@@ -18,11 +18,11 @@
import androidx.compose.ui.text.FontTestData
import androidx.compose.ui.text.matchers.assertThat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceSubsetTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceSubsetTest.kt
index 8667cf4..0410d86 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceSubsetTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/AndroidTypefaceSubsetTest.kt
@@ -24,11 +24,11 @@
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.font.Typeface
import androidx.compose.ui.text.matchers.assertThat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/GenericFontFamilyCacheTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/GenericFontFamilyCacheTest.kt
index 7852e76..121461be 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/GenericFontFamilyCacheTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/GenericFontFamilyCacheTest.kt
@@ -21,10 +21,10 @@
import androidx.compose.ui.text.font.FontSynthesis
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.matchers.assertThat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/compose/ui/ui-text/src/androidMain/AndroidManifest.xml b/compose/ui/ui-text/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/compose/ui/ui-text/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt
index cc2ed1d..d04fb59 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/AndroidParagraph.android.kt
@@ -16,7 +16,6 @@
package androidx.compose.ui.text
-import java.util.Locale as JavaLocale
import android.os.Build
import android.text.Spannable
import android.text.SpannableString
@@ -45,15 +44,15 @@
import androidx.compose.ui.text.android.LayoutCompat.BREAK_STRATEGY_HIGH_QUALITY
import androidx.compose.ui.text.android.LayoutCompat.BREAK_STRATEGY_SIMPLE
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_ALIGNMENT
-import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_HYPHENATION_FREQUENCY
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_BREAK_STRATEGY
+import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_HYPHENATION_FREQUENCY
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_JUSTIFICATION_MODE
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_LINESPACING_MULTIPLIER
-import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_NONE
-import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_FULL
-import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_FULL_FAST
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_LINE_BREAK_STYLE
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_LINE_BREAK_WORD_STYLE
+import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_FULL
+import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_FULL_FAST
+import androidx.compose.ui.text.android.LayoutCompat.HYPHENATION_FREQUENCY_NONE
import androidx.compose.ui.text.android.LayoutCompat.JUSTIFICATION_MODE_INTER_WORD
import androidx.compose.ui.text.android.LayoutCompat.LINE_BREAK_STYLE_LOOSE
import androidx.compose.ui.text.android.LayoutCompat.LINE_BREAK_STYLE_NONE
@@ -80,6 +79,7 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
+import java.util.Locale as JavaLocale
/**
* Android specific implementation for [Paragraph]
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt
index 0f87b74..8c3d370 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/intl/AndroidLocaleDelegate.android.kt
@@ -16,10 +16,10 @@
package androidx.compose.ui.text.intl
-import androidx.annotation.RequiresApi
import android.os.LocaleList as AndroidLocaleList
-import java.util.Locale as JavaLocale
+import androidx.annotation.RequiresApi
import androidx.compose.ui.text.platform.createSynchronizedObject
+import java.util.Locale as JavaLocale
/**
* An Android implementation of Locale object
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt
index e525241..f5fd858 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidTypeface.android.kt
@@ -16,11 +16,11 @@
package androidx.compose.ui.text.platform
-import androidx.compose.ui.text.font.Typeface
+import android.graphics.Typeface as NativeTypeface
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontSynthesis
import androidx.compose.ui.text.font.FontWeight
-import android.graphics.Typeface as NativeTypeface
+import androidx.compose.ui.text.font.Typeface
/**
* An interface of Android specific Typeface.
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
index 53effe0..61ac3a6 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextMeasurer.kt
@@ -133,6 +133,8 @@
* @param fontFamilyResolver to be used to load the font given in [SpanStyle]s. If not
* specified, defaults to the value that was given during initialization of this [TextMeasurer].
* @param skipCache Disables cache optimization if it is passed as true.
+ *
+ * @sample androidx.compose.ui.text.samples.measureTextAnnotatedString
*/
@Stable
fun measure(
@@ -221,6 +223,8 @@
* @param fontFamilyResolver to be used to load the font given in [SpanStyle]s. If not
* specified, defaults to the value that was given during initialization of this [TextMeasurer].
* @param skipCache Disables cache optimization if it is passed as true.
+ *
+ * @sample androidx.compose.ui.text.samples.measureTextStringWithConstraints
*/
@Stable
fun measure(
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
index f9aa838..23f39f9 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/TextPainter.kt
@@ -138,7 +138,7 @@
* ([TextOverflow.Clip]) or becomes no-op.
* @param blendMode Blending algorithm to be applied to the text
*
- * @see TextMeasurer
+ * @sample androidx.compose.ui.text.samples.DrawTextAnnotatedStringSample
*/
fun DrawScope.drawText(
textMeasurer: TextMeasurer,
@@ -205,7 +205,8 @@
* ([TextOverflow.Clip]) or becomes no-op.
* @param blendMode Blending algorithm to be applied to the text
*
- * @see TextMeasurer
+ * @sample androidx.compose.ui.text.samples.DrawTextSample
+ * @sample androidx.compose.ui.text.samples.DrawTextStyledSample
*/
fun DrawScope.drawText(
textMeasurer: TextMeasurer,
@@ -256,7 +257,8 @@
* @param drawStyle Whether or not the text is stroked or filled in.
* @param blendMode Blending algorithm to be applied to the text
*
- * @sample androidx.compose.ui.text.samples.DrawTextLayoutResultSample
+ * @sample androidx.compose.ui.text.samples.DrawTextMeasureInLayoutSample
+ * @sample androidx.compose.ui.text.samples.DrawTextDrawWithCacheSample
*/
fun DrawScope.drawText(
textLayoutResult: TextLayoutResult,
@@ -317,8 +319,6 @@
* @param textDecoration The decorations to paint on the text (e.g., an underline).
* @param drawStyle Whether or not the text is stroked or filled in.
* @param blendMode Blending algorithm to be applied to the text
- *
- * @sample androidx.compose.ui.text.samples.DrawTextLayoutResultSample
*/
fun DrawScope.drawText(
textLayoutResult: TextLayoutResult,
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/caches/LruCache.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/caches/LruCache.kt
index abf9bea..7cbb111 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/caches/LruCache.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/caches/LruCache.kt
@@ -18,7 +18,6 @@
import androidx.compose.ui.text.platform.createSynchronizedObject
import androidx.compose.ui.text.platform.synchronized
-
import kotlin.jvm.JvmName
/**
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
index 10b9df2..783254f 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/font/FontListFontFamilyTypefaceAdapter.kt
@@ -28,6 +28,9 @@
import androidx.compose.ui.text.platform.synchronized
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMap
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.coroutines.coroutineContext
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
@@ -42,9 +45,6 @@
import kotlinx.coroutines.withTimeout
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.coroutines.yield
-import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.coroutines.coroutineContext
internal class FontListFontFamilyTypefaceAdapter(
private val asyncTypefaceCache: AsyncTypefaceCache = AsyncTypefaceCache(),
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputAdapter.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputAdapter.kt
index 92a2f4c..c2f3ac6 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputAdapter.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/input/PlatformTextInputAdapter.kt
@@ -21,8 +21,8 @@
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateMapOf
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
@@ -294,7 +294,7 @@
* This is backed by a MutableState because it is incremented in [getOrCreateAdapter] which
* can be called directly from a composition, inside a [remember] block.
*/
- private var refCount by mutableStateOf(0)
+ private var refCount by mutableIntStateOf(0)
val isRefCountZero get() = refCount == 0
diff --git a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt
index 31381e8..29e7e35 100644
--- a/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt
+++ b/compose/ui/ui-text/src/commonMain/kotlin/androidx/compose/ui/text/style/TextMotion.kt
@@ -21,6 +21,8 @@
/**
* Defines ways to render and place glyphs to provide readability and smooth animations for text.
+ *
+ * @sample androidx.compose.ui.text.samples.TextMotionSample
*/
@ExperimentalTextApi
@Immutable
diff --git a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt
index 4a7a9f2..9471053 100644
--- a/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt
+++ b/compose/ui/ui-text/src/desktopMain/kotlin/androidx/compose/ui/text/platform/DesktopFont.desktop.kt
@@ -28,8 +28,8 @@
import java.io.File
import java.security.MessageDigest
import org.jetbrains.skia.Data
-import org.jetbrains.skia.makeFromFile
import org.jetbrains.skia.Typeface as SkTypeface
+import org.jetbrains.skia.makeFromFile
actual sealed class PlatformFont : Font {
actual abstract val identity: String
diff --git a/compose/ui/ui-text/src/desktopTest/kotlin/androidx/compose/ui/text/DesktopParagraphTest.kt b/compose/ui/ui-text/src/desktopTest/kotlin/androidx/compose/ui/text/DesktopParagraphTest.kt
index b772c2f..f9c9607 100644
--- a/compose/ui/ui-text/src/desktopTest/kotlin/androidx/compose/ui/text/DesktopParagraphTest.kt
+++ b/compose/ui/ui-text/src/desktopTest/kotlin/androidx/compose/ui/text/DesktopParagraphTest.kt
@@ -21,10 +21,10 @@
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.text.platform.Font
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.unit.Constraints
diff --git a/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
index 09a611f..62a82c2 100644
--- a/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
+++ b/compose/ui/ui-text/src/jvmMain/kotlin/androidx/compose/ui/text/JvmAnnotatedString.jvm.kt
@@ -18,7 +18,6 @@
import androidx.compose.ui.text.AnnotatedString.Range
import androidx.compose.ui.util.fastMap
-
import java.util.SortedSet
/**
diff --git a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt
index b91bd0f..1dde5de 100644
--- a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt
+++ b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/SkiaParagraph.skiko.kt
@@ -16,7 +16,6 @@
package androidx.compose.ui.text
-import org.jetbrains.skia.Rect as SkRect
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.BlendMode
@@ -35,6 +34,7 @@
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.Constraints
import kotlin.math.floor
+import org.jetbrains.skia.Rect as SkRect
import org.jetbrains.skia.paragraph.LineMetrics
import org.jetbrains.skia.paragraph.RectHeightMode
import org.jetbrains.skia.paragraph.RectWidthMode
diff --git a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.sikio.kt b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.sikio.kt
index 5be43e1f..73d9583 100644
--- a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.sikio.kt
+++ b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/font/FontFamilyResolver.sikio.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.text.font
-import androidx.compose.ui.text.platform.FontCache
import androidx.compose.ui.text.ExperimentalTextApi
+import androidx.compose.ui.text.platform.FontCache
import kotlin.coroutines.CoroutineContext
/**
diff --git a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt
index c8a98c8..9eb93ef 100644
--- a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt
+++ b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/PlatformFont.skiko.kt
@@ -17,6 +17,7 @@
import androidx.compose.ui.text.Cache
import androidx.compose.ui.text.ExperimentalTextApi
+import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontListFontFamily
import androidx.compose.ui.text.font.FontLoadingStrategy
@@ -24,13 +25,12 @@
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.font.GenericFontFamily
import androidx.compose.ui.text.font.LoadedFontFamily
+import androidx.compose.ui.text.font.Typeface
+import androidx.compose.ui.text.font.createFontFamilyResolver
import org.jetbrains.skia.FontMgr
import org.jetbrains.skia.Typeface as SkTypeface
import org.jetbrains.skia.paragraph.FontCollection
import org.jetbrains.skia.paragraph.TypefaceFontProvider
-import androidx.compose.ui.text.font.Font
-import androidx.compose.ui.text.font.Typeface
-import androidx.compose.ui.text.font.createFontFamilyResolver
expect sealed class PlatformFont : Font {
abstract val identity: String
diff --git a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaParagraph.skiko.kt b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaParagraph.skiko.kt
index bf56205..58f1b98 100644
--- a/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaParagraph.skiko.kt
+++ b/compose/ui/ui-text/src/skikoMain/kotlin/androidx/compose/ui/text/platform/SkiaParagraph.skiko.kt
@@ -15,22 +15,6 @@
*/
package androidx.compose.ui.text.platform
-import org.jetbrains.skia.Font as SkFont
-import org.jetbrains.skia.FontStyle as SkFontStyle
-import org.jetbrains.skia.paragraph.Alignment as SkAlignment
-import org.jetbrains.skia.paragraph.BaselineMode
-import org.jetbrains.skia.paragraph.DecorationLineStyle as SkDecorationLineStyle
-import org.jetbrains.skia.paragraph.DecorationStyle as SkDecorationStyle
-import org.jetbrains.skia.paragraph.Direction as SkDirection
-import org.jetbrains.skia.paragraph.Paragraph as SkParagraph
-import org.jetbrains.skia.paragraph.ParagraphBuilder as SkParagraphBuilder
-import org.jetbrains.skia.paragraph.ParagraphStyle
-import org.jetbrains.skia.paragraph.PlaceholderAlignment
-import org.jetbrains.skia.paragraph.PlaceholderStyle
-import org.jetbrains.skia.paragraph.Shadow as SkShadow
-import org.jetbrains.skia.paragraph.StrutStyle
-import org.jetbrains.skia.paragraph.TextBox
-import org.jetbrains.skia.paragraph.TextStyle as SkTextStyle
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.graphics.isSpecified
@@ -65,7 +49,23 @@
import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.unit.isUnspecified
import androidx.compose.ui.unit.sp
+import org.jetbrains.skia.Font as SkFont
+import org.jetbrains.skia.FontStyle as SkFontStyle
import org.jetbrains.skia.Paint
+import org.jetbrains.skia.paragraph.Alignment as SkAlignment
+import org.jetbrains.skia.paragraph.BaselineMode
+import org.jetbrains.skia.paragraph.DecorationLineStyle as SkDecorationLineStyle
+import org.jetbrains.skia.paragraph.DecorationStyle as SkDecorationStyle
+import org.jetbrains.skia.paragraph.Direction as SkDirection
+import org.jetbrains.skia.paragraph.Paragraph as SkParagraph
+import org.jetbrains.skia.paragraph.ParagraphBuilder as SkParagraphBuilder
+import org.jetbrains.skia.paragraph.ParagraphStyle
+import org.jetbrains.skia.paragraph.PlaceholderAlignment
+import org.jetbrains.skia.paragraph.PlaceholderStyle
+import org.jetbrains.skia.paragraph.Shadow as SkShadow
+import org.jetbrains.skia.paragraph.StrutStyle
+import org.jetbrains.skia.paragraph.TextBox
+import org.jetbrains.skia.paragraph.TextStyle as SkTextStyle
private val DefaultFontSize = 16.sp
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringTransformTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
index a510bfb..2f4bc88 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/AnnotatedStringTransformTest.kt
@@ -19,10 +19,10 @@
import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.unit.sp
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.Locale
@RunWith(JUnit4::class)
class AnnotatedStringTransformTest {
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/MultiParagraphTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/MultiParagraphTest.kt
index 01b844a..469aa3f 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/MultiParagraphTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/MultiParagraphTest.kt
@@ -17,10 +17,10 @@
package androidx.compose.ui.text
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
@RunWith(JUnit4::class)
class MultiParagraphTest {
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/ParagraphStyleTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/ParagraphStyleTest.kt
index 00d130c..1d3f964 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/ParagraphStyleTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/ParagraphStyleTest.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.text.style.Hyphens
import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.text.style.LineHeightStyle
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.text.style.TextIndent
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
index 998ac9c..f5576cf 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextInputServiceTest.kt
@@ -24,15 +24,15 @@
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.TextInputService
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@Suppress("DEPRECATION")
@RunWith(JUnit4::class)
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
index d6376fd..7b894df 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/TextStyleLayoutAttributesTest.kt
@@ -27,8 +27,8 @@
import androidx.compose.ui.text.style.BaselineShift
import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.text.style.LineHeightStyle
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextDirection
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
index 61855e3f..89883bd 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/font/AsyncFontListLoaderTest.kt
@@ -18,6 +18,9 @@
import androidx.compose.ui.text.ExperimentalTextApi
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.coroutines.coroutineContext
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
@@ -25,9 +28,6 @@
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.coroutines.coroutineContext
@ExperimentalTextApi
@RunWith(JUnit4::class)
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
index dc71dd4..64bd8a4 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/input/EditProcessorTest.kt
@@ -19,6 +19,10 @@
import androidx.compose.ui.text.InternalTextApi
import androidx.compose.ui.text.TextRange
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.eq
@@ -27,10 +31,6 @@
import org.mockito.kotlin.reset
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import kotlin.test.assertFailsWith
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@OptIn(InternalTextApi::class)
@RunWith(JUnit4::class)
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/matchers/EditBufferSubject.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/matchers/EditBufferSubject.kt
index 2505dfe..fcb894e 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/matchers/EditBufferSubject.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/matchers/EditBufferSubject.kt
@@ -21,8 +21,8 @@
import androidx.compose.ui.text.input.PartialGapBuffer
import com.google.common.truth.FailureMetadata
import com.google.common.truth.Subject
-import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertAbout
+import com.google.common.truth.Truth.assertThat
@OptIn(InternalTextApi::class)
internal fun assertThat(buffer: PartialGapBuffer): EditBufferSubject {
diff --git a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/style/LineHeightStyleTest.kt b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/style/LineHeightStyleTest.kt
index 46c7cfd..1aeef097 100644
--- a/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/style/LineHeightStyleTest.kt
+++ b/compose/ui/ui-text/src/test/java/androidx/compose/ui/text/style/LineHeightStyleTest.kt
@@ -18,8 +18,8 @@
package androidx.compose.ui.text.style
import androidx.compose.ui.text.ExperimentalTextApi
-import androidx.compose.ui.text.style.LineHeightStyle.Trim
import androidx.compose.ui.text.style.LineHeightStyle.Alignment
+import androidx.compose.ui.text.style.LineHeightStyle.Trim
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/ui/ui-tooling-data/build.gradle b/compose/ui/ui-tooling-data/build.gradle
index 13f1be5..b69203b 100644
--- a/compose/ui/ui-tooling-data/build.gradle
+++ b/compose/ui/ui-tooling-data/build.gradle
@@ -15,9 +15,8 @@
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,79 +24,70 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
-
- implementation(libs.kotlinStdlib)
-
- api "androidx.annotation:annotation:1.1.0"
-
- api("androidx.compose.runtime:runtime:1.2.1")
- api(project(":compose:ui:ui"))
-
- androidTestImplementation project(":compose:ui:ui-test-junit4")
-
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testRules)
-
- androidTestImplementation(libs.truth)
- androidTestImplementation(project(":compose:foundation:foundation-layout"))
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation(project(":compose:material:material"))
- androidTestImplementation("androidx.activity:activity-compose:1.3.1")
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
-
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
-
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlib)
- api "androidx.annotation:annotation:1.1.0"
-
- api("androidx.compose.runtime:runtime:1.2.1")
+ api(project(":compose:runtime:runtime"))
api(project(":compose:ui:ui"))
}
- jvmMain.dependencies {
- implementation(libs.kotlinStdlib)
- }
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.1.0")
- }
+ }
- commonTest.dependencies {
+ commonTest {
+ dependencies {
implementation(kotlin("test-junit"))
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.truth)
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
}
- androidAndroidTest.dependencies {
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:ui:ui-test-junit4"))
implementation(libs.junit)
@@ -112,9 +102,23 @@
implementation("androidx.activity:activity-compose:1.3.1")
}
}
- }
- dependencies {
- samples(projectOrArtifact(":compose:ui:ui-unit:ui-unit-samples"))
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+
+ }
+ }
+ }
}
}
diff --git a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
index a8d4eee..1ade585 100644
--- a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
+++ b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/BoundsTest.kt
@@ -34,11 +34,11 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@UiToolingDataApi
@MediumTest
diff --git a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/Inspectable.kt b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/Inspectable.kt
index cd30be8..b10d6135 100644
--- a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/Inspectable.kt
+++ b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/Inspectable.kt
@@ -17,10 +17,10 @@
package androidx.compose.ui.tooling.data
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.tooling.CompositionData
-import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.InternalComposeApi
import androidx.compose.runtime.currentComposer
+import androidx.compose.runtime.tooling.CompositionData
import androidx.compose.runtime.tooling.LocalInspectionTables
import androidx.compose.ui.platform.LocalInspectionMode
import java.util.Collections
diff --git a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/InspectableTests.kt b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/InspectableTests.kt
index 5f18bd8..a0802ab 100644
--- a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/InspectableTests.kt
+++ b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/InspectableTests.kt
@@ -35,6 +35,8 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
@@ -42,8 +44,6 @@
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@UiToolingDataApi
@MediumTest
diff --git a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/ToolingTest.kt b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/ToolingTest.kt
index cf7783c..96411de 100644
--- a/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/ToolingTest.kt
+++ b/compose/ui/ui-tooling-data/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/data/ToolingTest.kt
@@ -27,12 +27,12 @@
import androidx.compose.ui.R
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.ViewRootForTest
-import org.junit.Before
-import org.junit.Rule
import java.util.Collections
import java.util.WeakHashMap
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Before
+import org.junit.Rule
open class ToolingTest {
@Suppress("DEPRECATION")
diff --git a/compose/ui/ui-tooling-data/src/androidMain/AndroidManifest.xml b/compose/ui/ui-tooling-data/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 0648ec7..0000000
--- a/compose/ui/ui-tooling-data/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
\ No newline at end of file
diff --git a/compose/ui/ui-tooling-preview/build.gradle b/compose/ui/ui-tooling-preview/build.gradle
index a9f9236..a2aa077 100644
--- a/compose/ui/ui-tooling-preview/build.gradle
+++ b/compose/ui/ui-tooling-preview/build.gradle
@@ -14,10 +14,8 @@
* limitations under the License.
*/
-
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -25,49 +23,93 @@
id("com.android.library")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- implementation(libs.kotlinStdlib)
- api("androidx.annotation:annotation:1.2.0")
- api("androidx.compose.runtime:runtime:1.2.1")
- testImplementation(libs.junit)
- }
-}
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:runtime:runtime"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:runtime:runtime"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.2.0")
}
+ }
- androidTest.dependencies {
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+
+ }
+ }
+ }
+
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.junit)
}
}
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+
+ }
+ }
+ }
}
}
-
androidx {
- name = "Compose Tooling API"
+ name = "Compose UI Preview Tooling"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Compose tooling library API. This library provides the API required to declare" +
diff --git a/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt b/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt
index ba55dd6..348cc14 100644
--- a/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt
+++ b/compose/ui/ui-tooling-preview/src/androidMain/kotlin/androidx/compose/ui/tooling/preview/PreviewParameter.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.tooling.preview
-import kotlin.reflect.KClass
import kotlin.jvm.JvmDefaultWithCompatibility
+import kotlin.reflect.KClass
/**
* Interface to be implemented by any provider of values that you want to be injected as @[Preview]
diff --git a/compose/ui/ui-tooling/build.gradle b/compose/ui/ui-tooling/build.gradle
index 507d5fcf..ea90aee 100644
--- a/compose/ui/ui-tooling/build.gradle
+++ b/compose/ui/ui-tooling/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,69 +23,51 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- implementation(libs.kotlinStdlib)
-
- api("androidx.annotation:annotation:1.1.0")
- implementation(project(":compose:animation:animation"))
-
- api("androidx.compose.runtime:runtime:1.2.1")
- api(project(":compose:ui:ui"))
- api(project(":compose:ui:ui-tooling-preview"))
- api(project(":compose:ui:ui-tooling-data"))
- implementation("androidx.savedstate:savedstate-ktx:1.2.1")
- implementation("androidx.compose.material:material:1.0.0")
- implementation("androidx.activity:activity-compose:1.7.0")
- implementation("androidx.lifecycle:lifecycle-common:2.6.1")
-
- // kotlin-reflect and animation-tooling-internal are provided by Studio at runtime
- compileOnly(project(":compose:animation:animation-tooling-internal"))
- compileOnly(libs.kotlinReflect)
-
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
-
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(project(":compose:foundation:foundation-layout"))
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.kotlinReflect)
- androidTestImplementation(project(":compose:animation:animation-tooling-internal"))
- androidTestImplementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")
- androidTestImplementation(project(":compose:runtime:runtime-livedata"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:ui:ui-tooling-preview"))
api(project(":compose:runtime:runtime"))
api(project(":compose:ui:ui"))
api(project(":compose:ui:ui-tooling-data"))
}
- androidMain.dependencies {
+ }
+
+ commonTest {
+ dependencies {
+
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:runtime:runtime"))
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
implementation(project(":compose:animation:animation"))
implementation("androidx.savedstate:savedstate-ktx:1.2.1")
- implementation(project(":compose:material:material"))
+ implementation("androidx.compose.material:material:1.0.0")
implementation("androidx.activity:activity-compose:1.7.0")
implementation("androidx.lifecycle:lifecycle-common:2.6.1")
@@ -94,14 +75,29 @@
compileOnly(project(":compose:animation:animation-tooling-internal"))
compileOnly(libs.kotlinReflect)
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
- implementation(project(":compose:runtime:runtime"))
- implementation(project(":compose:ui:ui"))
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(skikoMain)
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ implementation(project(":compose:runtime:runtime"))
+ implementation(project(":compose:ui:ui"))
+ }
}
+ }
- androidAndroidTest.dependencies {
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(project(":compose:ui:ui-test-junit4"))
implementation(libs.junit)
@@ -117,10 +113,25 @@
implementation(project(":compose:runtime:runtime-livedata"))
}
}
+
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+
+ }
+ }
+ }
}
}
-
androidx {
name = "Compose Tooling"
type = LibraryType.PUBLISHED_LIBRARY
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/LazyColumnPreview.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/LazyColumnPreview.kt
index a9252ae..03e6561 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/LazyColumnPreview.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/LazyColumnPreview.kt
@@ -18,12 +18,12 @@
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.Surface
import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
@Preview
@Composable
diff --git a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ToolingTest.kt b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ToolingTest.kt
index 5bf2e09..b895328 100644
--- a/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ToolingTest.kt
+++ b/compose/ui/ui-tooling/src/androidAndroidTest/kotlin/androidx/compose/ui/tooling/ToolingTest.kt
@@ -24,10 +24,10 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
-import org.junit.Before
-import org.junit.Rule
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Before
+import org.junit.Rule
open class ToolingTest {
@Suppress("DEPRECATION")
diff --git a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/Inspectable.kt b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/Inspectable.kt
index f859c89..9014cde 100644
--- a/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/Inspectable.kt
+++ b/compose/ui/ui-tooling/src/androidMain/kotlin/androidx/compose/ui/tooling/Inspectable.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.tooling
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.tooling.CompositionData
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.currentComposer
+import androidx.compose.runtime.tooling.CompositionData
import androidx.compose.runtime.tooling.LocalInspectionTables
import androidx.compose.ui.platform.LocalInspectionMode
import java.util.Collections
diff --git a/compose/ui/ui-unit/build.gradle b/compose/ui/ui-unit/build.gradle
index bfbfed7..627cd87 100644
--- a/compose/ui/ui-unit/build.gradle
+++ b/compose/ui/ui-unit/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,85 +23,88 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- api(project(":compose:ui:ui-geometry"))
- api("androidx.annotation:annotation:1.1.0")
-
- implementation(libs.kotlinStdlib)
- implementation("androidx.compose.runtime:runtime:1.2.1")
- implementation(project(":compose:ui:ui-util"))
-
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.kotlinTest)
-
- samples(projectOrArtifact(":compose:ui:ui-unit:ui-unit-samples"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
-
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
api(project(":compose:ui:ui-geometry"))
implementation(project(":compose:runtime:runtime"))
implementation(project(":compose:ui:ui-util"))
}
- jvmMain.dependencies {
- implementation(libs.kotlinStdlib)
- }
- androidMain.dependencies {
- api("androidx.annotation:annotation:1.1.0")
- }
+ }
- commonTest.dependencies {
+ commonTest {
+ dependencies {
implementation(kotlin("test-junit"))
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.truth)
+ jvmMain {
+ dependencies {
+ implementation(libs.kotlinStdlib)
}
- androidAndroidTest.dependencies {
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ api("androidx.annotation:annotation:1.1.0")
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(project(":compose:runtime:runtime"))
+ }
+ }
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.testExtJunit)
implementation(libs.espressoCore)
}
}
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.truth)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
- dependencies {
- samples(projectOrArtifact(":compose:ui:ui-unit:ui-unit-samples"))
- }
+}
+
+dependencies {
+ samples(projectOrArtifact(":compose:ui:ui-unit:ui-unit-samples"))
}
androidx {
diff --git a/compose/ui/ui-unit/samples/build.gradle b/compose/ui/ui-unit/samples/build.gradle
index a1409de..45bec6c 100644
--- a/compose/ui/ui-unit/samples/build.gradle
+++ b/compose/ui/ui-unit/samples/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Compose UI Simple Unit Classes Samples"
+ name = "Compose UI Simple Unit Classes Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Simple Unit Classes"
diff --git a/compose/ui/ui-unit/samples/src/main/AndroidManifest.xml b/compose/ui/ui-unit/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/ui/ui-unit/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/DpDeviceTest.kt b/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/DpDeviceTest.kt
index 29722d3..dc7c3ea 100644
--- a/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/DpDeviceTest.kt
+++ b/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/DpDeviceTest.kt
@@ -18,13 +18,13 @@
import android.app.Activity
import android.util.TypedValue
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/SpDeviceTest.kt b/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/SpDeviceTest.kt
index c7ed473..8c08f71 100644
--- a/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/SpDeviceTest.kt
+++ b/compose/ui/ui-unit/src/androidAndroidTest/kotlin/androidx/compose/ui/unit/SpDeviceTest.kt
@@ -18,13 +18,13 @@
import android.app.Activity
import android.util.TypedValue
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui-unit/src/androidMain/AndroidManifest.xml b/compose/ui/ui-unit/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/compose/ui/ui-unit/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
index c173679..bd1d343 100644
--- a/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
+++ b/compose/ui/ui-unit/src/commonMain/kotlin/androidx/compose/ui/unit/Density.kt
@@ -21,8 +21,8 @@
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.isSpecified
-import kotlin.math.roundToInt
import androidx.compose.ui.unit.internal.JvmDefaultWithCompatibility
+import kotlin.math.roundToInt
/**
* A density of the screen. Used for convert [Dp] to pixels.
diff --git a/compose/ui/ui-util/api/current.txt b/compose/ui/ui-util/api/current.txt
index 5e5e30e..a4ae8f0 100644
--- a/compose/ui/ui-util/api/current.txt
+++ b/compose/ui/ui-util/api/current.txt
@@ -21,6 +21,7 @@
method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachIndexed(java.util.List<? extends T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachReversed(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
+ method public static inline <T> T? fastLastOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public static inline <T, R> java.util.List<R> fastMap(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R, C extends java.util.Collection<? super R>> C fastMapTo(java.util.List<? extends T>, C destination, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R extends java.lang.Comparable<? super R>> T? fastMaxBy(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> selector);
diff --git a/compose/ui/ui-util/api/public_plus_experimental_current.txt b/compose/ui/ui-util/api/public_plus_experimental_current.txt
index 5e5e30e..a4ae8f0 100644
--- a/compose/ui/ui-util/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui-util/api/public_plus_experimental_current.txt
@@ -21,6 +21,7 @@
method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachIndexed(java.util.List<? extends T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachReversed(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
+ method public static inline <T> T? fastLastOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public static inline <T, R> java.util.List<R> fastMap(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R, C extends java.util.Collection<? super R>> C fastMapTo(java.util.List<? extends T>, C destination, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R extends java.lang.Comparable<? super R>> T? fastMaxBy(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> selector);
diff --git a/compose/ui/ui-util/api/restricted_current.txt b/compose/ui/ui-util/api/restricted_current.txt
index 5e5e30e..a4ae8f0 100644
--- a/compose/ui/ui-util/api/restricted_current.txt
+++ b/compose/ui/ui-util/api/restricted_current.txt
@@ -21,6 +21,7 @@
method public static inline <T> void fastForEach(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachIndexed(java.util.List<? extends T>, kotlin.jvm.functions.Function2<? super java.lang.Integer,? super T,kotlin.Unit> action);
method public static inline <T> void fastForEachReversed(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,kotlin.Unit> action);
+ method public static inline <T> T? fastLastOrNull(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,java.lang.Boolean> predicate);
method public static inline <T, R> java.util.List<R> fastMap(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R, C extends java.util.Collection<? super R>> C fastMapTo(java.util.List<? extends T>, C destination, kotlin.jvm.functions.Function1<? super T,? extends R> transform);
method public static inline <T, R extends java.lang.Comparable<? super R>> T? fastMaxBy(java.util.List<? extends T>, kotlin.jvm.functions.Function1<? super T,? extends R> selector);
diff --git a/compose/ui/ui-util/build.gradle b/compose/ui/ui-util/build.gradle
index 8eeb75e..4c19723 100644
--- a/compose/ui/ui-util/build.gradle
+++ b/compose/ui/ui-util/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
@@ -24,59 +23,72 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- dependencies {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- implementation(libs.kotlinStdlib)
-
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.kotlinTest)
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
}
+ }
- jvmMain.dependencies {
- implementation(libs.kotlinStdlib)
- }
-
- androidMain.dependencies {
- implementation(libs.kotlinStdlib)
- }
-
- commonTest.dependencies {
+ commonTest {
+ dependencies {
implementation(kotlin("test-junit"))
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
+ jvmMain {
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ }
+ }
+
+ jvmTest {
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ }
+ }
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.truth)
}
}
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ }
+ }
}
}
diff --git a/compose/ui/ui-util/src/androidMain/AndroidManifest.xml b/compose/ui/ui-util/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index b47339d..0000000
--- a/compose/ui/ui-util/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/ListUtils.kt b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/ListUtils.kt
index 25b8c3c..217cc13 100644
--- a/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/ListUtils.kt
+++ b/compose/ui/ui-util/src/commonMain/kotlin/androidx/compose/ui/util/ListUtils.kt
@@ -203,3 +203,21 @@
}
return destination
}
+
+/**
+ * Returns the last element matching the given [predicate], or `null` if no such element was found.
+ *
+ * **Do not use for collections that come from public APIs**, since they may not support random
+ * access in an efficient way, and this method may actually be a lot slower. Only use for
+ * collections that are created by code we control and are known to support random access.
+ */
+@Suppress("BanInlineOptIn")
+@OptIn(ExperimentalContracts::class)
+inline fun <T> List<T>.fastLastOrNull(predicate: (T) -> Boolean): T? {
+ contract { callsInPlace(predicate) }
+ for (index in indices.reversed()) {
+ val item = get(index)
+ if (predicate(item)) return item
+ }
+ return null
+}
diff --git a/compose/ui/ui-util/src/test/kotlin/androidx/compose/ui/util/ListUtilsTest.kt b/compose/ui/ui-util/src/test/kotlin/androidx/compose/ui/util/ListUtilsTest.kt
index ec25815..d59b8b1 100644
--- a/compose/ui/ui-util/src/test/kotlin/androidx/compose/ui/util/ListUtilsTest.kt
+++ b/compose/ui/ui-util/src/test/kotlin/androidx/compose/ui/util/ListUtilsTest.kt
@@ -115,4 +115,16 @@
val list = listOf(0, -1, -500, 1)
assertEquals(1, list.fastFirstOrNull { it > 0 })
}
-}
\ No newline at end of file
+
+ @Test
+ fun lastOrNullFound() {
+ val list = listOf(1, -1, -500, 2)
+ assertEquals(2, list.fastLastOrNull { it > 0 })
+ }
+
+ @Test
+ fun lastOrNullNotFound() {
+ val list = listOf(-1, -1, -500, -2)
+ assertNull(list.fastLastOrNull { it > 0 })
+ }
+}
diff --git a/compose/ui/ui-viewbinding/samples/build.gradle b/compose/ui/ui-viewbinding/samples/build.gradle
index 29fab3b..88219c6 100644
--- a/compose/ui/ui-viewbinding/samples/build.gradle
+++ b/compose/ui/ui-viewbinding/samples/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "AndroidX Compose UI Simple Unit Classes Samples"
+ name = "Compose UI Simple Unit Classes Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Simple Unit Classes"
diff --git a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/AndroidViewBindingTest.kt b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/AndroidViewBindingTest.kt
index f1b25c9..908b85a 100644
--- a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/AndroidViewBindingTest.kt
+++ b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/AndroidViewBindingTest.kt
@@ -33,8 +33,8 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.viewinterop.AndroidViewBinding
import androidx.compose.ui.viewbinding.samples.databinding.SampleLayoutBinding
+import androidx.compose.ui.viewinterop.AndroidViewBinding
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
diff --git a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/FragmentRecreateTest.kt b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/FragmentRecreateTest.kt
index 8dea4a0..1439a9b 100644
--- a/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/FragmentRecreateTest.kt
+++ b/compose/ui/ui-viewbinding/samples/src/androidTest/java/androidx/compose/ui/samples/FragmentRecreateTest.kt
@@ -20,10 +20,10 @@
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.activity.compose.setContent
+import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.viewbinding.samples.R
import androidx.compose.ui.viewbinding.samples.databinding.TestFragmentLayoutBinding
import androidx.compose.ui.viewinterop.AndroidViewBinding
-import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentContainerView
diff --git a/compose/ui/ui-viewbinding/samples/src/main/AndroidManifest.xml b/compose/ui/ui-viewbinding/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/compose/ui/ui-viewbinding/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/compose/ui/ui-viewbinding/src/main/AndroidManifest.xml b/compose/ui/ui-viewbinding/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/compose/ui/ui-viewbinding/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index eeeb983..39aa37f 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -236,6 +236,7 @@
}
public final class DrawModifierKt {
+ method public static androidx.compose.ui.node.CacheDrawModifierNode CacheDrawModifierNode(kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawBehind(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
method public static androidx.compose.ui.Modifier drawWithCache(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawWithContent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.ContentDrawScope,kotlin.Unit> onDraw);
@@ -2264,6 +2265,10 @@
package androidx.compose.ui.node {
+ public interface CacheDrawModifierNode extends androidx.compose.ui.node.DrawModifierNode {
+ method public void invalidateDrawCache();
+ }
+
public interface CompositionLocalConsumerModifierNode extends androidx.compose.ui.node.DelegatableNode {
}
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index 2a98886..baaa2b1 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -318,6 +318,7 @@
}
public final class DrawModifierKt {
+ method public static androidx.compose.ui.node.CacheDrawModifierNode CacheDrawModifierNode(kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawBehind(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
method public static androidx.compose.ui.Modifier drawWithCache(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawWithContent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.ContentDrawScope,kotlin.Unit> onDraw);
@@ -2064,6 +2065,8 @@
public interface IntrinsicMeasureScope extends androidx.compose.ui.unit.Density {
method public androidx.compose.ui.unit.LayoutDirection getLayoutDirection();
+ method @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead();
+ property @androidx.compose.ui.ExperimentalComposeUiApi public default boolean isLookingAhead;
property public abstract androidx.compose.ui.unit.LayoutDirection layoutDirection;
}
@@ -2481,6 +2484,10 @@
package androidx.compose.ui.node {
+ public interface CacheDrawModifierNode extends androidx.compose.ui.node.DrawModifierNode {
+ method public void invalidateDrawCache();
+ }
+
public interface CompositionLocalConsumerModifierNode extends androidx.compose.ui.node.DelegatableNode {
}
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index c17196f..7ce042d 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -236,6 +236,7 @@
}
public final class DrawModifierKt {
+ method public static androidx.compose.ui.node.CacheDrawModifierNode CacheDrawModifierNode(kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawBehind(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.DrawScope,kotlin.Unit> onDraw);
method public static androidx.compose.ui.Modifier drawWithCache(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.draw.CacheDrawScope,androidx.compose.ui.draw.DrawResult> onBuildDrawCache);
method public static androidx.compose.ui.Modifier drawWithContent(androidx.compose.ui.Modifier, kotlin.jvm.functions.Function1<? super androidx.compose.ui.graphics.drawscope.ContentDrawScope,kotlin.Unit> onDraw);
@@ -2271,6 +2272,10 @@
package androidx.compose.ui.node {
+ public interface CacheDrawModifierNode extends androidx.compose.ui.node.DrawModifierNode {
+ method public void invalidateDrawCache();
+ }
+
@kotlin.PublishedApi internal interface ComposeUiNode {
method public androidx.compose.runtime.CompositionLocalMap getCompositionLocalMap();
method public androidx.compose.ui.unit.Density getDensity();
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/OnPositionedBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/OnPositionedBenchmark.kt
index b14c52c..564fce8a 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/OnPositionedBenchmark.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/OnPositionedBenchmark.kt
@@ -29,11 +29,11 @@
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/AndroidTapIntegrationBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/AndroidTapIntegrationBenchmark.kt
index c6c0d53..87a6eab 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/AndroidTapIntegrationBenchmark.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/AndroidTapIntegrationBenchmark.kt
@@ -32,13 +32,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import org.junit.Assert
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
/**
* Benchmark for simply tapping on an item in Android.
diff --git a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/VelocityTrackerBenchmark.kt b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/VelocityTrackerBenchmark.kt
index eb56a62..058b533 100644
--- a/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/VelocityTrackerBenchmark.kt
+++ b/compose/ui/ui/benchmark/src/androidTest/java/androidx/compose/ui/benchmark/input/pointer/VelocityTrackerBenchmark.kt
@@ -17,10 +17,8 @@
import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
import androidx.compose.ui.input.pointer.util.VelocityTracker1D
-
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
-
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 2b2f069..caff544 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -14,9 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import static androidx.inspection.gradle.InspectionPluginKt.packageInspector
@@ -26,130 +25,16 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
- constraints {
- // In 1.4.0-alpha02 there was a change made in :compose:ui:ui which fixed an issue where
- // we were over-invalidating layout. This change caused a corresponding regression in
- // foundation's CoreText, where it was expecting a layout to happen but with this change
- // it would not. A corresponding fix for this was added in 1.4.0-alpha02 of
- // :compose:foundation:foundation. By adding this constraint, we are ensuring that the
- // if an app has this ui module _and_ the foundation module as a dependency, then the
- // version of foundation will be at least this version. This will prevent the bug in
- // foundation from occurring. This does _NOT_ require that the app have foundation as
- // a dependency.
- implementation(project(":compose:foundation:foundation")) {
- because 'prevents a critical bug in Text'
- }
- }
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
- implementation(libs.kotlinCoroutinesCore)
- // when updating the runtime version please also update the runtime-saveable version
- implementation(project(":compose:runtime:runtime"))
- api(project(":compose:runtime:runtime-saveable"))
-
- api(project(":compose:ui:ui-geometry"))
- api(project(":compose:ui:ui-graphics"))
- api(project(":compose:ui:ui-text"))
- api(project(":compose:ui:ui-unit"))
- api("androidx.annotation:annotation:1.5.0")
-
- // This has stub APIs for access to legacy Android APIs, so we don't want
- // any dependency on this module.
- compileOnly(project(":compose:ui:ui-android-stubs"))
-
- implementation(project(":compose:ui:ui-util"))
- implementation(libs.kotlinStdlib)
- implementation("androidx.autofill:autofill:1.0.0")
- implementation(libs.kotlinCoroutinesAndroid)
-
- // Used to generate debug information in the layout inspector. If not present,
- // we may fall back to more limited data.
- compileOnly(libs.kotlinReflect)
- testImplementation(libs.kotlinReflect)
-
- implementation("androidx.activity:activity-ktx:1.7.0")
- implementation(project(":core:core"))
- implementation('androidx.collection:collection:1.0.0')
- implementation("androidx.customview:customview-poolingcontainer:1.0.0")
- implementation("androidx.savedstate:savedstate-ktx:1.2.1")
- implementation("androidx.lifecycle:lifecycle-runtime:2.6.1")
- implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
- implementation("androidx.profileinstaller:profileinstaller:1.3.0")
- implementation("androidx.emoji2:emoji2:1.2.0")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.kotlinCoroutinesTest)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
- testImplementation(libs.mockitoCore4)
- testImplementation(libs.mockitoKotlin4)
- testImplementation(libs.robolectric)
- testImplementation(project(":compose:ui:ui-test-junit4"))
- testImplementation(project(":compose:test-utils"))
-
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testExtJunitKtx)
- androidTestImplementation(libs.testUiautomator)
- androidTestImplementation(libs.kotlinCoroutinesTest)
- androidTestImplementation(libs.kotlinTest)
- androidTestImplementation(libs.espressoCore)
- androidTestImplementation(libs.bundles.espressoContrib)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.dexmakerMockito)
- androidTestImplementation(libs.mockitoCore)
- androidTestImplementation(libs.truth)
- androidTestImplementation(libs.mockitoKotlin)
- androidTestImplementation(libs.material)
- androidTestImplementation(project(":compose:animation:animation-core"))
- androidTestImplementation(project(":compose:foundation:foundation"))
- androidTestImplementation(project(":compose:foundation:foundation-layout"))
- androidTestImplementation(project(":compose:material:material"))
- androidTestImplementation(project(":compose:test-utils"))
- androidTestImplementation(project(":internal-testutils-fonts"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":internal-testutils-runtime"))
- androidTestImplementation(project(":test:screenshot:screenshot"))
- androidTestImplementation("androidx.lifecycle:lifecycle-runtime-testing:2.6.1")
- androidTestImplementation("androidx.recyclerview:recyclerview:1.3.0-alpha02")
- androidTestImplementation("androidx.core:core-ktx:1.9.0")
- androidTestImplementation("androidx.activity:activity-compose:1.7.0")
- androidTestImplementation("androidx.appcompat:appcompat:1.3.0")
- androidTestImplementation("androidx.fragment:fragment:1.3.0")
-
- lintChecks(project(":compose:ui:ui-lint"))
- lintPublish(project(":compose:ui:ui-lint"))
-
- samples(project(":compose:ui:ui:ui-samples"))
- }
-}
-
-packageInspector(project, ":compose:ui:ui-inspection")
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
implementation(libs.kotlinCoroutinesCore)
@@ -163,8 +48,33 @@
api project(":compose:ui:ui-unit")
implementation(project(":compose:ui:ui-util"))
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ implementation(libs.kotlinReflect)
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ }
+ }
+
+ if (desktopEnabled) {
+ skikoMain {
+ dependsOn(commonMain)
+ dependencies {
+ api(project(":compose:ui:ui-graphics"))
+ api(libs.skikoCommon)
+ }
+ }
+ }
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
implementation(libs.kotlinStdlib)
// This has stub APIs for access to legacy Android APIs, so we don't want
// any dependency on this module.
@@ -181,48 +91,32 @@
implementation("androidx.lifecycle:lifecycle-runtime:2.6.1")
implementation("androidx.lifecycle:lifecycle-viewmodel:2.6.1")
implementation("androidx.emoji2:emoji2:1.2.0")
- }
- jvmMain.dependencies {
- implementation(libs.kotlinStdlib)
+ implementation("androidx.profileinstaller:profileinstaller:1.3.0")
}
- skikoMain {
- dependsOn(commonMain)
- dependencies {
- api(project(":compose:ui:ui-graphics"))
- api(libs.skikoCommon)
- }
- }
+ }
+
+ if (desktopEnabled) {
desktopMain {
dependsOn(skikoMain)
+ dependsOn(jvmMain)
dependencies {
+ implementation(libs.kotlinStdlib)
implementation(libs.kotlinStdlibJdk8)
api(libs.kotlinCoroutinesSwing)
}
}
+ }
- commonTest.dependencies {
- implementation(libs.kotlinReflect)
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.kotlinCoroutinesTest)
- implementation(libs.junit)
- implementation(libs.truth)
- implementation(libs.mockitoCore4)
- implementation(libs.mockitoKotlin4)
- implementation(project(":compose:ui:ui-test-junit4"))
- implementation(project(":internal-testutils-fonts"))
- implementation(project(":compose:test-utils"))
- }
-
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation("androidx.fragment:fragment:1.3.0")
implementation("androidx.appcompat:appcompat:1.3.0")
implementation(libs.testUiautomator)
@@ -253,36 +147,84 @@
implementation("androidx.core:core-ktx:1.2.0")
implementation("androidx.activity:activity-compose:1.7.0")
}
+ }
- desktopTest.dependencies {
- implementation(libs.truth)
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.kotlinCoroutinesTest)
implementation(libs.junit)
- implementation(libs.mockitoCore)
- implementation(libs.mockitoKotlin)
- implementation(libs.skikoCurrentOs)
- implementation(project(":compose:material:material"))
+ implementation(libs.truth)
implementation(project(":compose:ui:ui-test-junit4"))
+ implementation(project(":internal-testutils-fonts"))
+ implementation(project(":compose:test-utils"))
+ }
+ }
+
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ implementation(libs.truth)
+ implementation(libs.junit)
+ implementation(libs.mockitoCore)
+ implementation(libs.mockitoKotlin)
+ implementation(libs.skikoCurrentOs)
+ implementation(project(":compose:material:material"))
+ implementation(project(":compose:ui:ui-test-junit4"))
+ }
}
}
}
- dependencies {
- samples(project(":compose:ui:ui:ui-samples"))
+}
- // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
- // leaks into instrumented tests (b/214407011)
- testImplementation(libs.robolectric)
+dependencies {
+
+ constraints {
+ // In 1.4.0-alpha02 there was a change made in :compose:ui:ui which fixed an issue where
+ // we were over-invalidating layout. This change caused a corresponding regression in
+ // foundation's CoreText, where it was expecting a layout to happen but with this change
+ // it would not. A corresponding fix for this was added in 1.4.0-alpha02 of
+ // :compose:foundation:foundation. By adding this constraint, we are ensuring that the
+ // if an app has this ui module _and_ the foundation module as a dependency, then the
+ // version of foundation will be at least this version. This will prevent the bug in
+ // foundation from occurring. This does _NOT_ require that the app have foundation as
+ // a dependency.
+ implementation(project(":compose:foundation:foundation")) {
+ because 'prevents a critical bug in Text'
+ }
}
}
+packageInspector(project, ":compose:ui:ui-inspection")
+
+dependencies {
+ lintChecks(project(":compose:ui:ui-lint"))
+ lintPublish(project(":compose:ui:ui-lint"))
+
+ // Can't declare this in kotlin { sourceSets { androidTest.dependencies { .. } } } as that
+ // leaks into instrumented tests (b/214407011)
+ testImplementation(libs.robolectric)
+ testImplementation(libs.mockitoCore4)
+ testImplementation(libs.mockitoKotlin4)
+}
+
androidx {
- name = "Compose UI primitives"
+ name = "Compose UI"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2019"
description = "Compose UI primitives. This library contains the primitives that form the Compose UI Toolkit, such as drawing, measurement and layout."
legacyDisableKotlinStrictApiMode = true
}
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
+if (desktopEnabled) {
tasks.findByName("desktopTest").configure {
systemProperties["GOLDEN_PATH"] = project.rootDir.absolutePath + "/../../golden"
}
@@ -304,24 +246,3 @@
// the androidx.compose.ui:ui-test library
testNamespace "androidx.compose.ui.tests"
}
-
-// Diagnostics for b/188565660
-def verifyKotlinModule(String variant) {
- project.afterEvaluate {
- def capitalVariant = variant.capitalize()
- def moduleFile = new File("${buildDir}/tmp/kotlin-classes/${variant}/META-INF/ui_${variant}.kotlin_module")
- tasks.named("compile${capitalVariant}Kotlin").configure { t ->
- t.doLast {
- // This file should be large, about 3.2K. If this file is short then many symbols will fail to resolve
- if (moduleFile.length() < 250) {
- throw new GradleException("kotlin_module file ($moduleFile) too short! See b/188565660 for more information. File text: ${moduleFile.text}")
- }
- }
- }
- }
-}
-if (!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- for (variant in ["debug", "release"]) {
- verifyKotlinModule(variant)
- }
-}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/MultipleCollect.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/MultipleCollect.kt
index 0496cc5..a6a1c30 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/MultipleCollect.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/MultipleCollect.kt
@@ -18,13 +18,13 @@
package androidx.compose.ui.demos
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.unit.Constraints
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/PopupDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/PopupDemo.kt
index 6e7516c..b5cc1be 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/PopupDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/PopupDemo.kt
@@ -27,9 +27,9 @@
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.requiredHeight
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
@@ -42,6 +42,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -59,7 +60,7 @@
@Composable
fun PopupDemo() {
- val exampleIndex = remember { mutableStateOf(0) }
+ var exampleIndex by remember { mutableIntStateOf(0) }
val totalExamples = 8
Column {
@@ -71,11 +72,11 @@
text = "Prev",
color = Color.Cyan,
onClick = {
- if (exampleIndex.value == 0) {
- exampleIndex.value = totalExamples
+ if (exampleIndex == 0) {
+ exampleIndex = totalExamples
}
- exampleIndex.value = (exampleIndex.value - 1) % totalExamples
+ exampleIndex = (exampleIndex - 1) % totalExamples
},
padding = 20.dp
)
@@ -85,7 +86,7 @@
contentAlignment = Alignment.Center
) {
val description: String = {
- when (exampleIndex.value) {
+ when (exampleIndex) {
0 -> "Shadow demo"
1 -> "Toggle a simple popup"
2 -> "Different content for the popup"
@@ -118,13 +119,13 @@
text = "Next",
color = Color.Cyan,
onClick = {
- exampleIndex.value = (exampleIndex.value + 1) % totalExamples
+ exampleIndex = (exampleIndex + 1) % totalExamples
},
padding = 20.dp
)
}
- when (exampleIndex.value) {
+ when (exampleIndex) {
0 -> PopupElevation()
1 -> PopupToggle()
2 -> PopupWithChangingContent()
@@ -143,7 +144,7 @@
var shape by remember { mutableStateOf(RectangleShape) }
var background by remember { mutableStateOf(Color.Transparent) }
var contentSize by remember { mutableStateOf(100.dp) }
- var dismissCounter by remember { mutableStateOf(0) }
+ var dismissCounter by remember { mutableIntStateOf(0) }
var elevation by remember { mutableStateOf(6.dp) }
// This example utilizes the Card to draw its shadow.
@@ -238,18 +239,18 @@
Column(Modifier.align(Alignment.CenterHorizontally)) {
val heightSize = 120.dp
val widthSize = 160.dp
- val popupContentState = remember { mutableStateOf(0) }
+ var popupContentState by remember { mutableIntStateOf(0) }
val totalContentExamples = 2
- val popupCounter = remember { mutableStateOf(0) }
+ var popupCounter by remember { mutableIntStateOf(0) }
Box(Modifier.size(widthSize, heightSize).background(Color.Gray)) {
Popup(Alignment.Center) {
- when (popupContentState.value % totalContentExamples) {
+ when (popupContentState % totalContentExamples) {
0 -> ClickableTextWithBackground(
- text = "Counter : ${popupCounter.value}",
+ text = "Counter : $popupCounter",
color = Color.Green,
onClick = {
- popupCounter.value += 1
+ popupCounter += 1
}
)
1 -> Box(
@@ -264,7 +265,7 @@
text = "Change content",
color = Color.Cyan,
onClick = {
- popupContentState.value += 1
+ popupContentState++
}
)
}
@@ -328,7 +329,7 @@
Column(Modifier.align(Alignment.CenterHorizontally)) {
val heightSize = 200.dp
val widthSize = 400.dp
- val counter = remember { mutableStateOf(0) }
+ var counter by remember { mutableIntStateOf(0) }
val popupAlignment = remember { mutableStateOf(Alignment.TopStart) }
Box(
modifier = Modifier.size(widthSize, heightSize).background(Color.Red),
@@ -339,8 +340,8 @@
text = "Click to change alignment",
color = Color.White,
onClick = {
- counter.value += 1
- when (counter.value % 9) {
+ counter++
+ when (counter % 9) {
0 -> popupAlignment.value = Alignment.TopStart
1 -> popupAlignment.value = Alignment.TopCenter
2 -> popupAlignment.value = Alignment.TopEnd
@@ -413,7 +414,7 @@
val showPopup = remember { mutableStateOf(true) }
val heightSize = 120.dp
val widthSize = 160.dp
- val rectangleState = remember { mutableStateOf(0) }
+ var rectangleState by remember { mutableIntStateOf(0) }
Spacer(Modifier.height(15.dp))
Box(
@@ -421,7 +422,7 @@
) {
if (showPopup.value) {
Popup(Alignment.Center) {
- val size = when (rectangleState.value % 4) {
+ val size = when (rectangleState % 4) {
0 -> Modifier.size(30.dp)
1 -> Modifier.size(100.dp)
2 -> Modifier.size(30.dp, 90.dp)
@@ -436,7 +437,7 @@
text = "Change size",
color = Color.Cyan,
onClick = {
- rectangleState.value += 1
+ rectangleState++
}
)
}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/UiDemos.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/UiDemos.kt
index 4e65849..7576a56 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/UiDemos.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/UiDemos.kt
@@ -33,12 +33,12 @@
import androidx.compose.ui.demos.focus.FocusInPopupDemo
import androidx.compose.ui.demos.focus.FocusManagerMoveFocusDemo
import androidx.compose.ui.demos.focus.FocusableDemo
+import androidx.compose.ui.demos.focus.LazyListChildFocusDemos
+import androidx.compose.ui.demos.focus.NestedLazyListFocusSearchDemo
import androidx.compose.ui.demos.focus.OneDimensionalFocusSearchDemo
import androidx.compose.ui.demos.focus.ReuseFocusRequesterDemo
import androidx.compose.ui.demos.focus.ScrollableLazyRowFocusDemo
import androidx.compose.ui.demos.focus.ScrollableRowFocusDemo
-import androidx.compose.ui.demos.focus.LazyListChildFocusDemos
-import androidx.compose.ui.demos.focus.NestedLazyListFocusSearchDemo
import androidx.compose.ui.demos.focus.TwoDimensionalFocusSearchDemo
import androidx.compose.ui.demos.gestures.ButtonMetaStateDemo
import androidx.compose.ui.demos.gestures.DetectTapGesturesDemo
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/DragSlopExceededGestureFilterDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/DragSlopExceededGestureFilterDemo.kt
index 4ffbac4..9834a47 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/DragSlopExceededGestureFilterDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/DragSlopExceededGestureFilterDemo.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.demos.gestures
import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitTouchSlopOrCancellation
-import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
index d11018e..f6aa708 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/HorizontalScrollersInVerticalScrollerDemo.kt
@@ -18,6 +18,7 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.border
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
@@ -28,12 +29,14 @@
import androidx.compose.foundation.layout.size
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.clipRect
@@ -80,28 +83,28 @@
@Composable
private fun Scrollable(orientation: Orientation, content: @Composable () -> Unit) {
val maxOffset = 0f
- val offset = remember { mutableStateOf(maxOffset) }
- val minOffset = remember { mutableStateOf(0f) }
+ var offset by remember { mutableFloatStateOf(maxOffset) }
+ var minOffset by remember { mutableFloatStateOf(0f) }
Layout(
content = content,
modifier = Modifier.scrollable(
orientation = orientation,
state = rememberScrollableState { scrollDistance ->
- val resultingOffset = offset.value + scrollDistance
+ val resultingOffset = offset + scrollDistance
val toConsume =
when {
resultingOffset > maxOffset -> {
- maxOffset - offset.value
+ maxOffset - offset
}
- resultingOffset < minOffset.value -> {
- minOffset.value - offset.value
+ resultingOffset < minOffset -> {
+ minOffset - offset
}
else -> {
scrollDistance
}
}
- offset.value = offset.value + toConsume
+ offset = offset + toConsume
toConsume
}
)
@@ -123,7 +126,7 @@
)
}
- minOffset.value =
+ minOffset =
when (orientation) {
Orientation.Horizontal -> constraints.maxWidth.toFloat() - placeable.width
Orientation.Vertical -> constraints.maxHeight.toFloat() - placeable.height
@@ -143,8 +146,8 @@
layout(width, height) {
when (orientation) {
- Orientation.Horizontal -> placeable.placeRelative(offset.value.roundToInt(), 0)
- Orientation.Vertical -> placeable.placeRelative(0, offset.value.roundToInt())
+ Orientation.Horizontal -> placeable.placeRelative(offset.roundToInt(), 0)
+ Orientation.Vertical -> placeable.placeRelative(0, offset.roundToInt())
}
}
}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
index 3978b89..213634a 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/NestedScrollingDemo.kt
@@ -19,23 +19,26 @@
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
-import androidx.compose.foundation.gestures.rememberScrollableState
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.Layout
@@ -79,8 +82,8 @@
*/
@Composable
private fun ScrollableContainer(content: @Composable () -> Unit) {
- val offset = remember { mutableStateOf(0f) }
- val maxOffset = remember { mutableStateOf(0f) }
+ var offset by remember { mutableFloatStateOf(0f) }
+ var maxOffset by remember { mutableFloatStateOf(0f) }
Layout(
content = content,
@@ -88,20 +91,20 @@
.scrollable(
orientation = Orientation.Vertical,
state = rememberScrollableState { scrollDistance ->
- val resultingOffset = offset.value + scrollDistance
+ val resultingOffset = offset + scrollDistance
val dyToConsume =
when {
resultingOffset > 0f -> {
- 0f - offset.value
+ 0f - offset
}
- resultingOffset < maxOffset.value -> {
- maxOffset.value - offset.value
+ resultingOffset < maxOffset -> {
+ maxOffset - offset
}
else -> {
scrollDistance
}
}
- offset.value += dyToConsume
+ offset += dyToConsume
dyToConsume
}
)
@@ -111,10 +114,10 @@
measurables.first()
.measure(constraints.copy(minHeight = 0, maxHeight = Constraints.Infinity))
- maxOffset.value = (constraints.maxHeight - placeable.height).toFloat()
+ maxOffset = (constraints.maxHeight - placeable.height).toFloat()
layout(constraints.maxWidth, constraints.maxHeight) {
- placeable.placeRelative(0, offset.value.roundToInt())
+ placeable.placeRelative(0, offset.roundToInt())
}
}
)
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
index 0e7c5e7..17e91b3 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/PointerInputDuringSubCompDemo.kt
@@ -26,8 +26,10 @@
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
@@ -68,16 +70,16 @@
.background(color = Color.White)
) {
items(100) {
- val pointerCount = remember { mutableStateOf(0) }
+ var pointerCount by remember { mutableIntStateOf(0) }
Box(
Modifier.fillParentMaxSize()
.border(width = 1.dp, color = Color.Black)
- .pointerCounterGestureFilter { newCount -> pointerCount.value = newCount },
+ .pointerCounterGestureFilter { newCount -> pointerCount = newCount },
contentAlignment = Alignment.Center
) {
Text(
- "${pointerCount.value}",
+ "$pointerCount",
fontSize = 16.em,
color = Color.Black
)
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/RawDragGestureDetectorDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/RawDragGestureDetectorDemo.kt
index 004e2b7..e1ec630 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/RawDragGestureDetectorDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/RawDragGestureDetectorDemo.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.demos.gestures
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
index fea7034..695fb40 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/ScrollGestureFilterDemo.kt
@@ -16,10 +16,11 @@
package androidx.compose.ui.demos.gestures
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsDraggedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -29,11 +30,12 @@
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
@@ -70,10 +72,10 @@
val interactionSource = remember { MutableInteractionSource() }
val color = if (interactionSource.collectIsDraggedAsState().value) activeColor else idleColor
- val offsetPx = remember { mutableStateOf(0f) }
+ var offsetPx by remember { mutableFloatStateOf(0f) }
val offsetDp = with(LocalDensity.current) {
- offsetPx.value.toDp()
+ offsetPx.toDp()
}
val (offsetX, offsetY) = when (orientation) {
Orientation.Horizontal -> offsetDp to Dp.Hairline
@@ -88,7 +90,7 @@
interactionSource = interactionSource,
orientation = orientation,
state = rememberScrollableState { scrollDistance ->
- offsetPx.value += scrollDistance
+ offsetPx += scrollDistance
scrollDistance
}
)
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/TapPressureGestureDetectorDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/TapPressureGestureDetectorDemo.kt
index 0acd6aa91..709b169 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/TapPressureGestureDetectorDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/TapPressureGestureDetectorDemo.kt
@@ -30,6 +30,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -68,9 +69,9 @@
"For some pen supported devices, a finger touch pressure will equal 1.0."
)
- var gestureOffsetX by remember { mutableStateOf(0f) }
- var gestureOffsetY by remember { mutableStateOf(0f) }
- var gesturePressure by remember { mutableStateOf(0f) }
+ var gestureOffsetX by remember { mutableFloatStateOf(0f) }
+ var gestureOffsetY by remember { mutableFloatStateOf(0f) }
+ var gesturePressure by remember { mutableFloatStateOf(0f) }
// Gestures (detectDragGestures) with pressure.
Box(
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
index 192a5b5..f755807 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/gestures/VerticalScrollerInDrawerLayoutDemo.kt
@@ -18,6 +18,7 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.border
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.gestures.scrollable
@@ -28,19 +29,21 @@
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.DrawModifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.clipRect
@@ -84,17 +87,16 @@
-drawerWidth.toPx()
}
- val currentOffset = remember { mutableStateOf(minOffset) }
+ var currentOffset by remember { mutableFloatStateOf(minOffset) }
val maxOffset = 0f
Box(
Modifier.scrollable(
orientation = Orientation.Horizontal,
state = rememberScrollableState { scrollDistance ->
- val originalOffset = currentOffset.value
- currentOffset.value =
- (currentOffset.value + scrollDistance).coerceIn(minOffset, maxOffset)
- currentOffset.value - originalOffset
+ val originalOffset = currentOffset
+ currentOffset = (currentOffset + scrollDistance).coerceIn(minOffset, maxOffset)
+ currentOffset - originalOffset
}
)
) {
@@ -103,7 +105,7 @@
Modifier
.fillMaxHeight()
.requiredWidth(drawerWidth)
- .offset { IntOffset(currentOffset.value.roundToInt(), 0) }
+ .offset { IntOffset(currentOffset.roundToInt(), 0) }
.background(color = DefaultBackgroundColor)
) {
Text(
@@ -122,28 +124,28 @@
@Composable
private fun Scrollable(orientation: Orientation, content: @Composable () -> Unit) {
val maxOffset = 0f
- val offset = remember { mutableStateOf(maxOffset) }
- val minOffset = remember { mutableStateOf(0f) }
+ var offset by remember { mutableFloatStateOf(maxOffset) }
+ var minOffset by remember { mutableFloatStateOf(0f) }
Layout(
content = content,
modifier = Modifier.scrollable(
orientation = orientation,
state = rememberScrollableState { scrollDistance ->
- val resultingOffset = offset.value + scrollDistance
+ val resultingOffset = offset + scrollDistance
val toConsume =
when {
resultingOffset > maxOffset -> {
- maxOffset - offset.value
+ maxOffset - offset
}
- resultingOffset < minOffset.value -> {
- minOffset.value - offset.value
+ resultingOffset < minOffset -> {
+ minOffset - offset
}
else -> {
scrollDistance
}
}
- offset.value = offset.value + toConsume
+ offset += toConsume
toConsume
}
).then(ClipModifier),
@@ -164,7 +166,7 @@
)
}
- minOffset.value =
+ minOffset =
when (orientation) {
Orientation.Horizontal -> constraints.maxWidth.toFloat() - placeable.width
Orientation.Vertical -> constraints.maxHeight.toFloat() - placeable.height
@@ -184,8 +186,8 @@
layout(width, height) {
when (orientation) {
- Orientation.Horizontal -> placeable.placeRelative(offset.value.roundToInt(), 0)
- Orientation.Vertical -> placeable.placeRelative(0, offset.value.roundToInt())
+ Orientation.Horizontal -> placeable.placeRelative(offset.roundToInt(), 0)
+ Orientation.Vertical -> placeable.placeRelative(0, offset.roundToInt())
}
}
}
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/modifier/CommunicatingModifierDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/modifier/CommunicatingModifierDemo.kt
index 6e04d4c..80b0d2e 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/modifier/CommunicatingModifierDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/modifier/CommunicatingModifierDemo.kt
@@ -38,8 +38,8 @@
import androidx.compose.ui.graphics.Color.Companion.Gray
import androidx.compose.ui.graphics.Color.Companion.Red
import androidx.compose.ui.modifier.modifierLocalConsumer
-import androidx.compose.ui.modifier.modifierLocalProvider
import androidx.compose.ui.modifier.modifierLocalOf
+import androidx.compose.ui.modifier.modifierLocalProvider
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/recyclerview/RecyclerViewInteropDemoFragment.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/recyclerview/RecyclerViewInteropDemoFragment.kt
index 507e519..6a610255 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/recyclerview/RecyclerViewInteropDemoFragment.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/recyclerview/RecyclerViewInteropDemoFragment.kt
@@ -34,6 +34,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -122,7 +123,7 @@
attrs: AttributeSet? = null,
defStyle: Int = 0
) : AbstractComposeView(context, attrs, defStyle) {
- var index by mutableStateOf(0)
+ var index by mutableIntStateOf(0)
var rowState: LazyListState? by mutableStateOf(null)
@Composable
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/FocusTransferDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/FocusTransferDemo.kt
index b412aa6..61c2a44 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/FocusTransferDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/FocusTransferDemo.kt
@@ -24,24 +24,24 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
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.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.focus.focusTarget
+import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.unit.sp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.recyclerview.widget.RecyclerView.VERTICAL
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.ui.focus.focusTarget
-import androidx.compose.ui.focus.onFocusEvent
-import androidx.compose.ui.unit.sp
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
@Composable
fun FocusTransferDemo() {
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/NestedScrollInterop.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/NestedScrollInterop.kt
index 8ccc757..c584f2e 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/NestedScrollInterop.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/NestedScrollInterop.kt
@@ -44,8 +44,10 @@
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.demos.R
@@ -73,14 +75,14 @@
@Composable
private fun OuterComposeWithNestedScroll(factory: (Context) -> View) {
val toolbarHeightPx = with(LocalDensity.current) { ToolbarHeight.roundToPx().toFloat() }
- val toolbarOffsetHeightPx = remember { mutableStateOf(0f) }
+ var toolbarOffsetHeightPx by remember { mutableFloatStateOf(0f) }
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
- val newOffset = toolbarOffsetHeightPx.value + delta
- toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)
+ val newOffset = toolbarOffsetHeightPx + delta
+ toolbarOffsetHeightPx = newOffset.coerceIn(-toolbarHeightPx, 0f)
return Offset.Zero
}
}
@@ -96,8 +98,8 @@
TopAppBar(
modifier = Modifier
.height(ToolbarHeight)
- .offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) },
- title = { Text("toolbar offset is ${toolbarOffsetHeightPx.value}") }
+ .offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.roundToInt()) },
+ title = { Text("toolbar offset is $toolbarOffsetHeightPx") }
)
// Android View
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
index 20eb48b..6cfb3ae 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ScrollingAndroidViewsDemo.kt
@@ -30,6 +30,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -79,7 +80,7 @@
checkedItems: Set<Int>,
onChangeCheck: (Int, Boolean) -> Unit
) {
- var allocationCounter by remember { mutableStateOf(0) }
+ var allocationCounter by remember { mutableIntStateOf(0) }
val resetViews = remember { mutableSetOf<View>() }
LazyColumn {
diff --git a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ViewInterop.kt b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ViewInterop.kt
index 4300e08..20cfb51 100644
--- a/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ViewInterop.kt
+++ b/compose/ui/ui/integration-tests/ui-demos/src/main/java/androidx/compose/ui/demos/viewinterop/ViewInterop.kt
@@ -30,7 +30,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -56,7 +56,7 @@
AndroidView({ context -> TextView(context).apply { text = "This is a TextView" } })
// Compose Android View and update its size based on state. The AndroidView takes modifiers.
- var size by remember { mutableStateOf(20) }
+ var size by remember { mutableIntStateOf(20) }
AndroidView(::View, Modifier.clickable { size += 20 }.background(Color.Blue)) { view ->
view.layoutParams = ViewGroup.LayoutParams(size, size)
}
@@ -74,7 +74,7 @@
Button(onClick = { squareRef.value!!.size += 50 }) {
Text("Increase size of Android view")
}
- val colorIndex = remember { mutableStateOf(0) }
+ val colorIndex = remember { mutableIntStateOf(0) }
Button(
onClick = {
colorIndex.value = (colorIndex.value + 1) % 4
diff --git a/compose/ui/ui/samples/build.gradle b/compose/ui/ui/samples/build.gradle
index f2675f6..d201f40 100644
--- a/compose/ui/ui/samples/build.gradle
+++ b/compose/ui/ui/samples/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "AndroidX Compose UI Core Classes Samples"
+ name = "Compose UI Core Classes Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Compose UI Core Classes"
diff --git a/compose/ui/ui/samples/src/main/AndroidManifest.xml b/compose/ui/ui/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a69672..0000000
--- a/compose/ui/ui/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2019 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 />
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/AlphaSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/AlphaSample.kt
index 0eda2b2..8dab4ab 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/AlphaSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/AlphaSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/BlurSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/BlurSample.kt
index c97aec8..4ecd92c 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/BlurSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/BlurSample.kt
@@ -18,8 +18,8 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/DialogSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/DialogSample.kt
index b5508de..d66efbd 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/DialogSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/DialogSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
index 6c41b9f8..6908017 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayoutSample.kt
@@ -22,11 +22,11 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
-import androidx.compose.ui.layout.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
+import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.LayoutModifier
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasurePolicy
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadLayoutSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadLayoutSample.kt
index 343c89d..6d4e513 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadLayoutSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LookaheadLayoutSample.kt
@@ -40,14 +40,17 @@
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
+import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.LookaheadScope
import androidx.compose.ui.layout.intermediateLayout
+import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
@@ -209,3 +212,53 @@
}
}
}
+
+@Sampled
+@Composable
+fun animateContentSizeAfterLookaheadPass() {
+ var sizeAnim by remember {
+ mutableStateOf<Animatable<IntSize, AnimationVector2D>?>(null)
+ }
+ var lookaheadSize by remember {
+ mutableStateOf<IntSize?>(null)
+ }
+ val coroutineScope = rememberCoroutineScope()
+ LookaheadScope {
+ // The Box is in a LookaheadScope. This means there will be a lookahead measure pass
+ // before the main measure pass.
+ // Here we are creating something similar to the `animateContentSize` modifier.
+ Box(
+ Modifier
+ .clipToBounds()
+ .layout { measurable, constraints ->
+ val placeable = measurable.measure(constraints)
+
+ val measuredSize = IntSize(placeable.width, placeable.height)
+ val (width, height) = if (isLookingAhead) {
+ // Record lookahead size if we are in lookahead pass. This lookahead size
+ // will be used for size animation, such that the main measure pass will
+ // gradually change size until it reaches the lookahead size.
+ lookaheadSize = measuredSize
+ measuredSize
+ } else {
+ // Since we are in an explicit lookaheadScope, we know the lookahead pass
+ // is guaranteed to happen, therefore the lookahead size that we recorded is
+ // not null.
+ val target = requireNotNull(lookaheadSize)
+ val anim = sizeAnim?.also {
+ coroutineScope.launch { it.animateTo(target) }
+ } ?: Animatable(target, IntSize.VectorConverter)
+ sizeAnim = anim
+ // By returning the animated size only during main pass, we are allowing
+ // lookahead pass to see the future layout past the animation.
+ anim.value
+ }
+
+ layout(width, height) {
+ placeable.place(0, 0)
+ }
+ }) {
+ // Some content that changes size
+ }
+ }
+}
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/ModifierLocalSamples.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/ModifierLocalSamples.kt
index 0db443d..d1869e6 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/ModifierLocalSamples.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/ModifierLocalSamples.kt
@@ -28,8 +28,8 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.modifier.modifierLocalConsumer
-import androidx.compose.ui.modifier.modifierLocalProvider
import androidx.compose.ui.modifier.modifierLocalOf
+import androidx.compose.ui.modifier.modifierLocalProvider
@OptIn(ExperimentalComposeUiApi::class)
@Sampled
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/OnGloballyPositionedSamples.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/OnGloballyPositionedSamples.kt
index 479029d..1b414e9 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/OnGloballyPositionedSamples.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/OnGloballyPositionedSamples.kt
@@ -17,15 +17,15 @@
package androidx.compose.ui.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.unit.dp
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PainterSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PainterSample.kt
index cbfcaea..f39a660 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PainterSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PainterSample.kt
@@ -18,8 +18,8 @@
import androidx.annotation.Sampled
import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.runtime.Composable
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PopupSample.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PopupSample.kt
index 5939d56..7d311d3 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PopupSample.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/PopupSample.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.samples
import androidx.annotation.Sampled
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
index ffa6615..bd38fe1 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AccessibilityIteratorsTest.kt
@@ -42,11 +42,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth
+import java.util.Locale
+import kotlin.math.abs
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Locale
-import kotlin.math.abs
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
index 5d49476..67b261a 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidAccessibilityTest.kt
@@ -43,8 +43,8 @@
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.focusable
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Arrangement
@@ -57,8 +57,8 @@
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.progressSemantics
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
@@ -158,8 +158,8 @@
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.DpOffset
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastMap
import androidx.compose.ui.viewinterop.AndroidView
@@ -171,13 +171,8 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.argThat
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
+import java.lang.reflect.Method
+import kotlin.math.max
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import org.junit.Assert.assertEquals
@@ -195,8 +190,13 @@
import org.mockito.ArgumentMatcher
import org.mockito.ArgumentMatchers.any
import org.mockito.internal.matchers.apachecommons.ReflectionEquals
-import java.lang.reflect.Method
-import kotlin.math.max
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
index 337f866..5a160ba 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidComposeViewAccessibilityDelegateCompatTest.kt
@@ -135,17 +135,6 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argThat
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.never
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
import java.util.concurrent.Executors
import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.asCoroutineDispatcher
@@ -158,6 +147,17 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/MemoryLeakTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/MemoryLeakTest.kt
index 9610e78..c6d3e83 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/MemoryLeakTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/MemoryLeakTest.kt
@@ -32,6 +32,8 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import java.text.NumberFormat
+import java.util.Locale
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@@ -39,8 +41,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.text.NumberFormat
-import java.util.Locale
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
index adf79b7..9f8bae1 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/ParentDataModifierTest.kt
@@ -37,6 +37,8 @@
import androidx.compose.ui.unit.Density
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
@@ -44,8 +46,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/RecyclerViewIntegrationTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/RecyclerViewIntegrationTest.kt
index 380b9b7..5d1a315 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/RecyclerViewIntegrationTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/RecyclerViewIntegrationTest.kt
@@ -34,10 +34,10 @@
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Test
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/AlphaTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/AlphaTest.kt
index d21fe8b..d67a405 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/AlphaTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/AlphaTest.kt
@@ -37,15 +37,15 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.max
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.max
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/DrawReorderingTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/DrawReorderingTest.kt
index 568809a..57531e5 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/DrawReorderingTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/DrawReorderingTest.kt
@@ -43,14 +43,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerModifierTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerModifierTest.kt
index 618ceb7..78b3042 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerModifierTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerModifierTest.kt
@@ -20,10 +20,10 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
-import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.DefaultCameraDistance
import androidx.compose.ui.graphics.DefaultShadowColor
import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.InspectableValue
import androidx.compose.ui.platform.ValueElement
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/PainterModifierTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/PainterModifierTest.kt
index 3d6683e..e49c957 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/PainterModifierTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/PainterModifierTest.kt
@@ -94,6 +94,8 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.max
+import kotlin.math.roundToInt
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
@@ -101,8 +103,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.max
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/ShadowTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/ShadowTest.kt
index f9d9136d..8f23d70 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/ShadowTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/ShadowTest.kt
@@ -50,6 +50,8 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertEquals
@@ -60,8 +62,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/CustomFocusTraversalTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/CustomFocusTraversalTest.kt
index e3749d3..d3eccf4 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/CustomFocusTraversalTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/CustomFocusTraversalTest.kt
@@ -27,12 +27,12 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.key.Key.Companion.Tab
-import androidx.compose.ui.input.key.Key.Companion.DirectionUp
import androidx.compose.ui.input.key.Key.Companion.DirectionDown
import androidx.compose.ui.input.key.Key.Companion.DirectionLeft
import androidx.compose.ui.input.key.Key.Companion.DirectionRight
+import androidx.compose.ui.input.key.Key.Companion.DirectionUp
import androidx.compose.ui.input.key.Key.Companion.Enter
+import androidx.compose.ui.input.key.Key.Companion.Tab
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.input.key.nativeKeyCode
import androidx.compose.ui.platform.LocalFocusManager
@@ -40,10 +40,10 @@
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performKeyPress
import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusChangedCountTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusChangedCountTest.kt
index f7b0dad..d1b5b2d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusChangedCountTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusChangedCountTest.kt
@@ -21,8 +21,8 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.FocusStateImpl.Inactive
import androidx.compose.ui.focus.FocusStateImpl.Active
+import androidx.compose.ui.focus.FocusStateImpl.Inactive
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusRequesterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusRequesterTest.kt
index 7f44c86..faa13ae 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusRequesterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/FocusRequesterTest.kt
@@ -28,11 +28,11 @@
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
+import androidx.compose.ui.focus.focusRequester as modifierNodeFocusRequester
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.focus.focusRequester as modifierNodeFocusRequester
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/KeyEventToFocusDirectionTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/KeyEventToFocusDirectionTest.kt
index 9cce01f..94dce03 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/KeyEventToFocusDirectionTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/focus/KeyEventToFocusDirectionTest.kt
@@ -16,8 +16,13 @@
package androidx.compose.ui.focus
+import android.view.KeyEvent as AndroidKeyEvent
+import android.view.KeyEvent.ACTION_DOWN as KeyDown
+import android.view.KeyEvent.META_SHIFT_ON as Shift
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.focus.FocusDirection.Companion.Down
+import androidx.compose.ui.focus.FocusDirection.Companion.Enter
+import androidx.compose.ui.focus.FocusDirection.Companion.Exit
import androidx.compose.ui.focus.FocusDirection.Companion.Left
import androidx.compose.ui.focus.FocusDirection.Companion.Next
import androidx.compose.ui.focus.FocusDirection.Companion.Previous
@@ -36,11 +41,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import android.view.KeyEvent as AndroidKeyEvent
-import android.view.KeyEvent.ACTION_DOWN as KeyDown
-import android.view.KeyEvent.META_SHIFT_ON as Shift
-import androidx.compose.ui.focus.FocusDirection.Companion.Enter
-import androidx.compose.ui.focus.FocusDirection.Companion.Exit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
index 0a383f3..190fd50 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/CursorAnchorInfoBuilderTest.kt
@@ -20,10 +20,10 @@
import android.view.inputmethod.CursorAnchorInfo
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.MultiParagraph
-import androidx.compose.ui.text.TextRange
-import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.TextLayoutInput
import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.TextRange
+import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
index 9028277..ed4776e 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/RecordingInputConnectionTest.kt
@@ -33,16 +33,16 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
index 0aff99c..2bec941 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidEmojiTest.kt
@@ -29,12 +29,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
index 73c44e6..9d383b7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/TextInputServiceAndroidOnStateUpdateTest.kt
@@ -31,6 +31,9 @@
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
@@ -38,9 +41,6 @@
import org.mockito.kotlin.reset
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
index 3baf4aa..6d7da47 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/focus/FocusAwareEventPropagationTest.kt
@@ -31,8 +31,8 @@
import androidx.compose.ui.input.focus.FocusAwareEventPropagationTest.NodeType.KeyInput
import androidx.compose.ui.input.focus.FocusAwareEventPropagationTest.NodeType.RotaryInput
import androidx.compose.ui.input.key.KeyEvent
-import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.onInterceptKeyBeforeSoftKeyboard
+import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.input.key.onPreInterceptKeyBeforeSoftKeyboard
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.rotary.RotaryScrollEvent
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/AndroidProcessKeyInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/AndroidProcessKeyInputTest.kt
index f17a1a2..f88a7ed 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/AndroidProcessKeyInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/AndroidProcessKeyInputTest.kt
@@ -16,6 +16,7 @@
package androidx.compose.ui.input.key
+import android.view.KeyEvent as AndroidKeyEvent
import android.view.KeyEvent.ACTION_DOWN as ActionDown
import android.view.KeyEvent.ACTION_UP as ActionUp
import android.view.KeyEvent.KEYCODE_A as KeyCodeA
@@ -30,18 +31,17 @@
import androidx.compose.ui.input.key.Key.Companion.A
import androidx.compose.ui.input.key.KeyEventType.Companion.KeyDown
import androidx.compose.ui.input.key.KeyEventType.Companion.KeyUp
+import androidx.compose.ui.node.DelegatingNode
import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.semantics.elementFor
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import android.view.KeyEvent as AndroidKeyEvent
-import androidx.compose.ui.node.DelegatingNode
-import androidx.compose.ui.semantics.elementFor
-import org.junit.Ignore
import org.mockito.kotlin.inOrder
/**
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/HardwareKeyInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/HardwareKeyInputTest.kt
index 5b4c1ba..262aaa7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/HardwareKeyInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/HardwareKeyInputTest.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.input.key
import android.view.KeyEvent as AndroidKeyEvent
-import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import android.view.KeyEvent.ACTION_DOWN
import android.view.KeyEvent.ACTION_UP
+import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.requiredSize
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/KeyTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/KeyTest.kt
index 6358175..3e73445 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/KeyTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/KeyTest.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.input.key
-import androidx.compose.ui.ExperimentalComposeUiApi
import android.view.KeyEvent.KEYCODE_A as KeyCodeA
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/MetaKeyTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/MetaKeyTest.kt
index 5acd3bb..f4e78eb 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/MetaKeyTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/MetaKeyTest.kt
@@ -16,9 +16,9 @@
package androidx.compose.ui.input.key
-import android.view.KeyEvent.KEYCODE_A as KeyCodeA
-import android.view.KeyEvent.ACTION_DOWN as KeyDown
import android.view.KeyEvent as AndroidKeyEvent
+import android.view.KeyEvent.ACTION_DOWN as KeyDown
+import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
index 0c88d69..b085af2 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/key/ProcessKeyInputTest.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.input.key
import android.view.KeyEvent as AndroidKeyEvent
-import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import android.view.KeyEvent.ACTION_DOWN
import android.view.KeyEvent.ACTION_UP
+import android.view.KeyEvent.KEYCODE_A as KeyCodeA
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
index 6470495..46f9946 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
@@ -80,10 +80,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
-import org.mockito.kotlin.never
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.verify
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -92,8 +90,10 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/ClipPointerInputTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/ClipPointerInputTest.kt
index 905cbb2..0777bc1 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/ClipPointerInputTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/ClipPointerInputTest.kt
@@ -46,12 +46,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/LayerTouchTransformTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/LayerTouchTransformTest.kt
index e065521..7f69a0d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/LayerTouchTransformTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/LayerTouchTransformTest.kt
@@ -43,14 +43,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.max
import org.junit.Assert
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.max
@LargeTest
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MouseEventTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MouseEventTest.kt
index 1899a3c..9f9ade5 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MouseEventTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/MouseEventTest.kt
@@ -35,10 +35,10 @@
import androidx.compose.ui.unit.dp
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Rule
+import org.junit.Test
@MediumTest
@OptIn(ExperimentalTestApi::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
index 849c2b9..877e911 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterAndroidViewOffsetsTest.kt
@@ -34,15 +34,15 @@
import androidx.compose.ui.viewinterop.AndroidView
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.clearInvocations
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
// Tests that pointer offsets are correct when a pointer is dispatched from Android through
// Compose and back into Android and each layer offsets the pointer during dispatch.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
index 32fd60c..f761c28 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/PointerInteropFilterTest.kt
@@ -4405,38 +4405,3 @@
)
internal typealias PointerEventHandler = (PointerEvent, PointerEventPass, IntSize) -> Unit
-
-private fun PointerEventHandler.invokeOverAllPasses(
- pointerEvent: PointerEvent,
- size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
-) {
- invokeOverPasses(
- pointerEvent,
- listOf(
- PointerEventPass.Initial,
- PointerEventPass.Main,
- PointerEventPass.Final
- ),
- size = size
- )
-}
-
-private fun PointerEventHandler.invokeOverPasses(
- pointerEvent: PointerEvent,
- vararg pointerEventPasses: PointerEventPass,
- size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
-) {
- invokeOverPasses(pointerEvent, pointerEventPasses.toList(), size)
-}
-
-private fun PointerEventHandler.invokeOverPasses(
- pointerEvent: PointerEvent,
- pointerEventPasses: List<PointerEventPass>,
- size: IntSize = IntSize(Int.MAX_VALUE, Int.MAX_VALUE)
-) {
- require(pointerEvent.changes.isNotEmpty())
- require(pointerEventPasses.isNotEmpty())
- pointerEventPasses.forEach {
- this.invoke(pointerEvent, it, size)
- }
-}
\ No newline at end of file
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
index c521919..6a82429 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilterTest.kt
@@ -52,9 +52,9 @@
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.Rule
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/AlignmentLineTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/AlignmentLineTest.kt
index b3b3736..5714cc7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/AlignmentLineTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/AlignmentLineTest.kt
@@ -22,8 +22,8 @@
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -33,8 +33,8 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import org.junit.Assert.assertEquals
import kotlin.math.min
+import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
index 302768a..378d5b7 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/LookaheadScopeTest.kt
@@ -65,8 +65,11 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Matrix
+import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.LayoutNode
+import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.platform.AndroidOwnerExtraAssertionsRule
+import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.unit.Constraints
@@ -83,6 +86,7 @@
import androidx.test.filters.MediumTest
import java.lang.Integer.max
import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import kotlin.math.roundToInt
import kotlin.random.Random
@@ -1928,6 +1932,218 @@
}
}
+ @OptIn(ExperimentalComposeUiApi::class)
+ @Test
+ fun testIsLookingAhead() {
+ var iterations by mutableStateOf(0)
+ val size = mutableMapOf<Boolean, IntSize>()
+ rule.setContent {
+ Box(Modifier.fillMaxSize()) {
+ LookaheadScope {
+ // Fill max size will cause the remeasure requests to go down the
+ // forceMeasureSubtree code path.
+ CompositionLocalProvider(LocalDensity provides Density(1f)) {
+ Column(Modifier.fillMaxSize()) {
+ // This box will get a remeasure request when `iterations` changes.
+ // Subsequently this Box's size change will trigger a measurement pass
+ // from Column.
+ Box(
+ Modifier
+ .layout { measurable, constraints ->
+ measurable
+ .measure(constraints)
+ .run {
+ size[isLookingAhead] = IntSize(width, height)
+ layout(width, height) {
+ place(0, 0)
+ }
+ }
+ }
+ .intermediateLayout { measurable, _ ->
+ // Force a state-read (similar to animation but more
+ // reliable)
+ measurable
+ .measure(Constraints.fixed(200 + 100 * iterations, 200))
+ .run {
+ layout(width, height) {
+ place(0, 0)
+ }
+ }
+ }) {
+ Box(Modifier.size(100.dp))
+ }
+ }
+ SubcomposeLayout(
+ Modifier
+ .fillMaxSize()
+ .requiredSize(200.dp),
+ intermediateMeasurePolicy = { constraints ->
+ assertFalse(isLookingAhead)
+ measurablesForSlot(Unit)[0].measure(constraints)
+ layout(0, 0) {}
+ }
+ ) { constraints ->
+ assertTrue(isLookingAhead)
+ val placeable = subcompose(Unit) {
+ Box(Modifier.requiredSize(400.dp, 600.dp))
+ }[0].measure(constraints)
+ layout(500, 300) {
+ placeable.place(0, 0)
+ }
+ }
+ }
+ }
+ }
+ }
+ repeat(4) {
+ rule.runOnIdle {
+ assertEquals(IntSize(100, 100), size[true])
+ assertEquals(IntSize(200 + 100 * it, 200), size[false])
+ iterations++
+ }
+ }
+ }
+
+ class TestLayoutModifierNode(
+ var lookaheadIntrinsicResult: MutableMap<String, Int>,
+ var intrinsicResult: MutableMap<String, Int>
+ ) : LayoutModifierNode, Modifier.Node() {
+ override fun MeasureScope.measure(
+ measurable: Measurable,
+ constraints: Constraints
+ ): MeasureResult {
+ return measurable.measure(constraints).run {
+ layout(width, height) {
+ place(0, 0)
+ }
+ }
+ }
+
+ override fun IntrinsicMeasureScope.maxIntrinsicHeight(
+ measurable: IntrinsicMeasurable,
+ width: Int
+ ): Int = measurable.maxIntrinsicHeight(width).also {
+ if (isLookingAhead) {
+ lookaheadIntrinsicResult["maxHeight"] = it
+ } else {
+ intrinsicResult["maxHeight"] = it
+ }
+ }
+
+ override fun IntrinsicMeasureScope.minIntrinsicHeight(
+ measurable: IntrinsicMeasurable,
+ width: Int
+ ): Int = measurable.minIntrinsicHeight(width).also {
+ if (isLookingAhead) {
+ lookaheadIntrinsicResult["minHeight"] = it
+ } else {
+ intrinsicResult["minHeight"] = it
+ }
+ }
+
+ override fun IntrinsicMeasureScope.maxIntrinsicWidth(
+ measurable: IntrinsicMeasurable,
+ height: Int
+ ): Int = measurable.maxIntrinsicWidth(height).also {
+ if (isLookingAhead) {
+ lookaheadIntrinsicResult["maxWidth"] = it
+ } else {
+ intrinsicResult["maxWidth"] = it
+ }
+ }
+
+ override fun IntrinsicMeasureScope.minIntrinsicWidth(
+ measurable: IntrinsicMeasurable,
+ height: Int
+ ): Int = measurable.minIntrinsicWidth(height).also {
+ if (isLookingAhead) {
+ lookaheadIntrinsicResult["minWidth"] = it
+ } else {
+ intrinsicResult["minWidth"] = it
+ }
+ }
+ }
+
+ data class TestElement(
+ val lookaheadIntrinsicResult: MutableMap<String, Int>,
+ val intrinsicResult: MutableMap<String, Int>
+ ) : ModifierNodeElement<TestLayoutModifierNode>() {
+ override fun create(): TestLayoutModifierNode =
+ TestLayoutModifierNode(lookaheadIntrinsicResult, intrinsicResult)
+
+ override fun update(node: TestLayoutModifierNode) {
+ node.lookaheadIntrinsicResult = lookaheadIntrinsicResult
+ node.intrinsicResult = intrinsicResult
+ }
+
+ override fun InspectorInfo.inspectableProperties() {
+ name = "TestElement"
+ properties["lookaheadIntrinsicResult"] = lookaheadIntrinsicResult
+ properties["intrinsicResult"] = intrinsicResult
+ }
+ }
+
+ @Test
+ fun testIsLookingAheadWithIntrinsics() {
+ val lookaheadIntrinsicsResult = mutableMapOf<String, Int>()
+ val intrinsicsResult = mutableMapOf<String, Int>()
+ val modifierList = listOf(
+ Modifier.width(IntrinsicSize.Max),
+ Modifier.width(IntrinsicSize.Min),
+ Modifier.height(IntrinsicSize.Max),
+ Modifier.height(IntrinsicSize.Min),
+ )
+ var iteration by mutableStateOf(0)
+ rule.setContent {
+ LookaheadScope {
+ CompositionLocalProvider(LocalDensity provides Density(1f)) {
+ Row(Modifier.width(IntrinsicSize.Max)) {
+ Box(
+ Modifier
+ .fillMaxSize()
+ .then(modifierList[iteration])
+ .then(
+ TestElement(
+ lookaheadIntrinsicsResult, intrinsicsResult
+ )
+ )
+ .layout { measurable, constraints ->
+ measurable
+ .measure(constraints)
+ .run {
+ if (isLookingAhead) {
+ layout(200, 250) {
+ place(0, 0)
+ }
+ } else {
+ layout(100, 150) {
+ place(0, 0)
+ }
+ }
+ }
+ }) {
+ Box(Modifier.size(10.dp))
+ }
+ }
+ }
+ }
+ }
+ repeat(3) {
+ rule.waitForIdle()
+ iteration++
+ }
+ rule.runOnIdle {
+ assertEquals(250, lookaheadIntrinsicsResult["maxHeight"])
+ assertEquals(250, lookaheadIntrinsicsResult["minHeight"])
+ assertEquals(200, lookaheadIntrinsicsResult["maxWidth"])
+ assertEquals(200, lookaheadIntrinsicsResult["minWidth"])
+ assertEquals(150, intrinsicsResult["maxHeight"])
+ assertEquals(150, intrinsicsResult["minHeight"])
+ assertEquals(100, intrinsicsResult["maxWidth"])
+ assertEquals(100, intrinsicsResult["minWidth"])
+ }
+ }
+
@Test
fun forceMeasureSubtreeWhileLookaheadMeasureRequestedFromSubtree() {
var iterations by mutableStateOf(0)
@@ -1960,13 +2176,17 @@
if (iterations % 2 == 0)
Modifier.size(100.dp)
else
- Modifier.intermediateLayout { measurable, constraints ->
- measurable.measure(constraints).run {
- layout(width, height) {
- place(5, 5)
- }
+ Modifier
+ .intermediateLayout { measurable, constraints ->
+ measurable
+ .measure(constraints)
+ .run {
+ layout(width, height) {
+ place(5, 5)
+ }
+ }
}
- }.padding(5.dp)
+ .padding(5.dp)
)
}
}
@@ -2099,6 +2319,7 @@
with(scope) {
this@composed
.intermediateLayout { measurable, constraints ->
+ assertFalse(isLookingAhead)
lookaheadSize = this.lookaheadSize
measureWithLambdas(
prePlacement = {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/MeasureInPlacementTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/MeasureInPlacementTest.kt
index d272794..6f18534 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/MeasureInPlacementTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/MeasureInPlacementTest.kt
@@ -38,11 +38,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnSizeChangedTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnSizeChangedTest.kt
index b825a77..cadfde0 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnSizeChangedTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/OnSizeChangedTest.kt
@@ -35,6 +35,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
@@ -43,8 +45,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RootNodeLayoutTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RootNodeLayoutTest.kt
index 26569b5..d850fd8 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RootNodeLayoutTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RootNodeLayoutTest.kt
@@ -27,6 +27,8 @@
import androidx.compose.ui.unit.Constraints
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull
@@ -35,8 +37,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
index 038a111..37fe213 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/layout/RtlLayoutTest.kt
@@ -43,6 +43,10 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.abs
+import kotlin.math.roundToInt
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@@ -50,10 +54,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.abs
-import kotlin.math.roundToInt
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/HotReloadTests.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/HotReloadTests.kt
index b84b840..f9326295 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/HotReloadTests.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/HotReloadTests.kt
@@ -33,12 +33,12 @@
import androidx.compose.ui.test.onNodeWithTag
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
index 08c37a0..42dc17d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/node/ModelReadsTest.kt
@@ -32,6 +32,8 @@
import androidx.compose.ui.test.TestActivity
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -39,8 +41,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInAppCompatActivityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInAppCompatActivityTest.kt
index 9bfe97c..6c8d88b 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInAppCompatActivityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInAppCompatActivityTest.kt
@@ -23,14 +23,14 @@
import androidx.lifecycle.LifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInComponentActivityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInComponentActivityTest.kt
index 336d599..9d79d60 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInComponentActivityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInComponentActivityTest.kt
@@ -23,14 +23,14 @@
import androidx.lifecycle.LifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInFragmentTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInFragmentTest.kt
index 44fb3a0..497f8be 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInFragmentTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/LifecycleOwnerInFragmentTest.kt
@@ -29,14 +29,14 @@
import androidx.lifecycle.LifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInAppCompatActivityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInAppCompatActivityTest.kt
index 2594fa9..f548965 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInAppCompatActivityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInAppCompatActivityTest.kt
@@ -23,14 +23,14 @@
import androidx.savedstate.SavedStateRegistryOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInComponentActivityTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInComponentActivityTest.kt
index d78a893..648ac1d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInComponentActivityTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInComponentActivityTest.kt
@@ -23,14 +23,14 @@
import androidx.savedstate.SavedStateRegistryOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInFragmentTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInFragmentTest.kt
index 0a290e5..9f5f371 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInFragmentTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/owners/SavedStateRegistryOwnerInFragmentTest.kt
@@ -28,14 +28,14 @@
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
index d9a4bc8..f35c3e2 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
@@ -32,15 +32,14 @@
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.sp
-
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidUiDispatcherTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidUiDispatcherTest.kt
index 5575793..e550f57 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidUiDispatcherTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidUiDispatcherTest.kt
@@ -32,10 +32,18 @@
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
+import java.util.concurrent.atomic.AtomicInteger
+import kotlin.coroutines.ContinuationInterceptor
+import kotlin.coroutines.CoroutineContext
+import kotlin.test.fail
import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Runnable
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
@@ -174,4 +182,60 @@
}
)
}
+
+ /**
+ * Test that an AndroidUiDispatcher can be wrapped by another ContinuationInterceptor
+ * without breaking the MonotonicFrameClock's ability to coordinate with its
+ * original dispatcher.
+ *
+ * Construct a situation where the Choreographer contains three frame callbacks:
+ * 1) checkpoint 1
+ * 2) the AndroidUiDispatcher awaiting-frame callback
+ * 3) checkpoint 2
+ * Confirm that a call to withFrameNanos made *after* these three frame callbacks
+ * are enqueued runs *before* checkpoint 2, indicating that it ran with the original
+ * dispatcher's awaiting-frame callback, even though we wrapped the dispatcher.
+ */
+ @Test
+ fun wrappedDispatcherPostsToDispatcherFrameClock() = runBlocking(Dispatchers.Main) {
+ val uiDispatcherContext = AndroidUiDispatcher.Main
+ val uiDispatcher = uiDispatcherContext[ContinuationInterceptor] as CoroutineDispatcher
+ val wrapperDispatcher = object : CoroutineDispatcher() {
+ override fun dispatch(context: CoroutineContext, block: Runnable) {
+ uiDispatcher.dispatch(context, block)
+ }
+ }
+
+ val choreographer = Choreographer.getInstance()
+
+ val expectCount = AtomicInteger(1)
+ fun expect(value: Int) {
+ while (true) {
+ val old = expectCount.get()
+ if (old != value) fail("expected sequence $old but encountered $value")
+ if (expectCount.compareAndSet(value, value + 1)) break
+ }
+ }
+
+ choreographer.postFrameCallback {
+ expect(1)
+ }
+
+ launch(uiDispatcherContext, start = CoroutineStart.UNDISPATCHED) {
+ withFrameNanos {
+ expect(2)
+ }
+ }
+
+ choreographer.postFrameCallback {
+ expect(4)
+ }
+
+ withContext(uiDispatcherContext + wrapperDispatcher) {
+ withFrameNanos {
+ expect(3)
+ }
+ expect(5)
+ }
+ }
}
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
index 54db114..432b2fe 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidViewCompatTest.kt
@@ -94,11 +94,14 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import junit.framework.TestCase.assertNotNull
-import org.hamcrest.CoreMatchers.`is`
+import kotlin.math.roundToInt
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.endsWith
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.not
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -107,9 +110,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
/**
* Testing the support for Android Views in Compose UI.
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
index 3893b7b..7de34c5 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DepthSortedSetTest.kt
@@ -23,11 +23,11 @@
import androidx.compose.ui.node.add
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import org.mockito.kotlin.spy
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.spy
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistryTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistryTest.kt
index e6e19a8..e5e4927 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistryTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/DisposableSaveableStateRegistryTest.kt
@@ -34,12 +34,12 @@
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.io.Serializable
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.Serializable
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LayoutIdTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LayoutIdTest.kt
index 81dbca9..6cc5157 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LayoutIdTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LayoutIdTest.kt
@@ -27,6 +27,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@@ -34,8 +36,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
index 0b6e22c..f3c9189 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/LocalSoftwareKeyboardControllerTest.kt
@@ -31,13 +31,13 @@
import androidx.compose.ui.text.input.TextInputService
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
@ExperimentalComposeUiApi
@LargeTest
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
index 8b828ae..2a2d199 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowInfoCompositionLocalTest.kt
@@ -31,12 +31,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.SECONDS
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit.SECONDS
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowRecomposerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowRecomposerTest.kt
index b4d9bbe..44ebf7c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowRecomposerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WindowRecomposerTest.kt
@@ -43,6 +43,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
+import java.lang.ref.WeakReference
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -62,8 +64,6 @@
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.ref.WeakReference
-import kotlin.coroutines.CoroutineContext
@RunWith(AndroidJUnit4::class)
class WindowRecomposerTest {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
index c4f9bbc..f6d5329 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/WrapperTest.kt
@@ -32,13 +32,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@Composable private fun Recompose(body: @Composable (recompose: () -> Unit) -> Unit) {
val scope = currentRecomposeScope
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/res/StringResourcesTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/res/StringResourcesTest.kt
index 9751449..89b9648 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/res/StringResourcesTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/res/StringResourcesTest.kt
@@ -25,10 +25,10 @@
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
index 2c1d8dd..f27b445 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/semantics/SemanticsTests.kt
@@ -44,8 +44,8 @@
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assert
-import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertContentDescriptionEquals
+import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.assertValueEquals
import androidx.compose.ui.test.junit4.createComposeRule
@@ -62,6 +62,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.max
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@@ -69,7 +70,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.max
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
index 0fe1ac4..8cef97d 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/viewinterop/ComposeViewTest.kt
@@ -73,6 +73,9 @@
import androidx.test.filters.FlakyTest
import androidx.test.filters.MediumTest
import androidx.test.filters.SmallTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import org.hamcrest.CoreMatchers.instanceOf
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -83,9 +86,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/DialogTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/DialogTest.kt
index b6579e5..1dec8ea 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/DialogTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/DialogTest.kt
@@ -45,12 +45,12 @@
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import com.google.common.truth.Truth
+import kotlin.math.roundToInt
import org.junit.Assert.assertEquals
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupAlignmentTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupAlignmentTest.kt
index 537c3fc..b9949ca 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupAlignmentTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupAlignmentTest.kt
@@ -26,8 +26,8 @@
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.height
@@ -35,12 +35,12 @@
import androidx.test.espresso.matcher.BoundedMatcher
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.hamcrest.Description
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
index fc01d13..edf32cd 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupDismissTest.kt
@@ -18,11 +18,11 @@
import android.os.Build
import android.view.View
-import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicText
+import androidx.compose.foundation.text.ClickableText
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@@ -41,13 +41,13 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assume
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@LargeTest
@RunWith(Parameterized::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupLayoutTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupLayoutTest.kt
index 1183a84..bcd39c1 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupLayoutTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupLayoutTest.kt
@@ -34,10 +34,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.UUID
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.UUID
/**
* Tests for the internal [PopupLayout] view used by [Popup].
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTest.kt
index 252b19d..36d5ef1 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTest.kt
@@ -23,8 +23,8 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.requiredHeight
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.size
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
@@ -64,15 +64,15 @@
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.UiDevice
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.Description
import org.hamcrest.TypeSafeMatcher
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTestUtils.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTestUtils.kt
index d37dd10..b6cbe5c 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTestUtils.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PopupTestUtils.kt
@@ -34,11 +34,11 @@
import androidx.test.espresso.Espresso
import androidx.test.espresso.Root
import androidx.test.espresso.assertion.ViewAssertions
+import kotlin.math.max
import org.hamcrest.CoreMatchers
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.TypeSafeMatcher
-import kotlin.math.max
// TODO(b/139861182): Remove all of this and provide helpers on rule
internal fun ComposeTestRule.popupMatches(popupTestTag: String, viewMatcher: Matcher<in View>) {
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
index 5952258..960ddd4 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/window/PositionInWindowTest.kt
@@ -19,8 +19,8 @@
import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.compose.foundation.background
-import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.awaitEachGesture
+import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.drag
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
@@ -52,13 +52,13 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/compose/ui/ui/src/androidMain/AndroidManifest.xml b/compose/ui/ui/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index b47339d..0000000
--- a/compose/ui/ui/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
index e583a5a..af1dbfc 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
@@ -280,7 +280,7 @@
else -> PointerType.Unknown
}
- val historical = mutableListOf<HistoricalChange>()
+ val historical = ArrayList<HistoricalChange>(motionEvent.historySize)
with(motionEvent) {
repeat(historySize) { pos ->
val x = getHistoricalX(index, pos)
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.android.kt
index 73a1193..e13bda9 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.android.kt
@@ -21,7 +21,6 @@
import android.view.MotionEvent.ACTION_SCROLL
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.util.fastForEach
-import androidx.compose.ui.util.fastMap
internal actual typealias NativePointerButtons = Int
internal actual typealias NativePointerKeyboardModifiers = Int
@@ -92,22 +91,22 @@
null -> PointerEvent(changes, null)
this.motionEvent -> PointerEvent(changes, internalPointerEvent)
else -> {
- val map = mutableMapOf<PointerId, PointerInputChange>()
+ val map = LinkedHashMap<PointerId, PointerInputChange>(changes.size)
+ val pointerEventData = ArrayList<PointerInputEventData>(changes.size)
changes.fastForEach { change ->
map[change.id] = change
- }
- val pointerEventData = changes.fastMap {
- PointerInputEventData(
- it.id,
- it.uptimeMillis,
- it.position,
- it.position,
- it.pressed,
- it.pressure,
- it.type,
- this.internalPointerEvent?.issuesEnterExitEvent(it.id) == true
+ pointerEventData += PointerInputEventData(
+ change.id,
+ change.uptimeMillis,
+ change.position,
+ change.position,
+ change.pressed,
+ change.pressure,
+ change.type,
+ this.internalPointerEvent?.issuesEnterExitEvent(change.id) == true
)
}
+
val pointerInputEvent =
PointerInputEvent(motionEvent.eventTime, pointerEventData, motionEvent)
val event = InternalPointerEvent(map, pointerInputEvent)
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerIcon.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerIcon.android.kt
index 054ec2b..c2c1350 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerIcon.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/PointerIcon.android.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.input.pointer
import android.view.PointerIcon.TYPE_CROSSHAIR
-import android.view.PointerIcon.TYPE_HAND
import android.view.PointerIcon.TYPE_DEFAULT
+import android.view.PointerIcon.TYPE_HAND
import android.view.PointerIcon.TYPE_TEXT
internal class AndroidPointerIconType(val type: Int) :
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 497be6e..553e319 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -16,7 +16,6 @@
package androidx.compose.ui.platform
-import android.view.KeyEvent as AndroidKeyEvent
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Configuration
@@ -26,6 +25,7 @@
import android.os.SystemClock
import android.util.Log
import android.util.SparseArray
+import android.view.KeyEvent as AndroidKeyEvent
import android.view.MotionEvent
import android.view.MotionEvent.ACTION_CANCEL
import android.view.MotionEvent.ACTION_DOWN
@@ -138,6 +138,7 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.util.fastLastOrNull
import androidx.compose.ui.util.trace
import androidx.compose.ui.viewinterop.AndroidViewHolder
import androidx.core.view.AccessibilityDelegateCompat
@@ -911,13 +912,20 @@
}
}
- private fun convertMeasureSpec(measureSpec: Int): Pair<Int, Int> {
+ @Suppress("NOTHING_TO_INLINE")
+ private inline operator fun ULong.component1() = (this shr 32).toInt()
+ @Suppress("NOTHING_TO_INLINE")
+ private inline operator fun ULong.component2() = (this and 0xFFFFFFFFUL).toInt()
+
+ private fun pack(a: Int, b: Int) = (a.toULong() shl 32 or b.toULong())
+
+ private fun convertMeasureSpec(measureSpec: Int): ULong {
val mode = MeasureSpec.getMode(measureSpec)
val size = MeasureSpec.getSize(measureSpec)
return when (mode) {
- MeasureSpec.EXACTLY -> size to size
- MeasureSpec.UNSPECIFIED -> 0 to Constraints.Infinity
- MeasureSpec.AT_MOST -> 0 to size
+ MeasureSpec.EXACTLY -> pack(size, size)
+ MeasureSpec.UNSPECIFIED -> pack(0, Constraints.Infinity)
+ MeasureSpec.AT_MOST -> pack(0, size)
else -> throw IllegalStateException()
}
}
@@ -1368,7 +1376,7 @@
// methods use semantics data, and because semantics coordinates are local to
// this view, the pointer _position_, not _positionOnScreen_, is the offset that
// needs to be cached.
- pointerInputEvent.pointers.lastOrNull { it.down }?.position?.let {
+ pointerInputEvent.pointers.fastLastOrNull { it.down }?.position?.let {
lastDownPointerPosition = it
}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiDispatcher.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiDispatcher.android.kt
index 5be4139..387b2244 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiDispatcher.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiDispatcher.android.kt
@@ -20,10 +20,10 @@
import android.view.Choreographer
import androidx.compose.runtime.MonotonicFrameClock
import androidx.core.os.HandlerCompat
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
-import kotlin.coroutines.CoroutineContext
/**
* A [CoroutineDispatcher] that will perform dispatch during a [handler] callback or
@@ -131,7 +131,7 @@
* A [MonotonicFrameClock] associated with this [AndroidUiDispatcher]'s [choreographer]
* that may be used to await [Choreographer] frame dispatch.
*/
- val frameClock: MonotonicFrameClock = AndroidUiFrameClock(choreographer)
+ val frameClock: MonotonicFrameClock = AndroidUiFrameClock(choreographer, this)
override fun dispatch(context: CoroutineContext, block: Runnable) {
synchronized(lock) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiFrameClock.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiFrameClock.android.kt
index fbc7b21..1f96ec4 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiFrameClock.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidUiFrameClock.android.kt
@@ -17,17 +17,24 @@
package androidx.compose.ui.platform
import android.view.Choreographer
-import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.coroutineContext
+import kotlinx.coroutines.suspendCancellableCoroutine
-class AndroidUiFrameClock(
- val choreographer: Choreographer
+class AndroidUiFrameClock internal constructor(
+ val choreographer: Choreographer,
+ private val dispatcher: AndroidUiDispatcher?
) : androidx.compose.runtime.MonotonicFrameClock {
+
+ constructor(
+ choreographer: Choreographer
+ ) : this(choreographer, null)
+
override suspend fun <R> withFrameNanos(
onFrame: (Long) -> R
): R {
- val uiDispatcher = coroutineContext[ContinuationInterceptor] as? AndroidUiDispatcher
+ val uiDispatcher = dispatcher
+ ?: coroutineContext[ContinuationInterceptor] as? AndroidUiDispatcher
return suspendCancellableCoroutine { co ->
// Important: this callback won't throw, and AndroidUiDispatcher counts on it.
val callback = Choreographer.FrameCallback { frameTimeNanos ->
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
index 0ec62b8..0b898b5 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
@@ -30,9 +30,9 @@
import androidx.compose.ui.UiComposable
import androidx.compose.ui.node.InternalCoreApi
import androidx.compose.ui.node.Owner
-import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.findViewTreeLifecycleOwner
import java.lang.ref.WeakReference
/**
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.android.kt
index 8663ca3..4dd7ef3 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.android.kt
@@ -18,11 +18,11 @@
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.platform.GlobalSnapshotManager.ensureStarted
+import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.launch
-import java.util.concurrent.atomic.AtomicBoolean
/**
* Platform-specific mechanism for starting a monitor of global snapshot state writes
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
index 6050279..090242b 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/OutlineResolver.android.kt
@@ -16,6 +16,7 @@
package androidx.compose.ui.platform
+import android.graphics.Outline as AndroidOutline
import android.os.Build
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
@@ -32,7 +33,6 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import kotlin.math.roundToInt
-import android.graphics.Outline as AndroidOutline
/**
* Resolves the [AndroidOutline] from the [Shape] of an [OwnedLayer].
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi23.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi23.android.kt
index 8b27e39..681b0c5 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi23.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi23.android.kt
@@ -18,9 +18,9 @@
import android.graphics.Color
import android.graphics.Outline
-import android.view.RenderNode
-import android.view.DisplayListCanvas
import android.os.Build
+import android.view.DisplayListCanvas
+import android.view.RenderNode
import android.view.View
import androidx.annotation.RequiresApi
import androidx.compose.ui.graphics.Canvas
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/WindowRecomposer.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/WindowRecomposer.android.kt
index 87b2aed..4d6135f 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/WindowRecomposer.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/WindowRecomposer.android.kt
@@ -28,7 +28,7 @@
import androidx.compose.runtime.PausableMonotonicFrameClock
import androidx.compose.runtime.Recomposer
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.InternalComposeUiApi
@@ -437,5 +437,5 @@
}
private class MotionDurationScaleImpl : MotionDurationScale {
- override var scaleFactor by mutableStateOf(1f)
+ override var scaleFactor by mutableFloatStateOf(1f)
}
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/FontResources.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/FontResources.android.kt
index 58262b0..9203d2b 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/FontResources.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/FontResources.android.kt
@@ -21,10 +21,10 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.text.font.Typeface
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.LoadedFontFamily
import androidx.compose.ui.text.font.SystemFontFamily
+import androidx.compose.ui.text.font.Typeface
private val cacheLock = Object()
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/ImageResources.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/ImageResources.android.kt
index 5e7f956..e679a116 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/ImageResources.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/ImageResources.android.kt
@@ -17,14 +17,14 @@
package androidx.compose.ui.res
import android.content.res.Resources
+import android.graphics.drawable.BitmapDrawable
import android.util.TypedValue
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalContext
-import android.graphics.drawable.BitmapDrawable
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
+import androidx.compose.ui.platform.LocalContext
/**
* Load an ImageBitmap from an image resource.
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/VectorResources.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/VectorResources.android.kt
index e484aff..136a23c 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/VectorResources.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/res/VectorResources.android.kt
@@ -31,8 +31,8 @@
import androidx.compose.ui.graphics.vector.compat.parseCurrentVectorNode
import androidx.compose.ui.graphics.vector.compat.seekToStartTag
import androidx.compose.ui.platform.LocalContext
-import org.xmlpull.v1.XmlPullParserException
import java.lang.ref.WeakReference
+import org.xmlpull.v1.XmlPullParserException
/**
* Load an ImageVector from a vector resource.
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
index 75b727e8..08611787 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/window/AndroidPopup.android.kt
@@ -75,8 +75,8 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastMap
import androidx.lifecycle.findViewTreeLifecycleOwner
-import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.findViewTreeViewModelStoreOwner
+import androidx.lifecycle.setViewTreeLifecycleOwner
import androidx.lifecycle.setViewTreeViewModelStoreOwner
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
index 440914e..b5d1bcf 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt
@@ -20,9 +20,9 @@
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.node.DelegatableNode
import androidx.compose.ui.node.DrawModifierNode
-import androidx.compose.ui.node.ObserverNodeOwnerScope
import androidx.compose.ui.node.NodeCoordinator
import androidx.compose.ui.node.NodeKind
+import androidx.compose.ui.node.ObserverNodeOwnerScope
import androidx.compose.ui.node.invalidateDraw
import androidx.compose.ui.node.requireOwner
import kotlinx.coroutines.CoroutineScope
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt
index aff7952..0408729 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt
@@ -22,6 +22,7 @@
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.node.CacheDrawModifierNode
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.Nodes
@@ -139,12 +140,12 @@
private data class DrawWithCacheElement(
val onBuildDrawCache: CacheDrawScope.() -> DrawResult
-) : ModifierNodeElement<CacheDrawNode>() {
- override fun create(): CacheDrawNode {
- return CacheDrawNode(CacheDrawScope(), onBuildDrawCache)
+) : ModifierNodeElement<CacheDrawModifierNodeImpl>() {
+ override fun create(): CacheDrawModifierNodeImpl {
+ return CacheDrawModifierNodeImpl(CacheDrawScope(), onBuildDrawCache)
}
- override fun update(node: CacheDrawNode) {
+ override fun update(node: CacheDrawModifierNodeImpl) {
node.block = onBuildDrawCache
}
@@ -154,10 +155,16 @@
}
}
-private class CacheDrawNode(
+fun CacheDrawModifierNode(
+ onBuildDrawCache: CacheDrawScope.() -> DrawResult
+): CacheDrawModifierNode {
+ return CacheDrawModifierNodeImpl(CacheDrawScope(), onBuildDrawCache)
+}
+
+private class CacheDrawModifierNodeImpl(
private val cacheDrawScope: CacheDrawScope,
block: CacheDrawScope.() -> DrawResult
-) : Modifier.Node(), DrawModifierNode, ObserverModifierNode, BuildDrawCacheParams {
+) : Modifier.Node(), CacheDrawModifierNode, ObserverModifierNode, BuildDrawCacheParams {
private var isCacheValid = false
var block: CacheDrawScope.() -> DrawResult = block
@@ -182,7 +189,7 @@
invalidateDrawCache()
}
- private fun invalidateDrawCache() {
+ override fun invalidateDrawCache() {
isCacheValid = false
cacheDrawScope.drawResult = null
invalidateDraw()
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
index e4eaeb0..f251943 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/PainterModifier.kt
@@ -17,21 +17,21 @@
package androidx.compose.ui.draw
import androidx.compose.ui.Alignment
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.isSpecified
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.layout.times
import androidx.compose.ui.layout.IntrinsicMeasurable
import androidx.compose.ui.layout.IntrinsicMeasureScope
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.layout.times
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
index 5fa03797..d838abf 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusInvalidationManager.kt
@@ -45,21 +45,22 @@
}
private fun <T> MutableSet<T>.scheduleInvalidation(node: T) {
- // We don't schedule a node if it is already scheduled during this composition.
- if (contains(node)) return
-
- add(node)
-
- // If this is the first node scheduled for invalidation,
- // we set up a listener that runs after onApplyChanges.
- if (focusTargetNodes.size + focusEventNodes.size + focusPropertiesNodes.size == 1) {
- onRequestApplyChangesListener.invoke(invalidateNodes)
+ if (add(node)) {
+ // If this is the first node scheduled for invalidation,
+ // we set up a listener that runs after onApplyChanges.
+ if (focusTargetNodes.size + focusEventNodes.size + focusPropertiesNodes.size == 1) {
+ onRequestApplyChangesListener.invoke(invalidateNodes)
+ }
}
}
private val invalidateNodes: () -> Unit = {
// Process all the invalidated FocusProperties nodes.
focusPropertiesNodes.forEach {
+ // We don't need to invalidate a focus properties node if it was scheduled for
+ // invalidation earlier in the composition but was then removed.
+ if (!it.node.isAttached) return@forEach
+
it.visitSelfAndChildren(Nodes.FocusTarget) { focusTarget ->
focusTargetNodes.add(focusTarget)
}
@@ -131,8 +132,8 @@
focusTargetNodes.clear()
focusTargetsWithInvalidatedFocusEvents.clear()
- check(focusPropertiesNodes.isEmpty())
- check(focusEventNodes.isEmpty())
- check(focusTargetNodes.isEmpty())
+ check(focusPropertiesNodes.isEmpty()) { "Unprocessed FocusProperties nodes" }
+ check(focusEventNodes.isEmpty()) { "Unprocessed FocusEvent nodes" }
+ check(focusTargetNodes.isEmpty()) { "Unprocessed FocusTarget nodes" }
}
}
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt
index 4241f32..783a2c3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerScope.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.graphics
import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.unit.Density
/**
* Default camera distance for all layers
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/Vector.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/Vector.kt
index 0e155ef..9c256c7 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/Vector.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/Vector.kt
@@ -24,6 +24,7 @@
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.PathMeasure
@@ -32,7 +33,6 @@
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.drawscope.withTransform
-import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.util.fastForEach
import kotlin.math.ceil
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
index 3963cc0..58b3cd3 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/vector/VectorPainter.kt
@@ -34,10 +34,10 @@
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* Default identifier for the root group if a Vector graphic
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
index 9a7ddac..abd9b6a 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/HitPathTracker.kt
@@ -376,12 +376,21 @@
@OptIn(ExperimentalComposeUiApi::class)
for ((key, change) in changes) {
- // Filter for changes that are associated with pointer ids that are relevant to this
- // node
- if (key in pointerIds) {
+ val keyValue = key.value
+
+ // Using for (key in pointerIds) causes key to be boxed and create allocations
+ var keyInPointerIds = false
+ for (i in 0..pointerIds.lastIndex) {
+ if (pointerIds[i].value == keyValue) {
+ keyInPointerIds = true
+ break
+ }
+ }
+
+ if (keyInPointerIds) {
// And translate their position relative to the parent coordinates, to give us a
// change local to the PointerInputFilter's coordinates
- val historical = mutableListOf<HistoricalChange>()
+ val historical = ArrayList<HistoricalChange>(change.historical.size)
change.historical.fastForEach {
historical.add(
HistoricalChange(
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
index b1671c9..7a6010a 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerEvent.kt
@@ -24,9 +24,9 @@
import androidx.compose.ui.input.pointer.PointerEventPass.Final
import androidx.compose.ui.input.pointer.PointerEventPass.Initial
import androidx.compose.ui.input.pointer.PointerEventPass.Main
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.layout.LayoutCoordinates
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* A [Modifier.Element] that can interact with pointer input.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
index 96c06cc..b71e1c4 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/SuspendingPointerInputFilter.kt
@@ -20,6 +20,11 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.fastMapNotNull
import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.PointerInputModifierNode
+import androidx.compose.ui.node.requireLayoutNode
+import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.platform.synchronized
@@ -37,16 +42,11 @@
import kotlin.math.max
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
-import androidx.compose.ui.node.ModifierNodeElement
-import androidx.compose.ui.node.PointerInputModifierNode
-import androidx.compose.ui.node.requireLayoutNode
-import androidx.compose.ui.platform.InspectorInfo
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.Job
/**
* Receiver scope for awaiting pointer events in a call to
@@ -497,7 +497,7 @@
override fun resetPointerInputHandler() {
val localJob = pointerInputJob
if (localJob != null) {
- localJob.cancel(CancellationException())
+ localJob.cancel()
pointerInputJob = null
}
}
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntermediateLayoutModifierNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntermediateLayoutModifierNode.kt
index 9b4c8f9..e0ad52d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntermediateLayoutModifierNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntermediateLayoutModifierNode.kt
@@ -317,6 +317,10 @@
}
}
+ // Intermediate layout pass is post-lookahead. Therefore return false here.
+ override val isLookingAhead: Boolean
+ get() = false
+
override val layoutDirection: LayoutDirection
get() = coordinator!!.layoutDirection
override val density: Float
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasureScope.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasureScope.kt
index 5c29e6c..657e31d 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasureScope.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasureScope.kt
@@ -16,6 +16,7 @@
package androidx.compose.ui.layout
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
@@ -28,4 +29,17 @@
* to measure their children.
*/
val layoutDirection: LayoutDirection
+
+ /**
+ * This indicates whether the ongoing measurement is for lookahead pass.
+ * [IntrinsicMeasureScope] implementations, especially [MeasureScope] implementations should
+ * override this flag to reflect whether the measurement is intended for lookahead pass.
+ *
+ * @sample androidx.compose.ui.samples.animateContentSizeAfterLookaheadPass
+ */
+ @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET")
+ @get:ExperimentalComposeUiApi
+ @ExperimentalComposeUiApi
+ val isLookingAhead: Boolean
+ get() = false
}
\ No newline at end of file
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
index 2b45ead..813a516 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt
@@ -32,7 +32,6 @@
import androidx.compose.ui.node.ComposeUiNode
import androidx.compose.ui.node.LayoutNode
import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
@@ -64,7 +63,8 @@
*/
@Suppress("ComposableLambdaParameterPosition")
@UiComposable
-@Composable inline fun Layout(
+@Composable
+inline fun Layout(
content: @Composable @UiComposable () -> Unit,
modifier: Modifier = Modifier,
measurePolicy: MeasurePolicy
@@ -322,6 +322,6 @@
* call.
*/
internal class IntrinsicsMeasureScope(
- density: Density,
- override val layoutDirection: LayoutDirection
-) : MeasureScope, Density by density
+ intrinsicMeasureScope: IntrinsicMeasureScope,
+ override val layoutDirection: LayoutDirection,
+) : MeasureScope, IntrinsicMeasureScope by intrinsicMeasureScope
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
index 83d9751..af49d34 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/LayoutCoordinates.kt
@@ -19,9 +19,9 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Matrix
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.node.NodeCoordinator
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* A holder of the measured bounds for the layout (MeasureBox).
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt
index 64dcbe3..7b10ef0 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt
@@ -17,11 +17,11 @@
package androidx.compose.ui.layout
import androidx.compose.runtime.Stable
-import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.util.fastMap
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.layout.RootMeasurePolicy.measure
import androidx.compose.ui.layout.RootMeasurePolicy.minIntrinsicWidth
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.util.fastMap
/**
* Defines the measure and layout behavior of a [Layout]. [Layout] and [MeasurePolicy] are the way
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
index eaef98e1d..a01db10 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasureScope.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.layout
-import androidx.compose.ui.node.LookaheadCapablePlaceable
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.node.LookaheadCapablePlaceable
/**
* The receiver scope of a layout's measure lambda. The return value of the
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/OnRemeasuredModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/OnRemeasuredModifier.kt
index 9da5ab4..6ebe14f 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/OnRemeasuredModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/OnRemeasuredModifier.kt
@@ -19,11 +19,11 @@
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.platform.InspectorValueInfo
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.IntSize
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* Invoked with the size of the modified Compose UI element when the element is first measured or
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ParentDataModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ParentDataModifier.kt
index c319547..9811bae 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ParentDataModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/ParentDataModifier.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.layout
import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.internal.JvmDefaultWithCompatibility
+import androidx.compose.ui.unit.Density
/**
* A [Modifier] that provides data to the parent [Layout]. This can be read from within the
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
index 99301bd..94893a6 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Placeable.kt
@@ -18,8 +18,8 @@
import androidx.compose.ui.graphics.GraphicsLayerScope
import androidx.compose.ui.node.LayoutNodeLayoutDelegate
-import androidx.compose.ui.node.NodeCoordinator
import androidx.compose.ui.node.LookaheadCapablePlaceable
+import androidx.compose.ui.node.NodeCoordinator
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
index 6ebfd55..d95d81b 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt
@@ -1000,6 +1000,9 @@
override var layoutDirection: LayoutDirection = LayoutDirection.Rtl
override var density: Float = 0f
override var fontScale: Float = 0f
+ override val isLookingAhead: Boolean
+ get() = root.layoutState == LayoutState.LookaheadLayingOut ||
+ root.layoutState == LayoutState.LookaheadMeasuring
override fun subcompose(slotId: Any?, content: @Composable () -> Unit) =
this@LayoutNodeSubcompositionsState.subcompose(slotId, content)
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalConsumer.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalConsumer.kt
index eea668b..cb2ad69 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalConsumer.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalConsumer.kt
@@ -19,10 +19,10 @@
import androidx.compose.runtime.Stable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.platform.InspectorValueInfo
import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* A Modifier that can be used to consume [ModifierLocal]s that were provided by other modifiers to
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalProvider.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalProvider.kt
index 7a38447..b689b69 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalProvider.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierLocalProvider.kt
@@ -21,9 +21,9 @@
import androidx.compose.runtime.getValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.platform.InspectorValueInfo
import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* A Modifier that can be used to provide [ModifierLocal]s that can be read by other modifiers to
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatableNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatableNode.kt
index d8b0359..4c6b373 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatableNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DelegatableNode.kt
@@ -55,7 +55,7 @@
// TODO(lmr): we might want to add some safety wheels to prevent this from being called
// while one of the chains is being diffed / updated. Although that might only be
// necessary for visiting subtree.
- check(node.isAttached)
+ check(node.isAttached) { "visitAncestors called on an unattached node" }
var node: Modifier.Node? = if (includeSelf) node else node.parent
var layout: LayoutNode? = requireLayoutNode()
while (layout != null) {
@@ -75,7 +75,7 @@
@Suppress("unused")
internal fun DelegatableNode.nearestAncestor(mask: Int): Modifier.Node? {
- check(node.isAttached)
+ check(node.isAttached) { "nearestAncestor called on an unattached node" }
var node: Modifier.Node? = node.parent
var layout: LayoutNode? = requireLayoutNode()
while (layout != null) {
@@ -97,7 +97,7 @@
internal inline fun DelegatableNode.visitSubtree(mask: Int, block: (Modifier.Node) -> Unit) {
// TODO(lmr): we might want to add some safety wheels to prevent this from being called
// while one of the chains is being diffed / updated.
- check(node.isAttached)
+ check(node.isAttached) { "visitSubtree called on an unattached node" }
var node: Modifier.Node? = node.child
var layout: LayoutNode? = requireLayoutNode()
// we use this bespoke data structure here specifically for traversing children. In the
@@ -130,7 +130,7 @@
}
internal inline fun DelegatableNode.visitChildren(mask: Int, block: (Modifier.Node) -> Unit) {
- check(node.isAttached)
+ check(node.isAttached) { "visitChildren called on an unattached node" }
val branches = mutableVectorOf<Modifier.Node>()
val child = node.child
if (child == null)
@@ -160,7 +160,7 @@
* traversing below it
*/
internal inline fun DelegatableNode.visitSubtreeIf(mask: Int, block: (Modifier.Node) -> Boolean) {
- check(node.isAttached)
+ check(node.isAttached) { "visitSubtreeIf called on an unattached node" }
val branches = mutableVectorOf<Modifier.Node>()
val child = node.child
if (child == null)
@@ -187,7 +187,7 @@
mask: Int,
block: (Modifier.Node) -> Unit
) {
- check(node.isAttached)
+ check(node.isAttached) { "visitLocalDescendants called on an unattached node" }
val self = node
if (self.aggregateChildKindSet and mask == 0) return
var next = self.child
@@ -203,7 +203,7 @@
mask: Int,
block: (Modifier.Node) -> Unit
) {
- check(node.isAttached)
+ check(node.isAttached) { "visitLocalAncestors called on an unattached node" }
var next = node.parent
while (next != null) {
if (next.kindSet and mask != 0) {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DrawModifierNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DrawModifierNode.kt
index 99cd8b2..05fb28e 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DrawModifierNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/DrawModifierNode.kt
@@ -33,6 +33,15 @@
}
/**
+ * Expands on the [androidx.compose.ui.node.DrawModifierNode] by adding the ability to invalidate
+ * the draw cache for changes in things like shapes and bitmaps (see Modifier.border for a usage
+ * examples).
+ */
+interface CacheDrawModifierNode : DrawModifierNode {
+ fun invalidateDrawCache()
+}
+
+/**
* Invalidates this modifier's draw layer, ensuring that a draw pass will
* be run on the next frame.
*/
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
index c9f3e51..aa215e9 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt
@@ -66,6 +66,8 @@
*/
private const val DebugChanges = false
+private val DefaultDensity = Density(1f)
+
/**
* An element in the layout hierarchy, built with compose UI.
*/
@@ -627,7 +629,7 @@
/**
* The screen density to be used by this layout.
*/
- override var density: Density = Density(1f)
+ override var density: Density = DefaultDensity
set(value) {
if (field != value) {
field = value
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LookaheadDelegate.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LookaheadDelegate.kt
index b34b523..ba59c04 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LookaheadDelegate.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LookaheadDelegate.kt
@@ -16,6 +16,7 @@
package androidx.compose.ui.node
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.graphics.GraphicsLayerScope
import androidx.compose.ui.layout.AlignmentLine
import androidx.compose.ui.layout.LayoutCoordinates
@@ -76,6 +77,10 @@
alignmentLinesOwner.parentAlignmentLinesOwner?.alignmentLines?.onAlignmentsChanged()
}
}
+
+ @OptIn(ExperimentalComposeUiApi::class)
+ override val isLookingAhead: Boolean
+ get() = false
}
internal abstract class LookaheadDelegate(
@@ -91,6 +96,8 @@
get() = _measureResult ?: error(
"LookaheadDelegate has not been measured yet when measureResult is requested."
)
+ override val isLookingAhead: Boolean
+ get() = true
override val layoutDirection: LayoutDirection
get() = coordinator.layoutDirection
override val density: Float
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
index 2b2847f..9043a07 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeChain.kt
@@ -743,7 +743,8 @@
private fun Modifier.fillVector(
result: MutableVector<Modifier.Element>
): MutableVector<Modifier.Element> {
- val stack = MutableVector<Modifier>(result.size).also { it.add(this) }
+ val capacity = result.size.coerceAtLeast(16)
+ val stack = MutableVector<Modifier>(capacity).also { it.add(this) }
while (stack.isNotEmpty()) {
when (val next = stack.removeAt(stack.size - 1)) {
is CombinedModifier -> {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
index 6519bf8..2a0b6e9 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/NodeCoordinator.kt
@@ -226,21 +226,25 @@
override val parentData: Any?
get() {
- var data: Any? = null
- val thisNode = tail
+ // NOTE: If you make changes to this getter, please check the generated bytecode to
+ // ensure no extra allocation is made. See the note below.
if (layoutNode.nodes.has(Nodes.ParentData)) {
- with(layoutNode.density) {
- layoutNode.nodes.tailToHead { node ->
- if (node.isKind(Nodes.ParentData)) {
- node.dispatchForKind(Nodes.ParentData) {
- data = with(it) { modifyParentData(data) }
- }
+ val thisNode = tail
+ // NOTE: Keep this mutable variable scoped inside the if statement. When moved
+ // to the outer scope of get(), this causes the compiler to generate a
+ // Ref$ObjectRef instance on every call of this getter.
+ var data: Any? = null
+ layoutNode.nodes.tailToHead { node ->
+ if (node.isKind(Nodes.ParentData)) {
+ node.dispatchForKind(Nodes.ParentData) {
+ data = with(it) { layoutNode.density.modifyParentData(data) }
}
- if (node === thisNode) return@tailToHead
}
+ if (node === thisNode) return@tailToHead
}
+ return data
}
- return data
+ return null
}
final override val parentLayoutCoordinates: LayoutCoordinates?
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
index b3fb83c..25b5cd5 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/InfiniteAnimationPolicy.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.platform
import androidx.compose.runtime.withFrameNanos
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.coroutineContext
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* Provides a policy that will be applied to animations that get their frame time from
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ShapeContainingUtil.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ShapeContainingUtil.kt
index 25b3abb..d52279c 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ShapeContainingUtil.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ShapeContainingUtil.kt
@@ -17,9 +17,9 @@
package androidx.compose.ui.platform
import androidx.compose.ui.geometry.CornerRadius
-import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.RoundRect
+import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.PathOperation
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ViewConfiguration.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ViewConfiguration.kt
index c7445f7..d74db18 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ViewConfiguration.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ViewConfiguration.kt
@@ -16,9 +16,9 @@
package androidx.compose.ui.platform
+import androidx.compose.ui.internal.JvmDefaultWithCompatibility
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.internal.JvmDefaultWithCompatibility
/**
* Contains methods to standard constants used in the UI for timeouts, sizes, and distances.
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
index e1b79a2..e68401c 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/window/Popup.kt
@@ -18,8 +18,8 @@
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Alignment
-import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.height
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeDialog.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeDialog.desktop.kt
index a4816ed..373e218 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeDialog.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeDialog.desktop.kt
@@ -19,13 +19,13 @@
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.window.DialogWindowScope
-import org.jetbrains.skiko.GraphicsApi
import java.awt.Component
import java.awt.Window
import java.awt.event.MouseListener
import java.awt.event.MouseMotionListener
import java.awt.event.MouseWheelListener
import javax.swing.JDialog
+import org.jetbrains.skiko.GraphicsApi
/**
* ComposeDialog is a dialog for building UI using Compose for Desktop.
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt
index 59f4f89..a246312 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeLayer.desktop.kt
@@ -17,26 +17,22 @@
package androidx.compose.ui.awt
import androidx.compose.runtime.Composable
+import androidx.compose.ui.ComposeScene
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.pointer.PointerEventType
-import androidx.compose.ui.input.pointer.PointerType
-import androidx.compose.ui.platform.PlatformComponent
-import androidx.compose.ui.ComposeScene
+import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent
import androidx.compose.ui.input.pointer.PointerButtons
+import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
-import androidx.compose.ui.platform.DesktopPlatform
+import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.platform.AccessibilityControllerImpl
+import androidx.compose.ui.platform.DesktopPlatform
+import androidx.compose.ui.platform.PlatformComponent
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.window.density
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.swing.Swing
-import org.jetbrains.skia.Canvas
-import org.jetbrains.skiko.SkiaLayer
-import org.jetbrains.skiko.SkikoView
-import java.awt.Cursor
import java.awt.Component
+import java.awt.Cursor
import java.awt.Dimension
import java.awt.Graphics
import java.awt.Point
@@ -54,7 +50,11 @@
import java.awt.im.InputMethodRequests
import javax.accessibility.Accessible
import javax.accessibility.AccessibleContext
-import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.swing.Swing
+import org.jetbrains.skia.Canvas
+import org.jetbrains.skiko.SkiaLayer
+import org.jetbrains.skiko.SkikoView
internal class ComposeLayer {
private var isDisposed = false
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
index a9c1dbb..18a78ff 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
@@ -17,13 +17,13 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
-import org.jetbrains.skiko.ClipComponent
-import org.jetbrains.skiko.GraphicsApi
import java.awt.Color
import java.awt.Component
import java.awt.Dimension
import javax.swing.JLayeredPane
import javax.swing.SwingUtilities.isEventDispatchThread
+import org.jetbrains.skiko.ClipComponent
+import org.jetbrains.skiko.GraphicsApi
/**
* ComposePanel is a panel for building UI using Compose for Desktop.
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindow.desktop.kt
index 235f530..95e8140 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindow.desktop.kt
@@ -20,13 +20,13 @@
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.window.FrameWindowScope
import androidx.compose.ui.window.WindowPlacement
-import org.jetbrains.skiko.GraphicsApi
import java.awt.Component
import java.awt.GraphicsConfiguration
import java.awt.event.MouseListener
import java.awt.event.MouseMotionListener
import java.awt.event.MouseWheelListener
import javax.swing.JFrame
+import org.jetbrains.skiko.GraphicsApi
/**
* ComposeWindow is a window for building UI using Compose for Desktop.
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt
index bb2dbb1..349923f 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowDelegate.desktop.kt
@@ -21,11 +21,6 @@
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.window.LocalWindow
import androidx.compose.ui.window.UndecoratedWindowResizer
-import org.jetbrains.skiko.ClipComponent
-import org.jetbrains.skiko.GraphicsApi
-import org.jetbrains.skiko.OS
-import org.jetbrains.skiko.SkiaLayer
-import org.jetbrains.skiko.hostOs
import java.awt.Color
import java.awt.Component
import java.awt.Window
@@ -33,6 +28,11 @@
import java.awt.event.MouseMotionListener
import java.awt.event.MouseWheelListener
import javax.swing.JLayeredPane
+import org.jetbrains.skiko.ClipComponent
+import org.jetbrains.skiko.GraphicsApi
+import org.jetbrains.skiko.OS
+import org.jetbrains.skiko.SkiaLayer
+import org.jetbrains.skiko.hostOs
internal class ComposeWindowDelegate(
private val window: Window,
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/key/Key.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/key/Key.desktop.kt
index bc20dca..cfe17cd 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/key/Key.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/input/key/Key.desktop.kt
@@ -17,12 +17,12 @@
package androidx.compose.ui.input.key
import androidx.compose.ui.input.key.Key.Companion.Number
+import androidx.compose.ui.util.unpackInt1
import java.awt.event.KeyEvent
import java.awt.event.KeyEvent.KEY_LOCATION_LEFT
import java.awt.event.KeyEvent.KEY_LOCATION_NUMPAD
import java.awt.event.KeyEvent.KEY_LOCATION_RIGHT
import java.awt.event.KeyEvent.KEY_LOCATION_STANDARD
-import androidx.compose.ui.util.unpackInt1
// TODO(demin): implement most of key codes
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt
index 53a47e7..f8aea9b 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/ComposeAccessible.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.node.requireCoordinator
import androidx.compose.ui.node.Nodes
+import androidx.compose.ui.node.requireCoordinator
import androidx.compose.ui.semantics.AccessibilityAction
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.SemanticsActions
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt
index 1786f77..0faafcf 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/GlobalSnapshotManager.desktop.kt
@@ -18,13 +18,13 @@
import androidx.compose.runtime.snapshots.Snapshot
import androidx.compose.ui.platform.GlobalSnapshotManager.ensureStarted
+import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
-import java.util.concurrent.atomic.AtomicBoolean
/**
* Platform-specific mechanism for starting a monitor of global snapshot state writes
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
index eea1038..bc88383 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/platform/TestComposeWindow.desktop.kt
@@ -32,18 +32,18 @@
import androidx.compose.ui.node.RootForTest
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancel
-import org.jetbrains.skia.Surface
-import org.jetbrains.skiko.FrameDispatcher
import java.awt.Component
import java.awt.event.MouseWheelEvent
import kotlin.coroutines.CoroutineContext
import kotlin.math.abs
import kotlin.math.roundToInt
import kotlin.math.sign
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.cancel
+import org.jetbrains.skia.Surface
+import org.jetbrains.skiko.FrameDispatcher
@PublishedApi
internal val EmptyDispatcher = object : CoroutineDispatcher() {
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopSvgResources.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopSvgResources.desktop.kt
index 1e33a0f..5413fa0 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopSvgResources.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopSvgResources.desktop.kt
@@ -27,6 +27,8 @@
import androidx.compose.ui.graphics.vector.DrawCache
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
+import java.io.InputStream
+import kotlin.math.ceil
import org.jetbrains.skia.Data
import org.jetbrains.skia.Rect
import org.jetbrains.skia.svg.SVGDOM
@@ -34,8 +36,6 @@
import org.jetbrains.skia.svg.SVGLengthUnit
import org.jetbrains.skia.svg.SVGPreserveAspectRatio
import org.jetbrains.skia.svg.SVGPreserveAspectRatioAlign
-import java.io.InputStream
-import kotlin.math.ceil
/**
* Synchronously load an SVG image from some [inputStream].
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopXmlVectorResources.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopXmlVectorResources.desktop.kt
index 9768f21..bfc4781 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopXmlVectorResources.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/DesktopXmlVectorResources.desktop.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vector.parseVectorRoot
import androidx.compose.ui.unit.Density
-import org.xml.sax.InputSource
import javax.xml.parsers.DocumentBuilderFactory
+import org.xml.sax.InputSource
/**
* Synchronously load an xml vector image from some [inputSource].
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/ImageResources.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/ImageResources.desktop.kt
index 948938e..e862143 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/ImageResources.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/ImageResources.desktop.kt
@@ -18,8 +18,8 @@
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.toComposeImageBitmap
-import org.jetbrains.skia.Image
import java.io.InputStream
+import org.jetbrains.skia.Image
/**
* Load and decode [ImageBitmap] from the given [inputStream]. [inputStream] should contain encoded
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/PainterResources.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/PainterResources.desktop.kt
index 4890aed..410f0d6 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/PainterResources.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/PainterResources.desktop.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.res
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.rememberVectorPainter
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
index 9340c9e..c326802 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/res/vector/DesktopXmlVectorParser.desktop.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.res.vector
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
@@ -36,9 +36,9 @@
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.res.vector.BuildContext.Group
import androidx.compose.ui.unit.Density
+import java.util.LinkedList
import org.w3c.dom.Element
import org.w3c.dom.Node
-import java.util.LinkedList
// Parsing logic is the same as in Android implementation
// (compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/graphics/vector/compat/XmlVectorParser.kt)
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/Windows.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/Windows.desktop.kt
index c3e807c..a50f886 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/Windows.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/util/Windows.desktop.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.awt.ComposeWindow
import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.toAwtImage
import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.graphics.toAwtImage
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt
index b4bc684..80d3f69 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt
@@ -35,6 +35,7 @@
import androidx.compose.ui.configureSwingGlobalsForCompose
import androidx.compose.ui.platform.GlobalSnapshotManager
import androidx.compose.ui.platform.LocalDensity
+import java.awt.Window
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -43,7 +44,6 @@
import kotlinx.coroutines.swing.Swing
import kotlinx.coroutines.withContext
import kotlinx.coroutines.yield
-import java.awt.Window
/**
* An entry point for the Compose application. See [awaitApplication] for more information.
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt
index d5d32eb..2b96713 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/AwtWindow.desktop.kt
@@ -25,13 +25,13 @@
import androidx.compose.ui.node.Ref
import androidx.compose.ui.util.UpdateEffect
import androidx.compose.ui.util.makeDisplayable
+import java.awt.Window
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.swing.Swing
-import java.awt.Window
/**
* Compose [Window] obtained from [create]. The [create] block will be called
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
index 7934126..17abbcd 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DesktopPopup.desktop.kt
@@ -31,8 +31,8 @@
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.platform.SkiaBasedOwner
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.SkiaBasedOwner
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt
index 3b8921b..4208152 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/LocalWindow.kt
@@ -16,10 +16,10 @@
package androidx.compose.ui.window
+import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.awt.ComposeDialog
import androidx.compose.ui.awt.ComposePanel
import androidx.compose.ui.awt.ComposeWindow
-import androidx.compose.runtime.compositionLocalOf
import java.awt.Window
/**
diff --git a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Tray.desktop.kt b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Tray.desktop.kt
index 642f0e2..f0987df 100644
--- a/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Tray.desktop.kt
+++ b/compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Tray.desktop.kt
@@ -28,14 +28,14 @@
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.toAwtImage
import androidx.compose.ui.platform.DesktopPlatform
+import java.awt.PopupMenu
+import java.awt.SystemTray
+import java.awt.TrayIcon
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.receiveAsFlow
-import java.awt.PopupMenu
-import java.awt.SystemTray
-import java.awt.TrayIcon
// In fact, this size doesn't affect anything on Windows/Linux, because they request what they
// need, and not what we provide. It only affects macOs. This size will be scaled in asAwtImage to
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ComposeSceneTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ComposeSceneTest.kt
index fbc3334..485c67e 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ComposeSceneTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/ComposeSceneTest.kt
@@ -61,21 +61,21 @@
import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.Layout
-import androidx.compose.ui.test.InternalTestApi
import androidx.compose.ui.platform.renderingTest
+import androidx.compose.ui.test.InternalTestApi
import androidx.compose.ui.test.junit4.DesktopScreenshotTestRule
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performKeyPress
import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
+import java.awt.event.KeyEvent
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertFalse
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
-import java.awt.event.KeyEvent
-import org.junit.Ignore
@OptIn(InternalTestApi::class, ExperimentalComposeUiApi::class)
class ComposeSceneTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt
index 371a453..66ac55a 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/awt/ComposePanelTest.kt
@@ -24,14 +24,14 @@
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.density
import com.google.common.truth.Truth.assertThat
+import java.awt.Dimension
+import java.awt.GraphicsEnvironment
+import javax.swing.JFrame
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.swing.Swing
import org.junit.Assume
import org.junit.Test
-import java.awt.Dimension
-import java.awt.GraphicsEnvironment
-import javax.swing.JFrame
class ComposePanelTest {
@Test
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/key/KeyInputUtil.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/key/KeyInputUtil.kt
index ca8ba74..043b142 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/key/KeyInputUtil.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/key/KeyInputUtil.kt
@@ -17,11 +17,11 @@
package androidx.compose.ui.input.key
import java.awt.Component
+import java.awt.event.KeyEvent as KeyEventAwt
import java.awt.event.KeyEvent.KEY_PRESSED
import java.awt.event.KeyEvent.KEY_RELEASED
import java.awt.event.KeyEvent.KEY_TYPED
import java.awt.event.KeyEvent.VK_UNDEFINED
-import java.awt.event.KeyEvent as KeyEventAwt
private object DummyComponent : Component()
/**
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/pointer/PointerIconTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/pointer/PointerIconTest.kt
index c586bfe..a4c7cbb 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/pointer/PointerIconTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/input/pointer/PointerIconTest.kt
@@ -25,10 +25,10 @@
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
+import java.awt.Cursor
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.awt.Cursor
@RunWith(JUnit4::class)
class PointerIconTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/AccessibilityTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/AccessibilityTest.kt
index 712be2d..4ae3e53 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/AccessibilityTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/AccessibilityTest.kt
@@ -20,12 +20,12 @@
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
+import javax.accessibility.AccessibleText
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import javax.accessibility.AccessibleText
@RunWith(JUnit4::class)
class AccessibilityTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
index 9bc4693..2ffaeea 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/DesktopInputComponentTest.kt
@@ -23,14 +23,14 @@
import androidx.compose.ui.text.input.ImeOptions
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.TextInputService
+import java.awt.Component
+import java.awt.event.InputMethodEvent
+import java.text.AttributedString
import org.junit.Assert
import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.awt.Component
-import java.awt.event.InputMethodEvent
-import java.text.AttributedString
private object DummyComponent : Component()
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcherTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcherTest.kt
index 55900fc..b784f0d 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcherTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcherTest.kt
@@ -16,6 +16,7 @@
package androidx.compose.ui.platform
+import kotlin.random.Random
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -26,7 +27,6 @@
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Test
-import kotlin.random.Random
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
class FlushCoroutineDispatcherTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
index dbc107b..81cc28a 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/RenderingTestScope.kt
@@ -23,6 +23,7 @@
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
@@ -31,7 +32,6 @@
import org.jetbrains.skia.Canvas
import org.jetbrains.skia.Surface
import org.jetbrains.skiko.FrameDispatcher
-import kotlin.coroutines.CoroutineContext
internal fun renderingTest(
width: Int,
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/SkiaLayerTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/SkiaLayerTest.kt
index af4ba78..2556f82 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/SkiaLayerTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/platform/SkiaLayerTest.kt
@@ -31,14 +31,14 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.round
+import kotlin.math.PI
+import kotlin.math.cos
+import kotlin.math.roundToInt
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
-import kotlin.math.PI
-import kotlin.math.cos
-import kotlin.math.roundToInt
class SkiaLayerTest {
@get:Rule
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/ApplicationTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/ApplicationTest.kt
index 9a5f7c9..95cb554 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/ApplicationTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/ApplicationTest.kt
@@ -23,8 +23,8 @@
import androidx.compose.runtime.ExperimentalComposeApi
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MonotonicFrameClock
-import androidx.compose.runtime.monotonicFrameClock
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.monotonicFrameClock
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/MenuBarTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/MenuBarTest.kt
index e03ef3d..40d329b 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/MenuBarTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/MenuBarTest.kt
@@ -26,10 +26,10 @@
import androidx.compose.ui.readFirstPixel
import androidx.compose.ui.testImage
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import javax.swing.JCheckBoxMenuItem
import javax.swing.JRadioButtonMenuItem
import javax.swing.JSeparator
+import org.junit.Test
@OptIn(ExperimentalComposeUiApi::class)
class MenuBarTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt
index d339947..427bda9 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/TestUtils.kt
@@ -21,6 +21,7 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
+import java.awt.GraphicsEnvironment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -33,7 +34,6 @@
import kotlinx.coroutines.withTimeout
import kotlinx.coroutines.yield
import org.junit.Assume.assumeFalse
-import java.awt.GraphicsEnvironment
import org.junit.Assume.assumeTrue
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/dialog/DialogTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/dialog/DialogTest.kt
index 7f1f30f..5009c3e 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/dialog/DialogTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/dialog/DialogTest.kt
@@ -48,11 +48,11 @@
import androidx.compose.ui.window.rememberDialogState
import androidx.compose.ui.window.runApplicationTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.awt.Dimension
import java.awt.event.KeyEvent
import java.awt.event.WindowAdapter
import java.awt.event.WindowEvent
+import org.junit.Test
@OptIn(ExperimentalComposeUiApi::class)
class DialogTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowInputEventTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowInputEventTest.kt
index 0e7f02c..b90df87 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowInputEventTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowInputEventTest.kt
@@ -49,11 +49,11 @@
import androidx.compose.ui.window.rememberWindowState
import androidx.compose.ui.window.runApplicationTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.awt.Toolkit
import java.awt.event.KeyEvent
import java.awt.event.MouseEvent
import java.awt.event.MouseWheelEvent
+import org.junit.Test
@OptIn(ExperimentalComposeUiApi::class)
class WindowInputEventTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowParameterTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowParameterTest.kt
index 1c60660..5e4cf77 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowParameterTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowParameterTest.kt
@@ -34,8 +34,8 @@
import androidx.compose.ui.window.launchApplication
import androidx.compose.ui.window.runApplicationTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.awt.event.WindowEvent
+import org.junit.Test
@OptIn(ExperimentalComposeUiApi::class)
class WindowParameterTest {
diff --git a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt
index ed7b79d..e8279f5 100644
--- a/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt
+++ b/compose/ui/ui/src/desktopTest/kotlin/androidx/compose/ui/window/window/WindowStateTest.kt
@@ -40,10 +40,6 @@
import androidx.compose.ui.window.rememberWindowState
import androidx.compose.ui.window.runApplicationTest
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.consumeEach
-import org.junit.Assume.assumeTrue
-import org.junit.Test
import java.awt.Dimension
import java.awt.Point
import java.awt.Rectangle
@@ -52,6 +48,10 @@
import javax.swing.JFrame
import kotlin.math.abs
import kotlin.math.max
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.consumeEach
+import org.junit.Assume.assumeTrue
+import org.junit.Test
// Note that on Linux some tests are flaky. Swing event listener's on Linux has non-deterministic
// nature. To avoid flaky'ness we use delays
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
index 6f092a6..2f16c79 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
@@ -27,34 +27,34 @@
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.geometry.Offset
-import androidx.compose.ui.input.pointer.PointerButtons
import androidx.compose.ui.input.key.KeyEvent as ComposeKeyEvent
+import androidx.compose.ui.input.pointer.PointerButtons
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.PointerInputEvent
import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.node.LayoutNode
+import androidx.compose.ui.node.RootForTest
import androidx.compose.ui.platform.AccessibilityController
-import androidx.compose.ui.platform.PlatformComponent
-import androidx.compose.ui.platform.SkiaBasedOwner
-import androidx.compose.ui.platform.PlatformInput
import androidx.compose.ui.platform.DummyPlatformComponent
import androidx.compose.ui.platform.FlushCoroutineDispatcher
import androidx.compose.ui.platform.GlobalSnapshotManager
+import androidx.compose.ui.platform.PlatformComponent
+import androidx.compose.ui.platform.PlatformInput
+import androidx.compose.ui.platform.SkiaBasedOwner
import androidx.compose.ui.platform.setContent
-import androidx.compose.ui.node.RootForTest
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
+import kotlin.coroutines.CoroutineContext
+import kotlin.jvm.Volatile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.jetbrains.skia.Canvas
-import kotlin.coroutines.CoroutineContext
-import kotlin.jvm.Volatile
internal val LocalComposeScene = staticCompositionLocalOf<ComposeScene> {
error("CompositionLocal LocalComposeScene not provided")
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/DefaultViewConfiguration.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/DefaultViewConfiguration.skiko.kt
index d581a1f..04067d8 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/DefaultViewConfiguration.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/DefaultViewConfiguration.skiko.kt
@@ -16,8 +16,8 @@
package androidx.compose.ui.platform
-import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.dp
class DefaultViewConfiguration(private val density: Density) : ViewConfiguration {
override val longPressTimeoutMillis: Long
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcher.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcher.skiko.kt
index 1caeef5..134f900 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcher.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/FlushCoroutineDispatcher.skiko.kt
@@ -16,13 +16,13 @@
package androidx.compose.ui.platform
+import kotlin.coroutines.CoroutineContext
+import kotlin.jvm.Volatile
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.launch
-import kotlin.coroutines.CoroutineContext
-import kotlin.jvm.Volatile
/**
* Dispatcher with the ability to immediately perform (flush) all pending tasks.
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/OutlineCache.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/OutlineCache.skiko.kt
index 9eca11a..1c339d4 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/OutlineCache.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/OutlineCache.skiko.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.toSize
/**
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
index 9aab9d9..5addad3 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaBasedOwner.skiko.kt
@@ -39,9 +39,9 @@
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.asComposeCanvas
+import androidx.compose.ui.input.InputMode.Companion.Keyboard
import androidx.compose.ui.input.InputModeManager
import androidx.compose.ui.input.InputModeManagerImpl
-import androidx.compose.ui.input.InputMode.Companion.Keyboard
import androidx.compose.ui.input.key.Key.Companion.Back
import androidx.compose.ui.input.key.Key.Companion.DirectionCenter
import androidx.compose.ui.input.key.Key.Companion.Tab
@@ -57,6 +57,7 @@
import androidx.compose.ui.input.pointer.PointerIconService
import androidx.compose.ui.input.pointer.PointerInputEvent
import androidx.compose.ui.input.pointer.PointerInputEventProcessor
+import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
import androidx.compose.ui.input.pointer.PositionCalculator
import androidx.compose.ui.input.pointer.ProcessResult
import androidx.compose.ui.input.pointer.TestPointerInputEventData
@@ -72,19 +73,18 @@
import androidx.compose.ui.semantics.EmptySemanticsElement
import androidx.compose.ui.semantics.SemanticsOwner
import androidx.compose.ui.text.ExperimentalTextApi
-import androidx.compose.ui.text.input.PlatformTextInputPluginRegistry
-import androidx.compose.ui.text.input.TextInputService
+import androidx.compose.ui.text.InternalTextApi
import androidx.compose.ui.text.font.createFontFamilyResolver
+import androidx.compose.ui.text.input.PlatformTextInputPluginRegistry
+import androidx.compose.ui.text.input.PlatformTextInputPluginRegistryImpl
+import androidx.compose.ui.text.input.TextInputService
import androidx.compose.ui.text.platform.FontLoader
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
-import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
-import androidx.compose.ui.text.InternalTextApi
-import androidx.compose.ui.text.input.PlatformTextInputPluginRegistryImpl
import kotlin.coroutines.CoroutineContext
private typealias Command = () -> Unit
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt
index 4091d4a..e7d9ae4 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/platform/SkiaLayer.skiko.kt
@@ -33,9 +33,9 @@
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.RenderEffect
import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.SkiaBackedCanvas
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.asComposeCanvas
-import androidx.compose.ui.graphics.SkiaBackedCanvas
import androidx.compose.ui.graphics.asSkiaPath
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.toArgb
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/ComposedModifierTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/ComposedModifierTest.kt
index 47c43e5..444cf73 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/ComposedModifierTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/ComposedModifierTest.kt
@@ -20,12 +20,12 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Composition
import androidx.compose.runtime.InternalComposeApi
-import androidx.compose.runtime.Recomposer
+import androidx.compose.runtime.MonotonicFrameClock
import androidx.compose.runtime.RecomposeScope
+import androidx.compose.runtime.Recomposer
+import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.currentComposer
import androidx.compose.runtime.currentRecomposeScope
-import androidx.compose.runtime.MonotonicFrameClock
-import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.withRunningRecomposer
import kotlinx.coroutines.channels.Channel
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
index 60064cf..9669e89 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/hapticfeedback/HapticFeedbackTest.kt
@@ -18,13 +18,13 @@
import android.view.HapticFeedbackConstants
import android.view.View
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
import org.mockito.kotlin.mock
import org.mockito.kotlin.spy
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class HapticFeedbackTest {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
index fa9d451..05a700a 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/input/RecordingInputConnectionInactiveTest.kt
@@ -21,11 +21,11 @@
import androidx.compose.ui.text.input.RecordingInputConnection
import androidx.compose.ui.text.input.TextFieldValue
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.mock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import org.mockito.kotlin.mock
@RunWith(JUnit4::class)
class RecordingInputConnectionInactiveTest {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
index 820b936..132d3dd6 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/layout/ConstraintsTest.kt
@@ -19,8 +19,8 @@
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.constrain
-import androidx.compose.ui.unit.offset
import androidx.compose.ui.unit.isSatisfiedBy
+import androidx.compose.ui.unit.offset
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
index 698d042..793d11e 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/DelegatingNodeTest.kt
@@ -23,12 +23,11 @@
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.unit.Constraints
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import com.google.common.truth.Truth.assertThat
-
@RunWith(JUnit4::class)
class DelegatingNodeTest {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/HitTestResultTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
index 665bb01..f23209c 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/node/HitTestResultTest.kt
@@ -17,12 +17,11 @@
package androidx.compose.ui.node
import androidx.compose.ui.Modifier
+import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import com.google.common.truth.Truth.assertThat
-
@RunWith(JUnit4::class)
class HitTestResultTest {
@Test
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
index 48c769f..a9048bc 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.platform
import androidx.compose.ui.text.AnnotatedString
-import org.junit.Test
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
class ClipboardManagerTest {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
index cdfda51..9a2a069 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/text/TextActionModeCallbackTest.kt
@@ -31,8 +31,8 @@
import androidx.compose.ui.platform.actionmodecallback.MenuItemOption
import androidx.compose.ui.platform.actionmodecallback.TextActionModeCallback
import androidx.test.filters.SdkSuppress
-import org.junit.Test
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N)
class TextActionModeCallbackTest {
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
index 5a0aec0..cb80640 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/window/PopupPositionProviderTest.kt
@@ -17,8 +17,8 @@
package androidx.compose.ui.window
import androidx.compose.ui.Alignment
-import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import com.google.common.truth.Truth.assertThat
diff --git a/concurrent/concurrent-futures-ktx/build.gradle b/concurrent/concurrent-futures-ktx/build.gradle
index 1c2ee74..3aee3a0 100644
--- a/concurrent/concurrent-futures-ktx/build.gradle
+++ b/concurrent/concurrent-futures-ktx/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Futures Kotlin Extensions"
+ name = "Futures Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Kotlin Extensions for Androidx implementation of Guava's ListenableFuture"
diff --git a/concurrent/concurrent-futures-ktx/src/main/java/androidx/concurrent/futures/ListenableFuture.kt b/concurrent/concurrent-futures-ktx/src/main/java/androidx/concurrent/futures/ListenableFuture.kt
index 8bf37d1..cf5f0a4 100644
--- a/concurrent/concurrent-futures-ktx/src/main/java/androidx/concurrent/futures/ListenableFuture.kt
+++ b/concurrent/concurrent-futures-ktx/src/main/java/androidx/concurrent/futures/ListenableFuture.kt
@@ -18,11 +18,11 @@
import androidx.concurrent.futures.AbstractResolvableFuture.getUninterruptibly
import com.google.common.util.concurrent.ListenableFuture
-import kotlinx.coroutines.CancellableContinuation
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.ExecutionException
import java.util.concurrent.Future
import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.CancellableContinuation
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Awaits completion of `this` [ListenableFuture] without blocking a thread.
diff --git a/concurrent/concurrent-futures-ktx/src/test/java/androidx/concurrent/futures/ListenableFutureTest.kt b/concurrent/concurrent-futures-ktx/src/test/java/androidx/concurrent/futures/ListenableFutureTest.kt
index 6b3366e..3385556 100644
--- a/concurrent/concurrent-futures-ktx/src/test/java/androidx/concurrent/futures/ListenableFutureTest.kt
+++ b/concurrent/concurrent-futures-ktx/src/test/java/androidx/concurrent/futures/ListenableFutureTest.kt
@@ -18,6 +18,9 @@
package androidx.concurrent.futures
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicInteger
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -27,15 +30,12 @@
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.concurrent.atomic.AtomicInteger
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
@OptIn(DelicateCoroutinesApi::class)
diff --git a/concurrent/concurrent-futures/build.gradle b/concurrent/concurrent-futures/build.gradle
index 2f134c0..94a63aa 100644
--- a/concurrent/concurrent-futures/build.gradle
+++ b/concurrent/concurrent-futures/build.gradle
@@ -29,7 +29,7 @@
}
androidx {
- name = "AndroidX Futures"
+ name = "Futures"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Androidx implementation of Guava's ListenableFuture"
diff --git a/constraintlayout/constraintlayout-compose/build.gradle b/constraintlayout/constraintlayout-compose/build.gradle
index 639aa60..207692f 100644
--- a/constraintlayout/constraintlayout-compose/build.gradle
+++ b/constraintlayout/constraintlayout-compose/build.gradle
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
import androidx.build.LibraryType
-import androidx.build.Publish
plugins {
id("AndroidXPlugin")
@@ -24,77 +22,49 @@
id("AndroidXComposePlugin")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+androidXMultiplatform {
+ android()
-dependencies {
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- implementation(project(":compose:ui:ui"))
- implementation(project(":compose:ui:ui-unit"))
- implementation(project(":compose:ui:ui-util"))
- implementation(project(":compose:foundation:foundation"))
- implementation(project(":compose:foundation:foundation-layout"))
-
- implementation(project(":constraintlayout:constraintlayout-core"))
-
- androidTestImplementation(project(":compose:material:material"))
- androidTestImplementation(project(":compose:ui:ui-test"))
- androidTestImplementation(project(":compose:ui:ui-test-junit4"))
- androidTestImplementation(project(":compose:ui:ui-test-manifest"))
- androidTestImplementation(project(":activity:activity"))
-
- androidTestImplementation(libs.kotlinTest)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
-
- lintPublish(project(":constraintlayout:constraintlayout-compose-lint"))
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
-// implementation(libs.kotlinStdlibCommon)
-
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(project(":compose:ui:ui"))
- implementation("androidx.compose.ui:ui-unit:1.4.0-beta02")
- implementation("androidx.compose.ui:ui-util:1.4.0-beta02")
- implementation("androidx.compose.foundation:foundation:1.4.0-beta02")
- implementation("androidx.compose.foundation:foundation-layout:1.4.0-beta02")
+ implementation(project(":compose:ui:ui-unit"))
+ implementation(project(":compose:ui:ui-util"))
+ implementation(project(":compose:foundation:foundation"))
+ implementation(project(":compose:foundation:foundation-layout"))
implementation(project(":constraintlayout:constraintlayout-core"))
-
}
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependencies {
+ }
+ }
+
+
+ androidMain {
+ dependsOn(commonMain)
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
implementation("androidx.core:core-ktx:1.5.0")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ jvmTest {
+ dependencies {
}
+ }
- // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
- // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
- // level dependencies block instead:
- // `dependencies { testImplementation(libs.robolectric) }`
- androidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- }
-
- androidAndroidTest.dependencies {
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.kotlinTest)
implementation(libs.testRules)
implementation(libs.testRunner)
@@ -107,11 +77,29 @@
implementation(project(":compose:test-utils"))
}
}
+
+
+ // TODO(b/214407011): These dependencies leak into instrumented tests as well. If you
+ // need to add Robolectric (which must be kept out of androidAndroidTest), use a top
+ // level dependencies block instead:
+ // `dependencies { testImplementation(libs.robolectric) }`
+ androidTest {
+ dependsOn(jvmTest)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ }
+ }
}
}
+dependencies {
+ lintPublish(project(":constraintlayout:constraintlayout-compose-lint"))
+}
+
androidx {
- name = "Android ConstraintLayout Compose Library"
+ name = "ConstraintLayout Compose"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CONSTRAINTLAYOUT_COMPOSE
inceptionYear = "2022"
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt
index 4121bed..53be7dc 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt
@@ -36,7 +36,7 @@
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -71,7 +71,7 @@
@Preview
@Composable
fun ComposeConstraintLayoutDemos() {
- var displayedDemoIndex by remember { mutableStateOf(-1) }
+ var displayedDemoIndex by remember { mutableIntStateOf(-1) }
val maxIndex = AllComposeConstraintLayoutDemos.size - 1
Column {
Column {
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/CollapsibleToolbarDemo.kt b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/CollapsibleToolbarDemo.kt
index 21dd10a..a1aa8cc 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/CollapsibleToolbarDemo.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/CollapsibleToolbarDemo.kt
@@ -34,7 +34,7 @@
import androidx.compose.material.icons.filled.Face
import androidx.compose.material.icons.filled.Menu
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -241,30 +241,30 @@
val maxPx = with(LocalDensity.current) { big.roundToPx().toFloat() }
val minPx = with(LocalDensity.current) { small.roundToPx().toFloat() }
- val toolbarHeight = remember { mutableStateOf(maxPx) }
+ val toolbarHeight = remember { mutableFloatStateOf(maxPx) }
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
- val height = toolbarHeight.value
+ val height = toolbarHeight.floatValue
if (height + available.y > maxPx) {
- toolbarHeight.value = maxPx
+ toolbarHeight.floatValue = maxPx
return Offset(0f, maxPx - height)
}
if (height + available.y < minPx) {
- toolbarHeight.value = minPx
+ toolbarHeight.floatValue = minPx
return Offset(0f, minPx - height)
}
- toolbarHeight.value += available.y
+ toolbarHeight.floatValue += available.y
return Offset(0f, available.y)
}
}
}
- val progress = 1 - (toolbarHeight.value - minPx) / (maxPx - minPx)
+ val progress = 1 - (toolbarHeight.floatValue - minPx) / (maxPx - minPx)
Column {
MotionLayout(
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/ReactionSelectorDemo.kt b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/ReactionSelectorDemo.kt
index 5377ef1..ecd1404 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/ReactionSelectorDemo.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/demos/src/main/java/androidx/constraintlayout/compose/demos/ReactionSelectorDemo.kt
@@ -28,6 +28,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -47,7 +48,7 @@
@Preview
@Composable
fun ReactionSelectorDemo() {
- var selected by remember { mutableStateOf(3) }
+ var selected by remember { mutableIntStateOf(3) }
val transitionName = remember { mutableStateOf("transition1") }
val emojis = remember { "😀 🙂 🤨 😐 😒 😬".split(' ') }
val emojiNames = remember {
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/MotionLayoutActivity.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/MotionLayoutActivity.kt
index 4e015c9..d104977 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/MotionLayoutActivity.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/MotionLayoutActivity.kt
@@ -22,9 +22,6 @@
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.newmessage.NewMotionMessagePreview
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.newmessage.NewMotionMessagePreviewWithDsl
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.toolbar.MotionCollapseToolbarPreview
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Recomposer
@@ -33,6 +30,9 @@
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.constraintlayout.compose.integration.macrobenchmark.target.graphs.DynamicGraphsPreview
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.newmessage.NewMotionMessagePreview
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.newmessage.NewMotionMessagePreviewWithDsl
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.toolbar.MotionCollapseToolbarPreview
class MotionLayoutActivity : ComponentActivity() {
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/CardSample.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/CardSample.kt
index 30960cf..a1c4b31 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/CardSample.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/CardSample.kt
@@ -28,10 +28,6 @@
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.LoremIpsum
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.newHourMinuteTimeStamp
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.randomAvatarId
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.randomFullName
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@@ -45,6 +41,10 @@
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.ConstraintSet
import androidx.constraintlayout.compose.Dimension
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.LoremIpsum
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.newHourMinuteTimeStamp
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.randomAvatarId
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata.randomFullName
@Preview
@Composable
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessage.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessage.kt
index 75c0dc8..95b79af 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessage.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessage.kt
@@ -29,7 +29,6 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.TestableButton
import androidx.compose.material.Button
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Icon
@@ -69,6 +68,7 @@
import androidx.constraintlayout.compose.MotionLayoutScope
import androidx.constraintlayout.compose.MotionScene
import androidx.constraintlayout.compose.Visibility
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.TestableButton
// Copied from ComposeMail project
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/toolbar/CollapsibleToolbar.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/toolbar/CollapsibleToolbar.kt
index 3fe6074..846fd83 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/toolbar/CollapsibleToolbar.kt
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/toolbar/CollapsibleToolbar.kt
@@ -27,8 +27,6 @@
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.CardSample
-import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.OutlinedSearchBar
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -55,6 +53,8 @@
import androidx.constraintlayout.compose.Dimension
import androidx.constraintlayout.compose.ExperimentalMotionApi
import androidx.constraintlayout.compose.MotionLayout
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.CardSample
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.common.components.OutlinedSearchBar
import kotlin.math.absoluteValue
@Preview
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle
index 5824041..488e08f 100644
--- a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle
@@ -14,11 +14,9 @@
* limitations under the License.
*/
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -30,26 +28,23 @@
// We need animations to work for MotionLayout
testOptions.animationsDisabled false
+ targetProjectPath = ":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(project(":internal-testutils-runtime"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
+ implementation(project(":benchmark:benchmark-junit4"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(project(":internal-testutils-runtime"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark-target:installRelease"
- )
- )
-}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
similarity index 100%
rename from constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
rename to constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/constraintlayout/compose/integration/macrobenchmark/MotionLayoutBenchmark.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/MotionLayoutBenchmark.kt
similarity index 100%
rename from constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/constraintlayout/compose/integration/macrobenchmark/MotionLayoutBenchmark.kt
rename to constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/MotionLayoutBenchmark.kt
diff --git a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/MotionParserTest.kt b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/MotionParserTest.kt
index bbb33db..b674c98 100644
--- a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/MotionParserTest.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/MotionParserTest.kt
@@ -31,12 +31,12 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import kotlin.test.assertFailsWith
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertFailsWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt
index 1896407..aa46490 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayout.kt
@@ -41,6 +41,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.remember
@@ -290,7 +291,7 @@
content = { content() })
} else {
val needsUpdate = remember {
- mutableStateOf(0L)
+ mutableLongStateOf(0L)
}
val contentTracker = remember { mutableStateOf(Unit, neverEqualPolicy()) }
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
index 2656198..61b5811 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionCarousel.kt
@@ -26,6 +26,8 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -168,9 +170,9 @@
val provider = rememberStateOfItemsProvider(content)
- var componentWidth by remember { mutableStateOf(1000f) }
+ var componentWidth by remember { mutableFloatStateOf(1000f) }
val swipeableState = rememberCarouselSwipeableState(swipeStateStart)
- var mprogress = (swipeableState.offset.value / componentWidth)
+ var mprogress = (swipeableState.offset.floatValue / componentWidth)
var state by remember {
mutableStateOf(
@@ -183,11 +185,11 @@
)
)
}
- var currentIndex = remember { mutableStateOf(0) }
+ var currentIndex by remember { mutableIntStateOf(0) }
- val anchors = if (currentIndex.value == 0) {
+ val anchors = if (currentIndex == 0) {
mapOf(0f to swipeStateStart, componentWidth to swipeStateForward)
- } else if (currentIndex.value == provider.value.count() - 1) {
+ } else if (currentIndex == provider.value.count() - 1) {
mapOf(-componentWidth to swipeStateBackward, 0f to swipeStateStart)
} else {
mapOf(
@@ -232,7 +234,7 @@
state.direction = MotionCarouselDirection.FORWARD
}
}
- currentIndex.value = state.index
+ currentIndex = state.index
}
MotionLayout(motionScene = motionScene,
@@ -254,7 +256,7 @@
}
) {
for (i in 0 until numSlots) {
- val idx = i + currentIndex.value - initialSlotIndex
+ val idx = i + currentIndex - initialSlotIndex
val visible = idx in 0 until provider.value.count()
ItemHolder(i, slotPrefix, showSlots) {
if (visible) {
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
index a003146..d1aff18 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionLayout.kt
@@ -29,6 +29,8 @@
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.remember
@@ -411,18 +413,18 @@
content: @Composable (MotionLayoutScope.() -> Unit)
) {
val needsUpdate = remember {
- mutableStateOf(0L)
+ mutableLongStateOf(0L)
}
- val transition = remember(motionScene, needsUpdate.value) {
+ val transition = remember(motionScene, needsUpdate.longValue) {
motionScene.getTransitionInstance("default")
}
- val initialStart = remember(motionScene, needsUpdate.value) {
+ val initialStart = remember(motionScene, needsUpdate.longValue) {
val startId = transition?.getStartConstraintSetId() ?: "start"
motionScene.getConstraintSetInstance(startId)
}
- val initialEnd = remember(motionScene, needsUpdate.value) {
+ val initialEnd = remember(motionScene, needsUpdate.longValue) {
val endId = transition?.getEndConstraintSetId() ?: "end"
motionScene.getConstraintSetInstance(endId)
}
@@ -557,8 +559,8 @@
val motionProgress = createAndUpdateMotionProgress(progress = progress)
val transitionImpl = (transition as? TransitionImpl) ?: TransitionImpl.EMPTY
// TODO: Merge this snippet with UpdateWithForcedIfNoUserChange
- val needsUpdate = remember { mutableStateOf(0L) }
- needsUpdate.value // Read the value to allow recomposition from informationReceiver
+ val needsUpdate = remember { mutableLongStateOf(0L) }
+ needsUpdate.longValue // Read the value to allow recomposition from informationReceiver
informationReceiver?.setUpdateFlag(needsUpdate)
UpdateWithForcedIfNoUserChange(
@@ -1005,7 +1007,7 @@
@Composable
internal fun createAndUpdateMotionProgress(progress: Float): MotionProgress {
val motionProgress = remember {
- MotionProgress.fromMutableState(mutableStateOf(progress))
+ MotionProgress.fromMutableState(mutableFloatStateOf(progress))
}
val last = remember { Ref<Float>().apply { value = progress } }
if (last.value != progress) {
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.java b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.java
deleted file mode 100644
index e259358..0000000
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * 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.
- */
-package androidx.constraintlayout.compose;
-
-import android.graphics.Canvas;
-import android.graphics.DashPathEffect;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-import androidx.constraintlayout.core.motion.Motion;
-import androidx.constraintlayout.core.motion.MotionPaths;
-
-import java.util.HashMap;
-
-class MotionRenderDebug {
- public static final int DEBUG_SHOW_NONE = 0;
- public static final int DEBUG_SHOW_PROGRESS = 1;
- public static final int DEBUG_SHOW_PATH = 2;
-
- static final int MAX_KEY_FRAMES = 50;
- private static final int DEBUG_PATH_TICKS_PER_MS = 16;
- float[] mPoints;
- int[] mPathMode;
- float[] mKeyFramePoints;
- Path mPath;
- Paint mPaint;
- Paint mPaintKeyframes;
- Paint mPaintGraph;
- Paint mTextPaint;
- Paint mFillPaint;
- private float[] mRectangle;
- final int mRedColor = 0xFFFFAA33;
- final int mKeyframeColor = 0xffe0759a;
- final int mGraphColor = 0xFF33AA00;
- final int mShadowColor = 0x77000000;
- final int mDiamondSize = 10;
- DashPathEffect mDashPathEffect;
- int mKeyFrameCount;
- Rect mBounds = new Rect();
- boolean mPresentationMode = false;
- int mShadowTranslate = 1;
-
- MotionRenderDebug(float textSize) {
-
- mPaint = new Paint();
- mPaint.setAntiAlias(true);
- mPaint.setColor(mRedColor);
- mPaint.setStrokeWidth(2);
- mPaint.setStyle(Paint.Style.STROKE);
-
- mPaintKeyframes = new Paint();
- mPaintKeyframes.setAntiAlias(true);
- mPaintKeyframes.setColor(mKeyframeColor);
- mPaintKeyframes.setStrokeWidth(2);
- mPaintKeyframes.setStyle(Paint.Style.STROKE);
-
- mPaintGraph = new Paint();
- mPaintGraph.setAntiAlias(true);
- mPaintGraph.setColor(mGraphColor);
- mPaintGraph.setStrokeWidth(2);
- mPaintGraph.setStyle(Paint.Style.STROKE);
-
- mTextPaint = new Paint();
- mTextPaint.setAntiAlias(true);
- mTextPaint.setColor(mGraphColor);
- mTextPaint.setTextSize(textSize);
- mRectangle = new float[8];
- mFillPaint = new Paint();
- mFillPaint.setAntiAlias(true);
- mDashPathEffect = new DashPathEffect(new float[]{4, 8}, 0);
- mPaintGraph.setPathEffect(mDashPathEffect);
- mKeyFramePoints = new float[MAX_KEY_FRAMES * 2];
- mPathMode = new int[MAX_KEY_FRAMES];
-
- if (mPresentationMode) {
- mPaint.setStrokeWidth(8);
- mFillPaint.setStrokeWidth(8);
- mPaintKeyframes.setStrokeWidth(8);
- mShadowTranslate = 4;
- }
- }
-
- public void draw(Canvas canvas,
- HashMap<String, Motion> frameArrayList,
- int duration, int debugPath,
- int layoutWidth, int layoutHeight) {
- if (frameArrayList == null || frameArrayList.size() == 0) {
- return;
- }
- canvas.save();
-
- for (Motion motionController : frameArrayList.values()) {
- draw(canvas, motionController, duration, debugPath,
- layoutWidth, layoutHeight);
- }
- canvas.restore();
- }
-
- public void draw(Canvas canvas,
- Motion motionController,
- int duration, int debugPath,
- int layoutWidth, int layoutHeight) {
- int mode = motionController.getDrawPath();
- if (debugPath > 0 && mode == Motion.DRAW_PATH_NONE) {
- mode = Motion.DRAW_PATH_BASIC;
- }
- if (mode == Motion.DRAW_PATH_NONE) { // do not draw path
- return;
- }
-
- mKeyFrameCount = motionController.buildKeyFrames(mKeyFramePoints, mPathMode, null);
-
- if (mode >= Motion.DRAW_PATH_BASIC) {
-
- int frames = duration / DEBUG_PATH_TICKS_PER_MS;
- if (mPoints == null || mPoints.length != frames * 2) {
- mPoints = new float[frames * 2];
- mPath = new Path();
- }
-
- canvas.translate(mShadowTranslate, mShadowTranslate);
-
- mPaint.setColor(mShadowColor);
- mFillPaint.setColor(mShadowColor);
- mPaintKeyframes.setColor(mShadowColor);
- mPaintGraph.setColor(mShadowColor);
- motionController.buildPath(mPoints, frames);
- drawAll(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight);
- mPaint.setColor(mRedColor);
- mPaintKeyframes.setColor(mKeyframeColor);
- mFillPaint.setColor(mKeyframeColor);
- mPaintGraph.setColor(mGraphColor);
-
- canvas.translate(-mShadowTranslate, -mShadowTranslate);
- drawAll(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight);
- if (mode == Motion.DRAW_PATH_RECTANGLE) {
- drawRectangle(canvas, motionController);
- }
- }
-
- }
-
-
- public void drawAll(Canvas canvas, int mode, int keyFrames, Motion motionController,
- int layoutWidth, int layoutHeight) {
- if (mode == Motion.DRAW_PATH_AS_CONFIGURED) {
- drawPathAsConfigured(canvas);
- }
- if (mode == Motion.DRAW_PATH_RELATIVE) {
- drawPathRelative(canvas);
- }
- if (mode == Motion.DRAW_PATH_CARTESIAN) {
- drawPathCartesian(canvas);
- }
- drawBasicPath(canvas);
- drawTicks(canvas, mode, keyFrames, motionController, layoutWidth, layoutHeight);
- }
-
-
- /**
- * Draws the paths of the given {@link Motion motionController}, forcing the drawing mode
- * {@link Motion#DRAW_PATH_BASIC}.
- *
- * @param canvas Canvas instance used to draw on
- * @param motionController Controller containing path information
- * @param duration Defined in milliseconds, sets the amount of ticks used to draw the path
- * based on {@link #DEBUG_PATH_TICKS_PER_MS}
- * @param layoutWidth Width of the containing MotionLayout
- * @param layoutHeight Height of the containing MotionLayout
- * @param drawPath Whether to draw the path, paths are drawn using dashed lines
- * @param drawTicks Whether to draw diamond shaped ticks that indicate KeyPositions along a path
- */
- void basicDraw(@NonNull Canvas canvas,
- @NonNull Motion motionController,
- int duration,
- int layoutWidth,
- int layoutHeight,
- boolean drawPath,
- boolean drawTicks) {
- int mode = Motion.DRAW_PATH_BASIC;
- mKeyFrameCount = motionController.buildKeyFrames(mKeyFramePoints, mPathMode, null);
-
- int frames = duration / DEBUG_PATH_TICKS_PER_MS;
- if (mPoints == null || mPoints.length != frames * 2) {
- mPoints = new float[frames * 2];
- mPath = new Path();
- }
-
- canvas.translate(mShadowTranslate, mShadowTranslate);
-
- mPaint.setColor(mShadowColor);
- mFillPaint.setColor(mShadowColor);
- mPaintKeyframes.setColor(mShadowColor);
- mPaintGraph.setColor(mShadowColor);
- motionController.buildPath(mPoints, frames);
- if (drawPath) {
- drawBasicPath(canvas);
- }
- if (drawTicks) {
- drawTicks(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight);
- }
-
- mPaint.setColor(mRedColor);
- mPaintKeyframes.setColor(mKeyframeColor);
- mFillPaint.setColor(mKeyframeColor);
- mPaintGraph.setColor(mGraphColor);
- canvas.translate(-mShadowTranslate, -mShadowTranslate);
- if (drawPath) {
- drawBasicPath(canvas);
- }
- if (drawTicks) {
- drawTicks(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight);
- }
- }
-
- private void drawBasicPath(Canvas canvas) {
- canvas.drawLines(mPoints, mPaint);
- }
-
- private void drawTicks(Canvas canvas, int mode, int keyFrames, Motion motionController,
- int layoutWidth, int layoutHeight) {
- int viewWidth = 0;
- int viewHeight = 0;
- if (motionController.getView() != null) {
- viewWidth = motionController.getView().getWidth();
- viewHeight = motionController.getView().getHeight();
- }
- for (int i = 1; i < keyFrames - 1; i++) {
- if (mode == Motion.DRAW_PATH_AS_CONFIGURED
- && mPathMode[i - 1] == Motion.DRAW_PATH_NONE) {
- continue;
-
- }
- float x = mKeyFramePoints[i * 2];
- float y = mKeyFramePoints[i * 2 + 1];
- mPath.reset();
- mPath.moveTo(x, y + mDiamondSize);
- mPath.lineTo(x + mDiamondSize, y);
- mPath.lineTo(x, y - mDiamondSize);
- mPath.lineTo(x - mDiamondSize, y);
- mPath.close();
- float dx = 0; //framePoint.translationX
- float dy = 0; //framePoint.translationY
- if (mode == Motion.DRAW_PATH_AS_CONFIGURED) {
-
- if (mPathMode[i - 1] == MotionPaths.PERPENDICULAR) {
- drawPathRelativeTicks(canvas, x - dx, y - dy);
- } else if (mPathMode[i - 1] == MotionPaths.CARTESIAN) {
- drawPathCartesianTicks(canvas, x - dx, y - dy);
- } else if (mPathMode[i - 1] == MotionPaths.SCREEN) {
- drawPathScreenTicks(canvas, x - dx, y - dy,
- viewWidth, viewHeight, layoutWidth, layoutHeight);
- }
-
- canvas.drawPath(mPath, mFillPaint);
- }
- if (mode == Motion.DRAW_PATH_RELATIVE) {
- drawPathRelativeTicks(canvas, x - dx, y - dy);
- }
- if (mode == Motion.DRAW_PATH_CARTESIAN) {
- drawPathCartesianTicks(canvas, x - dx, y - dy);
- }
- if (mode == Motion.DRAW_PATH_SCREEN) {
- drawPathScreenTicks(canvas, x - dx, y - dy,
- viewWidth, viewHeight, layoutWidth, layoutHeight);
- }
- if (dx != 0 || dy != 0) {
- drawTranslation(canvas, x - dx, y - dy, x, y);
- } else {
- canvas.drawPath(mPath, mFillPaint);
- }
- }
- if (mPoints.length > 1) {
- // Draw the starting and ending circle
- canvas.drawCircle(mPoints[0], mPoints[1], 8, mPaintKeyframes);
- canvas.drawCircle(mPoints[mPoints.length - 2],
- mPoints[mPoints.length - 1], 8, mPaintKeyframes);
- }
- }
-
- private void drawTranslation(Canvas canvas, float x1, float y1, float x2, float y2) {
- canvas.drawRect(x1, y1, x2, y2, mPaintGraph);
- canvas.drawLine(x1, y1, x2, y2, mPaintGraph);
- }
-
- private void drawPathRelative(Canvas canvas) {
- canvas.drawLine(mPoints[0], mPoints[1],
- mPoints[mPoints.length - 2], mPoints[mPoints.length - 1], mPaintGraph);
- }
-
- private void drawPathAsConfigured(Canvas canvas) {
- boolean path = false;
- boolean cart = false;
- for (int i = 0; i < mKeyFrameCount; i++) {
- if (mPathMode[i] == MotionPaths.PERPENDICULAR) {
- path = true;
- }
- if (mPathMode[i] == MotionPaths.CARTESIAN) {
- cart = true;
- }
- }
- if (path) {
- drawPathRelative(canvas);
- }
- if (cart) {
- drawPathCartesian(canvas);
- }
- }
-
- private void drawPathRelativeTicks(Canvas canvas, float x, float y) {
- float x1 = mPoints[0];
- float y1 = mPoints[1];
- float x2 = mPoints[mPoints.length - 2];
- float y2 = mPoints[mPoints.length - 1];
- float dist = (float) Math.hypot(x1 - x2, y1 - y2);
- float t = ((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1)) / (dist * dist);
- float xp = x1 + t * (x2 - x1);
- float yp = y1 + t * (y2 - y1);
-
- Path path = new Path();
- path.moveTo(x, y);
- path.lineTo(xp, yp);
- float len = (float) Math.hypot(xp - x, yp - y);
- String text = "" + ((int) (100 * len / dist)) / 100.0f;
- getTextBounds(text, mTextPaint);
- float off = len / 2 - mBounds.width() / 2;
- canvas.drawTextOnPath(text, path, off, -20, mTextPaint);
- canvas.drawLine(x, y, xp, yp, mPaintGraph);
- }
-
- void getTextBounds(String text, Paint paint) {
- paint.getTextBounds(text, 0, text.length(), mBounds);
- }
-
- private void drawPathCartesian(Canvas canvas) {
- float x1 = mPoints[0];
- float y1 = mPoints[1];
- float x2 = mPoints[mPoints.length - 2];
- float y2 = mPoints[mPoints.length - 1];
-
- canvas.drawLine(Math.min(x1, x2), Math.max(y1, y2),
- Math.max(x1, x2), Math.max(y1, y2), mPaintGraph);
- canvas.drawLine(Math.min(x1, x2), Math.min(y1, y2),
- Math.min(x1, x2), Math.max(y1, y2), mPaintGraph);
- }
-
- private void drawPathCartesianTicks(Canvas canvas, float x, float y) {
- float x1 = mPoints[0];
- float y1 = mPoints[1];
- float x2 = mPoints[mPoints.length - 2];
- float y2 = mPoints[mPoints.length - 1];
- float minx = Math.min(x1, x2);
- float maxy = Math.max(y1, y2);
- float xgap = x - Math.min(x1, x2);
- float ygap = Math.max(y1, y2) - y;
- // Horizontal line
- String text = "" + ((int) (0.5 + 100 * xgap / Math.abs(x2 - x1))) / 100.0f;
- getTextBounds(text, mTextPaint);
- float off = xgap / 2 - mBounds.width() / 2;
- canvas.drawText(text, off + minx, y - 20, mTextPaint);
- canvas.drawLine(x, y,
- Math.min(x1, x2), y, mPaintGraph);
-
- // Vertical line
- text = "" + ((int) (0.5 + 100 * ygap / Math.abs(y2 - y1))) / 100.0f;
- getTextBounds(text, mTextPaint);
- off = ygap / 2 - mBounds.height() / 2;
- canvas.drawText(text, x + 5, maxy - off, mTextPaint);
- canvas.drawLine(x, y,
- x, Math.max(y1, y2), mPaintGraph);
- }
-
- private void drawPathScreenTicks(Canvas canvas, float x, float y, int viewWidth, int viewHeight,
- int layoutWidth, int layoutHeight) {
- float x1 = 0;
- float y1 = 0;
- float x2 = 1;
- float y2 = 1;
- float minx = 0;
- float maxy = 0;
- float xgap = x;
- float ygap = y;
- // Horizontal line
- String text = "" + ((int) (0.5 + 100 * (xgap - viewWidth / 2)
- / (layoutWidth - viewWidth))) / 100.0f;
- getTextBounds(text, mTextPaint);
- float off = xgap / 2 - mBounds.width() / 2;
- canvas.drawText(text, off + minx, y - 20, mTextPaint);
- canvas.drawLine(x, y,
- Math.min(x1, x2), y, mPaintGraph);
-
- // Vertical line
- text = "" + ((int) (0.5 + 100 * (ygap - viewHeight / 2)
- / (layoutHeight - viewHeight))) / 100.0f;
- getTextBounds(text, mTextPaint);
- off = ygap / 2 - mBounds.height() / 2;
- canvas.drawText(text, x + 5, maxy - off, mTextPaint);
- canvas.drawLine(x, y,
- x, Math.max(y1, y2), mPaintGraph);
- }
-
- private void drawRectangle(Canvas canvas, Motion motionController) {
- mPath.reset();
- int rectFrames = 50;
- for (int i = 0; i <= rectFrames; i++) {
- float p = i / (float) rectFrames;
- motionController.buildRect(p, mRectangle, 0);
- mPath.moveTo(mRectangle[0], mRectangle[1]);
- mPath.lineTo(mRectangle[2], mRectangle[3]);
- mPath.lineTo(mRectangle[4], mRectangle[5]);
- mPath.lineTo(mRectangle[6], mRectangle[7]);
- mPath.close();
- }
- mPaint.setColor(0x44000000);
- canvas.translate(2, 2);
- canvas.drawPath(mPath, mPaint);
-
- canvas.translate(-2, -2);
- mPaint.setColor(0xFFFF0000);
- canvas.drawPath(mPath, mPaint);
- }
-}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.kt
new file mode 100644
index 0000000..1477c32
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/MotionRenderDebug.kt
@@ -0,0 +1,460 @@
+/*
+ * 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.
+ */
+package androidx.constraintlayout.compose
+
+import android.graphics.Canvas
+import android.graphics.DashPathEffect
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.Rect
+import androidx.constraintlayout.core.motion.Motion
+import androidx.constraintlayout.core.motion.MotionPaths
+
+internal class MotionRenderDebug(textSize: Float) {
+ var mPoints: FloatArray? = null
+ var mPathMode: IntArray
+ var mKeyFramePoints: FloatArray
+ var mPath: Path? = null
+ var mPaint: Paint
+ var mPaintKeyframes: Paint
+ var mPaintGraph: Paint
+ var mTextPaint: Paint
+ var mFillPaint: Paint
+ private val mRectangle: FloatArray
+ val mRedColor = -0x55cd
+ val mKeyframeColor = -0x1f8a66
+ val mGraphColor = -0xcc5600
+ val mShadowColor = 0x77000000
+ val mDiamondSize = 10
+ var mDashPathEffect: DashPathEffect
+ var mKeyFrameCount = 0
+ var mBounds = Rect()
+ var mPresentationMode = false
+ var mShadowTranslate = 1
+
+ init {
+ mPaint = Paint()
+ mPaint.isAntiAlias = true
+ mPaint.color = mRedColor
+ mPaint.strokeWidth = 2f
+ mPaint.style = Paint.Style.STROKE
+ mPaintKeyframes = Paint()
+ mPaintKeyframes.isAntiAlias = true
+ mPaintKeyframes.color = mKeyframeColor
+ mPaintKeyframes.strokeWidth = 2f
+ mPaintKeyframes.style = Paint.Style.STROKE
+ mPaintGraph = Paint()
+ mPaintGraph.isAntiAlias = true
+ mPaintGraph.color = mGraphColor
+ mPaintGraph.strokeWidth = 2f
+ mPaintGraph.style = Paint.Style.STROKE
+ mTextPaint = Paint()
+ mTextPaint.isAntiAlias = true
+ mTextPaint.color = mGraphColor
+ mTextPaint.textSize = textSize
+ mRectangle = FloatArray(8)
+ mFillPaint = Paint()
+ mFillPaint.isAntiAlias = true
+ mDashPathEffect = DashPathEffect(floatArrayOf(4f, 8f), 0f)
+ mPaintGraph.pathEffect = mDashPathEffect
+ mKeyFramePoints = FloatArray(MAX_KEY_FRAMES * 2)
+ mPathMode = IntArray(MAX_KEY_FRAMES)
+ if (mPresentationMode) {
+ mPaint.strokeWidth = 8f
+ mFillPaint.strokeWidth = 8f
+ mPaintKeyframes.strokeWidth = 8f
+ mShadowTranslate = 4
+ }
+ }
+
+ fun draw(
+ canvas: Canvas,
+ frameArrayList: HashMap<String?, Motion>?,
+ duration: Int,
+ debugPath: Int,
+ layoutWidth: Int,
+ layoutHeight: Int
+ ) {
+ if (frameArrayList == null || frameArrayList.size == 0) {
+ return
+ }
+ canvas.save()
+ for (motionController in frameArrayList.values) {
+ draw(
+ canvas, motionController, duration, debugPath,
+ layoutWidth, layoutHeight
+ )
+ }
+ canvas.restore()
+ }
+
+ fun draw(
+ canvas: Canvas,
+ motionController: Motion,
+ duration: Int,
+ debugPath: Int,
+ layoutWidth: Int,
+ layoutHeight: Int
+ ) {
+ var mode = motionController.drawPath
+ if (debugPath > 0 && mode == Motion.DRAW_PATH_NONE) {
+ mode = Motion.DRAW_PATH_BASIC
+ }
+ if (mode == Motion.DRAW_PATH_NONE) { // do not draw path
+ return
+ }
+ mKeyFrameCount = motionController.buildKeyFrames(mKeyFramePoints, mPathMode, null)
+ if (mode >= Motion.DRAW_PATH_BASIC) {
+ val frames = duration / DEBUG_PATH_TICKS_PER_MS
+ if (mPoints == null || mPoints!!.size != frames * 2) {
+ mPoints = FloatArray(frames * 2)
+ mPath = Path()
+ }
+ canvas.translate(mShadowTranslate.toFloat(), mShadowTranslate.toFloat())
+ mPaint.color = mShadowColor
+ mFillPaint.color = mShadowColor
+ mPaintKeyframes.color = mShadowColor
+ mPaintGraph.color = mShadowColor
+ motionController.buildPath(mPoints, frames)
+ drawAll(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight)
+ mPaint.color = mRedColor
+ mPaintKeyframes.color = mKeyframeColor
+ mFillPaint.color = mKeyframeColor
+ mPaintGraph.color = mGraphColor
+ canvas.translate(-mShadowTranslate.toFloat(), -mShadowTranslate.toFloat())
+ drawAll(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight)
+ if (mode == Motion.DRAW_PATH_RECTANGLE) {
+ drawRectangle(canvas, motionController)
+ }
+ }
+ }
+
+ fun drawAll(
+ canvas: Canvas,
+ mode: Int,
+ keyFrames: Int,
+ motionController: Motion,
+ layoutWidth: Int,
+ layoutHeight: Int
+ ) {
+ if (mode == Motion.DRAW_PATH_AS_CONFIGURED) {
+ drawPathAsConfigured(canvas)
+ }
+ if (mode == Motion.DRAW_PATH_RELATIVE) {
+ drawPathRelative(canvas)
+ }
+ if (mode == Motion.DRAW_PATH_CARTESIAN) {
+ drawPathCartesian(canvas)
+ }
+ drawBasicPath(canvas)
+ drawTicks(canvas, mode, keyFrames, motionController, layoutWidth, layoutHeight)
+ }
+
+ /**
+ * Draws the paths of the given [motionController][Motion], forcing the drawing mode
+ * [Motion.DRAW_PATH_BASIC].
+ *
+ * @param canvas Canvas instance used to draw on
+ * @param motionController Controller containing path information
+ * @param duration Defined in milliseconds, sets the amount of ticks used to draw the path
+ * based on [.DEBUG_PATH_TICKS_PER_MS]
+ * @param layoutWidth Width of the containing MotionLayout
+ * @param layoutHeight Height of the containing MotionLayout
+ * @param drawPath Whether to draw the path, paths are drawn using dashed lines
+ * @param drawTicks Whether to draw diamond shaped ticks that indicate KeyPositions along a path
+ */
+ fun basicDraw(
+ canvas: Canvas,
+ motionController: Motion,
+ duration: Int,
+ layoutWidth: Int,
+ layoutHeight: Int,
+ drawPath: Boolean,
+ drawTicks: Boolean
+ ) {
+ val mode = Motion.DRAW_PATH_BASIC
+ mKeyFrameCount = motionController.buildKeyFrames(mKeyFramePoints, mPathMode, null)
+ val frames = duration / DEBUG_PATH_TICKS_PER_MS
+ if (mPoints == null || mPoints!!.size != frames * 2) {
+ mPoints = FloatArray(frames * 2)
+ mPath = Path()
+ }
+ canvas.translate(mShadowTranslate.toFloat(), mShadowTranslate.toFloat())
+ mPaint.color = mShadowColor
+ mFillPaint.color = mShadowColor
+ mPaintKeyframes.color = mShadowColor
+ mPaintGraph.color = mShadowColor
+ motionController.buildPath(mPoints, frames)
+ if (drawPath) {
+ drawBasicPath(canvas)
+ }
+ if (drawTicks) {
+ drawTicks(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight)
+ }
+ mPaint.color = mRedColor
+ mPaintKeyframes.color = mKeyframeColor
+ mFillPaint.color = mKeyframeColor
+ mPaintGraph.color = mGraphColor
+ canvas.translate(-mShadowTranslate.toFloat(), -mShadowTranslate.toFloat())
+ if (drawPath) {
+ drawBasicPath(canvas)
+ }
+ if (drawTicks) {
+ drawTicks(canvas, mode, mKeyFrameCount, motionController, layoutWidth, layoutHeight)
+ }
+ }
+
+ private fun drawBasicPath(canvas: Canvas) {
+ canvas.drawLines(mPoints!!, mPaint)
+ }
+
+ private fun drawTicks(
+ canvas: Canvas,
+ mode: Int,
+ keyFrames: Int,
+ motionController: Motion,
+ layoutWidth: Int,
+ layoutHeight: Int
+ ) {
+ var viewWidth = 0
+ var viewHeight = 0
+ if (motionController.view != null) {
+ viewWidth = motionController.view.width
+ viewHeight = motionController.view.height
+ }
+ for (i in 1 until keyFrames - 1) {
+ if (
+ mode == Motion.DRAW_PATH_AS_CONFIGURED && mPathMode[i - 1] == Motion.DRAW_PATH_NONE
+ ) {
+ continue
+ }
+ val x = mKeyFramePoints[i * 2]
+ val y = mKeyFramePoints[i * 2 + 1]
+ mPath!!.reset()
+ mPath!!.moveTo(x, y + mDiamondSize)
+ mPath!!.lineTo(x + mDiamondSize, y)
+ mPath!!.lineTo(x, y - mDiamondSize)
+ mPath!!.lineTo(x - mDiamondSize, y)
+ mPath!!.close()
+ val dx = 0f // framePoint.translationX
+ val dy = 0f // framePoint.translationY
+ if (mode == Motion.DRAW_PATH_AS_CONFIGURED) {
+ if (mPathMode[i - 1] == MotionPaths.PERPENDICULAR) {
+ drawPathRelativeTicks(canvas, x - dx, y - dy)
+ } else if (mPathMode[i - 1] == MotionPaths.CARTESIAN) {
+ drawPathCartesianTicks(canvas, x - dx, y - dy)
+ } else if (mPathMode[i - 1] == MotionPaths.SCREEN) {
+ drawPathScreenTicks(
+ canvas, x - dx, y - dy,
+ viewWidth, viewHeight, layoutWidth, layoutHeight
+ )
+ }
+ canvas.drawPath(mPath!!, mFillPaint)
+ }
+ if (mode == Motion.DRAW_PATH_RELATIVE) {
+ drawPathRelativeTicks(canvas, x - dx, y - dy)
+ }
+ if (mode == Motion.DRAW_PATH_CARTESIAN) {
+ drawPathCartesianTicks(canvas, x - dx, y - dy)
+ }
+ if (mode == Motion.DRAW_PATH_SCREEN) {
+ drawPathScreenTicks(
+ canvas, x - dx, y - dy,
+ viewWidth, viewHeight, layoutWidth, layoutHeight
+ )
+ }
+ if (dx != 0f || dy != 0f) {
+ drawTranslation(canvas, x - dx, y - dy, x, y)
+ } else {
+ canvas.drawPath(mPath!!, mFillPaint)
+ }
+ }
+ if (mPoints!!.size > 1) {
+ // Draw the starting and ending circle
+ canvas.drawCircle(mPoints!![0], mPoints!![1], 8f, mPaintKeyframes)
+ canvas.drawCircle(
+ mPoints!![mPoints!!.size - 2],
+ mPoints!![mPoints!!.size - 1], 8f, mPaintKeyframes
+ )
+ }
+ }
+
+ private fun drawTranslation(canvas: Canvas, x1: Float, y1: Float, x2: Float, y2: Float) {
+ canvas.drawRect(x1, y1, x2, y2, mPaintGraph)
+ canvas.drawLine(x1, y1, x2, y2, mPaintGraph)
+ }
+
+ private fun drawPathRelative(canvas: Canvas) {
+ canvas.drawLine(
+ mPoints!![0], mPoints!![1],
+ mPoints!![mPoints!!.size - 2], mPoints!![mPoints!!.size - 1], mPaintGraph
+ )
+ }
+
+ private fun drawPathAsConfigured(canvas: Canvas) {
+ var path = false
+ var cart = false
+ for (i in 0 until mKeyFrameCount) {
+ if (mPathMode[i] == MotionPaths.PERPENDICULAR) {
+ path = true
+ }
+ if (mPathMode[i] == MotionPaths.CARTESIAN) {
+ cart = true
+ }
+ }
+ if (path) {
+ drawPathRelative(canvas)
+ }
+ if (cart) {
+ drawPathCartesian(canvas)
+ }
+ }
+
+ private fun drawPathRelativeTicks(canvas: Canvas, x: Float, y: Float) {
+ val x1 = mPoints!![0]
+ val y1 = mPoints!![1]
+ val x2 = mPoints!![mPoints!!.size - 2]
+ val y2 = mPoints!![mPoints!!.size - 1]
+ val dist = Math.hypot((x1 - x2).toDouble(), (y1 - y2).toDouble()).toFloat()
+ val t = ((x - x1) * (x2 - x1) + (y - y1) * (y2 - y1)) / (dist * dist)
+ val xp = x1 + t * (x2 - x1)
+ val yp = y1 + t * (y2 - y1)
+ val path = Path()
+ path.moveTo(x, y)
+ path.lineTo(xp, yp)
+ val len = Math.hypot((xp - x).toDouble(), (yp - y).toDouble()).toFloat()
+ val text = "" + (100 * len / dist).toInt() / 100.0f
+ getTextBounds(text, mTextPaint)
+ val off = len / 2 - mBounds.width() / 2
+ canvas.drawTextOnPath(text, path, off, -20f, mTextPaint)
+ canvas.drawLine(x, y, xp, yp, mPaintGraph)
+ }
+
+ fun getTextBounds(text: String, paint: Paint) {
+ paint.getTextBounds(text, 0, text.length, mBounds)
+ }
+
+ private fun drawPathCartesian(canvas: Canvas) {
+ val x1 = mPoints!![0]
+ val y1 = mPoints!![1]
+ val x2 = mPoints!![mPoints!!.size - 2]
+ val y2 = mPoints!![mPoints!!.size - 1]
+ canvas.drawLine(
+ Math.min(x1, x2), Math.max(y1, y2),
+ Math.max(x1, x2), Math.max(y1, y2), mPaintGraph
+ )
+ canvas.drawLine(
+ Math.min(x1, x2), Math.min(y1, y2),
+ Math.min(x1, x2), Math.max(y1, y2), mPaintGraph
+ )
+ }
+
+ private fun drawPathCartesianTicks(canvas: Canvas, x: Float, y: Float) {
+ val x1 = mPoints!![0]
+ val y1 = mPoints!![1]
+ val x2 = mPoints!![mPoints!!.size - 2]
+ val y2 = mPoints!![mPoints!!.size - 1]
+ val minx = Math.min(x1, x2)
+ val maxy = Math.max(y1, y2)
+ val xgap = x - Math.min(x1, x2)
+ val ygap = Math.max(y1, y2) - y
+ // Horizontal line
+ var text = "" + (0.5 + 100 * xgap / Math.abs(x2 - x1)).toInt() / 100.0f
+ getTextBounds(text, mTextPaint)
+ var off = xgap / 2 - mBounds.width() / 2
+ canvas.drawText(text, off + minx, y - 20, mTextPaint)
+ canvas.drawLine(
+ x, y,
+ Math.min(x1, x2), y, mPaintGraph
+ )
+
+ // Vertical line
+ text = "" + (0.5 + 100 * ygap / Math.abs(y2 - y1)).toInt() / 100.0f
+ getTextBounds(text, mTextPaint)
+ off = ygap / 2 - mBounds.height() / 2
+ canvas.drawText(text, x + 5, maxy - off, mTextPaint)
+ canvas.drawLine(
+ x, y,
+ x, Math.max(y1, y2), mPaintGraph
+ )
+ }
+
+ private fun drawPathScreenTicks(
+ canvas: Canvas,
+ x: Float,
+ y: Float,
+ viewWidth: Int,
+ viewHeight: Int,
+ layoutWidth: Int,
+ layoutHeight: Int
+ ) {
+ val x1 = 0f
+ val y1 = 0f
+ val x2 = 1f
+ val y2 = 1f
+ val minx = 0f
+ val maxy = 0f
+ // Horizontal line
+ var text = "" + (0.5 + 100 * (x - viewWidth / 2) /
+ (layoutWidth - viewWidth)).toInt() / 100.0f
+ getTextBounds(text, mTextPaint)
+ var off = x / 2 - mBounds.width() / 2
+ canvas.drawText(text, off + minx, y - 20, mTextPaint)
+ canvas.drawLine(
+ x, y,
+ Math.min(x1, x2), y, mPaintGraph
+ )
+
+ // Vertical line
+ text = "" + (0.5 + 100 * (y - viewHeight / 2) /
+ (layoutHeight - viewHeight)).toInt() / 100.0f
+ getTextBounds(text, mTextPaint)
+ off = y / 2 - mBounds.height() / 2
+ canvas.drawText(text, x + 5, maxy - off, mTextPaint)
+ canvas.drawLine(
+ x, y,
+ x, Math.max(y1, y2), mPaintGraph
+ )
+ }
+
+ private fun drawRectangle(canvas: Canvas, motionController: Motion) {
+ mPath!!.reset()
+ val rectFrames = 50
+ for (i in 0..rectFrames) {
+ val p = i / rectFrames.toFloat()
+ motionController.buildRect(p, mRectangle, 0)
+ mPath!!.moveTo(mRectangle[0], mRectangle[1])
+ mPath!!.lineTo(mRectangle[2], mRectangle[3])
+ mPath!!.lineTo(mRectangle[4], mRectangle[5])
+ mPath!!.lineTo(mRectangle[6], mRectangle[7])
+ mPath!!.close()
+ }
+ mPaint.color = 0x44000000
+ canvas.translate(2f, 2f)
+ canvas.drawPath(mPath!!, mPaint)
+ canvas.translate(-2f, -2f)
+ mPaint.color = -0x10000
+ canvas.drawPath(mPath!!, mPaint)
+ }
+
+ companion object {
+ const val DEBUG_SHOW_NONE = 0
+ const val DEBUG_SHOW_PROGRESS = 1
+ const val DEBUG_SHOW_PATH = 2
+ const val MAX_KEY_FRAMES = 50
+ private const val DEBUG_PATH_TICKS_PER_MS = 16
+ }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
index 3c7ee4d..a0bb06f 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/carousel/CarouselSwipeable.kt
@@ -189,7 +189,7 @@
internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
- internal var velocityThreshold by mutableStateOf(0f)
+ internal var velocityThreshold by mutableFloatStateOf(0f)
internal var resistance: ResistanceConfig? by mutableStateOf(null)
diff --git a/constraintlayout/constraintlayout-core/build.gradle b/constraintlayout/constraintlayout-core/build.gradle
index ce816fb..a466adb 100644
--- a/constraintlayout/constraintlayout-core/build.gradle
+++ b/constraintlayout/constraintlayout-core/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "Android ConstraintLayout Core Library"
+ name = "ConstraintLayout Core"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CONSTRAINTLAYOUT_CORE
inceptionYear = "2022"
diff --git a/constraintlayout/constraintlayout/build.gradle b/constraintlayout/constraintlayout/build.gradle
index 060d756..52a3d6e 100644
--- a/constraintlayout/constraintlayout/build.gradle
+++ b/constraintlayout/constraintlayout/build.gradle
@@ -54,7 +54,7 @@
}
androidx {
- name = "Android ConstraintLayout Library"
+ name = "ConstraintLayout"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CONSTRAINTLAYOUT
inceptionYear = "2022"
diff --git a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyFrames.java b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyFrames.java
index f7c980f..517236c 100644
--- a/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyFrames.java
+++ b/constraintlayout/constraintlayout/src/main/java/androidx/constraintlayout/motion/widget/KeyFrames.java
@@ -91,19 +91,30 @@
tagName = parser.getName();
if (sKeyMakers.containsKey(tagName)) {
- try {
- Constructor<? extends Key> keyMaker = sKeyMakers.get(tagName);
- if (keyMaker != null) {
- key = keyMaker.newInstance();
- key.load(context, Xml.asAttributeSet(parser));
- addKey(key);
- } else {
+
+ switch (tagName) {
+ case KeyAttributes.NAME:
+ key = new KeyAttributes();
+ break;
+ case KeyPosition.NAME:
+ key = new KeyPosition();
+ break;
+ case KeyCycle.NAME:
+ key = new KeyCycle();
+ break;
+ case KeyTimeCycle.NAME:
+ key = new KeyTimeCycle();
+ break;
+ case KeyTrigger.NAME:
+ key = new KeyTrigger();
+ break;
+ default:
throw new NullPointerException(
- "Keymaker for " + tagName + " not found");
- }
- } catch (Exception e) {
- Log.e(TAG, "unable to create ", e);
+ "Key " + tagName + " not found");
}
+ key.load(context, Xml.asAttributeSet(parser));
+ addKey(key);
+
} else if (tagName.equalsIgnoreCase(CUSTOM_ATTRIBUTE)) {
if (key != null && key.mCustomConstraints != null) {
ConstraintAttribute.parse(context, parser, key.mCustomConstraints);
diff --git a/contentpager/contentpager/build.gradle b/contentpager/contentpager/build.gradle
index d2624f7..81252bf 100644
--- a/contentpager/contentpager/build.gradle
+++ b/contentpager/contentpager/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "Android Support Content"
+ name = "Content"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Library providing support for paging across content exposed via a ContentProvider. Use of this library allows a client to avoid expensive interprocess \"cursor window swaps\" on the UI thread."
diff --git a/contentpager/contentpager/src/main/AndroidManifest.xml b/contentpager/contentpager/src/main/AndroidManifest.xml
deleted file mode 100644
index 95c4426..0000000
--- a/contentpager/contentpager/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 />
diff --git a/coordinatorlayout/coordinatorlayout/build.gradle b/coordinatorlayout/coordinatorlayout/build.gradle
index bc110f8..9578993 100644
--- a/coordinatorlayout/coordinatorlayout/build.gradle
+++ b/coordinatorlayout/coordinatorlayout/build.gradle
@@ -48,7 +48,7 @@
}
androidx {
- name = "Android Support Library Coordinator Layout"
+ name = "Coordinator Layout"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2011"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/coordinatorlayout/coordinatorlayout/src/main/AndroidManifest.xml b/coordinatorlayout/coordinatorlayout/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/coordinatorlayout/coordinatorlayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/core/core-animation-integration-tests/testapp/src/main/AndroidManifest.xml b/core/core-animation-integration-tests/testapp/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/core/core-animation-integration-tests/testapp/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/core/core-animation-testing/build.gradle b/core/core-animation-testing/build.gradle
index 046bc43..78bb2e4 100644
--- a/core/core-animation-testing/build.gradle
+++ b/core/core-animation-testing/build.gradle
@@ -29,7 +29,7 @@
}
androidx {
- name = "Android Support Animator Testing"
+ name = "Animation Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CORE_ANIMATION_TESTING
inceptionYear = "2018"
diff --git a/core/core-animation-testing/src/main/AndroidManifest.xml b/core/core-animation-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/core/core-animation-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/core/core-animation/build.gradle b/core/core-animation/build.gradle
index fb7cc95..940504b 100644
--- a/core/core-animation/build.gradle
+++ b/core/core-animation/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Support Animation"
+ name = "Animation"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CORE_ANIMATION
inceptionYear = "2018"
diff --git a/core/core-animation/src/main/AndroidManifest.xml b/core/core-animation/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/core/core-animation/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/core/core-appdigest/build.gradle b/core/core-appdigest/build.gradle
index a0d4af2..7dadc10 100644
--- a/core/core-appdigest/build.gradle
+++ b/core/core-appdigest/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "AndroidX AppDigest Library"
+ name = "AppDigest"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CORE_APPDIGEST
inceptionYear = "2020"
diff --git a/core/core-appdigest/src/main/AndroidManifest.xml b/core/core-appdigest/src/main/AndroidManifest.xml
deleted file mode 100644
index 3031a00..0000000
--- a/core/core-appdigest/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/core/core-google-shortcuts/build.gradle b/core/core-google-shortcuts/build.gradle
index 3071a80..615be8f 100644
--- a/core/core-google-shortcuts/build.gradle
+++ b/core/core-google-shortcuts/build.gradle
@@ -54,7 +54,7 @@
}
androidx {
- name = "Google Shortcuts Integration Library"
+ name = "Google Shortcuts Integration"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CORE_GOOGLE_SHORTCUTS
inceptionYear = "2021"
diff --git a/core/core-graphics-integration-tests/testapp/build.gradle b/core/core-graphics-integration-tests/testapp/build.gradle
index 59d5bb3..768d7b4 100644
--- a/core/core-graphics-integration-tests/testapp/build.gradle
+++ b/core/core-graphics-integration-tests/testapp/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "AndroidX bitmap scaling Sample"
+ name = "bitmap scaling Sample"
inceptionYear = "2021"
description = "Sample for the AndoridX graphics bitmap compatibility"
}
diff --git a/core/core-i18n/src/androidTest/java/androidx/core/i18n/CheckDeviceSettingsTest.kt b/core/core-i18n/src/androidTest/java/androidx/core/i18n/CheckDeviceSettingsTest.kt
index 877b8ca..a65431d 100644
--- a/core/core-i18n/src/androidTest/java/androidx/core/i18n/CheckDeviceSettingsTest.kt
+++ b/core/core-i18n/src/androidTest/java/androidx/core/i18n/CheckDeviceSettingsTest.kt
@@ -22,10 +22,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import java.util.Locale
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Locale
@RunWith(AndroidJUnit4::class)
class CheckDeviceSettingsTest {
diff --git a/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatJdkStylesTest.kt b/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatJdkStylesTest.kt
index 4f0a3ea..dae2fa6 100644
--- a/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatJdkStylesTest.kt
+++ b/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatJdkStylesTest.kt
@@ -19,13 +19,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
import java.text.DateFormat
import java.util.Calendar
import java.util.GregorianCalendar
import java.util.Locale
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
/**
* Instrumented test, which will execute on an Android device.
diff --git a/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatterTest.kt b/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatterTest.kt
index 9534b9f..94ff57d 100644
--- a/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatterTest.kt
+++ b/core/core-i18n/src/androidTest/java/androidx/core/i18n/DateTimeFormatterTest.kt
@@ -19,25 +19,25 @@
import android.annotation.SuppressLint
import android.os.Build
import android.util.Log
+import androidx.core.i18n.DateTimeFormatterSkeletonOptions as SkeletonOptions
import androidx.core.os.BuildCompat
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.BeforeClass
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.Calendar
import java.util.Date
import java.util.GregorianCalendar
import java.util.Locale
import java.util.TimeZone
import kotlin.test.assertFailsWith
-import androidx.core.i18n.DateTimeFormatterSkeletonOptions as SkeletonOptions
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
+import org.junit.runner.RunWith
/** Must execute on an Android device. */
@RunWith(AndroidJUnit4::class)
diff --git a/core/core-i18n/src/main/java/androidx/core/i18n/DateTimeFormatterCommonOptions.kt b/core/core-i18n/src/main/java/androidx/core/i18n/DateTimeFormatterCommonOptions.kt
index 4681fba..e5981a7 100644
--- a/core/core-i18n/src/main/java/androidx/core/i18n/DateTimeFormatterCommonOptions.kt
+++ b/core/core-i18n/src/main/java/androidx/core/i18n/DateTimeFormatterCommonOptions.kt
@@ -17,11 +17,11 @@
package androidx.core.i18n
import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Day
-import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Month
-import androidx.core.i18n.DateTimeFormatterSkeletonOptions.WeekDay
import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Hour
import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Minute
+import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Month
import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Second
+import androidx.core.i18n.DateTimeFormatterSkeletonOptions.WeekDay
import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Year
/** Used to support common styles, similar to the ones defined in Closure / Material.
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/content/ContentValuesTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/content/ContentValuesTest.kt
index a02e0f7..36c9173 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/content/ContentValuesTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/content/ContentValuesTest.kt
@@ -18,11 +18,11 @@
import androidx.test.filters.SmallTest
import androidx.testutils.assertThrows
+import java.util.concurrent.atomic.AtomicInteger
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
-import java.util.concurrent.atomic.AtomicInteger
@SmallTest
class ContentValuesTest {
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/content/ContextTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
index d733203..46c852a 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/content/ContextTest.kt
@@ -17,8 +17,8 @@
package androidx.core.content
import android.content.ContextWrapper
-import androidx.core.ktx.test.R
import androidx.core.getAttributeSet
+import androidx.core.ktx.test.R
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/content/res/TypedArrayTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/content/res/TypedArrayTest.kt
index fee7dd4..2c9a791 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/content/res/TypedArrayTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/content/res/TypedArrayTest.kt
@@ -18,9 +18,9 @@
import android.graphics.Color
import androidx.core.getAttributeSet
+import androidx.core.ktx.test.R
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SdkSuppress
-import androidx.core.ktx.test.R
import androidx.test.filters.SmallTest
import androidx.testutils.assertThrows
import org.junit.Assert.assertEquals
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/graphics/ImageDecoderTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/graphics/ImageDecoderTest.kt
index 34bdeec..5e0afa0 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/graphics/ImageDecoderTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/graphics/ImageDecoderTest.kt
@@ -20,11 +20,11 @@
import android.graphics.ImageDecoder
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import java.io.ByteArrayOutputStream
+import java.nio.ByteBuffer
import org.junit.Assert.assertEquals
import org.junit.BeforeClass
import org.junit.Test
-import java.io.ByteArrayOutputStream
-import java.nio.ByteBuffer
@SdkSuppress(minSdkVersion = 28)
@SmallTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/graphics/drawable/IconTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/graphics/drawable/IconTest.kt
index d124360..8392569 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/graphics/drawable/IconTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/graphics/drawable/IconTest.kt
@@ -26,9 +26,9 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import java.io.File
import org.junit.Assert.assertEquals
import org.junit.Test
-import java.io.File
@SdkSuppress(minSdkVersion = 26)
@SmallTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
index 600318f..129cd08 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/net/UriTest.kt
@@ -19,9 +19,9 @@
import android.net.Uri
import androidx.test.filters.SmallTest
import androidx.testutils.assertThrows
+import java.io.File
import org.junit.Assert.assertEquals
import org.junit.Test
-import java.io.File
@SmallTest
class UriTest {
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/os/BundleTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/os/BundleTest.kt
index c312bda..a1af056 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/os/BundleTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/os/BundleTest.kt
@@ -29,12 +29,12 @@
import androidx.test.filters.SmallTest
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicInteger
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertSame
import org.junit.Test
-import java.util.concurrent.atomic.AtomicInteger
@SmallTest
class BundleTest {
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/os/HandlerTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/os/HandlerTest.kt
index e8cc7e2..f167abd 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/os/HandlerTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/os/HandlerTest.kt
@@ -25,16 +25,16 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeUnit.MILLISECONDS
+import java.util.concurrent.TimeUnit.SECONDS
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.TimeUnit.MILLISECONDS
-import java.util.concurrent.TimeUnit.SECONDS
@SmallTest
@SdkSuppress(minSdkVersion = 26)
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/text/LocaleTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/text/LocaleTest.kt
index 1a2f5ed..73cd538 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/text/LocaleTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/text/LocaleTest.kt
@@ -19,9 +19,9 @@
import android.view.View
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import java.util.Locale
import org.junit.Assert.assertEquals
import org.junit.Test
-import java.util.Locale
@SdkSuppress(minSdkVersion = 21)
@SmallTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/transition/TransitionTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/transition/TransitionTest.kt
index e2ec8f0..4abd56a 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/transition/TransitionTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/transition/TransitionTest.kt
@@ -27,13 +27,13 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicBoolean
@SdkSuppress(minSdkVersion = 19)
@MediumTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/util/AtomicFileTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/util/AtomicFileTest.kt
index e2586fd..9101f82 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/util/AtomicFileTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/util/AtomicFileTest.kt
@@ -20,13 +20,13 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.testutils.assertThrows
+import java.io.IOException
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.IOException
@SdkSuppress(minSdkVersion = 17)
@SmallTest
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/util/PairTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/util/PairTest.kt
index 4be680d..dbc1686 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/util/PairTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/util/PairTest.kt
@@ -16,12 +16,12 @@
package androidx.core.util
+import android.util.Pair as AndroidPair
import androidx.test.filters.SmallTest
+import kotlin.Pair as KotlinPair
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
import org.junit.Test
-import android.util.Pair as AndroidPair
-import kotlin.Pair as KotlinPair
@SmallTest
class PairTest {
diff --git a/core/core-ktx/src/androidTest/java/androidx/core/widget/TextViewTest.kt b/core/core-ktx/src/androidTest/java/androidx/core/widget/TextViewTest.kt
index f20dbb4..b172a5d 100644
--- a/core/core-ktx/src/androidTest/java/androidx/core/widget/TextViewTest.kt
+++ b/core/core-ktx/src/androidTest/java/androidx/core/widget/TextViewTest.kt
@@ -21,11 +21,11 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.concurrent.atomic.AtomicBoolean
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.atomic.AtomicBoolean
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/core/core-ktx/src/main/AndroidManifest.xml b/core/core-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index cc947c5..0000000
--- a/core/core-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-<manifest />
diff --git a/core/core-location-altitude/build.gradle b/core/core-location-altitude/build.gradle
index 6f5e108..ccee9b7 100644
--- a/core/core-location-altitude/build.gradle
+++ b/core/core-location-altitude/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "Location Altitude Compatibility Library"
+ name = "Location Altitude"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CORE_LOCATION_ALTITUDE
inceptionYear = "2022"
diff --git a/core/core-remoteviews/build.gradle b/core/core-remoteviews/build.gradle
index eb33cc1..78adb5b 100644
--- a/core/core-remoteviews/build.gradle
+++ b/core/core-remoteviews/build.gradle
@@ -58,7 +58,7 @@
}
androidx {
- name = "AndroidX RemoteViews Support"
+ name = "RemoteViews"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CORE_REMOTEVIEWS
inceptionYear = "2021"
diff --git a/core/core-remoteviews/src/androidTest/java/androidx/core/widget/AppWidgetManagerDeviceTest.kt b/core/core-remoteviews/src/androidTest/java/androidx/core/widget/AppWidgetManagerDeviceTest.kt
index eaba22c..053b013 100644
--- a/core/core-remoteviews/src/androidTest/java/androidx/core/widget/AppWidgetManagerDeviceTest.kt
+++ b/core/core-remoteviews/src/androidTest/java/androidx/core/widget/AppWidgetManagerDeviceTest.kt
@@ -43,13 +43,13 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.test.fail
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.test.fail
@SdkSuppress(minSdkVersion = 29)
@MediumTest
diff --git a/core/core-remoteviews/src/androidTest/java/androidx/core/widget/RemoteViewsCompatTest.kt b/core/core-remoteviews/src/androidTest/java/androidx/core/widget/RemoteViewsCompatTest.kt
index 9282469..c5f9f09 100644
--- a/core/core-remoteviews/src/androidTest/java/androidx/core/widget/RemoteViewsCompatTest.kt
+++ b/core/core-remoteviews/src/androidTest/java/androidx/core/widget/RemoteViewsCompatTest.kt
@@ -42,15 +42,15 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertFailsWith
+import kotlin.test.fail
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.test.assertFailsWith
-import kotlin.test.fail
@SdkSuppress(minSdkVersion = 29)
@MediumTest
diff --git a/core/core-remoteviews/src/test/java/androidx/core/widget/AppWidgetManagerCompatTest.kt b/core/core-remoteviews/src/test/java/androidx/core/widget/AppWidgetManagerCompatTest.kt
index 9b160b0..dd00746 100644
--- a/core/core-remoteviews/src/test/java/androidx/core/widget/AppWidgetManagerCompatTest.kt
+++ b/core/core-remoteviews/src/test/java/androidx/core/widget/AppWidgetManagerCompatTest.kt
@@ -37,6 +37,7 @@
import androidx.core.util.component2
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@@ -44,7 +45,6 @@
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
import org.robolectric.util.ReflectionHelpers
-import kotlin.test.assertFailsWith
@RunWith(RobolectricTestRunner::class)
@DoNotInstrument
diff --git a/core/core-remoteviews/src/test/java/androidx/core/widget/RemoteViewsTest.kt b/core/core-remoteviews/src/test/java/androidx/core/widget/RemoteViewsTest.kt
index 181b000..0a38a01 100644
--- a/core/core-remoteviews/src/test/java/androidx/core/widget/RemoteViewsTest.kt
+++ b/core/core-remoteviews/src/test/java/androidx/core/widget/RemoteViewsTest.kt
@@ -28,7 +28,6 @@
import android.widget.RemoteViews
import android.widget.TextView
import androidx.annotation.RequiresApi
-import androidx.test.core.app.ApplicationProvider
import androidx.core.remoteviews.test.R
import androidx.core.widget.RemoteViewsCompat.setLinearLayoutWeightSum
import androidx.core.widget.RemoteViewsCompat.setTextViewError
@@ -36,16 +35,17 @@
import androidx.core.widget.RemoteViewsCompat.setTextViewMaxLines
import androidx.core.widget.RemoteViewsCompat.setViewBackgroundColorResource
import androidx.core.widget.RemoteViewsCompat.setViewEnabled
+import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import java.util.Locale
+import kotlin.test.assertIs
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
-import java.util.Locale
-import kotlin.test.assertIs
@RunWith(RobolectricTestRunner::class)
@DoNotInstrument
diff --git a/core/core-role/build.gradle b/core/core-role/build.gradle
index e2f2c0a..f820a13 100644
--- a/core/core-role/build.gradle
+++ b/core/core-role/build.gradle
@@ -14,7 +14,7 @@
}
androidx {
- name = "Android Support Library Role"
+ name = "Role"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CORE_ROLE
inceptionYear = "2019"
diff --git a/core/core-role/src/main/AndroidManifest.xml b/core/core-role/src/main/AndroidManifest.xml
deleted file mode 100644
index 5e016ed..0000000
--- a/core/core-role/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/core/core-splashscreen/samples/build.gradle b/core/core-splashscreen/samples/build.gradle
index 3c59a31..ae1d810 100644
--- a/core/core-splashscreen/samples/build.gradle
+++ b/core/core-splashscreen/samples/build.gradle
@@ -42,7 +42,7 @@
}
androidx {
- name = "AndroidX Splashscreen Samples"
+ name = "Splashscreen Samples"
type = LibraryType.SAMPLES
mavenVersion = LibraryVersions.CORE_SPLASHSCREEN
inceptionYear = "2021"
diff --git a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestController.kt b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestController.kt
index 27d75f7..4c96776 100644
--- a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestController.kt
+++ b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestController.kt
@@ -23,12 +23,12 @@
import android.util.TypedValue
import android.view.View
import androidx.appcompat.app.AppCompatActivity
+import androidx.core.splashscreen.R as SR
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.splashscreen.SplashScreenViewProvider
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicBoolean
-import androidx.core.splashscreen.R as SR
-import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
/**
* If true, sets an [androidx.core.splashscreen.SplashScreen.OnExitAnimationListener] on the
diff --git a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestUtils.kt b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestUtils.kt
index ab7c012..490eea2 100644
--- a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestUtils.kt
+++ b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashScreenTestUtils.kt
@@ -26,10 +26,10 @@
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
-import org.hamcrest.core.IsNull
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Assert
import kotlin.reflect.KClass
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.core.IsNull
+import org.junit.Assert
private const val SPLASH_SCREEN_STYLE_ICON = 1
private const val KEY_SPLASH_SCREEN_STYLE: String = "android.activity.splashScreenStyle"
diff --git a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashscreenParametrizedTest.kt b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashscreenParametrizedTest.kt
index e84532f..b5df1b0 100644
--- a/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashscreenParametrizedTest.kt
+++ b/core/core-splashscreen/src/androidTest/java/androidx/core/splashscreen/test/SplashscreenParametrizedTest.kt
@@ -28,6 +28,12 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.screenshot.matchers.MSSIMMatcher
import androidx.test.uiautomator.UiDevice
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.reflect.KClass
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
@@ -38,12 +44,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.io.File
-import java.io.FileOutputStream
-import java.io.IOException
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.reflect.KClass
@LargeTest
@RunWith(Parameterized::class)
diff --git a/core/core-testing/build.gradle b/core/core-testing/build.gradle
index fdc6f76..1708420 100644
--- a/core/core-testing/build.gradle
+++ b/core/core-testing/build.gradle
@@ -41,9 +41,9 @@
}
androidx {
- name = "androidx.core:core-testing"
+ name = "Core Testing"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CORE
inceptionYear = "2023"
- description = "Write tests using core APIs."
+ description = "Provides extensions for tests using Core APIs."
}
diff --git a/core/core/api/current.txt b/core/core/api/current.txt
index 7ce3b2f..1e6c816 100644
--- a/core/core/api/current.txt
+++ b/core/core/api/current.txt
@@ -1078,6 +1078,7 @@
method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
method public static java.io.File? getDataDir(android.content.Context);
+ method public static android.view.Display getDisplayOrDefault(@DisplayContext android.content.Context);
method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
method public static java.io.File![] getExternalCacheDirs(android.content.Context);
method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
@@ -2399,6 +2400,31 @@
field public static final int START = 8388611; // 0x800003
}
+ public final class HapticFeedbackConstantsCompat {
+ field public static final int CLOCK_TICK = 4; // 0x4
+ field public static final int CONFIRM = 16; // 0x10
+ field public static final int CONTEXT_CLICK = 6; // 0x6
+ field public static final int DRAG_START = 25; // 0x19
+ field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
+ field public static final int GESTURE_END = 13; // 0xd
+ field public static final int GESTURE_START = 12; // 0xc
+ field public static final int GESTURE_THRESHOLD_ACTIVATE = 23; // 0x17
+ field public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; // 0x18
+ field public static final int KEYBOARD_PRESS = 3; // 0x3
+ field public static final int KEYBOARD_RELEASE = 7; // 0x7
+ field public static final int KEYBOARD_TAP = 3; // 0x3
+ field public static final int LONG_PRESS = 0; // 0x0
+ field public static final int NO_HAPTICS = -1; // 0xffffffff
+ field public static final int REJECT = 17; // 0x11
+ field public static final int SEGMENT_FREQUENT_TICK = 27; // 0x1b
+ field public static final int SEGMENT_TICK = 26; // 0x1a
+ field public static final int TEXT_HANDLE_MOVE = 9; // 0x9
+ field public static final int TOGGLE_OFF = 22; // 0x16
+ field public static final int TOGGLE_ON = 21; // 0x15
+ field public static final int VIRTUAL_KEY = 1; // 0x1
+ field public static final int VIRTUAL_KEY_RELEASE = 8; // 0x8
+ }
+
public final class InputDeviceCompat {
field public static final int SOURCE_ANY = -256; // 0xffffff00
field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
@@ -2846,6 +2872,8 @@
method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+ method public static boolean performHapticFeedback(android.view.View, int);
+ method public static boolean performHapticFeedback(android.view.View, int, int);
method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
method public static void postInvalidateOnAnimation(android.view.View);
method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
diff --git a/core/core/api/public_plus_experimental_current.txt b/core/core/api/public_plus_experimental_current.txt
index 77a0578..2a81007 100644
--- a/core/core/api/public_plus_experimental_current.txt
+++ b/core/core/api/public_plus_experimental_current.txt
@@ -1078,6 +1078,7 @@
method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
method public static java.io.File? getDataDir(android.content.Context);
+ method public static android.view.Display getDisplayOrDefault(@DisplayContext android.content.Context);
method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
method public static java.io.File![] getExternalCacheDirs(android.content.Context);
method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
@@ -2406,6 +2407,31 @@
field public static final int START = 8388611; // 0x800003
}
+ public final class HapticFeedbackConstantsCompat {
+ field public static final int CLOCK_TICK = 4; // 0x4
+ field public static final int CONFIRM = 16; // 0x10
+ field public static final int CONTEXT_CLICK = 6; // 0x6
+ field public static final int DRAG_START = 25; // 0x19
+ field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
+ field public static final int GESTURE_END = 13; // 0xd
+ field public static final int GESTURE_START = 12; // 0xc
+ field public static final int GESTURE_THRESHOLD_ACTIVATE = 23; // 0x17
+ field public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; // 0x18
+ field public static final int KEYBOARD_PRESS = 3; // 0x3
+ field public static final int KEYBOARD_RELEASE = 7; // 0x7
+ field public static final int KEYBOARD_TAP = 3; // 0x3
+ field public static final int LONG_PRESS = 0; // 0x0
+ field public static final int NO_HAPTICS = -1; // 0xffffffff
+ field public static final int REJECT = 17; // 0x11
+ field public static final int SEGMENT_FREQUENT_TICK = 27; // 0x1b
+ field public static final int SEGMENT_TICK = 26; // 0x1a
+ field public static final int TEXT_HANDLE_MOVE = 9; // 0x9
+ field public static final int TOGGLE_OFF = 22; // 0x16
+ field public static final int TOGGLE_ON = 21; // 0x15
+ field public static final int VIRTUAL_KEY = 1; // 0x1
+ field public static final int VIRTUAL_KEY_RELEASE = 8; // 0x8
+ }
+
public final class InputDeviceCompat {
field public static final int SOURCE_ANY = -256; // 0xffffff00
field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
@@ -2853,6 +2879,8 @@
method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+ method public static boolean performHapticFeedback(android.view.View, int);
+ method public static boolean performHapticFeedback(android.view.View, int, int);
method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
method public static void postInvalidateOnAnimation(android.view.View);
method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
diff --git a/core/core/api/restricted_current.txt b/core/core/api/restricted_current.txt
index 9d411f1..c27d0b0 100644
--- a/core/core/api/restricted_current.txt
+++ b/core/core/api/restricted_current.txt
@@ -1195,6 +1195,7 @@
method @ColorInt public static int getColor(android.content.Context, @ColorRes int);
method public static android.content.res.ColorStateList? getColorStateList(android.content.Context, @ColorRes int);
method public static java.io.File? getDataDir(android.content.Context);
+ method public static android.view.Display getDisplayOrDefault(@DisplayContext android.content.Context);
method public static android.graphics.drawable.Drawable? getDrawable(android.content.Context, @DrawableRes int);
method public static java.io.File![] getExternalCacheDirs(android.content.Context);
method public static java.io.File![] getExternalFilesDirs(android.content.Context, String?);
@@ -2833,6 +2834,31 @@
field public static final int START = 8388611; // 0x800003
}
+ public final class HapticFeedbackConstantsCompat {
+ field public static final int CLOCK_TICK = 4; // 0x4
+ field public static final int CONFIRM = 16; // 0x10
+ field public static final int CONTEXT_CLICK = 6; // 0x6
+ field public static final int DRAG_START = 25; // 0x19
+ field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
+ field public static final int GESTURE_END = 13; // 0xd
+ field public static final int GESTURE_START = 12; // 0xc
+ field public static final int GESTURE_THRESHOLD_ACTIVATE = 23; // 0x17
+ field public static final int GESTURE_THRESHOLD_DEACTIVATE = 24; // 0x18
+ field public static final int KEYBOARD_PRESS = 3; // 0x3
+ field public static final int KEYBOARD_RELEASE = 7; // 0x7
+ field public static final int KEYBOARD_TAP = 3; // 0x3
+ field public static final int LONG_PRESS = 0; // 0x0
+ field public static final int NO_HAPTICS = -1; // 0xffffffff
+ field public static final int REJECT = 17; // 0x11
+ field public static final int SEGMENT_FREQUENT_TICK = 27; // 0x1b
+ field public static final int SEGMENT_TICK = 26; // 0x1a
+ field public static final int TEXT_HANDLE_MOVE = 9; // 0x9
+ field public static final int TOGGLE_OFF = 22; // 0x16
+ field public static final int TOGGLE_ON = 21; // 0x15
+ field public static final int VIRTUAL_KEY = 1; // 0x1
+ field public static final int VIRTUAL_KEY_RELEASE = 8; // 0x8
+ }
+
public final class InputDeviceCompat {
field public static final int SOURCE_ANY = -256; // 0xffffff00
field public static final int SOURCE_CLASS_BUTTON = 1; // 0x1
@@ -3290,6 +3316,8 @@
method public static void onInitializeAccessibilityNodeInfo(android.view.View, androidx.core.view.accessibility.AccessibilityNodeInfoCompat);
method @Deprecated public static void onPopulateAccessibilityEvent(android.view.View!, android.view.accessibility.AccessibilityEvent!);
method public static boolean performAccessibilityAction(android.view.View, int, android.os.Bundle?);
+ method public static boolean performHapticFeedback(android.view.View, int);
+ method public static boolean performHapticFeedback(android.view.View, int, int);
method public static androidx.core.view.ContentInfoCompat? performReceiveContent(android.view.View, androidx.core.view.ContentInfoCompat);
method public static void postInvalidateOnAnimation(android.view.View);
method public static void postInvalidateOnAnimation(android.view.View, int, int, int, int);
diff --git a/core/core/build.gradle b/core/core/build.gradle
index fa351a1..832085f 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -90,10 +90,11 @@
}
androidx {
- name = "Android Support Library compat"
+ name = "Core"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CORE
inceptionYear = "2015"
- description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+ description = "Provides backward-compatible implementations of Android platform APIs and " +
+ "features."
failOnDeprecationWarnings = false
}
diff --git a/core/core/src/androidTest/AndroidManifest.xml b/core/core/src/androidTest/AndroidManifest.xml
index 8e9f2ea..2688f36 100644
--- a/core/core/src/androidTest/AndroidManifest.xml
+++ b/core/core/src/androidTest/AndroidManifest.xml
@@ -137,6 +137,10 @@
android:exported="true" />
<activity
+ android:name="androidx.core.view.inputmethod.ImeSecondarySplitViewCompatTestActivity"
+ android:exported="true" />
+
+ <activity
android:name="androidx.core.view.inputmethod.ImeSecondarySplitTestActivity"
android:exported="true" />
diff --git a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
index 7f2a7de..36b0b0a 100644
--- a/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
+++ b/core/core/src/androidTest/java/androidx/core/app/ActivityCompatRecreateFromLifecycleStatesTestCase.kt
@@ -24,12 +24,12 @@
import androidx.test.rule.ActivityTestRule
import androidx.testutils.LifecycleOwnerUtils
import androidx.testutils.PollingCheck
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import junit.framework.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/core/core/src/androidTest/java/androidx/core/app/NotificationTester.kt b/core/core/src/androidTest/java/androidx/core/app/NotificationTester.kt
index e73a557..aab6d1e 100644
--- a/core/core/src/androidTest/java/androidx/core/app/NotificationTester.kt
+++ b/core/core/src/androidTest/java/androidx/core/app/NotificationTester.kt
@@ -18,8 +18,8 @@
import android.app.Notification
import android.os.Build
import android.os.Bundle
-import org.junit.Assert.assertEquals
import java.util.TreeSet
+import org.junit.Assert.assertEquals
internal object NotificationTester {
@JvmStatic
diff --git a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
index 85db291..03b73b5 100644
--- a/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/content/ContextCompatTest.java
@@ -66,6 +66,7 @@
import static android.content.Context.WIFI_P2P_SERVICE;
import static android.content.Context.WIFI_SERVICE;
import static android.content.Context.WINDOW_SERVICE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -137,6 +138,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -146,8 +148,10 @@
import androidx.annotation.OptIn;
import androidx.core.app.NotificationManagerCompat;
+import androidx.core.hardware.display.DisplayManagerCompat;
import androidx.core.os.BuildCompat;
import androidx.core.test.R;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SdkSuppress;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -601,4 +605,58 @@
Manifest.permission.POST_NOTIFICATIONS));
}
}
+
+ @Test
+ public void testGetDisplayFromActivity() {
+ final Display actualDisplay = ContextCompat.getDisplayOrDefault(mContext);
+ if (Build.VERSION.SDK_INT >= 30) {
+ assertEquals(mContext.getDisplay(), actualDisplay);
+ } else {
+ final WindowManager windowManager =
+ (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
+ assertEquals(actualDisplay, windowManager.getDefaultDisplay());
+ }
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 17)
+ public void testGetDisplayFromDisplayContext() {
+ final DisplayManagerCompat displayManagerCompat = DisplayManagerCompat
+ .getInstance(mContext);
+ final Display defaultDisplay = displayManagerCompat.getDisplay(Display.DEFAULT_DISPLAY);
+ final Context displayContext = mContext.createDisplayContext(defaultDisplay);
+
+ assertEquals(ContextCompat.getDisplayOrDefault(displayContext), defaultDisplay);
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 30)
+ public void testGetDisplayFromWindowContext() {
+ final Context windowContext = mContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null);
+
+ assertEquals(ContextCompat.getDisplayOrDefault(windowContext), windowContext.getDisplay());
+ }
+
+ @Test
+ public void testGetDisplayFromApplication() {
+ final Context applicationContext = ApplicationProvider.getApplicationContext();
+ final Context spyContext = spy(applicationContext);
+ final Display actualDisplay = ContextCompat.getDisplayOrDefault(spyContext);
+
+ if (Build.VERSION.SDK_INT >= 30) {
+ verify(spyContext).getSystemService(eq(DisplayManager.class));
+
+ final Display defaultDisplay = DisplayManagerCompat.getInstance(spyContext)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+ assertEquals(defaultDisplay, actualDisplay);
+ } else {
+ final WindowManager windowManager =
+ (WindowManager) spyContext.getSystemService(WINDOW_SERVICE);
+ // Don't verify if the returned display is the same instance because Application is
+ // not a DisplayContext and the framework always create a fallback Display for
+ // the Context that not associated with a Display.
+ assertEquals(windowManager.getDefaultDisplay().getDisplayId(),
+ actualDisplay.getDisplayId());
+ }
+ }
}
diff --git a/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt b/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
index bc98c5f..156affb 100644
--- a/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/content/pm/PackageInfoCompatHasSignaturesTest.kt
@@ -29,6 +29,7 @@
import androidx.testutils.mockito.mockThrowOnUnmocked
import androidx.testutils.mockito.whenever
import com.google.common.truth.Truth.assertThat
+import java.security.MessageDigest
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -38,7 +39,6 @@
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.eq
import org.mockito.internal.util.reflection.FieldSetter
-import java.security.MessageDigest
/**
* Verifies [PackageInfoCompat.hasSignatures].
diff --git a/core/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java b/core/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
index 41b6b15..a27a4e2 100644
--- a/core/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
+++ b/core/core/src/androidTest/java/androidx/core/view/ViewCompatTest.java
@@ -15,6 +15,26 @@
*/
package androidx.core.view;
+import static androidx.core.view.HapticFeedbackConstantsCompat.CLOCK_TICK;
+import static androidx.core.view.HapticFeedbackConstantsCompat.CONFIRM;
+import static androidx.core.view.HapticFeedbackConstantsCompat.CONTEXT_CLICK;
+import static androidx.core.view.HapticFeedbackConstantsCompat.DRAG_START;
+import static androidx.core.view.HapticFeedbackConstantsCompat.GESTURE_END;
+import static androidx.core.view.HapticFeedbackConstantsCompat.GESTURE_START;
+import static androidx.core.view.HapticFeedbackConstantsCompat.GESTURE_THRESHOLD_ACTIVATE;
+import static androidx.core.view.HapticFeedbackConstantsCompat.GESTURE_THRESHOLD_DEACTIVATE;
+import static androidx.core.view.HapticFeedbackConstantsCompat.KEYBOARD_RELEASE;
+import static androidx.core.view.HapticFeedbackConstantsCompat.KEYBOARD_TAP;
+import static androidx.core.view.HapticFeedbackConstantsCompat.LONG_PRESS;
+import static androidx.core.view.HapticFeedbackConstantsCompat.NO_HAPTICS;
+import static androidx.core.view.HapticFeedbackConstantsCompat.REJECT;
+import static androidx.core.view.HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK;
+import static androidx.core.view.HapticFeedbackConstantsCompat.SEGMENT_TICK;
+import static androidx.core.view.HapticFeedbackConstantsCompat.TEXT_HANDLE_MOVE;
+import static androidx.core.view.HapticFeedbackConstantsCompat.TOGGLE_OFF;
+import static androidx.core.view.HapticFeedbackConstantsCompat.TOGGLE_ON;
+import static androidx.core.view.HapticFeedbackConstantsCompat.VIRTUAL_KEY;
+import static androidx.core.view.HapticFeedbackConstantsCompat.VIRTUAL_KEY_RELEASE;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ARGUMENT_PRESS_AND_HOLD_DURATION_MILLIS_INT;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
@@ -33,6 +53,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Activity;
@@ -401,6 +422,168 @@
assertEquals(contentCaptureSession, result.toContentCaptureSession());
}
+ @Test
+ public void testPerformHapticFeedback_skipsHapticFeedbackForNoHapticsConstant() {
+ View spyView = spy(mView);
+ ViewCompat.performHapticFeedback(spyView, NO_HAPTICS);
+ verify(spyView, never()).performHapticFeedback(anyInt(), anyInt());
+ }
+
+ @SdkSuppress(minSdkVersion = 34)
+ @Test
+ public void testPerformHapticFeedback_useSameInputFeedbackConstantOnSdk34() {
+ for (int constant = HapticFeedbackConstantsCompat.FIRST_CONSTANT_INT;
+ constant < HapticFeedbackConstantsCompat.LAST_CONSTANT_INT; constant++) {
+ assertHapticFeedbackPerformed(constant);
+ }
+ }
+
+ @SdkSuppress(minSdkVersion = 30, maxSdkVersion = 33)
+ @Test
+ public void testPerformHapticFeedback_useFallbackForConstantsFromSdk34() {
+ // Maintain constants supported in SDK >= 30
+ assertHapticFeedbackPerformed(CONFIRM);
+ assertHapticFeedbackPerformed(REJECT);
+ assertHapticFeedbackPerformed(GESTURE_START);
+ assertHapticFeedbackPerformed(GESTURE_END);
+
+ // Fallbacks for constants from SDK >= 34
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, DRAG_START);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, TOGGLE_ON);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, SEGMENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, GESTURE_THRESHOLD_ACTIVATE);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, TOGGLE_OFF);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, SEGMENT_FREQUENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_THRESHOLD_DEACTIVATE);
+ }
+
+ @SdkSuppress(minSdkVersion = 27, maxSdkVersion = 29)
+ @Test
+ public void testPerformHapticFeedback_useFallbackForConstantsFromSdk30() {
+ // Maintain constants supported in SDK >= 27
+ assertHapticFeedbackPerformed(TEXT_HANDLE_MOVE);
+ assertHapticFeedbackPerformed(KEYBOARD_RELEASE);
+ assertHapticFeedbackPerformed(VIRTUAL_KEY_RELEASE);
+
+ // Fallbacks for constants from SDK >= 30
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, DRAG_START);
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, REJECT);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, CONFIRM);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, GESTURE_START);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, GESTURE_END);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, TOGGLE_ON);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, SEGMENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, GESTURE_THRESHOLD_ACTIVATE);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, TOGGLE_OFF);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, SEGMENT_FREQUENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_THRESHOLD_DEACTIVATE);
+ }
+
+ @SdkSuppress(minSdkVersion = 23, maxSdkVersion = 26)
+ @Test
+ public void testPerformHapticFeedback_useFallbackForConstantsFromSdk27() {
+ // Maintain constants supported in SDK >= 23
+ assertHapticFeedbackPerformed(CONTEXT_CLICK);
+
+ // Fallbacks for constants from SDK >= 27
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, DRAG_START);
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, REJECT);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, CONFIRM);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, GESTURE_START);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, GESTURE_END);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, TOGGLE_ON);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, SEGMENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CONTEXT_CLICK, GESTURE_THRESHOLD_ACTIVATE);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, TOGGLE_OFF);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, SEGMENT_FREQUENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_THRESHOLD_DEACTIVATE);
+ assertNoHapticFeedbackPerformed(TEXT_HANDLE_MOVE);
+ assertNoHapticFeedbackPerformed(KEYBOARD_RELEASE);
+ assertNoHapticFeedbackPerformed(VIRTUAL_KEY_RELEASE);
+ }
+
+ @SdkSuppress(minSdkVersion = 21, maxSdkVersion = 22)
+ @Test
+ public void testPerformHapticFeedback_useFallbackForConstantsFromSdk23() {
+ // Maintain constants supported in SDK >= 21
+ assertHapticFeedbackPerformed(CLOCK_TICK);
+
+ // Fallbacks for constants from SDK >= 23
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, DRAG_START);
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, REJECT);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, CONFIRM);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, GESTURE_START);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_END);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, TOGGLE_ON);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, SEGMENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_THRESHOLD_ACTIVATE);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, TOGGLE_OFF);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, SEGMENT_FREQUENT_TICK);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, GESTURE_THRESHOLD_DEACTIVATE);
+ assertFallbackHapticFeedbackPerformed(CLOCK_TICK, CONTEXT_CLICK);
+ assertNoHapticFeedbackPerformed(TEXT_HANDLE_MOVE);
+ assertNoHapticFeedbackPerformed(KEYBOARD_RELEASE);
+ assertNoHapticFeedbackPerformed(VIRTUAL_KEY_RELEASE);
+ }
+
+ @SdkSuppress(maxSdkVersion = 20)
+ @Test
+ public void testPerformHapticFeedback_useFallbackForConstantsFromSdk21() {
+ // Maintain constants supported in SDK < 21
+ assertHapticFeedbackPerformed(KEYBOARD_TAP);
+
+ // Fallbacks for constants from SDK >= 21
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, DRAG_START);
+ assertFallbackHapticFeedbackPerformed(LONG_PRESS, REJECT);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, CONFIRM);
+ assertFallbackHapticFeedbackPerformed(VIRTUAL_KEY, GESTURE_START);
+ assertNoHapticFeedbackPerformed(GESTURE_END);
+ assertNoHapticFeedbackPerformed(TOGGLE_ON);
+ assertNoHapticFeedbackPerformed(SEGMENT_TICK);
+ assertNoHapticFeedbackPerformed(GESTURE_THRESHOLD_ACTIVATE);
+ assertNoHapticFeedbackPerformed(TOGGLE_OFF);
+ assertNoHapticFeedbackPerformed(SEGMENT_FREQUENT_TICK);
+ assertNoHapticFeedbackPerformed(GESTURE_THRESHOLD_DEACTIVATE);
+ assertNoHapticFeedbackPerformed(CONTEXT_CLICK);
+ assertNoHapticFeedbackPerformed(CLOCK_TICK);
+ assertNoHapticFeedbackPerformed(TEXT_HANDLE_MOVE);
+ assertNoHapticFeedbackPerformed(KEYBOARD_RELEASE);
+ assertNoHapticFeedbackPerformed(VIRTUAL_KEY_RELEASE);
+ }
+
+ private void assertHapticFeedbackPerformed(int feedbackConstant) {
+ View spyView = spy(mView);
+ int flags = HapticFeedbackConstantsCompat.FLAG_IGNORE_VIEW_SETTING;
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant);
+ verify(spyView).performHapticFeedback(eq(feedbackConstant));
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant, flags);
+ verify(spyView).performHapticFeedback(eq(feedbackConstant), eq(flags));
+ }
+
+ private void assertNoHapticFeedbackPerformed(int feedbackConstant) {
+ View spyView = spy(mView);
+ int flags = HapticFeedbackConstantsCompat.FLAG_IGNORE_VIEW_SETTING;
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant);
+ verify(spyView, never()).performHapticFeedback(anyInt());
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant, flags);
+ verify(spyView, never()).performHapticFeedback(anyInt(), anyInt());
+ }
+
+ private void assertFallbackHapticFeedbackPerformed(int expectedFallback, int feedbackConstant) {
+ View spyView = spy(mView);
+ int flags = HapticFeedbackConstantsCompat.FLAG_IGNORE_VIEW_SETTING;
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant);
+ verify(spyView).performHapticFeedback(eq(expectedFallback));
+
+ ViewCompat.performHapticFeedback(spyView, feedbackConstant, flags);
+ verify(spyView).performHapticFeedback(eq(expectedFallback), eq(flags));
+ }
+
private static boolean isViewIdGenerated(int id) {
return (id & 0xFF000000) == 0 && (id & 0x00FFFFFF) != 0;
}
diff --git a/core/core/src/androidTest/java/androidx/core/view/WindowCompatTest.kt b/core/core/src/androidTest/java/androidx/core/view/WindowCompatTest.kt
index 110a615..eb75b11 100644
--- a/core/core/src/androidTest/java/androidx/core/view/WindowCompatTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/view/WindowCompatTest.kt
@@ -22,12 +22,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsAnimationCompatActivityTest.kt b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsAnimationCompatActivityTest.kt
index 971024c..633908c 100644
--- a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsAnimationCompatActivityTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsAnimationCompatActivityTest.kt
@@ -36,14 +36,14 @@
import androidx.test.filters.SdkSuppress
import androidx.testutils.withActivity
import com.google.common.truth.Truth
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Assume
import org.junit.Before
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@SdkSuppress(minSdkVersion = 21)
@RequiresApi(21)
diff --git a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
index e50c0bf..ffa754f 100644
--- a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsCompatActivityTest.kt
@@ -40,6 +40,9 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.testutils.withActivity
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicReference
import org.hamcrest.Matchers.`is`
import org.junit.After
import org.junit.Assert.assertEquals
@@ -52,9 +55,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicReference
@Suppress("DEPRECATION") // Testing deprecated methods
@SdkSuppress(minSdkVersion = 16)
diff --git a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsControllerCompatActivityTest.kt b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsControllerCompatActivityTest.kt
index 6a40e06..42f97ba 100644
--- a/core/core/src/androidTest/java/androidx/core/view/WindowInsetsControllerCompatActivityTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/view/WindowInsetsControllerCompatActivityTest.kt
@@ -36,8 +36,12 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.testutils.withActivity
-import org.hamcrest.Matchers.`is`
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicReference
+import kotlin.concurrent.thread
import org.hamcrest.Matchers.equalTo
+import org.hamcrest.Matchers.`is`
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
@@ -46,10 +50,6 @@
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicReference
-import kotlin.concurrent.thread
@Suppress("DEPRECATION")
@SdkSuppress(minSdkVersion = 23)
diff --git a/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeSecondarySplitViewCompatTestActivity.java b/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeSecondarySplitViewCompatTestActivity.java
new file mode 100644
index 0000000..5bcd1e28
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeSecondarySplitViewCompatTestActivity.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.core.view.inputmethod;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.EditText;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.R;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowCompat;
+import androidx.core.view.WindowInsetsCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
+
+@RequiresApi(30)
+public class ImeSecondarySplitViewCompatTestActivity extends Activity {
+
+ EditText mEditText;
+
+ Button mHideImeButton;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.ime_secondary_split_test_activity);
+ mEditText = findViewById(R.id.edit_text_id);
+ mHideImeButton = findViewById(R.id.hide_ime_id);
+ mHideImeButton.setOnClickListener(view -> hideIme());
+ }
+
+ private void hideIme() {
+ // Use deprecated WindowInsetsControllerCompat method to attempt to hide ime.
+ WindowInsetsControllerCompat insetsController =
+ ViewCompat.getWindowInsetsController(mEditText);
+ if (insetsController != null) {
+ insetsController.hide(WindowInsetsCompat.Type.ime());
+ }
+ }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeViewCompatMultiWindowTest.java b/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeViewCompatMultiWindowTest.java
new file mode 100644
index 0000000..c5fa2ef
--- /dev/null
+++ b/core/core/src/androidTest/java/androidx/core/view/inputmethod/ImeViewCompatMultiWindowTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.core.view.inputmethod;
+
+import static android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.RemoteException;
+import android.support.v4.BaseInstrumentationTestCase;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+
+import androidx.core.view.WindowInsetsCompat;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiDevice;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+import androidx.testutils.PollingCheck;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+@SdkSuppress(minSdkVersion = 30)
+public class ImeViewCompatMultiWindowTest extends BaseInstrumentationTestCase<ImeBaseSplitTestActivity> {
+
+ private static final long ACTIVITY_LAUNCH_TIMEOUT_MS = 10000;
+ private static final long VISIBILITY_TIMEOUT_MS = 2000;
+ private static final long FIND_OBJECT_TIMEOUT_MS = 5000;
+ private static final long CLICK_DURATION_MS = 200;
+
+ private static final String TEST_APP = "androidx.core.test";
+
+ private Activity mActivity;
+
+ private UiDevice mDevice;
+
+ public ImeViewCompatMultiWindowTest() {
+ super(ImeBaseSplitTestActivity.class);
+ }
+
+ @Before
+ public void setup() throws RemoteException {
+ mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mDevice.wakeUp();
+ mActivity = mActivityTestRule.getActivity();
+ }
+
+ /**
+ * This test is using a deprecated codepath that doesn't support the workaround, so it is
+ * expected to fail hiding the IME.
+ * If this test begins failing on a new API version (that is, an assertion error is no longer
+ * being thrown), it is likely that the workaround is no longer needed on that API version:
+ * b/280532442
+ */
+ @Test(expected = AssertionError.class)
+ @SdkSuppress(minSdkVersion = 30)
+ public void testImeShowAndHide_splitScreen() {
+ if (Build.VERSION.SDK_INT < 32) {
+ // FLAG_ACTIVITY_LAUNCH_ADJACENT is not support before Sdk 32, using the
+ // GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN instead.
+ InstrumentationRegistry.getInstrumentation().getUiAutomation()
+ .performGlobalAction(GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN);
+ }
+
+ // Launch ime test activity in secondary split.
+ Intent intent = new Intent(mActivity, ImeSecondarySplitViewCompatTestActivity.class)
+ .addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT | Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ mActivity.startActivity(intent);
+
+ assertTrue("Test app is not visible after launching activity",
+ mDevice.wait(Until.hasObject(By.pkg(TEST_APP)), ACTIVITY_LAUNCH_TIMEOUT_MS));
+
+ UiObject2 editText = waitForFindObject("edit_text_id");
+ editText.click(CLICK_DURATION_MS);
+
+ WindowManager wm = mActivity.getSystemService(WindowManager.class);
+ PollingCheck.waitFor(VISIBILITY_TIMEOUT_MS, () -> {
+ WindowInsets insets = wm.getCurrentWindowMetrics().getWindowInsets();
+ return insets.isVisible(WindowInsetsCompat.Type.ime());
+ });
+
+ UiObject2 hideImeButton = waitForFindObject("hide_ime_id");
+ hideImeButton.click();
+
+ PollingCheck.waitFor(VISIBILITY_TIMEOUT_MS, () -> {
+ WindowInsets insets = wm.getCurrentWindowMetrics().getWindowInsets();
+ return !insets.isVisible(WindowInsetsCompat.Type.ime());
+ });
+ }
+
+ private UiObject2 waitForFindObject(String resId) {
+ final UiObject2 object =
+ mDevice.wait(Until.findObject(By.res(TEST_APP, resId)), FIND_OBJECT_TIMEOUT_MS);
+ assertNotNull("Find object fail", object);
+ return object;
+ }
+}
diff --git a/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewNestedScrollingFlingVelocityTest.kt b/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewNestedScrollingFlingVelocityTest.kt
index 4eed461..4f73447 100644
--- a/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewNestedScrollingFlingVelocityTest.kt
+++ b/core/core/src/androidTest/java/androidx/core/widget/NestedScrollViewNestedScrollingFlingVelocityTest.kt
@@ -25,6 +25,7 @@
import androidx.core.view.NestedScrollingParent3
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.LargeTest
+import java.util.Arrays
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.closeTo
import org.junit.Before
@@ -32,7 +33,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.Arrays
/**
* This test verifies that the velocity that NestedScrollView flings with in response to finger
diff --git a/core/core/src/main/java/androidx/core/content/ContextCompat.java b/core/core/src/main/java/androidx/core/content/ContextCompat.java
index cd4e613..8cd98dd 100644
--- a/core/core/src/main/java/androidx/core/content/ContextCompat.java
+++ b/core/core/src/main/java/androidx/core/content/ContextCompat.java
@@ -70,6 +70,7 @@
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
@@ -131,6 +132,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -140,6 +142,7 @@
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
+import androidx.annotation.DisplayContext;
import androidx.annotation.DoNotInline;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
@@ -753,6 +756,31 @@
}
/**
+ * Get the display this context is associated with or the
+ * {@link Display#DEFAULT_DISPLAY default display} as the fallback if the context is not
+ * associated with any {@link Display}.
+ * <p>
+ * Applications must use this method with {@link Activity} or a context associated with a
+ * {@link Display} via {@link Context#createDisplayContext(Display)} or
+ * {@link Context#createWindowContext(Display, int, Bundle)}, or the reported {@link Display}
+ * instance is not reliable. </p>
+ *
+ * @param context Context to obtain the associated display
+ * @return The display associated with the Context or the default display if the context
+ * doesn't associated with any display.
+ */
+ @NonNull
+ public static Display getDisplayOrDefault(@NonNull @DisplayContext Context context) {
+ if (Build.VERSION.SDK_INT >= 30) {
+ return Api30Impl.getDisplayOrDefault(context);
+ } else {
+ final WindowManager windowManager =
+ (WindowManager) context.getSystemService(WINDOW_SERVICE);
+ return windowManager.getDefaultDisplay();
+ }
+ }
+
+ /**
* Return the handle to a system-level service by class.
*
* @param context Context to retrieve service from.
@@ -1113,6 +1141,19 @@
static String getAttributionTag(Context obj) {
return obj.getAttributionTag();
}
+
+ @DoNotInline
+ static Display getDisplayOrDefault(Context obj) {
+ try {
+ return obj.getDisplay();
+ } catch (UnsupportedOperationException e) {
+ // Provide a fallback display if the context is not associated with any display.
+ Log.w(TAG, "The context:" + obj + " is not associated with any display. Return a "
+ + "fallback display instead.");
+ return obj.getSystemService(DisplayManager.class)
+ .getDisplay(Display.DEFAULT_DISPLAY);
+ }
+ }
}
@RequiresApi(33)
diff --git a/core/core/src/main/java/androidx/core/view/HapticFeedbackConstantsCompat.java b/core/core/src/main/java/androidx/core/view/HapticFeedbackConstantsCompat.java
new file mode 100644
index 0000000..4ed4078
--- /dev/null
+++ b/core/core/src/main/java/androidx/core/view/HapticFeedbackConstantsCompat.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.core.view;
+
+import android.os.Build;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Helper class for accessing values in {@link android.view.HapticFeedbackConstants}.
+ */
+public final class HapticFeedbackConstantsCompat {
+
+ /**
+ * No haptic feedback should be performed. Applications may use this value to indicate skipping
+ * a call to {@link android.view.View#performHapticFeedback} entirely, or else rely that it
+ * will immediately return {@code false}.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same behavior, immediately returns false</li>
+ * </ul>
+ */
+ public static final int NO_HAPTICS = -1;
+
+ /**
+ * The user has performed a long press on an object that is resulting in an action being
+ * performed.
+ */
+ public static final int LONG_PRESS = 0;
+
+ /**
+ * The user has pressed on a virtual on-screen key.
+ */
+ public static final int VIRTUAL_KEY = 1;
+
+ /**
+ * The user has pressed a soft keyboard key.
+ */
+ public static final int KEYBOARD_TAP = 3;
+
+ /**
+ * The user has pressed either an hour or minute tick of a Clock.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int CLOCK_TICK = 4;
+
+ /**
+ * The user has performed a context click on an object.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 23: Same feedback as CLOCK_TICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int CONTEXT_CLICK = 6;
+
+ /**
+ * The user has pressed a virtual or software keyboard key.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 27: Same feedback as KEYBOARD_TAP</li>
+ * </ul>
+ */
+ public static final int KEYBOARD_PRESS = KEYBOARD_TAP; // Platform constant is also the same.
+
+ /**
+ * The user has released a virtual keyboard key.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 27: No-op</li>
+ * </ul>
+ */
+ public static final int KEYBOARD_RELEASE = 7;
+
+ /**
+ * The user has released a virtual key.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 27: No-op</li>
+ * </ul>
+ */
+ public static final int VIRTUAL_KEY_RELEASE = 8;
+
+ /**
+ * The user has performed a selection/insertion handle move on text field.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 27: No-op</li>
+ * </ul>
+ */
+ public static final int TEXT_HANDLE_MOVE = 9;
+
+ /**
+ * The user has started a gesture (e.g. on the soft keyboard).
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 30: Same feedback as VIRTUAL_KEY</li>
+ * </ul>
+ */
+ public static final int GESTURE_START = 12;
+
+ /**
+ * The user has finished a gesture (e.g. on the soft keyboard).
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 30: Same feedback as CONTEXT_CLICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int GESTURE_END = 13;
+
+ /**
+ * A haptic effect to signal the confirmation or successful completion of a user interaction.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 30: Same feedback as VIRTUAL_KEY</li>
+ * </ul>
+ */
+ public static final int CONFIRM = 16;
+
+ /**
+ * A haptic effect to signal the rejection or failure of a user interaction.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 30: Same feedback as LONG_PRESS</li>
+ * </ul>
+ */
+ public static final int REJECT = 17;
+
+ /**
+ * The user has toggled a switch or button into the on position.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CONTEXT_CLICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int TOGGLE_ON = 21;
+
+ /**
+ * The user has toggled a switch or button into the off position.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CLOCK_TICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int TOGGLE_OFF = 22;
+
+ /**
+ * The user is executing a swipe/drag-style gesture, such as pull-to-refresh, where the
+ * gesture action is “eligible” at a certain threshold of movement, and can be cancelled by
+ * moving back past the threshold. This constant indicates that the user's motion has just
+ * passed the threshold for the action to be activated on release.
+ *
+ * @see #GESTURE_THRESHOLD_DEACTIVATE
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CONTEXT_CLICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int GESTURE_THRESHOLD_ACTIVATE = 23;
+
+ /**
+ * The user is executing a swipe/drag-style gesture, such as pull-to-refresh, where the
+ * gesture action is “eligible” at a certain threshold of movement, and can be cancelled by
+ * moving back past the threshold. This constant indicates that the user's motion has just
+ * re-crossed back "under" the threshold for the action to be activated, meaning the gesture is
+ * currently in a cancelled state.
+ *
+ * @see #GESTURE_THRESHOLD_ACTIVATE
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CLOCK_TICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int GESTURE_THRESHOLD_DEACTIVATE = 24;
+
+ /**
+ * The user has started a drag-and-drop gesture. The drag target has just been "picked up".
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as LONG_PRESS</li>
+ * </ul>
+ */
+ public static final int DRAG_START = 25;
+
+ /**
+ * The user is switching between a series of potential choices, for example items in a list
+ * or discrete points on a slider.
+ *
+ * <p>See also {@link #SEGMENT_FREQUENT_TICK} for cases where density of choices is high, and
+ * the haptics should be lighter or suppressed for a better user experience.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CONTEXT_CLICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int SEGMENT_TICK = 26;
+
+ /**
+ * The user is switching between a series of many potential choices, for example minutes on a
+ * clock face, or individual percentages. This constant is expected to be very soft, so as
+ * not to be uncomfortable when performed a lot in quick succession. If the device can’t make
+ * a suitably soft vibration, then it may not make any vibration.
+ *
+ * <p>Some specializations of this constant exist for specific actions, notably
+ * {@link #CLOCK_TICK} and {@link #TEXT_HANDLE_MOVE}.
+ *
+ * <p>See also {@link #SEGMENT_TICK}.
+ *
+ * <p>Compatibility:
+ * <ul>
+ * <li>API < 34: Same feedback as CLOCK_TICK</li>
+ * <li>API < 21: No-op</li>
+ * </ul>
+ */
+ public static final int SEGMENT_FREQUENT_TICK = 27;
+
+ /** First constant value, excluding {@link #NO_HAPTICS} constant. */
+ @VisibleForTesting
+ static final int FIRST_CONSTANT_INT = LONG_PRESS;
+
+ /** Last constant value used. */
+ @VisibleForTesting
+ static final int LAST_CONSTANT_INT = SEGMENT_FREQUENT_TICK;
+
+ /**
+ * Flag for {@link ViewCompat#performHapticFeedback(android.view.View, int, int)}: Ignore the
+ * setting in the view for whether to perform haptic feedback, do it always.
+ */
+ public static final int FLAG_IGNORE_VIEW_SETTING = 0x0001;
+
+ /** Haptic feedback types. */
+ @IntDef(value = {
+ NO_HAPTICS,
+ LONG_PRESS,
+ VIRTUAL_KEY,
+ KEYBOARD_TAP,
+ CLOCK_TICK,
+ CONTEXT_CLICK,
+ KEYBOARD_PRESS,
+ KEYBOARD_RELEASE,
+ VIRTUAL_KEY_RELEASE,
+ TEXT_HANDLE_MOVE,
+ GESTURE_START,
+ GESTURE_END,
+ CONFIRM,
+ REJECT,
+ TOGGLE_ON,
+ TOGGLE_OFF,
+ GESTURE_THRESHOLD_ACTIVATE,
+ GESTURE_THRESHOLD_DEACTIVATE,
+ DRAG_START,
+ SEGMENT_TICK,
+ SEGMENT_FREQUENT_TICK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ public @interface HapticFeedbackType {
+ }
+
+ /** Flags for performing haptic feedback. */
+ @IntDef(flag = true, value = {
+ FLAG_IGNORE_VIEW_SETTING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ public @interface HapticFeedbackFlags {
+ }
+
+ /**
+ * Returns a haptic feedback constant that is available for this platform build.
+ *
+ * @param feedbackConstant The feedback constant requested
+ * @return The same constant, if supported by this platform build, or a supported fallback.
+ */
+ @HapticFeedbackType
+ static int getFeedbackConstantOrFallback(@HapticFeedbackType int feedbackConstant) {
+ if (feedbackConstant == NO_HAPTICS) {
+ // Skip fallback logic if constant is no-op.
+ return NO_HAPTICS;
+ }
+ if (Build.VERSION.SDK_INT < 34) {
+ switch (feedbackConstant) {
+ case DRAG_START:
+ feedbackConstant = LONG_PRESS;
+ break;
+ case TOGGLE_ON:
+ case SEGMENT_TICK:
+ case GESTURE_THRESHOLD_ACTIVATE:
+ feedbackConstant = CONTEXT_CLICK;
+ break;
+ case TOGGLE_OFF:
+ case SEGMENT_FREQUENT_TICK:
+ case GESTURE_THRESHOLD_DEACTIVATE:
+ feedbackConstant = CLOCK_TICK;
+ break;
+ }
+ }
+ if (Build.VERSION.SDK_INT < 30) {
+ switch (feedbackConstant) {
+ case REJECT:
+ feedbackConstant = LONG_PRESS;
+ break;
+ case CONFIRM:
+ case GESTURE_START:
+ feedbackConstant = VIRTUAL_KEY;
+ break;
+ case GESTURE_END:
+ feedbackConstant = CONTEXT_CLICK;
+ break;
+ }
+ }
+ if (Build.VERSION.SDK_INT < 27) {
+ switch (feedbackConstant) {
+ case KEYBOARD_RELEASE:
+ case VIRTUAL_KEY_RELEASE:
+ case TEXT_HANDLE_MOVE:
+ feedbackConstant = NO_HAPTICS;
+ break;
+ }
+ }
+ if (Build.VERSION.SDK_INT < 23) {
+ switch (feedbackConstant) {
+ case CONTEXT_CLICK:
+ feedbackConstant = CLOCK_TICK;
+ break;
+ }
+ }
+ if (Build.VERSION.SDK_INT < 21) {
+ switch (feedbackConstant) {
+ case CLOCK_TICK:
+ feedbackConstant = NO_HAPTICS;
+ break;
+ }
+ }
+ return feedbackConstant;
+ }
+
+ private HapticFeedbackConstantsCompat() {}
+}
diff --git a/core/core/src/main/java/androidx/core/view/SoftwareKeyboardControllerCompat.java b/core/core/src/main/java/androidx/core/view/SoftwareKeyboardControllerCompat.java
index 5ccc392..dee46e1 100644
--- a/core/core/src/main/java/androidx/core/view/SoftwareKeyboardControllerCompat.java
+++ b/core/core/src/main/java/androidx/core/view/SoftwareKeyboardControllerCompat.java
@@ -215,7 +215,7 @@
// callback current controllable insets. Adding the listener here to check if
// ime inset is controllable.
insetsController.addOnControllableInsetsChangedListener(listener);
- if (!isImeInsetsControllable.get()) {
+ if (!isImeInsetsControllable.get() && mView != null) {
final InputMethodManager imm = (InputMethodManager) mView.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
// This is a backport when the app is in multi-windowing mode, it cannot
diff --git a/core/core/src/main/java/androidx/core/view/ViewCompat.java b/core/core/src/main/java/androidx/core/view/ViewCompat.java
index 856e06d..5f551cf 100644
--- a/core/core/src/main/java/androidx/core/view/ViewCompat.java
+++ b/core/core/src/main/java/androidx/core/view/ViewCompat.java
@@ -76,6 +76,8 @@
import androidx.core.R;
import androidx.core.util.Preconditions;
import androidx.core.view.AccessibilityDelegateCompat.AccessibilityDelegateAdapter;
+import androidx.core.view.HapticFeedbackConstantsCompat.HapticFeedbackFlags;
+import androidx.core.view.HapticFeedbackConstantsCompat.HapticFeedbackType;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
import androidx.core.view.accessibility.AccessibilityNodeProviderCompat;
@@ -1483,6 +1485,58 @@
}
/**
+ * Perform a haptic feedback to the user for the view.
+ *
+ * <p>The framework will provide haptic feedback for some built in actions, such as long
+ * presses, but you may wish to provide feedback for your own widget.
+ *
+ * <p>The feedback will only be performed if {@link android.view.View#isHapticFeedbackEnabled()}
+ * is true.
+ *
+ * <em>Note:</em> Check compatibility support for each feedback constant described at
+ * {@link HapticFeedbackConstantsCompat}.
+ *
+ * @param view The view.
+ * @param feedbackConstant One of the constants defined in {@link HapticFeedbackConstantsCompat}
+ * @return Whether the feedback might be performed - generally this result should be ignored
+ */
+ public static boolean performHapticFeedback(@NonNull View view,
+ @HapticFeedbackType int feedbackConstant) {
+ feedbackConstant =
+ HapticFeedbackConstantsCompat.getFeedbackConstantOrFallback(feedbackConstant);
+ if (feedbackConstant == HapticFeedbackConstantsCompat.NO_HAPTICS) {
+ // This compat implementation is straightforward.
+ return false;
+ }
+ return view.performHapticFeedback(feedbackConstant);
+ }
+
+ /**
+ * Perform a haptic feedback to the user for the view.
+ *
+ * <p>This is similar to {@link #performHapticFeedback(android.view.View, int)}, with
+ * additional options.
+ *
+ * <em>Note:</em> Check compatibility support for each feedback constant described at
+ * {@link HapticFeedbackConstantsCompat}.
+ *
+ * @param view The view.
+ * @param feedbackConstant One of the constants defined in {@link HapticFeedbackConstantsCompat}
+ * @param flags Additional flags as per {@link HapticFeedbackConstantsCompat}
+ * @return Whether the feedback might be performed - generally this result should be ignored
+ */
+ public static boolean performHapticFeedback(@NonNull View view,
+ @HapticFeedbackType int feedbackConstant, @HapticFeedbackFlags int flags) {
+ feedbackConstant =
+ HapticFeedbackConstantsCompat.getFeedbackConstantOrFallback(feedbackConstant);
+ if (feedbackConstant == HapticFeedbackConstantsCompat.NO_HAPTICS) {
+ // This compat implementation is straightforward.
+ return false;
+ }
+ return view.performHapticFeedback(feedbackConstant, flags);
+ }
+
+ /**
* Adds an accessibility action that can be performed on a node associated with a view.
* A view can only have 32 actions created with this API.
*
diff --git a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
index 768e166..3837165 100644
--- a/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/core/core/src/main/java/androidx/core/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -814,13 +814,55 @@
/**
* Class with information if a node is a collection.
* <p>
- * A collection of items has rows and columns and may be hierarchical.
- * For example, a horizontal list is a collection with one column, as
- * many rows as the list items, and is not hierarchical; A table is a
- * collection with several rows, several columns, and is not hierarchical;
- * A vertical tree is a hierarchical collection with one column and
- * as many rows as the first level children.
- * </p>
+ * A collection of items has rows and columns and may be marked as hierarchical.
+ *
+ * <p>
+ * For example, a list where the items are placed in a vertical layout is a collection with one
+ * column and as many rows as the list items. This collection has 3 rows and 1 column and should
+ * not be marked as hierarchical since items do not exist at different levels/ranks and there
+ * are no nested collections.
+ * <ul>
+ * <li>Item 1</li>
+ * <li>Item 2</li>
+ * <li>Item 3</li>
+ * </ul>
+ *
+ * <p>
+ * A table is a collection with several rows and several columns. This collection has 2 rows and
+ * 3 columns and is not marked as hierarchical:
+ *<table>
+ * <tr>
+ * <td>Item 1</td>
+ * <td>Item 2</td>
+ * <td>Item 3</td>
+ * </tr>
+ * <tr>
+ * <td>Item 4</td>
+ * <td>Item 5</td>
+ * <td>Item 6</td>
+ * </tr>
+ * </table>
+ *
+ * <p>
+ * Nested collections could be marked as hierarchical. To add outer and inner collections to the
+ * same hierarchy, mark them both as hierarchical.
+ *
+ * <p> For example, if you have a collection with two lists - this collection has an outer
+ * list with 3 rows and 1 column and an inner list within "Item 2" with 2 rows and 1 -
+ * you can mark both the outer list and the inner list as hierarchical to make them part of
+ * the same hierarchy. If a collection does not have any ancestor or descendant hierarchical
+ * collections, it does not need to be marked as hierarchical.
+ * <ul>
+ * <li>Item 1</li>
+ * <li> Item 2
+ * <ul>
+ * <li>Item 2A</li>
+ * <li>Item 2B</li>
+ * </ul>
+ * </li>
+ * <li>Item 3</li>
+ * </ul>
+ *
* <p>
* To be a valid list, a collection has 1 row and any number of columns or 1 column and any
* number of rows.
diff --git a/core/uwb/uwb-rxjava3/src/androidTest/java/androidx/core/uwb/rxjava3/mock/TestUwbManager.kt b/core/uwb/uwb-rxjava3/src/androidTest/java/androidx/core/uwb/rxjava3/mock/TestUwbManager.kt
index 92785bf3..112a643 100644
--- a/core/uwb/uwb-rxjava3/src/androidTest/java/androidx/core/uwb/rxjava3/mock/TestUwbManager.kt
+++ b/core/uwb/uwb-rxjava3/src/androidTest/java/androidx/core/uwb/rxjava3/mock/TestUwbManager.kt
@@ -16,12 +16,12 @@
package androidx.core.uwb.rxjava3.mock
-import androidx.core.uwb.UwbManager
-import androidx.core.uwb.UwbAddress
import androidx.core.uwb.RangingCapabilities
+import androidx.core.uwb.UwbAddress
import androidx.core.uwb.UwbClientSessionScope
import androidx.core.uwb.UwbControleeSessionScope
import androidx.core.uwb.UwbControllerSessionScope
+import androidx.core.uwb.UwbManager
import com.google.android.gms.nearby.uwb.UwbComplexChannel
/** A default implementation of [UwbManager] used in testing. */
diff --git a/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbClientSessionScopeImpl.kt b/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbClientSessionScopeImpl.kt
index 86c1559..aafd713 100644
--- a/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbClientSessionScopeImpl.kt
+++ b/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbClientSessionScopeImpl.kt
@@ -20,10 +20,11 @@
import androidx.core.uwb.RangingCapabilities
import androidx.core.uwb.RangingMeasurement
import androidx.core.uwb.RangingParameters
-import androidx.core.uwb.RangingResult.RangingResultPosition
import androidx.core.uwb.RangingResult.RangingResultPeerDisconnected
+import androidx.core.uwb.RangingResult.RangingResultPosition
import androidx.core.uwb.UwbAddress
import androidx.core.uwb.UwbControleeSessionScope
+import androidx.core.uwb.helper.handleApiException
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.nearby.uwb.RangingPosition
import com.google.android.gms.nearby.uwb.RangingSessionCallback
@@ -32,11 +33,10 @@
import com.google.android.gms.nearby.uwb.UwbDevice
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
-import androidx.core.uwb.helper.handleApiException
-import kotlinx.coroutines.channels.awaitClose
internal class UwbClientSessionScopeImpl(
private val uwbClient: UwbClient,
diff --git a/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbManagerImpl.kt b/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbManagerImpl.kt
index 4edf85e..34ff68e 100644
--- a/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbManagerImpl.kt
+++ b/core/uwb/uwb/src/main/java/androidx/core/uwb/impl/UwbManagerImpl.kt
@@ -30,13 +30,13 @@
import androidx.core.uwb.UwbControllerSessionScope
import androidx.core.uwb.UwbManager
import androidx.core.uwb.backend.IUwb
-import com.google.android.gms.common.api.ApiException
-import com.google.android.gms.nearby.Nearby
-import kotlinx.coroutines.tasks.await
import androidx.core.uwb.helper.checkSystemFeature
import androidx.core.uwb.helper.handleApiException
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
+import com.google.android.gms.common.api.ApiException
+import com.google.android.gms.nearby.Nearby
+import kotlinx.coroutines.tasks.await
internal class UwbManagerImpl(private val context: Context) : UwbManager {
companion object {
diff --git a/credentials/credentials-play-services-auth/build.gradle b/credentials/credentials-play-services-auth/build.gradle
index 4558801..dab1da2 100644
--- a/credentials/credentials-play-services-auth/build.gradle
+++ b/credentials/credentials-play-services-auth/build.gradle
@@ -68,7 +68,7 @@
}
androidx {
- name = "Credentials Play Services Auth Library"
+ name = "Credentials Play Services Auth"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "sign into apps using play-services-auth library"
diff --git a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
index 9652061..a783ea6 100644
--- a/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
+++ b/credentials/credentials-play-services-auth/src/androidTest/java/androidx/credentials/playservices/beginsignin/CredentialProviderBeginSignInControllerTest.kt
@@ -25,10 +25,10 @@
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.google.android.libraries.identity.googleid.GetGoogleIdOption
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import com.google.android.libraries.identity.googleid.GetGoogleIdOption
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
index 3524fe2..d4dc2c5 100644
--- a/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
+++ b/credentials/credentials-play-services-auth/src/main/java/androidx/credentials/playservices/CredentialProviderPlayServicesImpl.kt
@@ -20,8 +20,8 @@
import android.content.Context
import android.os.CancellationSignal
import android.util.Log
-import androidx.credentials.ClearCredentialStateRequest
import androidx.annotation.VisibleForTesting
+import androidx.credentials.ClearCredentialStateRequest
import androidx.credentials.CreateCredentialRequest
import androidx.credentials.CreateCredentialResponse
import androidx.credentials.CreatePasswordRequest
diff --git a/credentials/credentials-provider/build.gradle b/credentials/credentials-provider/build.gradle
index 0f5fb6d..a2d506c 100644
--- a/credentials/credentials-provider/build.gradle
+++ b/credentials/credentials-provider/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Credentials Provider Library"
+ name = "Credentials Provider"
publish = Publish.NONE
inceptionYear = "2022"
description = "use utility APIs to process requests from, and return responses to the android" +
diff --git a/credentials/credentials/build.gradle b/credentials/credentials/build.gradle
index 0c8c3fb..c548aa0 100644
--- a/credentials/credentials/build.gradle
+++ b/credentials/credentials/build.gradle
@@ -47,7 +47,7 @@
}
androidx {
- name = "Credentials Core Library"
+ name = "Credentials"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Android Credentials Library"
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
index fafee67..1f477d4 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetCredentialRequestTest.kt
@@ -16,13 +16,10 @@
package androidx.credentials
-import com.google.common.truth.Truth.assertThat
-
-import org.junit.Assert.assertThrows
-
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/cursoradapter/cursoradapter/build.gradle b/cursoradapter/cursoradapter/build.gradle
index 486beb8..05db38f 100644
--- a/cursoradapter/cursoradapter/build.gradle
+++ b/cursoradapter/cursoradapter/build.gradle
@@ -10,7 +10,7 @@
}
androidx {
- name = "Android Support Library Cursor Adapter"
+ name = "Cursor Adapter"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/cursoradapter/cursoradapter/src/main/AndroidManifest.xml b/cursoradapter/cursoradapter/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/cursoradapter/cursoradapter/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/customview/customview-poolingcontainer/build.gradle b/customview/customview-poolingcontainer/build.gradle
index 49ae408..524083d 100644
--- a/customview/customview-poolingcontainer/build.gradle
+++ b/customview/customview-poolingcontainer/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "androidx.customview:poolingcontainer"
+ name = "CustomView Pooling Container"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.CUSTOMVIEW_POOLINGCONTAINER
inceptionYear = "2021"
diff --git a/customview/customview/build.gradle b/customview/customview/build.gradle
index 041da7f..e184a65 100644
--- a/customview/customview/build.gradle
+++ b/customview/customview/build.gradle
@@ -20,7 +20,7 @@
}
androidx {
- name = "Android Support Library Custom View"
+ name = "Custom View"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.CUSTOMVIEW
inceptionYear = "2018"
diff --git a/customview/customview/src/androidTest/java/androidx/customview/widget/TestActivity.kt b/customview/customview/src/androidTest/java/androidx/customview/widget/TestActivity.kt
index 65fd739..af04aa5 100644
--- a/customview/customview/src/androidTest/java/androidx/customview/widget/TestActivity.kt
+++ b/customview/customview/src/androidTest/java/androidx/customview/widget/TestActivity.kt
@@ -18,7 +18,6 @@
import android.app.Activity
import android.os.Bundle
-
import androidx.customview.test.R
class TestActivity : Activity() {
diff --git a/customview/customview/src/main/AndroidManifest.xml b/customview/customview/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/customview/customview/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/CountActivity.kt b/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/CountActivity.kt
index ec8bea7..ff0c660 100644
--- a/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/CountActivity.kt
+++ b/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/CountActivity.kt
@@ -18,7 +18,6 @@
import android.os.Bundle
import android.os.StrictMode
-
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
diff --git a/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/data/CountRepository.kt b/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/data/CountRepository.kt
index 52a3ec0..428b189 100644
--- a/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/data/CountRepository.kt
+++ b/datastore/datastore-compose-samples/src/main/java/com/example/datastorecomposesamples/data/CountRepository.kt
@@ -27,13 +27,13 @@
import androidx.datastore.preferences.preferencesDataStore
import com.example.datastorecomposesamples.CountPreferences
import java.io.File
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.map
import java.io.IOException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
data class CountState(val count: Int)
diff --git a/datastore/datastore-core-okio/build.gradle b/datastore/datastore-core-okio/build.gradle
index d1c5ba1..99bb8ec 100644
--- a/datastore/datastore-core-okio/build.gradle
+++ b/datastore/datastore-core-okio/build.gradle
@@ -97,7 +97,7 @@
}
androidx {
- name = "Android DataStore Core Okio"
+ name = "DataStore Core Okio"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
description = "Android DataStore Core Okio- contains APIs to use datastore-core in multiplatform via okio"
diff --git a/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioStorage.kt b/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioStorage.kt
index e2ff9fb..234680e 100644
--- a/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioStorage.kt
+++ b/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioStorage.kt
@@ -23,9 +23,9 @@
import androidx.datastore.core.WriteScope
import androidx.datastore.core.createSingleProcessCoordinator
import androidx.datastore.core.use
-import kotlinx.atomicfu.locks.synchronized
-import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.atomic
+import kotlinx.atomicfu.locks.SynchronizedObject
+import kotlinx.atomicfu.locks.synchronized
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okio.FileNotFoundException
diff --git a/datastore/datastore-core-okio/src/commonTest/kotlin/androidx/datastore/core/okio/OkioStorageTest.kt b/datastore/datastore-core-okio/src/commonTest/kotlin/androidx/datastore/core/okio/OkioStorageTest.kt
index f2b88b1..11db7e0 100644
--- a/datastore/datastore-core-okio/src/commonTest/kotlin/androidx/datastore/core/okio/OkioStorageTest.kt
+++ b/datastore/datastore-core-okio/src/commonTest/kotlin/androidx/datastore/core/okio/OkioStorageTest.kt
@@ -17,6 +17,8 @@
package androidx.datastore.core.okio
import androidx.datastore.OkioTestIO
+import androidx.datastore.TestingOkioSerializer
+import androidx.datastore.TestingSerializerConfig
import androidx.datastore.core.ReadScope
import androidx.datastore.core.Storage
import androidx.datastore.core.StorageConnection
@@ -24,19 +26,17 @@
import androidx.datastore.core.readData
import androidx.datastore.core.use
import androidx.datastore.core.writeData
-import androidx.datastore.TestingOkioSerializer
-import androidx.datastore.TestingSerializerConfig
import androidx.kruth.assertThat
import androidx.kruth.assertThrows
-import kotlin.test.Test
import kotlin.test.BeforeTest
+import kotlin.test.Test
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
import okio.FileSystem
import okio.IOException
diff --git a/datastore/datastore-core-okio/src/nativeMain/kotlin/androidx/datastore/core/okio/Atomic.native.kt b/datastore/datastore-core-okio/src/nativeMain/kotlin/androidx/datastore/core/okio/Atomic.native.kt
index 6498e6f..a27d82f 100644
--- a/datastore/datastore-core-okio/src/nativeMain/kotlin/androidx/datastore/core/okio/Atomic.native.kt
+++ b/datastore/datastore-core-okio/src/nativeMain/kotlin/androidx/datastore/core/okio/Atomic.native.kt
@@ -16,8 +16,8 @@
package androidx.datastore.core.okio
-import kotlinx.atomicfu.AtomicInt as AtomicFuAtomicInt
import kotlinx.atomicfu.AtomicBoolean as AtomicFuAtomicBoolean
+import kotlinx.atomicfu.AtomicInt as AtomicFuAtomicInt
import kotlinx.atomicfu.atomic
internal actual class AtomicInt actual constructor(initialValue: Int) {
diff --git a/datastore/datastore-core/build.gradle b/datastore/datastore-core/build.gradle
index da45ae9..67e6e17 100644
--- a/datastore/datastore-core/build.gradle
+++ b/datastore/datastore-core/build.gradle
@@ -156,7 +156,7 @@
}
androidx {
- name = "Android DataStore Core"
+ name = "DataStore Core"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
description = "Android DataStore Core - contains the underlying store used by each serialization method"
diff --git a/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/SharedCounterTest.kt b/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/SharedCounterTest.kt
index d7f9f21..5179249 100644
--- a/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/SharedCounterTest.kt
+++ b/datastore/datastore-core/src/androidTest/java/androidx/datastore/core/SharedCounterTest.kt
@@ -26,10 +26,10 @@
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
-import org.junit.Rule
-import org.junit.rules.TemporaryFolder
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
+import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt
index ccc6edb..c61f858 100644
--- a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt
+++ b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/DataMigrationInitializerTest.kt
@@ -23,13 +23,12 @@
import androidx.kruth.assertThrows
import kotlin.test.BeforeTest
import kotlin.test.Test
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
index dfa3273..6d93034 100644
--- a/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
+++ b/datastore/datastore-core/src/commonTest/kotlin/androidx/datastore/core/SingleProcessDataStoreTest.kt
@@ -24,16 +24,24 @@
import androidx.datastore.core.handlers.NoOpCorruptionHandler
import androidx.kruth.assertThat
import androidx.kruth.assertThrows
+import kotlin.coroutines.AbstractCoroutineContextElement
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.cancellation.CancellationException
+import kotlin.random.Random
+import kotlin.test.BeforeTest
+import kotlin.test.Test
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.flow.toList
@@ -41,17 +49,9 @@
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.withContext
-import kotlinx.coroutines.test.runTest
-import kotlin.coroutines.AbstractCoroutineContextElement
-import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.cancellation.CancellationException
-import kotlin.random.Random
-import kotlin.test.BeforeTest
-import kotlin.test.Test
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.withContext
@OptIn(ExperimentalCoroutinesApi::class)
abstract class SingleProcessDataStoreTest<F : TestFile>(private val testIO: TestIO<F, *>) {
diff --git a/datastore/datastore-core/src/jvmMain/kotlin/androidx/datastore/core/DataStoreFactory.jvm.kt b/datastore/datastore-core/src/jvmMain/kotlin/androidx/datastore/core/DataStoreFactory.jvm.kt
index 285e940..5908528 100644
--- a/datastore/datastore-core/src/jvmMain/kotlin/androidx/datastore/core/DataStoreFactory.jvm.kt
+++ b/datastore/datastore-core/src/jvmMain/kotlin/androidx/datastore/core/DataStoreFactory.jvm.kt
@@ -18,10 +18,10 @@
import androidx.datastore.core.handlers.NoOpCorruptionHandler
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
+import java.io.File
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
-import java.io.File
/**
* Public factory for creating DataStore instances.
diff --git a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/FileStorageTest.kt b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/FileStorageTest.kt
index 273bd30..b12adcb 100644
--- a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/FileStorageTest.kt
+++ b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/FileStorageTest.kt
@@ -22,15 +22,15 @@
import java.io.File
import java.io.IOException
import kotlin.random.Random
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlin.test.Test
import kotlin.test.BeforeTest
+import kotlin.test.Test
import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.yield
@ExperimentalCoroutinesApi
diff --git a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/JvmTests.kt b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/JvmTests.kt
index 033a8c9..b8a32d1 100644
--- a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/JvmTests.kt
+++ b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/JvmTests.kt
@@ -20,13 +20,13 @@
import androidx.datastore.JavaIOFile
import androidx.kruth.assertThat
import androidx.kruth.assertThrows
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
-import java.io.IOException
-import java.io.InputStream
-import java.io.OutputStream
import kotlinx.coroutines.flow.first
import org.junit.Test
diff --git a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/handlers/ReplaceFileCorruptionHandlerTest.kt b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/handlers/ReplaceFileCorruptionHandlerTest.kt
index c6cdd67..951f37c 100644
--- a/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/handlers/ReplaceFileCorruptionHandlerTest.kt
+++ b/datastore/datastore-core/src/jvmTest/kotlin/androidx/datastore/core/handlers/ReplaceFileCorruptionHandlerTest.kt
@@ -17,11 +17,11 @@
package androidx.datastore.core.handlers
import androidx.datastore.TestingSerializerConfig
-import androidx.datastore.core.FileStorage
import androidx.datastore.core.DataStoreImpl
+import androidx.datastore.core.FileStorage
import androidx.datastore.core.TestingSerializer
-import androidx.kruth.assertThrows
import androidx.kruth.assertThat
+import androidx.kruth.assertThrows
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit
diff --git a/datastore/datastore-preferences-core/build.gradle b/datastore/datastore-preferences-core/build.gradle
index a9112b0..9567f6b 100644
--- a/datastore/datastore-preferences-core/build.gradle
+++ b/datastore/datastore-preferences-core/build.gradle
@@ -119,7 +119,7 @@
}
androidx {
- name = "Android Preferences DataStore Core"
+ name = "Preferences DataStore Core"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
description = "Android Preferences DataStore without the Android Dependencies"
diff --git a/datastore/datastore-preferences-core/src/commonMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.kt b/datastore/datastore-preferences-core/src/commonMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.kt
index 20e6cbc..085b1a6 100644
--- a/datastore/datastore-preferences-core/src/commonMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.kt
+++ b/datastore/datastore-preferences-core/src/commonMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.kt
@@ -21,9 +21,9 @@
import androidx.datastore.core.DataStore
import androidx.datastore.core.Storage
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
+import kotlin.jvm.JvmOverloads
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
-import kotlin.jvm.JvmOverloads
import okio.Path
expect object PreferenceDataStoreFactory {
diff --git a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt
index aa06488..b216558 100644
--- a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt
+++ b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerTest.kt
@@ -19,11 +19,11 @@
import androidx.datastore.OkioPath
import androidx.datastore.OkioTestIO
import androidx.datastore.core.okio.OkioSerializer
-import kotlinx.coroutines.test.runTest
-import kotlin.test.assertEquals
import kotlin.test.BeforeTest
import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import okio.FileSystem
@OptIn(
diff --git a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesTest.kt b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesTest.kt
index 7f2dc36..61d7c07 100644
--- a/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesTest.kt
+++ b/datastore/datastore-preferences-core/src/commonTest/kotlin/androidx/datastore/preferences/core/PreferencesTest.kt
@@ -17,10 +17,10 @@
package androidx.datastore.preferences.core
import kotlin.test.Test
-import kotlin.test.assertNull
-import kotlin.test.assertTrue
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
class PreferencesTest {
diff --git a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/Actual.jvm.kt b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/Actual.jvm.kt
index aaef346..1b12a57 100644
--- a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/Actual.jvm.kt
+++ b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/Actual.jvm.kt
@@ -19,7 +19,6 @@
package androidx.datastore.preferences.core
import androidx.annotation.RestrictTo
-
import java.util.Collections
import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
diff --git a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.jvm.kt b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.jvm.kt
index d1bc635..d458300 100644
--- a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.jvm.kt
+++ b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactory.jvm.kt
@@ -23,10 +23,10 @@
import androidx.datastore.core.Storage
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.core.okio.OkioStorage
+import java.io.File
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
-import java.io.File
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toOkioPath
diff --git a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferencesSerializer.jvm.kt b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferencesSerializer.jvm.kt
index c413194..3ba4afd 100644
--- a/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferencesSerializer.jvm.kt
+++ b/datastore/datastore-preferences-core/src/jvmMain/kotlin/androidx/datastore/preferences/core/PreferencesSerializer.jvm.kt
@@ -17,11 +17,11 @@
package androidx.datastore.preferences.core
import androidx.datastore.core.CorruptionException
-import androidx.datastore.preferences.PreferencesProto.PreferenceMap
-import androidx.datastore.preferences.PreferencesProto.Value
-import androidx.datastore.preferences.PreferencesProto.StringSet
import androidx.datastore.core.okio.OkioSerializer
import androidx.datastore.preferences.PreferencesMapCompat
+import androidx.datastore.preferences.PreferencesProto.PreferenceMap
+import androidx.datastore.preferences.PreferencesProto.StringSet
+import androidx.datastore.preferences.PreferencesProto.Value
import androidx.datastore.preferences.protobuf.ByteString
import kotlin.jvm.Throws
import okio.BufferedSink
diff --git a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryTest.kt b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryTest.kt
index 89aaab4..355b3c1 100644
--- a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryTest.kt
+++ b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryTest.kt
@@ -18,6 +18,10 @@
import androidx.datastore.core.DataMigration
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
+import java.io.File
+import java.lang.IllegalStateException
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.flow.first
@@ -28,10 +32,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.lang.IllegalStateException
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
@ObsoleteCoroutinesApi
@kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt
index eed8f1f..74fb405 100644
--- a/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt
+++ b/datastore/datastore-preferences-core/src/jvmTest/kotlin/androidx/datastore/preferences/core/PreferencesSerializerJavaTest.kt
@@ -20,13 +20,13 @@
import androidx.datastore.OkioTestIO
import androidx.datastore.core.CorruptionException
import androidx.datastore.core.okio.OkioSerializer
-import kotlinx.coroutines.test.runTest
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
import kotlin.test.BeforeTest
import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import okio.FileSystem
@kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/datastore/datastore-preferences-core/src/nativeTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryNativeTest.kt b/datastore/datastore-preferences-core/src/nativeTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryNativeTest.kt
index a0a60f2..145b556 100644
--- a/datastore/datastore-preferences-core/src/nativeTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryNativeTest.kt
+++ b/datastore/datastore-preferences-core/src/nativeTest/kotlin/androidx/datastore/preferences/core/PreferenceDataStoreFactoryNativeTest.kt
@@ -19,15 +19,15 @@
import androidx.datastore.OkioTestIO
import androidx.datastore.core.DataMigration
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
+import kotlin.test.BeforeTest
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
-import kotlin.test.BeforeTest
-import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import okio.FileSystem
import okio.Path
import okio.Path.Companion.toPath
diff --git a/datastore/datastore-preferences-proto/build.gradle b/datastore/datastore-preferences-proto/build.gradle
index 258630b..f599a23 100644
--- a/datastore/datastore-preferences-proto/build.gradle
+++ b/datastore/datastore-preferences-proto/build.gradle
@@ -73,7 +73,7 @@
artifacts.add(jarjarConf.name, preferencesProtoJarJarTask.flatMap { it.archiveFile })
androidx {
- name = "Android Preferences DataStore Proto"
+ name = "Preferences DataStore Proto"
publish = Publish.NONE
inceptionYear = "2020"
description = "Jarjar the generated proto and proto-lite dependency for use by " +
diff --git a/datastore/datastore-preferences-rxjava2/build.gradle b/datastore/datastore-preferences-rxjava2/build.gradle
index d58618b..f80ea3d 100644
--- a/datastore/datastore-preferences-rxjava2/build.gradle
+++ b/datastore/datastore-preferences-rxjava2/build.gradle
@@ -56,7 +56,7 @@
}
androidx {
- name = "Android DataStore Core RxJava2 Wrappers"
+ name = "DataStore Preferences RxJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreDelegateTest.kt b/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreDelegateTest.kt
index d307a3a..225374a 100644
--- a/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreDelegateTest.kt
+++ b/datastore/datastore-preferences-rxjava2/src/androidTest/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreDelegateTest.kt
@@ -26,13 +26,13 @@
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import io.reactivex.Single
+import java.io.File
+import java.io.FileOutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.io.FileOutputStream
val intKey = intPreferencesKey("int_key")
diff --git a/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt b/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
index f374b78..f3540b9 100644
--- a/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
+++ b/datastore/datastore-preferences-rxjava2/src/main/java/androidx/datastore/preferences/rxjava2/RxPreferenceDataStoreBuilder.kt
@@ -27,12 +27,12 @@
import androidx.datastore.rxjava2.RxDataStore
import io.reactivex.Scheduler
import io.reactivex.schedulers.Schedulers
+import java.io.File
+import java.util.concurrent.Callable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.rx2.asCoroutineDispatcher
import kotlinx.coroutines.rx2.await
-import java.io.File
-import java.util.concurrent.Callable
/**
* Builder for a Preferences RxDataStore that works on a single process.
diff --git a/datastore/datastore-preferences-rxjava3/build.gradle b/datastore/datastore-preferences-rxjava3/build.gradle
index 8461448..7a06c51 100644
--- a/datastore/datastore-preferences-rxjava3/build.gradle
+++ b/datastore/datastore-preferences-rxjava3/build.gradle
@@ -56,7 +56,7 @@
}
androidx {
- name = "Android DataStore Core RxJava2 Wrappers"
+ name = "DataStore Preferences RxJava3"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-preferences-rxjava3/src/androidTest/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreDelegateTest.kt b/datastore/datastore-preferences-rxjava3/src/androidTest/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreDelegateTest.kt
index d162a6f..74e85ff 100644
--- a/datastore/datastore-preferences-rxjava3/src/androidTest/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreDelegateTest.kt
+++ b/datastore/datastore-preferences-rxjava3/src/androidTest/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreDelegateTest.kt
@@ -26,13 +26,13 @@
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import io.reactivex.rxjava3.core.Single
+import java.io.File
+import java.io.FileOutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.io.FileOutputStream
val intKey = intPreferencesKey("int_key")
diff --git a/datastore/datastore-preferences-rxjava3/src/main/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreBuilder.kt b/datastore/datastore-preferences-rxjava3/src/main/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreBuilder.kt
index a9cf37a..57bef8b 100644
--- a/datastore/datastore-preferences-rxjava3/src/main/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreBuilder.kt
+++ b/datastore/datastore-preferences-rxjava3/src/main/java/androidx/datastore/preferences/rxjava3/RxPreferenceDataStoreBuilder.kt
@@ -27,12 +27,12 @@
import androidx.datastore.rxjava3.RxDataStore
import io.reactivex.rxjava3.core.Scheduler
import io.reactivex.rxjava3.schedulers.Schedulers
+import java.io.File
+import java.util.concurrent.Callable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.rx3.asCoroutineDispatcher
import kotlinx.coroutines.rx3.await
-import java.io.File
-import java.util.concurrent.Callable
/**
* Builder for a Preferences RxDataStore that works on a single process.
diff --git a/datastore/datastore-preferences/build.gradle b/datastore/datastore-preferences/build.gradle
index 37dfd741e..0bbbbe6 100644
--- a/datastore/datastore-preferences/build.gradle
+++ b/datastore/datastore-preferences/build.gradle
@@ -77,7 +77,7 @@
androidx {
- name = "Android Preferences DataStore"
+ name = "Preferences DataStore"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Preferences DataStore"
diff --git a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegateTest.kt b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegateTest.kt
index cce1184..031ec48 100644
--- a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegateTest.kt
+++ b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegateTest.kt
@@ -25,6 +25,7 @@
import androidx.datastore.preferences.core.preferencesOf
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.test.core.app.ApplicationProvider
+import kotlin.test.assertEquals
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.flow.first
@@ -35,7 +36,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import kotlin.test.assertEquals
val stringKey = stringPreferencesKey("key1")
val booleanKey = booleanPreferencesKey("key2")
diff --git a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreFileTest.kt b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreFileTest.kt
index 55ac285..78989fa 100644
--- a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreFileTest.kt
+++ b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/PreferenceDataStoreFileTest.kt
@@ -18,9 +18,9 @@
import android.content.Context
import androidx.test.core.app.ApplicationProvider
-import org.junit.Test
import java.io.File
import kotlin.test.assertEquals
+import org.junit.Test
public class PreferenceDataStoreFileTest {
@Test
diff --git a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/SharedPreferencesToPreferencesTest.kt b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/SharedPreferencesToPreferencesTest.kt
index 21a14d2..76f1db1 100644
--- a/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/SharedPreferencesToPreferencesTest.kt
+++ b/datastore/datastore-preferences/src/androidAndroidTest/kotlin/androidx/datastore/preferences/SharedPreferencesToPreferencesTest.kt
@@ -29,19 +29,19 @@
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.MediumTest
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.runTest
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TemporaryFolder
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
private val sharedPrefsName = "shared_prefs_name"
diff --git a/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegate.kt b/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegate.kt
index 9d15f5a..7532736 100644
--- a/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegate.kt
+++ b/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/PreferenceDataStoreDelegate.kt
@@ -25,11 +25,11 @@
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
-import kotlin.properties.ReadOnlyProperty
-import kotlin.reflect.KProperty
/**
* Creates a property delegate for a single process DataStore. This should only be called once
diff --git a/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/SharedPreferencesMigration.kt b/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/SharedPreferencesMigration.kt
index 635df8e..c7e8c2a 100644
--- a/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/SharedPreferencesMigration.kt
+++ b/datastore/datastore-preferences/src/androidMain/kotlin/androidx/datastore/preferences/SharedPreferencesMigration.kt
@@ -18,8 +18,8 @@
import android.content.Context
import android.content.SharedPreferences
-import androidx.datastore.migrations.SharedPreferencesView
import androidx.datastore.migrations.SharedPreferencesMigration
+import androidx.datastore.migrations.SharedPreferencesView
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.floatPreferencesKey
diff --git a/datastore/datastore-proto/build.gradle b/datastore/datastore-proto/build.gradle
index a3680b0..658823c 100644
--- a/datastore/datastore-proto/build.gradle
+++ b/datastore/datastore-proto/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "Android Proto DataStore"
+ name = "Proto DataStore"
publish = Publish.NONE
inceptionYear = "2020"
description = "Android Proto DataStore"
diff --git a/datastore/datastore-proto/src/test/java/androidx/datastore/protos/ProtoSerializerTest.kt b/datastore/datastore-proto/src/test/java/androidx/datastore/protos/ProtoSerializerTest.kt
index 90d38c7..f093509 100644
--- a/datastore/datastore-proto/src/test/java/androidx/datastore/protos/ProtoSerializerTest.kt
+++ b/datastore/datastore-proto/src/test/java/androidx/datastore/protos/ProtoSerializerTest.kt
@@ -17,16 +17,16 @@
package androidx.datastore.protos
import androidx.datastore.core.CorruptionException
-import org.junit.Test
-import androidx.testing.TestMessageProto.FooProto
import androidx.testing.TestMessageProto.ExtendableProto
import androidx.testing.TestMessageProto.ExtensionProto
+import androidx.testing.TestMessageProto.FooProto
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
import com.google.protobuf.ExtensionRegistryLite
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Rule
+import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/datastore/datastore-rxjava2/build.gradle b/datastore/datastore-rxjava2/build.gradle
index 20edf8fb..f2354c5 100644
--- a/datastore/datastore-rxjava2/build.gradle
+++ b/datastore/datastore-rxjava2/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "Android DataStore Core RxJava2 Wrappers"
+ name = "DataStore RxJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreDelegateTest.kt b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreDelegateTest.kt
index f0ec624..fb05a48 100644
--- a/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreDelegateTest.kt
+++ b/datastore/datastore-rxjava2/src/androidTest/java/androidx/datastore/rxjava2/RxDataStoreDelegateTest.kt
@@ -22,13 +22,13 @@
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import io.reactivex.Single
+import java.io.File
+import java.io.FileOutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.io.FileOutputStream
val Context.rxDataStore by rxDataStore("file1", TestingSerializer())
diff --git a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
index dfe8026..468b761 100644
--- a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
+++ b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStore.kt
@@ -21,16 +21,16 @@
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.disposables.Disposable
+import io.reactivex.functions.Function
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
+import kotlinx.coroutines.job
import kotlinx.coroutines.rx2.asFlowable
import kotlinx.coroutines.rx2.asSingle
import kotlinx.coroutines.rx2.await
-import io.reactivex.functions.Function
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.job
import kotlinx.coroutines.rx2.rxCompletable
/**
diff --git a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
index 1dee9d1..cf20f5e 100644
--- a/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
+++ b/datastore/datastore-rxjava2/src/main/java/androidx/datastore/rxjava2/RxDataStoreBuilder.kt
@@ -25,12 +25,12 @@
import androidx.datastore.dataStoreFile
import io.reactivex.Scheduler
import io.reactivex.schedulers.Schedulers
+import java.io.File
+import java.util.concurrent.Callable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.rx2.asCoroutineDispatcher
import kotlinx.coroutines.rx2.await
-import java.io.File
-import java.util.concurrent.Callable
/**
* Builder class for an RxDataStore that works on a single process.
diff --git a/datastore/datastore-rxjava3/build.gradle b/datastore/datastore-rxjava3/build.gradle
index c9bfe85..8de1572 100644
--- a/datastore/datastore-rxjava3/build.gradle
+++ b/datastore/datastore-rxjava3/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "Android DataStore Core RxJava2 Wrappers"
+ name = "DataStore RxJava3"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-rxjava3/src/androidTest/java/androidx/datastore/rxjava3/RxDataStoreDelegateTest.kt b/datastore/datastore-rxjava3/src/androidTest/java/androidx/datastore/rxjava3/RxDataStoreDelegateTest.kt
index dadae22..aca2cd7 100644
--- a/datastore/datastore-rxjava3/src/androidTest/java/androidx/datastore/rxjava3/RxDataStoreDelegateTest.kt
+++ b/datastore/datastore-rxjava3/src/androidTest/java/androidx/datastore/rxjava3/RxDataStoreDelegateTest.kt
@@ -22,13 +22,13 @@
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import io.reactivex.rxjava3.core.Single
+import java.io.File
+import java.io.FileOutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.io.FileOutputStream
val Context.rxDataStore by rxDataStore("file1", TestingSerializer())
diff --git a/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt b/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
index 8e05c50..68365dd 100644
--- a/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
+++ b/datastore/datastore-rxjava3/src/main/java/androidx/datastore/rxjava3/RxDataStoreBuilder.kt
@@ -25,12 +25,12 @@
import androidx.datastore.dataStoreFile
import io.reactivex.rxjava3.core.Scheduler
import io.reactivex.rxjava3.schedulers.Schedulers
+import java.io.File
+import java.util.concurrent.Callable
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.rx3.asCoroutineDispatcher
import kotlinx.coroutines.rx3.await
-import java.io.File
-import java.util.concurrent.Callable
/**
* Builder class for an RxDataStore that works on a single process.
diff --git a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/KotlinSerializationActivity.kt b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/KotlinSerializationActivity.kt
index 1d78255..e1057f7 100644
--- a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/KotlinSerializationActivity.kt
+++ b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/KotlinSerializationActivity.kt
@@ -27,6 +27,10 @@
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.Serializer
import androidx.lifecycle.lifecycleScope
+import java.io.File
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -38,11 +42,6 @@
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
-import java.io.File
-import java.io.IOException
-import java.io.InputStream
-import java.io.OutputStream
-
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
class KotlinSerializationActivity : AppCompatActivity() {
private val TAG = "SerializationActivity"
diff --git a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/PreferencesDataStoreActivity.kt b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/PreferencesDataStoreActivity.kt
index b8ed192..3ff3a6a 100644
--- a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/PreferencesDataStoreActivity.kt
+++ b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/PreferencesDataStoreActivity.kt
@@ -28,12 +28,12 @@
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import androidx.lifecycle.lifecycleScope
+import java.io.IOException
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-import java.io.IOException
val Context.prefsDs by preferencesDataStore("datastore_test_app")
diff --git a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/ProtoDataStoreActivity.kt b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/ProtoDataStoreActivity.kt
index 1bce259..476e5be 100644
--- a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/ProtoDataStoreActivity.kt
+++ b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/ProtoDataStoreActivity.kt
@@ -28,15 +28,15 @@
import androidx.datastore.core.Serializer
import androidx.lifecycle.lifecycleScope
import com.google.protobuf.InvalidProtocolBufferException
+import java.io.File
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-import java.io.File
-import java.io.IOException
-import java.io.InputStream
-import java.io.OutputStream
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
class ProtoDataStoreActivity : AppCompatActivity() {
diff --git a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/SettingsFragment.kt b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/SettingsFragment.kt
index 246dbae..0b68e58 100644
--- a/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/SettingsFragment.kt
+++ b/datastore/datastore-sampleapp/src/main/java/com/example/datastoresampleapp/SettingsFragment.kt
@@ -27,13 +27,17 @@
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.Serializer
import androidx.lifecycle.Lifecycle
-import androidx.preference.Preference
-import androidx.preference.SwitchPreference
-import androidx.preference.PreferenceFragmentCompat
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import androidx.preference.Preference
+import androidx.preference.PreferenceFragmentCompat
+import androidx.preference.SwitchPreference
import androidx.preference.TwoStatePreference
import com.google.protobuf.InvalidProtocolBufferException
+import java.io.File
+import java.io.IOException
+import java.io.InputStream
+import java.io.OutputStream
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@@ -42,10 +46,6 @@
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
-import java.io.File
-import java.io.IOException
-import java.io.InputStream
-import java.io.OutputStream
private val TAG = "SettingsActivity"
diff --git a/datastore/datastore/build.gradle b/datastore/datastore/build.gradle
index d450a9b..8b4451d 100644
--- a/datastore/datastore/build.gradle
+++ b/datastore/datastore/build.gradle
@@ -106,7 +106,7 @@
}
androidx {
- name = "Android DataStore"
+ name = "DataStore"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2020"
description = "Android DataStore - contains the underlying store used by each serialization " +
diff --git a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreDelegateTest.kt b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreDelegateTest.kt
index 68b88be..11ace8e 100644
--- a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreDelegateTest.kt
+++ b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreDelegateTest.kt
@@ -23,6 +23,9 @@
import androidx.test.filters.SdkSuppress
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.io.FileOutputStream
+import java.lang.IllegalStateException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
@@ -33,9 +36,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
-import java.io.FileOutputStream
-import java.lang.IllegalStateException
val Context.globalDs by dataStore("file1", TestingSerializer())
diff --git a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreFileTest.kt b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreFileTest.kt
index 3f8806b..7eca1d1 100644
--- a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreFileTest.kt
+++ b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/DataStoreFileTest.kt
@@ -19,8 +19,8 @@
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.io.File
+import org.junit.Test
class DataStoreFileTest {
@Test
diff --git a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/migrations/SharedPreferencesMigrationTest.kt b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/migrations/SharedPreferencesMigrationTest.kt
index a0a2452..51dd177 100644
--- a/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/migrations/SharedPreferencesMigrationTest.kt
+++ b/datastore/datastore/src/androidAndroidTest/kotlin/androidx/datastore/migrations/SharedPreferencesMigrationTest.kt
@@ -18,15 +18,16 @@
import android.content.Context
import android.content.SharedPreferences
+import androidx.datastore.TestingSerializer
import androidx.datastore.core.DataMigration
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
-import androidx.datastore.TestingSerializer
import androidx.datastore.dataStore
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.MediumTest
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import java.io.File
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestScope
@@ -36,7 +37,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
-import java.io.File
private const val sharedPrefsName = "shared_prefs_name"
diff --git a/datastore/datastore/src/androidMain/kotlin/androidx/datastore/DataStoreDelegate.kt b/datastore/datastore/src/androidMain/kotlin/androidx/datastore/DataStoreDelegate.kt
index b53904f..aa35674 100644
--- a/datastore/datastore/src/androidMain/kotlin/androidx/datastore/DataStoreDelegate.kt
+++ b/datastore/datastore/src/androidMain/kotlin/androidx/datastore/DataStoreDelegate.kt
@@ -21,15 +21,15 @@
import androidx.datastore.core.DataMigration
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
-import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.core.Serializer
+import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.core.okio.OkioSerializer
import androidx.datastore.core.okio.OkioStorage
+import kotlin.properties.ReadOnlyProperty
+import kotlin.reflect.KProperty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
-import kotlin.properties.ReadOnlyProperty
-import kotlin.reflect.KProperty
import okio.BufferedSink
import okio.BufferedSource
import okio.FileSystem
diff --git a/datastore/datastore/src/androidMain/kotlin/androidx/datastore/migrations/SharedPreferencesMigration.kt b/datastore/datastore/src/androidMain/kotlin/androidx/datastore/migrations/SharedPreferencesMigration.kt
index 4fc7b7c..2bb5174 100644
--- a/datastore/datastore/src/androidMain/kotlin/androidx/datastore/migrations/SharedPreferencesMigration.kt
+++ b/datastore/datastore/src/androidMain/kotlin/androidx/datastore/migrations/SharedPreferencesMigration.kt
@@ -16,10 +16,10 @@
package androidx.datastore.migrations
-import androidx.annotation.DoNotInline
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
+import androidx.annotation.DoNotInline
import androidx.annotation.RequiresApi
import androidx.datastore.core.DataMigration
import java.io.File
diff --git a/development/build_log_simplifier/messages.ignore b/development/build_log_simplifier/messages.ignore
index ce7f919..10836a5 100644
--- a/development/build_log_simplifier/messages.ignore
+++ b/development/build_log_simplifier/messages.ignore
@@ -122,6 +122,14 @@
WARN: Missing @param tag for parameter `autoMirror` of function androidx\.compose\.ui\.graphics\.vector//rememberVectorPainter/\#androidx\.compose\.ui\.unit\.Dp\#androidx\.compose\.ui\.unit\.Dp\#kotlin\.Float\#kotlin\.Float\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.BlendMode\#kotlin\.Boolean\#kotlin\.Function[0-9]+\[kotlin\.Float,kotlin\.Float,kotlin\.Unit\]/PointingToDeclaration/
WARN: Missing @param tag for parameter `trimPathEnd` of function androidx\.compose\.ui\.graphics\.vector/ImageVector\.Builder/addPath/\#kotlin\.collections\.List\[androidx\.compose\.ui\.graphics\.vector\.PathNode\]\#androidx\.compose\.ui\.graphics\.PathFillType\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.StrokeCap\#androidx\.compose\.ui\.graphics\.StrokeJoin\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float\#kotlin\.Float/PointingToDeclaration/
WARN: Missing @param tag for parameter `pathFillType` of function androidx\.compose\.ui\.graphics\.vector/ImageVector\.Builder/path/androidx\.compose\.ui\.graphics\.vector\.ImageVector\.Builder\#kotlin\.String\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.Brush\?\#kotlin\.Float\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.StrokeCap\#androidx\.compose\.ui\.graphics\.StrokeJoin\#kotlin\.Float\#androidx\.compose\.ui\.graphics\.PathFillType\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.vector\.PathBuilder,kotlin\.Unit\]/PointingToDeclaration/
+WARN: Failed to resolve `@see SdkSandboxManager\.startSdkSandboxActivity`!
+Did you mean SdkSandboxManager\#startSdkSandboxActivity\?
+WARN: Failed to resolve `@see SdkSandboxActivityHandler\.onActivityCreated`!
+Did you mean SdkSandboxActivityHandler\#onActivityCreated\?
+WARN: Failed to resolve `@see SdkSandboxController\.registerSdkSandboxActivityHandler`!
+Did you mean SdkSandboxController\#registerSdkSandboxActivityHandler\?
+WARN: Failed to resolve `@see SdkSandboxController\.unregisterSdkSandboxActivityHandler`!
+Did you mean SdkSandboxController\#unregisterSdkSandboxActivityHandler\?
WARN: Missing @param tag for parameter `position` of function androidx\.compose\.ui\.layout/Placeable/placeAt/\#androidx\.compose\.ui\.unit\.IntOffset\#kotlin\.Float\#kotlin\.Function[0-9]+\[androidx\.compose\.ui\.graphics\.GraphicsLayerScope,kotlin\.Unit\]\?/PointingToDeclaration/
WARN: Missing @param tag for parameter `x` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/place/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
WARN: Missing @param tag for parameter `y` of function androidx\.compose\.ui\.layout/Placeable\.PlacementScope/place/androidx\.compose\.ui\.layout\.Placeable\#kotlin\.Int\#kotlin\.Int\#kotlin\.Float/PointingToDeclaration/
@@ -189,6 +197,7 @@
WARN: Missing @param tag for parameter `content` of function androidx\.wear\.compose\.material[0-9]+//MaterialTheme/\#androidx\.wear\.compose\.material[0-9]+\.ColorScheme\#androidx\.wear\.compose\.material[0-9]+\.Typography\#androidx\.wear\.compose\.material[0-9]+\.Shapes\#kotlin\.Function[0-9]+\[kotlin\.Unit\]/PointingToDeclaration/
WARN: Missing @param tag for parameter `content` of function androidx\.wear\.compose\.material[0-9]+//OutlinedButton/\#kotlin\.Function[0-9]+\[kotlin\.Unit\]\#androidx\.compose\.ui\.Modifier\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Shape\#androidx\.wear\.compose\.material[0-9]+\.ButtonColors\#androidx\.compose\.foundation\.BorderStroke\?\#androidx\.compose\.foundation\.layout\.PaddingValues\#androidx\.compose\.foundation\.interaction\.MutableInteractionSource\#androidx\.compose\.ui\.semantics\.Role\?\#kotlin\.Function[0-9]+\[androidx\.compose\.foundation\.layout\.RowScope,kotlin\.Unit\]/PointingToDeclaration/
WARN: Missing @param tag for parameter `enabled` of function androidx\.wear\.compose\.material[0-9]+/ButtonDefaults/outlinedButtonBorder/\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
+WARN: Missing @param tag for parameter `enabled` of function androidx\.wear\.compose\.material[0-9]+/IconButtonDefaults/outlinedIconButtonBorder/\#kotlin\.Boolean\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.graphics\.Color\#androidx\.compose\.ui\.unit\.Dp/PointingToDeclaration/
WARN: Unable to find what is referred to by
# > Task :docs-tip-of-tree:dackkaDocs
WARN\: Failed to resolve \`\@see SplitAttributes\.shouldExpandSecondaryContainer\`\!
diff --git a/development/project-creator/compose-template/groupId/artifactId/build.gradle b/development/project-creator/compose-template/groupId/artifactId/build.gradle
index a47774d..e09ec31 100644
--- a/development/project-creator/compose-template/groupId/artifactId/build.gradle
+++ b/development/project-creator/compose-template/groupId/artifactId/build.gradle
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-import androidx.build.AndroidXComposePlugin
import androidx.build.LibraryType
+import androidx.build.KmpPlatformsKt
plugins {
id("AndroidXPlugin")
@@ -24,68 +24,75 @@
id("org.jetbrains.kotlin.android")
}
-AndroidXComposePlugin.applyAndConfigureKotlinPlugin(project)
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
-dependencies {
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
-
- if(!AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block below
- */
- implementation(libs.kotlinStdlibCommon)
-
- api("androidx.annotation:annotation:1.1.0")
-
- testImplementation(libs.testRules)
- testImplementation(libs.testRunner)
- testImplementation(libs.junit)
- testImplementation(libs.truth)
-
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.junit)
- androidTestImplementation(libs.truth)
- }
-}
-
-if(AndroidXComposePlugin.isMultiplatformEnabled(project)) {
- androidXComposeMultiplatform {
- android()
- desktop()
- }
-
- kotlin {
- /*
- * When updating dependencies, make sure to make the an an analogous update in the
- * corresponding block above
- */
- sourceSets {
- commonMain.dependencies {
+ sourceSets {
+ commonMain {
+ dependencies {
implementation(libs.kotlinStdlibCommon)
}
+ }
+ androidMain.dependencies {
+ }
- androidMain.dependencies {
+ commonTest {
+ dependencies {
+ }
+ }
+
+ jvmMain {
+ dependsOn(commonMain)
+ dependencies {
+ implementation(libs.testRules)
+ implementation(libs.testRunner)
+ implementation(libs.junit)
+ implementation(libs.truth)
+ }
+ }
+
+
+ androidMain {
+ dependsOn(jvmMain)
+ dependencies {
api("androidx.annotation:annotation:1.1.0")
}
+ }
- desktopMain.dependencies {
- implementation(libs.kotlinStdlib)
+ if (desktopEnabled) {
+ desktopMain {
+ dependsOn(jvmMain)
+ dependencies {
+ implementation(libs.kotlinStdlib)
+ }
}
+ }
- test.dependencies {
+ jvmTest {
+ dependsOn(commonTest)
+ dependencies {
+ }
+ }
+
+ androidAndroidTest {
+ dependsOn(jvmTest)
+ dependencies {
implementation(libs.testRules)
implementation(libs.testRunner)
implementation(libs.junit)
implementation(libs.truth)
}
+ }
- androidAndroidTest.dependencies {
- implementation(libs.testRules)
- implementation(libs.testRunner)
- implementation(libs.junit)
- implementation(libs.truth)
+ if (desktopEnabled) {
+ desktopTest {
+ dependsOn(jvmTest)
+ dependsOn(desktopMain)
+ dependencies {
+ }
}
}
}
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 569d1ac..d082aaf 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -8,10 +8,10 @@
}
dependencies {
- docs("androidx.activity:activity:1.8.0-alpha03")
- docs("androidx.activity:activity-compose:1.8.0-alpha03")
- samples("androidx.activity:activity-compose-samples:1.8.0-alpha03")
- docs("androidx.activity:activity-ktx:1.8.0-alpha03")
+ docs("androidx.activity:activity:1.8.0-alpha04")
+ docs("androidx.activity:activity-compose:1.8.0-alpha04")
+ samples("androidx.activity:activity-compose-samples:1.8.0-alpha04")
+ docs("androidx.activity:activity-ktx:1.8.0-alpha04")
docs("androidx.ads:ads-identifier:1.0.0-alpha05")
docs("androidx.ads:ads-identifier-common:1.0.0-alpha05")
docs("androidx.ads:ads-identifier-provider:1.0.0-alpha05")
@@ -55,55 +55,55 @@
docs("androidx.cardview:cardview:1.0.0")
kmpDocs("androidx.collection:collection:1.3.0-alpha03")
docs("androidx.collection:collection-ktx:1.3.0-alpha03")
- docs("androidx.compose.animation:animation:1.5.0-alpha03")
- docs("androidx.compose.animation:animation-core:1.5.0-alpha03")
- docs("androidx.compose.animation:animation-graphics:1.5.0-alpha03")
- samples("androidx.compose.animation:animation-samples:1.5.0-alpha03")
- samples("androidx.compose.animation:animation-core-samples:1.5.0-alpha03")
- samples("androidx.compose.animation:animation-graphics-samples:1.5.0-alpha03")
- docs("androidx.compose.foundation:foundation:1.5.0-alpha03")
- docs("androidx.compose.foundation:foundation-layout:1.5.0-alpha03")
- samples("androidx.compose.foundation:foundation-layout-samples:1.5.0-alpha03")
- samples("androidx.compose.foundation:foundation-samples:1.5.0-alpha03")
- docs("androidx.compose.material3:material3:1.1.0-rc01")
- samples("androidx.compose.material3:material3-samples:1.1.0-rc01")
- docs("androidx.compose.material3:material3-window-size-class:1.1.0-rc01")
- samples("androidx.compose.material3:material3-window-size-class-samples:1.1.0-rc01")
- docs("androidx.compose.material:material:1.5.0-alpha03")
- docs("androidx.compose.material:material-icons-core:1.5.0-alpha03")
- samples("androidx.compose.material:material-icons-core-samples:1.5.0-alpha03")
- docs("androidx.compose.material:material-ripple:1.5.0-alpha03")
- samples("androidx.compose.material:material-samples:1.5.0-alpha03")
- docs("androidx.compose.runtime:runtime:1.5.0-alpha03")
- docs("androidx.compose.runtime:runtime-livedata:1.5.0-alpha03")
- samples("androidx.compose.runtime:runtime-livedata-samples:1.5.0-alpha03")
- docs("androidx.compose.runtime:runtime-rxjava2:1.5.0-alpha03")
- samples("androidx.compose.runtime:runtime-rxjava2-samples:1.5.0-alpha03")
- docs("androidx.compose.runtime:runtime-rxjava3:1.5.0-alpha03")
- samples("androidx.compose.runtime:runtime-rxjava3-samples:1.5.0-alpha03")
- docs("androidx.compose.runtime:runtime-saveable:1.5.0-alpha03")
- samples("androidx.compose.runtime:runtime-saveable-samples:1.5.0-alpha03")
- samples("androidx.compose.runtime:runtime-samples:1.5.0-alpha03")
+ docs("androidx.compose.animation:animation:1.5.0-alpha04")
+ docs("androidx.compose.animation:animation-core:1.5.0-alpha04")
+ docs("androidx.compose.animation:animation-graphics:1.5.0-alpha04")
+ samples("androidx.compose.animation:animation-samples:1.5.0-alpha04")
+ samples("androidx.compose.animation:animation-core-samples:1.5.0-alpha04")
+ samples("androidx.compose.animation:animation-graphics-samples:1.5.0-alpha04")
+ docs("androidx.compose.foundation:foundation:1.5.0-alpha04")
+ docs("androidx.compose.foundation:foundation-layout:1.5.0-alpha04")
+ samples("androidx.compose.foundation:foundation-layout-samples:1.5.0-alpha04")
+ samples("androidx.compose.foundation:foundation-samples:1.5.0-alpha04")
+ docs("androidx.compose.material3:material3:1.2.0-alpha01")
+ samples("androidx.compose.material3:material3-samples:1.2.0-alpha01")
+ docs("androidx.compose.material3:material3-window-size-class:1.2.0-alpha01")
+ samples("androidx.compose.material3:material3-window-size-class-samples:1.2.0-alpha01")
+ docs("androidx.compose.material:material:1.5.0-alpha04")
+ docs("androidx.compose.material:material-icons-core:1.5.0-alpha04")
+ samples("androidx.compose.material:material-icons-core-samples:1.5.0-alpha04")
+ docs("androidx.compose.material:material-ripple:1.5.0-alpha04")
+ samples("androidx.compose.material:material-samples:1.5.0-alpha04")
+ docs("androidx.compose.runtime:runtime:1.5.0-alpha04")
+ docs("androidx.compose.runtime:runtime-livedata:1.5.0-alpha04")
+ samples("androidx.compose.runtime:runtime-livedata-samples:1.5.0-alpha04")
+ docs("androidx.compose.runtime:runtime-rxjava2:1.5.0-alpha04")
+ samples("androidx.compose.runtime:runtime-rxjava2-samples:1.5.0-alpha04")
+ docs("androidx.compose.runtime:runtime-rxjava3:1.5.0-alpha04")
+ samples("androidx.compose.runtime:runtime-rxjava3-samples:1.5.0-alpha04")
+ docs("androidx.compose.runtime:runtime-saveable:1.5.0-alpha04")
+ samples("androidx.compose.runtime:runtime-saveable-samples:1.5.0-alpha04")
+ samples("androidx.compose.runtime:runtime-samples:1.5.0-alpha04")
docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha03")
- docs("androidx.compose.ui:ui:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-geometry:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-graphics:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-graphics-samples:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-test:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-test-junit4:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-test-samples:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-text:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-text-google-fonts:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-text-samples:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-tooling:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-tooling-data:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-tooling-preview:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-unit:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-unit-samples:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-util:1.5.0-alpha03")
- docs("androidx.compose.ui:ui-viewbinding:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-viewbinding-samples:1.5.0-alpha03")
- samples("androidx.compose.ui:ui-samples:1.5.0-alpha03")
+ docs("androidx.compose.ui:ui:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-geometry:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-graphics:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-graphics-samples:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-test:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-test-junit4:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-test-samples:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-text:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-text-google-fonts:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-text-samples:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-tooling:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-tooling-data:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-tooling-preview:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-unit:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-unit-samples:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-util:1.5.0-alpha04")
+ docs("androidx.compose.ui:ui-viewbinding:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-viewbinding-samples:1.5.0-alpha04")
+ samples("androidx.compose.ui:ui-samples:1.5.0-alpha04")
docs("androidx.concurrent:concurrent-futures:1.2.0-alpha01")
docs("androidx.concurrent:concurrent-futures-ktx:1.2.0-alpha01")
docs("androidx.constraintlayout:constraintlayout:2.2.0-alpha09")
@@ -116,11 +116,11 @@
docs("androidx.core:core-google-shortcuts:1.1.0")
docs("androidx.core:core-performance:1.0.0-alpha03")
samples("androidx.core:core-performance-samples:1.0.0-alpha03")
- docs("androidx.core:core-remoteviews:1.0.0-beta03")
+ docs("androidx.core:core-remoteviews:1.0.0-beta04")
docs("androidx.core:core-role:1.2.0-alpha01")
docs("androidx.core:core-animation:1.0.0-beta02")
docs("androidx.core:core-animation-testing:1.0.0-beta01")
- docs("androidx.core:core:1.12.0-alpha03")
+ docs("androidx.core:core:1.12.0-alpha04")
docs("androidx.core:core-ktx:1.12.0-alpha03")
docs("androidx.core:core-splashscreen:1.1.0-alpha01")
docs("androidx.core:core-testing:1.12.0-alpha03")
@@ -144,27 +144,28 @@
docs("androidx.drawerlayout:drawerlayout:1.2.0")
docs("androidx.dynamicanimation:dynamicanimation:1.1.0-alpha02")
docs("androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03")
- docs("androidx.emoji2:emoji2:1.4.0-beta02")
- docs("androidx.emoji2:emoji2-bundled:1.4.0-beta02")
- docs("androidx.emoji2:emoji2-emojipicker:1.4.0-beta02")
- docs("androidx.emoji2:emoji2-views:1.4.0-beta02")
- docs("androidx.emoji2:emoji2-views-helper:1.4.0-beta02")
+ docs("androidx.emoji2:emoji2:1.4.0-beta03")
+ docs("androidx.emoji2:emoji2-bundled:1.4.0-beta03")
+ docs("androidx.emoji2:emoji2-emojipicker:1.4.0-beta03")
+ docs("androidx.emoji2:emoji2-views:1.4.0-beta03")
+ docs("androidx.emoji2:emoji2-views-helper:1.4.0-beta03")
docs("androidx.emoji:emoji:1.2.0-alpha03")
docs("androidx.emoji:emoji-appcompat:1.2.0-alpha03")
docs("androidx.emoji:emoji-bundled:1.2.0-alpha03")
docs("androidx.enterprise:enterprise-feedback:1.1.0")
docs("androidx.enterprise:enterprise-feedback-testing:1.1.0")
docs("androidx.exifinterface:exifinterface:1.3.6")
- docs("androidx.fragment:fragment:1.6.0-beta01")
- docs("androidx.fragment:fragment-ktx:1.6.0-beta01")
- docs("androidx.fragment:fragment-testing:1.6.0-beta01")
- docs("androidx.glance:glance:1.0.0-alpha05")
- docs("androidx.glance:glance-appwidget:1.0.0-alpha05")
- docs("androidx.glance:glance-appwidget-preview:1.0.0-alpha05")
+ docs("androidx.fragment:fragment:1.6.0-rc01")
+ docs("androidx.fragment:fragment-ktx:1.6.0-rc01")
+ docs("androidx.fragment:fragment-testing:1.6.0-rc01")
+ docs("androidx.glance:glance:1.0.0-beta01")
+ samples("androidx.glance:glance-appwidget-samples:1.0.0-beta01")
+ docs("androidx.glance:glance-appwidget:1.0.0-beta01")
+ docs("androidx.glance:glance-appwidget-preview:1.0.0-alpha06")
docs("androidx.glance:glance-appwidget-proto:1.0.0-alpha03")
- docs("androidx.glance:glance-preview:1.0.0-alpha05")
- docs("androidx.glance:glance-wear-tiles:1.0.0-alpha05")
- docs("androidx.glance:glance-wear-tiles-preview:1.0.0-alpha05")
+ docs("androidx.glance:glance-preview:1.0.0-alpha06")
+ docs("androidx.glance:glance-wear-tiles:1.0.0-alpha06")
+ docs("androidx.glance:glance-wear-tiles-preview:1.0.0-alpha06")
docs("androidx.graphics:graphics-core:1.0.0-alpha03")
docs("androidx.gridlayout:gridlayout:1.1.0-alpha01")
docs("androidx.health.connect:connect-client:1.0.0-alpha11")
@@ -239,19 +240,19 @@
docs("androidx.mediarouter:mediarouter:1.6.0-alpha03")
docs("androidx.mediarouter:mediarouter-testing:1.6.0-alpha03")
docs("androidx.metrics:metrics-performance:1.0.0-alpha04")
- docs("androidx.navigation:navigation-common:2.6.0-beta01")
- docs("androidx.navigation:navigation-common-ktx:2.6.0-beta01")
- docs("androidx.navigation:navigation-compose:2.6.0-beta01")
- samples("androidx.navigation:navigation-compose-samples:2.6.0-beta01")
- docs("androidx.navigation:navigation-dynamic-features-fragment:2.6.0-beta01")
- docs("androidx.navigation:navigation-dynamic-features-runtime:2.6.0-beta01")
- docs("androidx.navigation:navigation-fragment:2.6.0-beta01")
- docs("androidx.navigation:navigation-fragment-ktx:2.6.0-beta01")
- docs("androidx.navigation:navigation-runtime:2.6.0-beta01")
- docs("androidx.navigation:navigation-runtime-ktx:2.6.0-beta01")
- docs("androidx.navigation:navigation-testing:2.6.0-beta01")
- docs("androidx.navigation:navigation-ui:2.6.0-beta01")
- docs("androidx.navigation:navigation-ui-ktx:2.6.0-beta01")
+ docs("androidx.navigation:navigation-common:2.6.0-rc01")
+ docs("androidx.navigation:navigation-common-ktx:2.6.0-rc01")
+ docs("androidx.navigation:navigation-compose:2.6.0-rc01")
+ samples("androidx.navigation:navigation-compose-samples:2.6.0-rc01")
+ docs("androidx.navigation:navigation-dynamic-features-fragment:2.6.0-rc01")
+ docs("androidx.navigation:navigation-dynamic-features-runtime:2.6.0-rc01")
+ docs("androidx.navigation:navigation-fragment:2.6.0-rc01")
+ docs("androidx.navigation:navigation-fragment-ktx:2.6.0-rc01")
+ docs("androidx.navigation:navigation-runtime:2.6.0-rc01")
+ docs("androidx.navigation:navigation-runtime-ktx:2.6.0-rc01")
+ docs("androidx.navigation:navigation-testing:2.6.0-rc01")
+ docs("androidx.navigation:navigation-ui:2.6.0-rc01")
+ docs("androidx.navigation:navigation-ui-ktx:2.6.0-rc01")
docs("androidx.paging:paging-common:3.2.0-alpha05")
docs("androidx.paging:paging-common-ktx:3.2.0-alpha05")
docs("androidx.paging:paging-compose:1.0.0-alpha19")
@@ -270,10 +271,10 @@
docs("androidx.preference:preference:1.2.0")
docs("androidx.preference:preference-ktx:1.2.0")
docs("androidx.print:print:1.1.0-beta01")
- docs("androidx.privacysandbox.ads:ads-adservices:1.0.0-beta03")
- docs("androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta03")
- docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha03")
- docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha03")
+ docs("androidx.privacysandbox.ads:ads-adservices:1.0.0-beta04")
+ docs("androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta04")
+ docs("androidx.privacysandbox.sdkruntime:sdkruntime-client:1.0.0-alpha04")
+ docs("androidx.privacysandbox.sdkruntime:sdkruntime-core:1.0.0-alpha04")
docs("androidx.privacysandbox.tools:tools:1.0.0-alpha03")
docs("androidx.privacysandbox.tools:tools-apigenerator:1.0.0-alpha03")
docs("androidx.privacysandbox.tools:tools-apipackager:1.0.0-alpha03")
@@ -343,8 +344,8 @@
docs("androidx.tracing:tracing-ktx:1.2.0-beta04")
docs("androidx.tracing:tracing-perfetto:1.0.0-alpha15")
docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha15")
- docs("androidx.transition:transition:1.4.1")
- docs("androidx.transition:transition-ktx:1.4.1")
+ docs("androidx.transition:transition:1.5.0-alpha01")
+ docs("androidx.transition:transition-ktx:1.5.0-alpha01")
docs("androidx.tv:tv-foundation:1.0.0-alpha06")
docs("androidx.tv:tv-material:1.0.0-alpha06")
samples("androidx.tv:tv-samples:1.0.0-alpha06")
@@ -355,27 +356,27 @@
docs("androidx.versionedparcelable:versionedparcelable:1.1.1")
docs("androidx.viewpager2:viewpager2:1.1.0-beta01")
docs("androidx.viewpager:viewpager:1.1.0-alpha01")
- docs("androidx.wear.compose:compose-foundation:1.2.0-alpha09")
- samples("androidx.wear.compose:compose-foundation-samples:1.2.0-alpha09")
- docs("androidx.wear.compose:compose-material:1.2.0-alpha09")
- docs("androidx.wear.compose:compose-material-core:1.2.0-alpha09")
- samples("androidx.wear.compose:compose-material-samples:1.2.0-alpha09")
- docs("androidx.wear.compose:compose-material3:1.0.0-alpha03")
- samples("androidx.wear.compose:compose-material3-samples:1.2.0-alpha09")
- docs("androidx.wear.compose:compose-navigation:1.2.0-alpha09")
- samples("androidx.wear.compose:compose-navigation-samples:1.2.0-alpha09")
- docs("androidx.wear.compose:compose-ui-tooling:1.2.0-alpha09")
- docs("androidx.wear.protolayout:protolayout:1.0.0-alpha08")
- docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha08")
- docs("androidx.wear.protolayout:protolayout-material:1.0.0-alpha08")
- docs("androidx.wear.protolayout:protolayout-proto:1.0.0-alpha08")
- docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha08")
- docs("androidx.wear.tiles:tiles:1.2.0-alpha04")
- docs("androidx.wear.tiles:tiles-material:1.2.0-alpha04")
- docs("androidx.wear.tiles:tiles-proto:1.2.0-alpha04")
- docs("androidx.wear.tiles:tiles-renderer:1.2.0-alpha04")
- docs("androidx.wear.tiles:tiles-testing:1.2.0-alpha04")
- docs("androidx.wear.tiles:tiles-tooling:1.2.0-alpha04")
+ docs("androidx.wear.compose:compose-foundation:1.2.0-alpha10")
+ samples("androidx.wear.compose:compose-foundation-samples:1.2.0-alpha10")
+ docs("androidx.wear.compose:compose-material:1.2.0-alpha10")
+ docs("androidx.wear.compose:compose-material-core:1.2.0-alpha10")
+ samples("androidx.wear.compose:compose-material-samples:1.2.0-alpha10")
+ docs("androidx.wear.compose:compose-material3:1.0.0-alpha04")
+ samples("androidx.wear.compose:compose-material3-samples:1.2.0-alpha10")
+ docs("androidx.wear.compose:compose-navigation:1.2.0-alpha10")
+ samples("androidx.wear.compose:compose-navigation-samples:1.2.0-alpha10")
+ docs("androidx.wear.compose:compose-ui-tooling:1.2.0-alpha10")
+ docs("androidx.wear.protolayout:protolayout:1.0.0-alpha09")
+ docs("androidx.wear.protolayout:protolayout-expression:1.0.0-alpha09")
+ docs("androidx.wear.protolayout:protolayout-material:1.0.0-alpha09")
+ docs("androidx.wear.protolayout:protolayout-proto:1.0.0-alpha09")
+ docs("androidx.wear.protolayout:protolayout-renderer:1.0.0-alpha09")
+ docs("androidx.wear.tiles:tiles:1.2.0-alpha05")
+ docs("androidx.wear.tiles:tiles-material:1.2.0-alpha05")
+ docs("androidx.wear.tiles:tiles-proto:1.2.0-alpha05")
+ docs("androidx.wear.tiles:tiles-renderer:1.2.0-alpha05")
+ docs("androidx.wear.tiles:tiles-testing:1.2.0-alpha05")
+ docs("androidx.wear.tiles:tiles-tooling:1.2.0-alpha05")
docs("androidx.wear.watchface:watchface:1.2.0-alpha08")
docs("androidx.wear.watchface:watchface-client:1.2.0-alpha08")
docs("androidx.wear.watchface:watchface-client-guava:1.2.0-alpha08")
@@ -400,17 +401,17 @@
docs("androidx.wear:wear-input:1.2.0-alpha02")
samples("androidx.wear:wear-input-samples:1.2.0-alpha01")
docs("androidx.wear:wear-input-testing:1.2.0-alpha02")
- docs("androidx.webkit:webkit:1.7.0-beta01")
+ docs("androidx.webkit:webkit:1.7.0-rc01")
docs("androidx.window.extensions.core:core:1.0.0-rc01")
- docs("androidx.window:window:1.1.0-beta02")
+ docs("androidx.window:window:1.1.0-rc01")
stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
- docs("androidx.window:window-core:1.1.0-beta02")
+ docs("androidx.window:window-core:1.1.0-rc01")
stubs("androidx.window:window-extensions:1.0.0-alpha01")
- docs("androidx.window:window-java:1.1.0-beta02")
- docs("androidx.window:window-rxjava2:1.1.0-beta02")
- docs("androidx.window:window-rxjava3:1.1.0-beta02")
- samples("androidx.window:window-samples:1.1.0-beta02")
- docs("androidx.window:window-testing:1.1.0-beta02")
+ docs("androidx.window:window-java:1.1.0-rc01")
+ docs("androidx.window:window-rxjava2:1.1.0-rc01")
+ docs("androidx.window:window-rxjava3:1.1.0-rc01")
+ samples("androidx.window:window-samples:1.1.0-rc01")
+ docs("androidx.window:window-testing:1.1.0-rc01")
docs("androidx.work:work-gcm:2.8.1")
docs("androidx.work:work-multiprocess:2.8.1")
docs("androidx.work:work-runtime:2.8.1")
diff --git a/docs-tip-of-tree/build.gradle b/docs-tip-of-tree/build.gradle
index c221e4d..e62e0d7 100644
--- a/docs-tip-of-tree/build.gradle
+++ b/docs-tip-of-tree/build.gradle
@@ -53,9 +53,10 @@
stubs(fileTree(dir: "../camera/camera-extensions-stub", include: ["camera-extensions-stub.jar"]))
docs(project(":camera:camera-mlkit-vision"))
docs(project(":camera:camera-lifecycle"))
- docs(project(":camera:camera-viewfinder"))
docs(project(":camera:camera-video"))
docs(project(":camera:camera-view"))
+ docs(project(":camera:camera-viewfinder"))
+ docs(project(":camera:camera-viewfinder-compose"))
docs(project(":camera:camera-viewfinder-core"))
docs(project(":car:app:app"))
docs(project(":car:app:app-automotive"))
diff --git a/docs/api_guidelines/compat.md b/docs/api_guidelines/compat.md
index 147b4b4..90860c8 100644
--- a/docs/api_guidelines/compat.md
+++ b/docs/api_guidelines/compat.md
@@ -56,7 +56,13 @@
```
When developing against pre-release SDKs where the `SDK_INT` has not been
-finalized, SDK checks **must** use `BuildCompat.isAtLeastX()` methods.
+finalized, SDK checks **must** use `BuildCompat.isAtLeastX()` methods and
+**must** use a tip-of-tree `project` dependency to ensure that the
+implementation of `BuildCompat` stays up-to-date when the SDK is finalized.
+
+**Do not** assume that the next SDK release's `SDK_INT` will be N+1. The value
+is not finalized until SDK finalization happens, at which point the `isAtLeast`
+check will be updated. **Never** write your own check for a pre-release SDK.
```java {.good}
@NonNull
@@ -68,6 +74,12 @@
}
```
+```kotlin {.good}
+dependencies {
+ api(project(":core:core"))
+}
+```
+
##### Preventing invalid casting {#compat-casting}
Even when a call to a new API is moved to a version-specific class, a class
diff --git a/docs/api_guidelines/modules.md b/docs/api_guidelines/modules.md
index 85259bd..c125cc5 100644
--- a/docs/api_guidelines/modules.md
+++ b/docs/api_guidelines/modules.md
@@ -40,6 +40,45 @@
should follow the naming convention `com.android.extensions.<feature-name>` to
avoid placing `androidx`-packaged code in the platform's boot classpath.
+#### Maven name and description
+
+The `name` and `description` fields of the `androidx` configuration block are
+used to generate Maven artifact metadata, which is displayed on the artifact's
+maven.google.com entry and d.android.com landing page.
+
+```
+androidx {
+ name = "WorkManager Kotlin Extensions"
+ description = "Kotlin-friendly extensions for WorkManager."
+}
+```
+
+The name should be a human-readable, title-cased representation of the
+artifact's Maven coordinate. All components of the name **must** appear in the
+artifact's Maven group or artifact ID, with some exceptions:
+
+- Marketing names may be shortened when used in the Maven group or artifact
+ ID, ex. "WorkManager" as `work`, "Android for Cars" as `car`, or "Kotlin
+ Extensions" as `ktx`
+- Long (>10 character) words may be truncated to a short (>5 character) prefix
+- Pluralization may be changed, ex. "Views" as `view`
+- The following descriptive terms may appear in the name:
+ - "extension(s)"
+ - "for"
+ - "integration"
+ - "with"
+
+**Do not** use the following terms in the name:
+
+- "AndroidX"
+- "Library"
+- "Implementation"
+
+The description should be a single phrase that completes the sentence, "This
+library provides ...". This phrase should provide enough description that a
+developer can decide whether they might want to learn more about using your
+library. **Do not** simply repeat the name of the library.
+
#### Project directory structure {#module-structure}
Libraries developed in AndroidX follow a consistent project naming and directory
@@ -284,7 +323,7 @@
...
androidx {
- name = "Android Support Library collections"
+ name = "Collection"
type = LibraryType.KMP_LIBRARY
mavenGroup = LibraryGroups.COLLECTION
mavenVersion = KmpPlatformsKt.enableNative(project) ? LibraryVersions.COLLECTION_KMP : LibraryVersions.KMP
diff --git a/documentfile/documentfile/build.gradle b/documentfile/documentfile/build.gradle
index 4993c26..f9ab3ec 100644
--- a/documentfile/documentfile/build.gradle
+++ b/documentfile/documentfile/build.gradle
@@ -17,7 +17,7 @@
}
androidx {
- name = "Android Support Library Document File"
+ name = "Document File"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/documentfile/documentfile/src/main/AndroidManifest.xml b/documentfile/documentfile/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/documentfile/documentfile/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/draganddrop/draganddrop/build.gradle b/draganddrop/draganddrop/build.gradle
index 37b0365..41c3462 100644
--- a/draganddrop/draganddrop/build.gradle
+++ b/draganddrop/draganddrop/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "AndroidX Drag and Drop Library"
+ name = "Drag and Drop"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "This library makes it easy for developers to accept data dragged-and-dropped from another app, and show a consistent affordance."
diff --git a/drawerlayout/drawerlayout/build.gradle b/drawerlayout/drawerlayout/build.gradle
index 6405b31..2e717e7 100644
--- a/drawerlayout/drawerlayout/build.gradle
+++ b/drawerlayout/drawerlayout/build.gradle
@@ -22,7 +22,7 @@
}
androidx {
- name = "Android Support Library Drawer Layout"
+ name = "Drawer Layout"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/drawerlayout/drawerlayout/src/main/AndroidManifest.xml b/drawerlayout/drawerlayout/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/drawerlayout/drawerlayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/dynamicanimation/dynamicanimation-ktx/src/androidTest/java/androidx/dynamicanimation/tests/DynamicAnimationTest.kt b/dynamicanimation/dynamicanimation-ktx/src/androidTest/java/androidx/dynamicanimation/tests/DynamicAnimationTest.kt
index 13e3a47..0486ceb 100644
--- a/dynamicanimation/dynamicanimation-ktx/src/androidTest/java/androidx/dynamicanimation/tests/DynamicAnimationTest.kt
+++ b/dynamicanimation/dynamicanimation-ktx/src/androidTest/java/androidx/dynamicanimation/tests/DynamicAnimationTest.kt
@@ -17,7 +17,6 @@
package androidx.dynamicanimation.tests
import android.view.View
-
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.SpringForce
import androidx.dynamicanimation.animation.flingAnimationOf
@@ -27,7 +26,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
-
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
diff --git a/dynamicanimation/dynamicanimation-ktx/src/main/AndroidManifest.xml b/dynamicanimation/dynamicanimation-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 9db011d..0000000
--- a/dynamicanimation/dynamicanimation-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright 2018 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 />
\ No newline at end of file
diff --git a/dynamicanimation/dynamicanimation/build.gradle b/dynamicanimation/dynamicanimation/build.gradle
index b3a6d81..29f51a5 100644
--- a/dynamicanimation/dynamicanimation/build.gradle
+++ b/dynamicanimation/dynamicanimation/build.gradle
@@ -19,7 +19,7 @@
}
androidx {
- name = "Android Support DynamicAnimation"
+ name = "DynamicAnimation"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.DYNAMICANIMATION
inceptionYear = "2017"
diff --git a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
index 58b53c0..7caf3e7 100644
--- a/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
+++ b/dynamicanimation/dynamicanimation/src/androidTest/java/androidx/dynamicanimation/tests/SpringTests.java
@@ -126,6 +126,7 @@
* Test that spring animation can work with a single property without an object.
*/
@Test
+ @Ignore("b/280665072")
public void testFloatValueHolder() {
final FloatValueHolder floatValueHolder = new FloatValueHolder(0f);
DynamicAnimation.OnAnimationUpdateListener updateListener =
@@ -354,6 +355,7 @@
*/
@LargeTest
@Test
+ @Ignore("b/280665072")
public void testStiffness() {
float[] dampingRatios = {0.3f, 0.5f, 1f, 5f};
final float[] stiffness = {50f, 500f, 1500f, 5000f};
diff --git a/dynamicanimation/dynamicanimation/src/main/AndroidManifest.xml b/dynamicanimation/dynamicanimation/src/main/AndroidManifest.xml
deleted file mode 100644
index 95c4426..0000000
--- a/dynamicanimation/dynamicanimation/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 />
diff --git a/emoji/emoji-appcompat/build.gradle b/emoji/emoji-appcompat/build.gradle
index df0af37..b0e39af 100644
--- a/emoji/emoji-appcompat/build.gradle
+++ b/emoji/emoji-appcompat/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "Android Emoji AppCompat"
+ name = "Emoji AppCompat"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI
inceptionYear = "2017"
diff --git a/emoji/emoji-appcompat/src/main/AndroidManifest.xml b/emoji/emoji-appcompat/src/main/AndroidManifest.xml
deleted file mode 100644
index c7003d8..0000000
--- a/emoji/emoji-appcompat/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 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 />
diff --git a/emoji/emoji-bundled/build.gradle b/emoji/emoji-bundled/build.gradle
index d757fb1..3414c36 100644
--- a/emoji/emoji-bundled/build.gradle
+++ b/emoji/emoji-bundled/build.gradle
@@ -21,7 +21,7 @@
}
androidx {
- name = "Android Emoji Compat"
+ name = "Emoji Bundled"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI
inceptionYear = "2017"
diff --git a/emoji/emoji-bundled/src/main/AndroidManifest.xml b/emoji/emoji-bundled/src/main/AndroidManifest.xml
deleted file mode 100644
index c50336e..0000000
--- a/emoji/emoji-bundled/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 />
\ No newline at end of file
diff --git a/emoji/emoji/build.gradle b/emoji/emoji/build.gradle
index 5e135b6..cfb14e4 100644
--- a/emoji/emoji/build.gradle
+++ b/emoji/emoji/build.gradle
@@ -54,7 +54,7 @@
}
androidx {
- name = "Android Emoji Compat"
+ name = "Emoji"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.EMOJI
inceptionYear = "2017"
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
index e75969a..5130a65 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiInputFilterTest.java
@@ -30,13 +30,19 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.text.Spannable;
import android.text.SpannableString;
+import android.widget.EditText;
import android.widget.TextView;
import androidx.emoji.text.EmojiCompat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
+import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -126,4 +132,31 @@
verify(mEmojiCompat, times(0)).process(any(Spannable.class), anyInt(), anyInt());
verify(mEmojiCompat, times(1)).registerInitCallback(any(EmojiCompat.InitCallback.class));
}
+
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void initCallback_doesntCrashWhenNotAttached() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ EditText editText = new EditText(context);
+ EmojiInputFilter subject = new EmojiInputFilter(editText);
+ subject.getInitCallback().onInitialized();
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 29)
+ public void initCallback_sendsToNonMainHandler_beforeSetText() {
+ // this is just testing that onInitialized dispatches to editText.getHandler before setText
+ EditText mockEditText = mock(EditText.class);
+ HandlerThread thread = new HandlerThread("random thread");
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ thread.quitSafely();
+ when(mockEditText.getHandler()).thenReturn(handler);
+ EmojiInputFilter subject = new EmojiInputFilter(mockEditText);
+ EmojiInputFilter.InitCallbackImpl initCallback =
+ (EmojiInputFilter.InitCallbackImpl) subject.getInitCallback();
+ initCallback.onInitialized();
+
+ handler.hasCallbacks(initCallback);
+ }
}
diff --git a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
index fe3da64..50b0169 100644
--- a/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
+++ b/emoji/emoji/src/androidTest/java/androidx/emoji/widget/EmojiTextWatcherTest.java
@@ -27,13 +27,18 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.text.Spannable;
import android.text.SpannableString;
import android.widget.EditText;
import androidx.emoji.text.EmojiCompat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -41,6 +46,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
+@SdkSuppress(minSdkVersion = 19)
public class EmojiTextWatcherTest {
private EmojiTextWatcher mTextWatcher;
@@ -120,4 +126,31 @@
verify(mEmojiCompat, times(0)).process(any(Spannable.class), anyInt(), anyInt());
verify(mEmojiCompat, times(1)).registerInitCallback(any(EmojiCompat.InitCallback.class));
}
+
+ @Test
+ public void initCallback_doesntCrashWhenNotAttached() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ EditText editText = new EditText(context);
+ EmojiTextWatcher subject = new EmojiTextWatcher(editText);
+ subject.getInitCallback().onInitialized();
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 29)
+ public void initCallback_sendsToNonMainHandler_beforeSetText() {
+ // this is just testing that onInitialized dispatches to editText.getHandler before setText
+ EditText mockEditText = mock(EditText.class);
+ HandlerThread thread = new HandlerThread("random thread");
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ thread.quitSafely();
+ when(mockEditText.getHandler()).thenReturn(handler);
+ EmojiTextWatcher subject = new EmojiTextWatcher(mockEditText);
+ EmojiTextWatcher.InitCallbackImpl initCallback =
+ (EmojiTextWatcher.InitCallbackImpl) subject.getInitCallback();
+ initCallback.onInitialized();
+
+ handler.hasCallbacks(initCallback);
+ }
}
+
diff --git a/emoji/emoji/src/main/AndroidManifest.xml b/emoji/emoji/src/main/AndroidManifest.xml
deleted file mode 100644
index a213cdc..0000000
--- a/emoji/emoji/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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/>
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
index 27d1aa0..25f9478 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiInputFilter.java
@@ -15,8 +15,10 @@
*/
package androidx.emoji.widget;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+import android.os.Handler;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
@@ -88,14 +90,16 @@
}
}
- private InitCallback getInitCallback() {
+ @RestrictTo(LIBRARY)
+ InitCallback getInitCallback() {
if (mInitCallback == null) {
mInitCallback = new InitCallbackImpl(mTextView);
}
return mInitCallback;
}
- private static class InitCallbackImpl extends InitCallback {
+ @RestrictTo(LIBRARY)
+ static class InitCallbackImpl extends InitCallback implements Runnable {
private final Reference<TextView> mViewRef;
InitCallbackImpl(TextView textView) {
@@ -106,7 +110,23 @@
public void onInitialized() {
super.onInitialized();
final TextView textView = mViewRef.get();
- if (textView != null && textView.isAttachedToWindow()) {
+ if (textView == null) {
+ return;
+ }
+ // we need to move to the actual thread this view is using as main
+ Handler handler = textView.getHandler();
+ if (handler != null) {
+ handler.post(this);
+ }
+ }
+
+ @Override
+ public void run() {
+ final TextView textView = mViewRef.get();
+ if (textView == null) {
+ return;
+ }
+ if (textView.isAttachedToWindow()) {
final CharSequence result = EmojiCompat.get().process(textView.getText());
final int selectionStart = Selection.getSelectionStart(result);
diff --git a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextWatcher.java b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextWatcher.java
index 2a4572f..6e6fcf3 100644
--- a/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextWatcher.java
+++ b/emoji/emoji/src/main/java/androidx/emoji/widget/EmojiTextWatcher.java
@@ -15,8 +15,10 @@
*/
package androidx.emoji.widget;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+import android.os.Handler;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
@@ -99,14 +101,16 @@
// do nothing
}
- private InitCallback getInitCallback() {
+ @RestrictTo(LIBRARY)
+ InitCallback getInitCallback() {
if (mInitCallback == null) {
mInitCallback = new InitCallbackImpl(mEditText);
}
return mInitCallback;
}
- private static class InitCallbackImpl extends InitCallback {
+ @RestrictTo(LIBRARY)
+ static class InitCallbackImpl extends InitCallback implements Runnable {
private final Reference<EditText> mViewRef;
InitCallbackImpl(EditText editText) {
@@ -117,6 +121,19 @@
public void onInitialized() {
super.onInitialized();
final EditText editText = mViewRef.get();
+ if (editText == null) {
+ return;
+ }
+ Handler handler = editText.getHandler();
+ if (handler == null) {
+ return;
+ }
+ handler.post(this);
+ }
+
+ @Override
+ public void run() {
+ final EditText editText = mViewRef.get();
if (editText != null && editText.isAttachedToWindow()) {
final Editable text = editText.getEditableText();
diff --git a/emoji2/emoji2-benchmark/src/main/AndroidManifest.xml b/emoji2/emoji2-benchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 29b496b..0000000
--- a/emoji2/emoji2-benchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/emoji2/emoji2-bundled/build.gradle b/emoji2/emoji2-bundled/build.gradle
index 5be609e..da5a158 100644
--- a/emoji2/emoji2-bundled/build.gradle
+++ b/emoji2/emoji2-bundled/build.gradle
@@ -46,7 +46,7 @@
}
androidx {
- name = "Android Emoji2 Compat"
+ name = "Emoji2 Bundled"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Library bundled with assets to enable emoji compatibility in Kitkat and newer " +
diff --git a/emoji2/emoji2-emojipicker/build.gradle b/emoji2/emoji2-emojipicker/build.gradle
index 2ab0c6a..0761e00 100644
--- a/emoji2/emoji2-emojipicker/build.gradle
+++ b/emoji2/emoji2-emojipicker/build.gradle
@@ -57,7 +57,7 @@
}
androidx {
- name = "androidx.emoji2:emoji2-emojipicker"
+ name = "Emoji2 Emoji Picker"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "This library provides the latest emoji support and emoji picker UI to input " +
diff --git a/emoji2/emoji2-emojipicker/src/androidTest/java/androidx/emoji2/emojipicker/EmojiPickerViewTest.kt b/emoji2/emoji2-emojipicker/src/androidTest/java/androidx/emoji2/emojipicker/EmojiPickerViewTest.kt
index f6bbac1..77f976d 100644
--- a/emoji2/emoji2-emojipicker/src/androidTest/java/androidx/emoji2/emojipicker/EmojiPickerViewTest.kt
+++ b/emoji2/emoji2-emojipicker/src/androidTest/java/androidx/emoji2/emojipicker/EmojiPickerViewTest.kt
@@ -16,7 +16,6 @@
package androidx.emoji2.emojipicker
-import androidx.emoji2.emojipicker.R as EmojiPickerViewR
import android.app.Activity
import android.content.Context
import android.os.Bundle
@@ -25,6 +24,7 @@
import android.widget.ImageView
import androidx.core.view.children
import androidx.core.view.isVisible
+import androidx.emoji2.emojipicker.R as EmojiPickerViewR
import androidx.emoji2.emojipicker.test.R
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider
diff --git a/emoji2/emoji2-views-helper/build.gradle b/emoji2/emoji2-views-helper/build.gradle
index ed51ab7..62b7b69 100644
--- a/emoji2/emoji2-views-helper/build.gradle
+++ b/emoji2/emoji2-views-helper/build.gradle
@@ -27,8 +27,8 @@
}
androidx {
- name = "Android Emoji2 Compat view helpers"
+ name = "Emoji2 Views Helper"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
- description = "View helpers for Emoji2"
+ description = "Provide helper classes for Emoji2 views."
}
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiInputFilterTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiInputFilterTest.java
index 3349e6d..a21adf7 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiInputFilterTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiInputFilterTest.java
@@ -30,9 +30,13 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.text.InputFilter;
import android.text.Spannable;
import android.text.SpannableString;
+import android.widget.EditText;
import android.widget.TextView;
import androidx.emoji2.text.EmojiCompat;
@@ -40,6 +44,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SdkSuppress;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -191,7 +196,7 @@
when(mEmojiCompat.getLoadState()).thenReturn(EmojiCompat.LOAD_STATE_SUCCEEDED);
// trigger initialized
- captor.getValue().onInitialized();
+ ((Runnable) captor.getValue()).run();
verify(mEmojiCompat).process(eq(testString));
}
@@ -223,7 +228,7 @@
when(mEmojiCompat.process(eq(testString))).thenReturn(testString);
when(mEmojiCompat.getLoadState()).thenReturn(EmojiCompat.LOAD_STATE_SUCCEEDED);
// trigger initialized
- captor.getValue().onInitialized();
+ ((Runnable) captor.getValue()).run();
// validate interactions don't do anything except check for update
verify(mTextView).getFilters();
@@ -233,4 +238,31 @@
// if you add a safe interaction please update test
verifyNoMoreInteractions(mTextView);
}
+
+ @Test
+ @SdkSuppress(minSdkVersion = 19)
+ public void initCallback_doesntCrashWhenNotAttached() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ EditText editText = new EditText(context);
+ EmojiInputFilter subject = new EmojiInputFilter(editText);
+ subject.getInitCallback().onInitialized();
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 29)
+ public void initCallback_sendsToNonMainHandler_beforeSetText() {
+ // this is just testing that onInitialized dispatches to editText.getHandler before setText
+ EditText mockEditText = mock(EditText.class);
+ HandlerThread thread = new HandlerThread("random thread");
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ thread.quitSafely();
+ when(mockEditText.getHandler()).thenReturn(handler);
+ EmojiInputFilter subject = new EmojiInputFilter(mockEditText);
+ EmojiInputFilter.InitCallbackImpl initCallback =
+ (EmojiInputFilter.InitCallbackImpl) subject.getInitCallback();
+ initCallback.onInitialized();
+
+ handler.hasCallbacks(initCallback);
+ }
}
diff --git a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTextWatcherTest.java b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTextWatcherTest.java
index 8f149da..5c3c5de 100644
--- a/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTextWatcherTest.java
+++ b/emoji2/emoji2-views-helper/src/androidTest/java/androidx/emoji2/viewsintegration/EmojiTextWatcherTest.java
@@ -27,6 +27,9 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.content.Context;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -37,6 +40,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -149,4 +153,30 @@
mTextWatcher.onTextChanged(expected, 0, 0, 1);
assertTrue(TextUtils.equals(expected, "abc"));
}
+
+ @Test
+ public void initCallback_doesntCrashWhenNotAttached() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ EditText editText = new EditText(context);
+ EmojiTextWatcher subject = new EmojiTextWatcher(editText, false);
+ subject.getInitCallback().onInitialized();
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = 29)
+ public void initCallback_sendsToNonMainHandler_beforeSetText() {
+ // this is just testing that onInitialized dispatches to editText.getHandler before setText
+ EditText mockEditText = mock(EditText.class);
+ HandlerThread thread = new HandlerThread("random thread");
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ thread.quitSafely();
+ when(mockEditText.getHandler()).thenReturn(handler);
+ EmojiTextWatcher subject = new EmojiTextWatcher(mockEditText, false);
+ EmojiTextWatcher.InitCallbackImpl initCallback =
+ (EmojiTextWatcher.InitCallbackImpl) subject.getInitCallback();
+ initCallback.onInitialized();
+
+ handler.hasCallbacks(initCallback);
+ }
}
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiInputFilter.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiInputFilter.java
index 530fc52..9c9b485 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiInputFilter.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiInputFilter.java
@@ -15,6 +15,9 @@
*/
package androidx.emoji2.viewsintegration;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import android.os.Handler;
import android.text.InputFilter;
import android.text.Selection;
import android.text.Spannable;
@@ -39,7 +42,7 @@
* effects.
*
*/
-@RestrictTo(RestrictTo.Scope.LIBRARY)
+@RestrictTo(LIBRARY)
@RequiresApi(19)
final class EmojiInputFilter implements android.text.InputFilter {
private final TextView mTextView;
@@ -88,15 +91,17 @@
}
}
- private InitCallback getInitCallback() {
+ @RestrictTo(LIBRARY)
+ InitCallback getInitCallback() {
if (mInitCallback == null) {
mInitCallback = new InitCallbackImpl(mTextView, this);
}
return mInitCallback;
}
+ @RestrictTo(LIBRARY)
@RequiresApi(19)
- private static class InitCallbackImpl extends InitCallback {
+ static class InitCallbackImpl extends InitCallback implements Runnable {
private final Reference<TextView> mViewRef;
private final Reference<EmojiInputFilter> mEmojiInputFilterReference;
@@ -109,6 +114,19 @@
@Override
public void onInitialized() {
super.onInitialized();
+ final TextView textView = mViewRef.get();
+ if (textView == null) {
+ return;
+ }
+ // we need to move to the actual thread this view is using as main
+ Handler handler = textView.getHandler();
+ if (handler != null) {
+ handler.post(this);
+ }
+ }
+
+ @Override
+ public void run() {
@Nullable final TextView textView = mViewRef.get();
@Nullable final InputFilter myInputFilter = mEmojiInputFilterReference.get();
if (!isInputFilterCurrentlyRegisteredOnTextView(textView, myInputFilter)) return;
diff --git a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextWatcher.java b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextWatcher.java
index 55c37da..691f995 100644
--- a/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextWatcher.java
+++ b/emoji2/emoji2-views-helper/src/main/java/androidx/emoji2/viewsintegration/EmojiTextWatcher.java
@@ -15,6 +15,9 @@
*/
package androidx.emoji2.viewsintegration;
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import android.os.Handler;
import android.text.Editable;
import android.text.Selection;
import android.text.Spannable;
@@ -34,7 +37,7 @@
* TextWatcher used for an EditText.
*
*/
-@RestrictTo(RestrictTo.Scope.LIBRARY)
+@RestrictTo(LIBRARY)
@RequiresApi(19)
final class EmojiTextWatcher implements android.text.TextWatcher {
private final EditText mEditText;
@@ -107,7 +110,11 @@
// do nothing
}
- private InitCallback getInitCallback() {
+ /**
+ * @return
+ */
+ @RestrictTo(LIBRARY)
+ InitCallback getInitCallback() {
if (mInitCallback == null) {
mInitCallback = new InitCallbackImpl(mEditText);
}
@@ -130,8 +137,9 @@
}
}
+ @RestrictTo(LIBRARY)
@RequiresApi(19)
- private static class InitCallbackImpl extends InitCallback {
+ static class InitCallbackImpl extends InitCallback implements Runnable {
private final Reference<EditText> mViewRef;
InitCallbackImpl(EditText editText) {
@@ -142,6 +150,19 @@
public void onInitialized() {
super.onInitialized();
final EditText editText = mViewRef.get();
+ if (editText == null) {
+ return;
+ }
+ Handler handler = editText.getHandler();
+ if (handler == null) {
+ return;
+ }
+ handler.post(this);
+ }
+
+ @Override
+ public void run() {
+ final EditText editText = mViewRef.get();
processTextOnEnablingEvent(editText, EmojiCompat.LOAD_STATE_SUCCEEDED);
}
}
diff --git a/emoji2/emoji2-views/build.gradle b/emoji2/emoji2-views/build.gradle
index 597d3b1..eae7eb2 100644
--- a/emoji2/emoji2-views/build.gradle
+++ b/emoji2/emoji2-views/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "Android Emoji2 Compat Views"
+ name = "Emoji2 Views"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Support for using emoji2 directly with Android Views, for use in apps without " +
diff --git a/emoji2/emoji2/build.gradle b/emoji2/emoji2/build.gradle
index f1a2cdd..3ab8724 100644
--- a/emoji2/emoji2/build.gradle
+++ b/emoji2/emoji2/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Emoji2 Compat"
+ name = "Emoji2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Core library to enable emoji compatibility in Kitkat and newer devices to avoid the empty emoji characters."
diff --git a/emoji2/integration-tests/init-disabled-macrobenchmark/build.gradle b/emoji2/integration-tests/init-disabled-macrobenchmark/build.gradle
index 708a1b6..4a65042 100644
--- a/emoji2/integration-tests/init-disabled-macrobenchmark/build.gradle
+++ b/emoji2/integration-tests/init-disabled-macrobenchmark/build.gradle
@@ -16,7 +16,7 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -25,23 +25,20 @@
minSdkVersion 23
}
namespace "androidx.emoji2.integration.macrobenchmark.disabled"
+ targetProjectPath = ":emoji2:integration-tests:init-disabled-macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":emoji2:integration-tests:init-disabled-macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":emoji2:integration-tests:init-disabled-macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
}
diff --git a/emoji2/integration-tests/init-disabled-macrobenchmark/src/androidTest/AndroidManifest.xml b/emoji2/integration-tests/init-disabled-macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/emoji2/integration-tests/init-disabled-macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/emoji2/integration-tests/init-disabled-macrobenchmark/src/main/AndroidManifest.xml b/emoji2/integration-tests/init-disabled-macrobenchmark/src/main/AndroidManifest.xml
index ed173d5..5b41847 100644
--- a/emoji2/integration-tests/init-disabled-macrobenchmark/src/main/AndroidManifest.xml
+++ b/emoji2/integration-tests/init-disabled-macrobenchmark/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/emoji2/integration-tests/init-disabled-macrobenchmark/src/androidTest/java/androidx/emoji2/integration/macrobenchmark/disabled/EmojiStartupBenchmark.kt b/emoji2/integration-tests/init-disabled-macrobenchmark/src/main/java/androidx/emoji2/integration/macrobenchmark/disabled/EmojiStartupBenchmark.kt
similarity index 100%
rename from emoji2/integration-tests/init-disabled-macrobenchmark/src/androidTest/java/androidx/emoji2/integration/macrobenchmark/disabled/EmojiStartupBenchmark.kt
rename to emoji2/integration-tests/init-disabled-macrobenchmark/src/main/java/androidx/emoji2/integration/macrobenchmark/disabled/EmojiStartupBenchmark.kt
diff --git a/emoji2/integration-tests/init-enabled-macrobenchmark/build.gradle b/emoji2/integration-tests/init-enabled-macrobenchmark/build.gradle
index 1dee7de..c1f5ed9 100644
--- a/emoji2/integration-tests/init-enabled-macrobenchmark/build.gradle
+++ b/emoji2/integration-tests/init-enabled-macrobenchmark/build.gradle
@@ -16,7 +16,7 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -25,24 +25,21 @@
minSdkVersion 23
}
namespace "androidx.emoji2.integration.macrobenchmark.enabled"
+ targetProjectPath = ":emoji2:integration-tests:init-enabled-macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":emoji2:emoji2"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":emoji2:integration-tests:init-enabled-macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":emoji2:integration-tests:init-enabled-macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":emoji2:emoji2"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
}
diff --git a/emoji2/integration-tests/init-enabled-macrobenchmark/src/androidTest/AndroidManifest.xml b/emoji2/integration-tests/init-enabled-macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/emoji2/integration-tests/init-enabled-macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/emoji2/integration-tests/init-enabled-macrobenchmark/src/main/AndroidManifest.xml b/emoji2/integration-tests/init-enabled-macrobenchmark/src/main/AndroidManifest.xml
index ed173d5..5b41847 100644
--- a/emoji2/integration-tests/init-enabled-macrobenchmark/src/main/AndroidManifest.xml
+++ b/emoji2/integration-tests/init-enabled-macrobenchmark/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/emoji2/integration-tests/init-enabled-macrobenchmark/src/androidTest/java/androidx/emoji2/integration/macrobenchmark/enabled/EmojiStartupBenchmark.kt b/emoji2/integration-tests/init-enabled-macrobenchmark/src/main/java/androidx/emoji2/integration/macrobenchmark/enabled/EmojiStartupBenchmark.kt
similarity index 100%
rename from emoji2/integration-tests/init-enabled-macrobenchmark/src/androidTest/java/androidx/emoji2/integration/macrobenchmark/enabled/EmojiStartupBenchmark.kt
rename to emoji2/integration-tests/init-enabled-macrobenchmark/src/main/java/androidx/emoji2/integration/macrobenchmark/enabled/EmojiStartupBenchmark.kt
diff --git a/enterprise/enterprise-feedback-testing/src/main/AndroidManifest.xml b/enterprise/enterprise-feedback-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index de53569..0000000
--- a/enterprise/enterprise-feedback-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/exifinterface/exifinterface/build.gradle b/exifinterface/exifinterface/build.gradle
index b6bcaab..12e623a 100644
--- a/exifinterface/exifinterface/build.gradle
+++ b/exifinterface/exifinterface/build.gradle
@@ -16,7 +16,7 @@
}
androidx {
- name = "Android Support ExifInterface"
+ name = "ExifInterface"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2016"
description = "Android Support ExifInterface"
diff --git a/exifinterface/exifinterface/src/main/AndroidManifest.xml b/exifinterface/exifinterface/src/main/AndroidManifest.xml
deleted file mode 100644
index 5197378..0000000
--- a/exifinterface/exifinterface/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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 />
diff --git a/external/libyuv/src/main/AndroidManifest.xml b/external/libyuv/src/main/AndroidManifest.xml
deleted file mode 100644
index 95ab252..0000000
--- a/external/libyuv/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright 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.
- -->
-<manifest />
\ No newline at end of file
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt
index 745753a..7345548 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/DeviceConfig.kt
@@ -47,13 +47,13 @@
import com.android.resources.TouchScreen
import com.android.resources.UiMode
import com.google.android.collect.Maps
-import org.xmlpull.v1.XmlPullParser
-import org.xmlpull.v1.XmlPullParserException
-import org.xmlpull.v1.XmlPullParserFactory
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.Properties
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+import org.xmlpull.v1.XmlPullParserFactory
/**
* Provides [FolderConfiguration] and [HardwareConfig] for various devices. Also provides utility
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt
index 4c1eabc..c43f4fb 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/HtmlReportWriter.kt
@@ -18,13 +18,6 @@
import app.cash.paparazzi.SnapshotHandler.FrameHandler
import app.cash.paparazzi.internal.PaparazziJson
import com.google.common.base.CharMatcher
-import okio.BufferedSink
-import okio.HashingSink
-import okio.blackholeSink
-import okio.buffer
-import okio.sink
-import okio.source
-import org.jcodec.api.awt.AWTSequenceEncoder
import java.awt.image.BufferedImage
import java.io.File
import java.text.SimpleDateFormat
@@ -32,6 +25,13 @@
import java.util.Locale
import java.util.UUID
import javax.imageio.ImageIO
+import okio.BufferedSink
+import okio.HashingSink
+import okio.blackholeSink
+import okio.buffer
+import okio.sink
+import okio.source
+import org.jcodec.api.awt.AWTSequenceEncoder
/**
* Creates an HTML report that avoids writing files that have already been written.
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt
index 40ce39e..c6f0042 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Paparazzi.kt
@@ -70,13 +70,13 @@
import com.android.layoutlib.bridge.BridgeRenderSession
import com.android.layoutlib.bridge.impl.RenderAction
import com.android.layoutlib.bridge.impl.RenderSessionImpl
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
import java.awt.image.BufferedImage
import java.util.Date
import java.util.concurrent.TimeUnit
import kotlin.coroutines.ContinuationInterceptor
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
class Paparazzi @JvmOverloads constructor(
private val environment: Environment = detectEnvironment(),
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt
index b6a4ac6..15617f0 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/Reflections.kt
@@ -1,9 +1,9 @@
package app.cash.paparazzi
-import sun.misc.Unsafe
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.security.PrivilegedAction
+import sun.misc.Unsafe
/**
* Inspired by and ported from:
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
index 8406d6d3..8e7111c 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
@@ -16,9 +16,6 @@
package app.cash.paparazzi.internal
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
import java.awt.AlphaComposite
import java.awt.Color
import java.awt.Graphics2D
@@ -35,6 +32,9 @@
import java.io.IOException
import javax.imageio.ImageIO
import kotlin.math.max
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
/**
* Utilities related to image processing.
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt
index f6e164c..6e2b62e 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/PaparazziCallback.kt
@@ -30,9 +30,6 @@
import com.android.resources.ResourceType
import com.android.resources.ResourceType.STYLE
import com.google.common.io.ByteStreams
-import org.kxml2.io.KXmlParser
-import org.xmlpull.v1.XmlPullParser
-import org.xmlpull.v1.XmlPullParserException
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
@@ -40,6 +37,9 @@
import java.io.FileNotFoundException
import java.io.IOException
import java.lang.reflect.Modifier
+import org.kxml2.io.KXmlParser
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
internal class PaparazziCallback(
private val logger: PaparazziLogger,
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt
index dd4a7f1..8f1a94a 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/LayoutPullParser.kt
@@ -24,9 +24,6 @@
import com.android.SdkConstants.TOOLS_URI
import com.android.ide.common.rendering.api.ILayoutPullParser
import com.android.ide.common.rendering.api.ResourceNamespace
-import okio.buffer
-import okio.source
-import org.xmlpull.v1.XmlPullParserException
import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileInputStream
@@ -34,6 +31,9 @@
import java.io.IOError
import java.io.InputStream
import java.nio.charset.Charset
+import okio.buffer
+import okio.source
+import org.xmlpull.v1.XmlPullParserException
/**
* A layout parser that holds an in-memory tree of a given resource for subsequent traversal
diff --git a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt
index 574e18d..f90475b 100644
--- a/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt
+++ b/external/paparazzi/paparazzi/src/main/java/app/cash/paparazzi/internal/parsers/ResourceParser.kt
@@ -17,8 +17,8 @@
import com.android.SdkConstants.AAPT_URI
import com.android.SdkConstants.TAG_ATTR
-import org.kxml2.io.KXmlParser
import java.io.InputStream
+import org.kxml2.io.KXmlParser
/**
* An XML resource parser that creates a tree of [TagSnapshot]s
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
index dc38b1c..80979c7 100644
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
+++ b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
@@ -15,10 +15,6 @@
*/
package app.cash.paparazzi
-import org.assertj.core.api.Assertions.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TemporaryFolder
import java.awt.image.BufferedImage
import java.io.File
import java.nio.file.Files
@@ -27,6 +23,10 @@
import java.nio.file.attribute.FileTime
import java.time.Instant
import java.util.Date
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
class HtmlReportWriterTest {
@get:Rule
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt
index 498d456..356a6c8 100644
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt
+++ b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/PaparazziTest.kt
@@ -27,11 +27,11 @@
import android.view.animation.LinearInterpolator
import android.widget.Button
import com.android.internal.lang.System_Delegate
+import java.util.concurrent.TimeUnit
import org.assertj.core.api.Assertions.assertThat
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
-import java.util.concurrent.TimeUnit
class PaparazziTest {
@get:Rule
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt
index c67ab76..d774099 100644
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt
+++ b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/RenderingModeTest.kt
@@ -11,12 +11,12 @@
import android.widget.TextView
import app.cash.paparazzi.internal.ImageUtils
import com.android.ide.common.rendering.api.SessionParams
-import org.junit.Test
-import org.junit.runner.Description
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.Description
class RenderingModeTest {
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt
index 6399c8c..b9afe6e 100644
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt
+++ b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/accessibility/AccessibilityRenderExtensionTest.kt
@@ -16,12 +16,12 @@
import app.cash.paparazzi.Snapshot
import app.cash.paparazzi.SnapshotHandler
import app.cash.paparazzi.internal.ImageUtils
-import org.junit.Rule
-import org.junit.Test
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
class AccessibilityRenderExtensionTest {
private val snapshotHandler = TestSnapshotVerifier()
diff --git a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt
index e1ab916..89d7823 100644
--- a/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt
+++ b/external/paparazzi/paparazzi/src/test/java/app/cash/paparazzi/internal/PaparazziLoggerTest.kt
@@ -1,10 +1,10 @@
package app.cash.paparazzi.internal
import app.cash.paparazzi.internal.PaparazziLogger.MultipleFailuresException
+import java.io.FileNotFoundException
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.fail
import org.junit.Test
-import java.io.FileNotFoundException
class PaparazziLoggerTest {
@Test
diff --git a/fragment/fragment-ktx/src/main/AndroidManifest.xml b/fragment/fragment-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/fragment/fragment-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/fragment/fragment-lint/build.gradle b/fragment/fragment-lint/build.gradle
index 9a091e2..b4f8162 100644
--- a/fragment/fragment-lint/build.gradle
+++ b/fragment/fragment-lint/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Android Fragment Lint Checks"
+ name = "Fragment Lint Checks"
type = LibraryType.LINT
inceptionYear = "2019"
description = "Android Fragment Lint Checks"
diff --git a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentTagDetector.kt b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentTagDetector.kt
index ac26747..8a5cd4c 100644
--- a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentTagDetector.kt
+++ b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/FragmentTagDetector.kt
@@ -26,8 +26,8 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.XmlContext
-import org.w3c.dom.Element
import java.util.Collections
+import org.w3c.dom.Element
/**
* Lint check for detecting use of fragment tag in layout xml files. This provides a warning that
diff --git a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UseRequireInsteadOfGet.kt b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UseRequireInsteadOfGet.kt
index 9529d0c..0e8b728c 100644
--- a/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UseRequireInsteadOfGet.kt
+++ b/fragment/fragment-lint/src/main/java/androidx/fragment/lint/UseRequireInsteadOfGet.kt
@@ -29,6 +29,7 @@
import com.android.tools.lint.detector.api.isKotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiMethod
+import java.util.Locale
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
@@ -42,7 +43,6 @@
import org.jetbrains.uast.skipParenthesizedExprUp
import org.jetbrains.uast.toUElement
import org.jetbrains.uast.tryResolve
-import java.util.Locale
/**
* Androidx added new "require____()" versions of common "get___()" APIs, such as
diff --git a/fragment/fragment-testing-lint/build.gradle b/fragment/fragment-testing-lint/build.gradle
index 91a6a84..a9641c7 100644
--- a/fragment/fragment-testing-lint/build.gradle
+++ b/fragment/fragment-testing-lint/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "Android Fragment-Testing Lint Checks"
+ name = "Fragment-Testing Lint Checks"
type = LibraryType.LINT
inceptionYear = "2019"
description = "Lint Checks for the Fragment Testing module"
diff --git a/fragment/fragment-testing-manifest-lint/build.gradle b/fragment/fragment-testing-manifest-lint/build.gradle
index 3f8af05..9b4b9f4 100644
--- a/fragment/fragment-testing-manifest-lint/build.gradle
+++ b/fragment/fragment-testing-manifest-lint/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "Android Fragment-Testing-Manifest Lint Checks"
+ name = "Fragment-Testing-Manifest Lint Checks"
type = LibraryType.LINT
inceptionYear = "2022"
description = "Lint Checks for the Fragment Testing Manifest module"
diff --git a/fragment/fragment-testing/build.gradle b/fragment/fragment-testing/build.gradle
index 4ef2ed4..0230108 100644
--- a/fragment/fragment-testing/build.gradle
+++ b/fragment/fragment-testing/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "Fragment Test Extensions"
+ name = "Fragment Testing Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Extensions for testing 'fragment' artifact"
diff --git a/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/FragmentScenarioViewModelTest.kt b/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/FragmentScenarioViewModelTest.kt
index d88bcba..2ff83ba 100644
--- a/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/FragmentScenarioViewModelTest.kt
+++ b/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/FragmentScenarioViewModelTest.kt
@@ -25,8 +25,8 @@
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
/**
* End-to-end integration test using a mock [ViewModel] injected in via a
diff --git a/fragment/fragment-truth/src/main/AndroidManifest.xml b/fragment/fragment-truth/src/main/AndroidManifest.xml
deleted file mode 100644
index cf0d807..0000000
--- a/fragment/fragment-truth/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/fragment/fragment/build.gradle b/fragment/fragment/build.gradle
index 91b6c0f..e2863b8 100644
--- a/fragment/fragment/build.gradle
+++ b/fragment/fragment/build.gradle
@@ -71,7 +71,7 @@
}
androidx {
- name = "Android Support Library fragment"
+ name = "fragment"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2011"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/ChildFragmentStateTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/ChildFragmentStateTest.kt
index f9ed241..cdb4b07 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/ChildFragmentStateTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/ChildFragmentStateTest.kt
@@ -23,7 +23,6 @@
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import leakcanary.DetectLeaksAfterTestSuccess
-
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
index e312fa9..c2dea61 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentAnimationTest.kt
@@ -39,14 +39,14 @@
import androidx.testutils.waitForExecution
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
index 9afccb3..7874c18 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
@@ -39,15 +39,15 @@
import androidx.testutils.waitForExecution
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import leakcanary.DetectLeaksAfterTestSuccess
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import leakcanary.DetectLeaksAfterTestSuccess
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
index b897a54..9567a88 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
@@ -29,14 +29,14 @@
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Assert.fail
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.Assert.fail
+import org.junit.Rule
+import org.junit.Test
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
/**
* Tests for Fragment startActivityForResult and startIntentSenderForResult.
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentStateManagerTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentStateManagerTest.kt
index 1af6505..b8096d2 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentStateManagerTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentStateManagerTest.kt
@@ -25,7 +25,6 @@
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
index e10aa608..2f174b5 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentTransitionTest.kt
@@ -38,17 +38,17 @@
import androidx.testutils.withUse
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.After
import org.junit.Assert.fail
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@MediumTest
@RunWith(Parameterized::class)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/NestedFragmentTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/NestedFragmentTest.kt
index 5004ac0..e7a22a9 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/NestedFragmentTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/NestedFragmentTest.kt
@@ -26,13 +26,13 @@
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.Rule
+import org.junit.Test
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
@Suppress("DEPRECATION")
@RunWith(AndroidJUnit4::class)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/PostponedTransitionTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/PostponedTransitionTest.kt
index fb7c81e..c5378713 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/PostponedTransitionTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/PostponedTransitionTest.kt
@@ -33,13 +33,13 @@
import androidx.testutils.waitForExecution
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.Rule
+import org.junit.Test
import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/NewIntentActivity.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/NewIntentActivity.kt
index cbd332d..bdccc7a 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/NewIntentActivity.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/test/NewIntentActivity.kt
@@ -18,10 +18,8 @@
import android.content.Intent
import android.os.Bundle
-
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-
import java.util.concurrent.CountDownLatch
class NewIntentActivity : FragmentActivity() {
diff --git a/fragment/fragment/src/main/AndroidManifest.xml b/fragment/fragment/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/fragment/fragment/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
index 2f826a4..c659047 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentContainerView.kt
@@ -15,8 +15,6 @@
*/
package androidx.fragment.app
-import android.widget.FrameLayout
-import androidx.fragment.R
import android.animation.LayoutTransition
import android.content.Context
import android.graphics.Canvas
@@ -25,10 +23,12 @@
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
+import android.widget.FrameLayout
import androidx.annotation.RequiresApi
import androidx.core.content.withStyledAttributes
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
+import androidx.fragment.R
/**
* FragmentContainerView is a customized Layout designed specifically for Fragments. It extends
diff --git a/glance/glance-appwidget-preview/build.gradle b/glance/glance-appwidget-preview/build.gradle
index 07567f5..20fd21c 100644
--- a/glance/glance-appwidget-preview/build.gradle
+++ b/glance/glance-appwidget-preview/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "Android Glance AppWidget Preview"
+ name = "Glance AppWidget Preview"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GLANCE_PREVIEW
inceptionYear = "2022"
diff --git a/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetPreviews.kt b/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetPreviews.kt
index 5d35a4f..de68697 100644
--- a/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetPreviews.kt
+++ b/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetPreviews.kt
@@ -18,9 +18,9 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
-import androidx.glance.action.Action
import androidx.glance.Button
import androidx.glance.GlanceModifier
+import androidx.glance.action.Action
import androidx.glance.appwidget.appWidgetBackground
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
diff --git a/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapterTest.kt b/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapterTest.kt
index 92d17b07..20f1961 100644
--- a/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapterTest.kt
+++ b/glance/glance-appwidget-preview/src/androidAndroidTest/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapterTest.kt
@@ -16,7 +16,6 @@
package androidx.glance.appwidget.preview
-import androidx.glance.appwidget.preview.test.R
import android.app.Activity
import android.os.Bundle
import android.view.View
@@ -26,6 +25,7 @@
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
+import androidx.glance.appwidget.preview.test.R
import androidx.test.filters.MediumTest
import org.junit.Assert.assertNotNull
import org.junit.Before
diff --git a/glance/glance-appwidget-preview/src/androidMain/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapter.kt b/glance/glance-appwidget-preview/src/androidMain/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapter.kt
index fab1843..53c5222 100644
--- a/glance/glance-appwidget-preview/src/androidMain/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapter.kt
+++ b/glance/glance-appwidget-preview/src/androidMain/kotlin/androidx/glance/appwidget/preview/GlanceAppWidgetViewAdapter.kt
@@ -19,14 +19,12 @@
import android.appwidget.AppWidgetHostView
import android.content.Context
import android.util.AttributeSet
-
import androidx.compose.runtime.Composable
import androidx.compose.runtime.currentComposer
import androidx.compose.ui.unit.DpSize
import androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi
import androidx.glance.appwidget.GlanceRemoteViews
import androidx.glance.appwidget.preview.ComposableInvoker.invokeComposable
-
import kotlinx.coroutines.runBlocking
private const val TOOLS_NS_URI = "http://schemas.android.com/tools"
diff --git a/glance/glance-appwidget/build.gradle b/glance/glance-appwidget/build.gradle
index 85a163f..158c764 100644
--- a/glance/glance-appwidget/build.gradle
+++ b/glance/glance-appwidget/build.gradle
@@ -70,6 +70,7 @@
androidTestImplementation(project(":test:screenshot:screenshot"))
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
+ androidTestImplementation("androidx.room:room-runtime:2.4.3")
androidTestImplementation('androidx.core:core-ktx:1.7.0')
androidTestImplementation("androidx.work:work-testing:2.7.1")
androidTestImplementation(libs.espressoCore)
diff --git a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/GenerateRegistry.kt b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/GenerateRegistry.kt
index ccbb397..9886504 100644
--- a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/GenerateRegistry.kt
+++ b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/GenerateRegistry.kt
@@ -23,8 +23,8 @@
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.INT
import com.squareup.kotlinpoet.KModifier
-import com.squareup.kotlinpoet.KModifier.PRIVATE
import com.squareup.kotlinpoet.KModifier.INTERNAL
+import com.squareup.kotlinpoet.KModifier.PRIVATE
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.MemberName.Companion.member
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
diff --git a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
index 480095c4..aae62fc 100644
--- a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
+++ b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/LayoutGenerator.kt
@@ -17,14 +17,14 @@
package androidx.glance.appwidget.layoutgenerator
import com.squareup.kotlinpoet.MemberName
-import org.w3c.dom.Document
-import org.w3c.dom.Node
import java.io.File
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
+import org.w3c.dom.Document
+import org.w3c.dom.Node
/**
* Generate the layouts from the templates provided to the task.
diff --git a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
index fbe5c31..75f6129 100644
--- a/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
+++ b/glance/glance-appwidget/glance-layout-generator/src/main/kotlin/androidx/glance/appwidget/layoutgenerator/gradle/LayoutGeneratorTask.kt
@@ -21,6 +21,7 @@
import androidx.glance.appwidget.layoutgenerator.cleanResources
import androidx.glance.appwidget.layoutgenerator.generateRegistry
import com.android.build.gradle.LibraryExtension
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
@@ -30,7 +31,6 @@
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
/**
* Task generating the layouts from a set of Layout templates.
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
index 597ba896..6c4eaec 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/CompoundButtonAppWidget.kt
@@ -37,8 +37,8 @@
import androidx.glance.appwidget.SwitchDefaults
import androidx.glance.appwidget.appWidgetBackground
import androidx.glance.appwidget.cornerRadius
-import androidx.glance.appwidget.selectableGroup
import androidx.glance.appwidget.provideContent
+import androidx.glance.appwidget.selectableGroup
import androidx.glance.background
import androidx.glance.color.ColorProvider
import androidx.glance.layout.Alignment
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
index 3f5283a..171a220 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ProgressIndicatorAppWidget.kt
@@ -17,22 +17,30 @@
package androidx.glance.appwidget.demos
import android.content.Context
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
+import androidx.glance.GlanceTheme
import androidx.glance.appwidget.CircularProgressIndicator
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.LinearProgressIndicator
import androidx.glance.appwidget.provideContent
import androidx.glance.background
+import androidx.glance.color.ColorProvider
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
+import androidx.glance.layout.Row
import androidx.glance.layout.Spacer
import androidx.glance.layout.fillMaxSize
import androidx.glance.layout.padding
import androidx.glance.layout.size
+import androidx.glance.layout.width
+import androidx.glance.material3.ColorProviders
import androidx.glance.unit.ColorProvider
class ProgressIndicatorAppWidget : GlanceAppWidget() {
@@ -40,31 +48,97 @@
context: Context,
id: GlanceId
) = provideContent {
- Column(
- modifier = GlanceModifier.fillMaxSize()
- .background(R.color.default_widget_background),
- verticalAlignment = Alignment.CenterVertically,
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
+ GlanceTheme(ProgressIndicatorDemoColorScheme.colors) {
+ Column(
+ modifier = GlanceModifier.fillMaxSize()
+ .background(R.color.default_widget_background),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Row {
+ LinearProgressIndicatorsDemo(modifier = GlanceModifier.defaultWeight())
+ Spacer(modifier = GlanceModifier.width(10.dp))
+ CircularProgressIndicatorsDemo()
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun CircularProgressIndicatorsDemo(modifier: GlanceModifier = GlanceModifier) {
+ Column(modifier) {
+ CircularProgressIndicator()
+ Spacer(GlanceModifier.size(8.dp))
+ CircularProgressIndicator(
+ color = GlanceTheme.colors.primary
+ )
+ Spacer(GlanceModifier.size(8.dp))
+ CircularProgressIndicator(
+ color = ColorProvider(day = Color.White, night = Color.Red)
+ )
+ Spacer(GlanceModifier.size(8.dp))
+ CircularProgressIndicator(
+ color = ColorProvider(androidx.glance.R.color.glance_colorSecondary)
+ )
+ Spacer(GlanceModifier.size(8.dp))
+ CircularProgressIndicator(
+ color = ColorProvider(Color.Red)
+ )
+ }
+ }
+
+ @Composable
+ private fun LinearProgressIndicatorsDemo(modifier: GlanceModifier) {
+ Column(modifier) {
LinearProgressIndicator()
Spacer(GlanceModifier.size(8.dp))
- LinearProgressIndicator(0.5f)
+ LinearProgressIndicator(
+ progress = 0.5f,
+ color = GlanceTheme.colors.primary,
+ backgroundColor = GlanceTheme.colors.onBackground
+ )
Spacer(GlanceModifier.size(8.dp))
LinearProgressIndicator(
progress = .66f,
modifier = GlanceModifier.padding(bottom = 8.dp),
color = ColorProvider(androidx.glance.R.color.glance_colorError),
- backgroundColor = ColorProvider(androidx.glance.R.color.glance_colorSecondary)
+ backgroundColor = ColorProvider(
+ resId = androidx.glance.R.color.glance_colorSecondary
+ )
)
+ Spacer(GlanceModifier.size(8.dp))
+ LinearProgressIndicator(
+ progress = .66f,
+ modifier = GlanceModifier.padding(bottom = 8.dp),
+ color = ColorProvider(day = Color.White, night = Color.Red),
+ backgroundColor = ColorProvider(day = Color.Red, night = Color.White)
+ )
+ Spacer(GlanceModifier.size(8.dp))
LinearProgressIndicator(progress = 0.8f, color = ColorProvider(Color.White))
- Spacer(GlanceModifier.size(8.dp))
- CircularProgressIndicator()
- Spacer(GlanceModifier.size(8.dp))
- CircularProgressIndicator(color = ColorProvider(Color.White))
}
}
}
class ProgressIndicatorAppWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = ProgressIndicatorAppWidget()
+}
+
+internal object ProgressIndicatorDemoColorScheme {
+ private val md_theme_light_primary = Color(0xFF026E00)
+ private val md_theme_light_onBackground = Color(0xFF1E1C00)
+
+ private val md_theme_dark_primary = Color(0xFF02E600)
+ private val md_theme_dark_onBackground = Color(0xFFF2E720)
+
+ private val LightColors = lightColorScheme(
+ primary = md_theme_light_primary,
+ onBackground = md_theme_light_onBackground,
+ )
+
+ private val DarkColors = darkColorScheme(
+ primary = md_theme_dark_primary,
+ onBackground = md_theme_dark_onBackground,
+ )
+
+ val colors = ColorProviders(light = LightColors, dark = DarkColors)
}
\ No newline at end of file
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ScrollableAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ScrollableAppWidget.kt
index 8cdae1e..dcb80bb 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ScrollableAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/ScrollableAppWidget.kt
@@ -16,13 +16,13 @@
package androidx.glance.appwidget.demos
-import androidx.compose.material.Text as ComposeText
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.compose.material.Text as ComposeText
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -84,14 +84,15 @@
modifier = GlanceModifier.fillMaxSize()
.background(R.color.default_widget_background)
) {
+ val localSize = LocalSize.current
Text(
- text = "Fix header",
+ text = "Fix header, LocalSize: ${localSize.width}x${localSize.height}",
modifier = GlanceModifier
.fillMaxWidth()
.padding(16.dp)
.background(Color(0x0a000000))
)
- val width = LocalSize.current.width
+ val width = localSize.width
when {
width <= singleColumn.width -> ScrollColumn(GlanceModifier.fillMaxSize())
width <= doubleColumn.width -> Row {
@@ -107,9 +108,22 @@
@Composable
private fun ScrollColumn(modifier: GlanceModifier) {
+ val localSize = LocalSize.current
LazyColumn(modifier) {
item {
SectionHeading(
+ title = "LocalSize",
+ description = "inside lazyColumn"
+ )
+ }
+ item {
+ Text(
+ text = "${localSize.width}x${localSize.height}",
+ modifier = GlanceModifier.padding(10.dp)
+ )
+ }
+ item {
+ SectionHeading(
title = "Activities",
description = "Click the buttons to open activities"
)
diff --git a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/VerticalGridAppWidget.kt b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/VerticalGridAppWidget.kt
index 9c4f452..ef88370 100644
--- a/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/VerticalGridAppWidget.kt
+++ b/glance/glance-appwidget/integration-tests/demos/src/main/java/androidx/glance/appwidget/demos/VerticalGridAppWidget.kt
@@ -17,14 +17,15 @@
package androidx.glance.appwidget.demos
import android.content.Context
-import android.os.Build
import android.content.Intent
+import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.glance.Button
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.LocalContext
+import androidx.glance.LocalSize
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.action.actionStartActivity
@@ -66,6 +67,7 @@
@Composable
fun SampleGrid(cells: GridCells, modifier: GlanceModifier = GlanceModifier.fillMaxSize()) {
+ val localSize = LocalSize.current
LazyVerticalGrid(
modifier = modifier,
gridCells = cells
@@ -73,6 +75,9 @@
item {
Text("LazyVerticalGrid")
}
+ item {
+ Text("${localSize.width}x${localSize.height}")
+ }
items(count = 20, itemId = { it * 2L }) { index ->
Text("Item $index")
}
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle b/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle
index 19b0df6..cfa7f61 100644
--- a/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle
@@ -16,31 +16,37 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
android {
+ defaultConfig {
+ minSdkVersion 23
+ }
namespace "androidx.glance.appwidget.macrobenchmark"
+ targetProjectPath = ":glance:glance-appwidget:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
-android.defaultConfig {
- minSdkVersion 23
-}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
dependencies {
implementation 'androidx.compose.ui:ui-unit:1.2.1'
- androidTestImplementation(project(':benchmark:benchmark-macro'))
- androidTestImplementation(project(':benchmark:benchmark-common'))
- androidTestImplementation(project(':benchmark:benchmark-macro-junit4'))
- androidTestImplementation('androidx.core:core-ktx:1.7.0')
- androidTestImplementation(project(":glance:glance"))
- androidTestImplementation(project(":glance:glance-appwidget"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.kotlinTest)
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
+ implementation(project(':benchmark:benchmark-macro'))
+ implementation(project(':benchmark:benchmark-common'))
+ implementation(project(':benchmark:benchmark-macro-junit4'))
+ implementation('androidx.core:core-ktx:1.7.0')
+ implementation(project(":glance:glance"))
+ implementation(project(":glance:glance-appwidget"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.kotlinTest)
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
}
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 05a1d72..0000000
--- a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?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">
- <uses-permission android:name="android.permission.BIND_APPWIDGET" />
-
- <application
- android:supportsRtl="true">
- <uses-library android:name="android.test.runner" />
- <activity
- android:name="androidx.glance.appwidget.macrobenchmark.AppWidgetHostTestActivity"
- android:configChanges="orientation|screenLayout|screenSize"
- android:exported="true"/>
- </application>
-</manifest>
\ No newline at end of file
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
index 5b41847..e7eaa978 100644
--- a/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2020 The Android Open Source Project
+ ~ 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.
@@ -14,4 +14,15 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<manifest />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <uses-permission android:name="android.permission.BIND_APPWIDGET" />
+
+ <application
+ android:supportsRtl="true">
+ <uses-library android:name="android.test.runner" />
+ <activity
+ android:name="androidx.glance.appwidget.macrobenchmark.AppWidgetHostTestActivity"
+ android:configChanges="orientation|screenLayout|screenSize"
+ android:exported="true"/>
+ </application>
+</manifest>
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt
similarity index 100%
rename from glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt
rename to glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt
similarity index 100%
rename from glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt
rename to glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt
similarity index 100%
rename from glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt
rename to glance/glance-appwidget/integration-tests/macrobenchmark/src/main/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/res/layout/app_widget_host_activity.xml b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/res/layout/app_widget_host_activity.xml
similarity index 100%
rename from glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/res/layout/app_widget_host_activity.xml
rename to glance/glance-appwidget/integration-tests/macrobenchmark/src/main/res/layout/app_widget_host_activity.xml
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AndroidTestUtils.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AndroidTestUtils.kt
index fa6fcab..164ee74 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AndroidTestUtils.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AndroidTestUtils.kt
@@ -161,6 +161,17 @@
findViewById<View>(emptyLoadingViewID) != null
}
+fun ListView.isItemLoaded(text: String): Boolean {
+ if (childCount > 0 && adapter != null) {
+ return children.any {
+ val matches = arrayListOf<View>()
+ it.findViewsWithText(matches, text, View.FIND_VIEWS_WITH_TEXT)
+ matches.isNotEmpty()
+ }
+ }
+ return false
+}
+
/**
* Returns true if list items are fully loaded (i.e. not in loading... state).
*/
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AppWidgetHostTestActivity.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AppWidgetHostTestActivity.kt
index e8dc6c6..f42506b 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AppWidgetHostTestActivity.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/AppWidgetHostTestActivity.kt
@@ -35,13 +35,13 @@
import android.widget.FrameLayout
import android.widget.RemoteViews
import androidx.annotation.RequiresApi
-import androidx.glance.appwidget.test.R
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
-import org.junit.Assert.fail
+import androidx.glance.appwidget.test.R
import java.util.Locale
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Assert.fail
private const val TAG = "AppWidgetHostTestActivity"
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CheckBoxTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CheckBoxTest.kt
index 29ea48be..8b42c7c 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CheckBoxTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CheckBoxTest.kt
@@ -31,10 +31,10 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
import kotlin.test.assertIs
import kotlin.test.assertNotNull
+import org.junit.Rule
+import org.junit.Test
@SdkSuppress(minSdkVersion = 29)
@MediumTest
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
index 40ad5f8..74454f9 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiverTest.kt
@@ -26,9 +26,6 @@
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.isActive
-import org.junit.Test
import java.io.FileInputStream
import java.nio.charset.StandardCharsets
import java.time.Duration
@@ -37,6 +34,9 @@
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
import kotlin.math.min
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.isActive
+import org.junit.Test
@SdkSuppress(minSdkVersion = 26)
class CoroutineBroadcastReceiverTest {
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
index af28347..927111b 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/LazyColumnTest.kt
@@ -27,6 +27,9 @@
import android.widget.TextView
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.glance.Button
@@ -332,6 +335,48 @@
}
@Test
+ fun adapter_emptyList() {
+ TestGlanceAppWidget.uiDefinition = {
+ LazyColumn { }
+ }
+
+ mHostRule.startHost()
+
+ mHostRule.waitForListView { list ->
+ assertThat(list.childCount).isEqualTo(0)
+ assertThat(list.adapter.count).isEqualTo(0)
+ assertThat(list.adapter.viewTypeCount).isAtLeast(1)
+ assertThat(list.adapter.hasStableIds()).isFalse()
+ }
+ }
+
+ @Test
+ fun adapter_itemContentChangesOnClick_appliedCorrectly() {
+ TestGlanceAppWidget.uiDefinition = {
+ var count by remember { mutableStateOf(1) }
+ LazyColumn {
+ item {
+ Text(
+ text = "Row item 0, count $count",
+ modifier = GlanceModifier.clickable {
+ count++
+ })
+ }
+ }
+ }
+
+ mHostRule.startHost()
+
+ mHostRule.waitForListViewChildren { list ->
+ val row = list.getUnboxedListItem<FrameLayout>(0)
+ val rowItem0 = row.notGoneChildren.first()
+ rowItem0.performClick()
+ }
+
+ mHostRule.waitForListViewChildWithText(text = "Row item 0, count 1") {}
+ }
+
+ @Test
@SdkSuppress(minSdkVersion = 31)
fun clickable_addsClickHandlers() {
TestGlanceAppWidget.uiDefinition = {
@@ -503,6 +548,23 @@
}
}
+/**
+ * Wait until the ListView is loaded and has an adapter (irrespective of whether it has children or
+ * not). Use waitForListViewChildren if the list is expected to have children.
+ */
+internal fun AppWidgetHostRule.waitForListView(action: (list: ListView) -> Unit = {}) {
+ onHostView { }
+
+ runAndObserveUntilDraw(condition = "ListView did not load in time") {
+ mHostView.let { host ->
+ val list = host.findChildByType<ListView>()
+ host.childCount > 0 && list != null && list.adapter != null
+ }
+ }
+
+ onUnboxedHostView(action)
+}
+
internal fun AppWidgetHostRule.waitForListViewChildren(action: (list: ListView) -> Unit = {}) {
onHostView { }
@@ -516,6 +578,22 @@
onUnboxedHostView(action)
}
+internal fun AppWidgetHostRule.waitForListViewChildWithText(
+ text: String,
+ action: (list: ListView) -> Unit = {}
+) {
+ onHostView { }
+
+ runAndObserveUntilDraw(condition = "List child with text '$text' not load in time") {
+ mHostView.let { host ->
+ val list = host.findChildByType<ListView>()
+ host.childCount > 0 && list?.isItemLoaded(text) ?: false
+ }
+ }
+
+ onUnboxedHostView(action)
+}
+
/**
* Wait until the first ListView child under the root AppWidgetHostView has [count] children.
*
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/RemoteCollectionItemsTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/RemoteCollectionItemsTest.kt
new file mode 100644
index 0000000..41561f8
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/RemoteCollectionItemsTest.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.glance.appwidget
+
+import android.content.Context
+import android.widget.RemoteViews
+import androidx.glance.appwidget.test.R
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
+import org.junit.Test
+
+@SdkSuppress(maxSdkVersion = 29)
+@MediumTest
+class RemoteCollectionItemsTest {
+ private val context = ApplicationProvider.getApplicationContext<Context>()
+ private val packageName = context.packageName
+
+ @Test
+ fun testBuilder_empty() {
+ val items = RemoteCollectionItems.Builder().build()
+
+ assertThat(items.itemCount).isEqualTo(0)
+ assertThat(items.viewTypeCount).isEqualTo(1)
+ assertThat(items.hasStableIds()).isFalse()
+ }
+
+ @Test
+ fun testBuilder_viewTypeCountUnspecified() {
+ val firstItem = RemoteViews(packageName, R.layout.list_view_row)
+ val secondItem = RemoteViews(packageName, R.layout.list_view_row_2)
+ val items = RemoteCollectionItems.Builder()
+ .setHasStableIds(true)
+ .addItem(id = 3, firstItem)
+ .addItem(id = 5, secondItem)
+ .build()
+
+ assertThat(items.itemCount).isEqualTo(2)
+ assertThat(items.getItemId(0)).isEqualTo(3)
+ assertThat(items.getItemId(1)).isEqualTo(5)
+ assertThat(items.getItemView(0).layoutId).isEqualTo(R.layout.list_view_row)
+ assertThat(items.getItemView(1).layoutId).isEqualTo(R.layout.list_view_row_2)
+ assertThat(items.hasStableIds()).isTrue()
+ // The view type count should be derived from the number of different layout ids if
+ // unspecified.
+ assertThat(items.viewTypeCount).isEqualTo(2)
+ }
+
+ @Test
+ fun testBuilder_viewTypeCountSpecified() {
+ val firstItem = RemoteViews(packageName, R.layout.list_view_row)
+ val secondItem = RemoteViews(packageName, R.layout.list_view_row_2)
+ val items = RemoteCollectionItems.Builder()
+ .addItem(id = 3, firstItem)
+ .addItem(id = 5, secondItem)
+ .setViewTypeCount(15)
+ .build()
+
+ assertThat(items.viewTypeCount).isEqualTo(15)
+ }
+
+ @Test
+ fun testBuilder_repeatedIdsAndLayouts() {
+ val firstItem = RemoteViews(packageName, R.layout.list_view_row)
+ val secondItem = RemoteViews(packageName, R.layout.list_view_row)
+ val thirdItem = RemoteViews(packageName, R.layout.list_view_row)
+ val items = RemoteCollectionItems.Builder()
+ .setHasStableIds(false)
+ .addItem(id = 42, firstItem)
+ .addItem(id = 42, secondItem)
+ .addItem(id = 42, thirdItem)
+ .build()
+
+ assertThat(items.itemCount).isEqualTo(3)
+ assertThat(items.getItemId(0)).isEqualTo(42)
+ assertThat(items.getItemId(1)).isEqualTo(42)
+ assertThat(items.getItemId(2)).isEqualTo(42)
+ assertThat(items.getItemView(0)).isSameInstanceAs(firstItem)
+ assertThat(items.getItemView(1)).isSameInstanceAs(secondItem)
+ assertThat(items.getItemView(2)).isSameInstanceAs(thirdItem)
+ assertThat(items.hasStableIds()).isFalse()
+ assertThat(items.viewTypeCount).isEqualTo(1)
+ }
+
+ @Test
+ fun testBuilder_viewTypeCountLowerThanLayoutCount() {
+ assertFailsWith(IllegalArgumentException::class) {
+ RemoteCollectionItems.Builder()
+ .setHasStableIds(true)
+ .setViewTypeCount(1)
+ .addItem(3, RemoteViews(packageName, R.layout.list_view_row))
+ .addItem(5, RemoteViews(packageName, R.layout.list_view_row_2))
+ .build()
+ }
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt
index c733193..35ef162 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/ResourceResolutionTest.kt
@@ -28,9 +28,9 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertNotNull
import org.junit.Rule
import org.junit.Test
-import kotlin.test.assertNotNull
@SdkSuppress(minSdkVersion = 29)
@MediumTest
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/StrictModeTest.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/StrictModeTest.kt
index 6a3e51f..0caab64 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/StrictModeTest.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/StrictModeTest.kt
@@ -168,4 +168,4 @@
Truth.assertThat(CallbackTest.latch.await(5, TimeUnit.SECONDS)).isTrue()
Truth.assertThat(CallbackTest.received.get()).containsExactly(1, 2)
}
-}
\ No newline at end of file
+}
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithNightMode.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithNightMode.kt
index 45492af..cf36c45 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithNightMode.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithNightMode.kt
@@ -18,11 +18,11 @@
import android.content.res.Configuration
import android.os.Build
+import java.lang.reflect.AnnotatedElement
+import java.lang.reflect.Method
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
-import java.lang.reflect.AnnotatedElement
-import java.lang.reflect.Method
/**
* Annotation for specifying a per-test or per-method override of the device night mode
diff --git a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithRtl.kt b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithRtl.kt
index b15b830..b7f7961 100644
--- a/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithRtl.kt
+++ b/glance/glance-appwidget/src/androidAndroidTest/kotlin/androidx/glance/appwidget/WithRtl.kt
@@ -16,12 +16,12 @@
package androidx.glance.appwidget
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
import java.lang.reflect.AnnotatedElement
import java.lang.reflect.Method
import java.util.Locale
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
/**
* Annotation for specifying a per-test or per-method override of the default locale. Multiple
diff --git a/appsearch/appsearch-test-util/src/main/AndroidManifest.xml b/glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row.xml
similarity index 72%
rename from appsearch/appsearch-test-util/src/main/AndroidManifest.xml
rename to glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row.xml
index e0788d6..73eeb18 100644
--- a/appsearch/appsearch-test-util/src/main/AndroidManifest.xml
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright 2021 The Android Open Source Project
+ Copyright 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,4 +15,8 @@
limitations under the License.
-->
-<manifest />
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row_2.xml b/glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row_2.xml
new file mode 100644
index 0000000..7d2ccd3
--- /dev/null
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/layout/list_view_row_2.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ 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.
+ -->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="48dp"/>
+</FrameLayout>
\ No newline at end of file
diff --git a/camera/camera-camera2-pipe-testing/src/main/AndroidManifest.xml b/glance/glance-appwidget/src/androidAndroidTest/res/layout/remote_views_list.xml
similarity index 68%
rename from camera/camera-camera2-pipe-testing/src/main/AndroidManifest.xml
rename to glance/glance-appwidget/src/androidAndroidTest/res/layout/remote_views_list.xml
index 9515a11..8d0b5c9 100644
--- a/camera/camera-camera2-pipe-testing/src/main/AndroidManifest.xml
+++ b/glance/glance-appwidget/src/androidAndroidTest/res/layout/remote_views_list.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!--
- Copyright 2020 The Android Open Source Project
+ Copyright 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,4 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<manifest />
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/list_view"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/AndroidManifest.xml b/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
index 9bcafb2..a78692f 100644
--- a/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
+++ b/glance/glance-appwidget/src/androidMain/AndroidManifest.xml
@@ -41,5 +41,9 @@
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
+ <service
+ android:name="androidx.glance.appwidget.GlanceRemoteViewsService"
+ android:permission="android.permission.BIND_REMOTEVIEWS"
+ android:exported="true" />
</application>
</manifest>
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt
index 92f688c..74bc2e5 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt
@@ -42,6 +42,7 @@
import androidx.glance.state.ConfigManager
import androidx.glance.state.GlanceState
import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.channels.Channel
/**
* A session that composes UI for a single app widget.
@@ -73,6 +74,7 @@
private val glanceState = mutableStateOf<Any?>(null, neverEqualPolicy())
private val options = mutableStateOf(Bundle(), neverEqualPolicy())
private var lambdas = mapOf<String, List<LambdaAction>>()
+
@VisibleForTesting
internal var lastRemoteViews: RemoteViews? = null
private set
@@ -184,6 +186,7 @@
lambdas[event.key]?.forEach { it.block() }
} ?: Log.w(TAG, "Triggering Action(${event.key}) for session($key) failed")
}
+ is WaitForReady -> event.resume.send(Unit)
else -> {
throw IllegalArgumentException(
"Sent unrecognized event type ${event.javaClass} to AppWidgetSession"
@@ -204,6 +207,13 @@
sendEvent(RunLambda(key))
}
+ suspend fun waitForReady() {
+ WaitForReady().let {
+ sendEvent(it)
+ it.resume.receive()
+ }
+ }
+
// Event types that this session supports.
@VisibleForTesting
internal object UpdateGlanceState
@@ -211,4 +221,8 @@
internal class UpdateAppWidgetOptions(val newOptions: Bundle)
@VisibleForTesting
internal class RunLambda(val key: String)
+ @VisibleForTesting
+ internal class WaitForReady(
+ val resume: Channel<Unit> = Channel(Channel.CONFLATED)
+ )
}
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
index 7ab9e6a..b963763 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/CoroutineBroadcastReceiver.kt
@@ -18,13 +18,13 @@
import android.content.BroadcastReceiver
import android.util.Log
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
-import kotlin.coroutines.CoroutineContext
/**
* Execute the block asynchronously in a scope with the lifetime of the broadcast.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceRemoteViewsService.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceRemoteViewsService.kt
new file mode 100644
index 0000000..a9b49c7
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceRemoteViewsService.kt
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.glance.appwidget
+
+import android.appwidget.AppWidgetManager
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Build
+import android.widget.RemoteViews
+import android.widget.RemoteViewsService
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.glance.session.GlanceSessionManager
+import kotlinx.coroutines.runBlocking
+
+/**
+ * [RemoteViewsService] to be connected to for a remote adapter that returns RemoteViews for lazy
+ * lists / grids.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class GlanceRemoteViewsService : RemoteViewsService() {
+ override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
+ val appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)
+ check(appWidgetId != -1) { "No app widget id was present in the intent" }
+
+ val viewId = intent.getIntExtra(EXTRA_VIEW_ID, -1)
+ check(viewId != -1) { "No view id was present in the intent" }
+
+ val sizeInfo = intent.getStringExtra(EXTRA_SIZE_INFO)
+ check(!sizeInfo.isNullOrEmpty()) { "No size info was present in the intent" }
+
+ return GlanceRemoteViewsFactory(this, appWidgetId, viewId, sizeInfo)
+ }
+
+ companion object {
+ const val EXTRA_VIEW_ID = "androidx.glance.widget.extra.view_id"
+ const val EXTRA_SIZE_INFO = "androidx.glance.widget.extra.size_info"
+
+ // An in-memory store containing items to be returned via the adapter when requested.
+ private val InMemoryStore = RemoteCollectionItemsInMemoryStore()
+
+ // Adds items to the store for later use by the list adapter to display the items.
+ internal fun saveItems(
+ appWidgetId: Int,
+ viewId: Int,
+ sizeInfo: String,
+ remoteCollectionItems: RemoteCollectionItems
+ ) {
+ synchronized(InMemoryStore) {
+ InMemoryStore.save(appWidgetId, viewId, sizeInfo, remoteCollectionItems)
+ }
+ }
+
+ // Returns items in the store for the requested view in appwidget for the specified size.
+ private fun getItems(
+ appWidgetId: Int,
+ viewId: Int,
+ sizeInfo: String
+ ): RemoteCollectionItems {
+ return synchronized(InMemoryStore) {
+ InMemoryStore.getItems(appWidgetId, viewId, sizeInfo)
+ }
+ }
+
+ // Removes items in the store for the requested view in appwidget for the specified size.
+ private fun removeItems(appWidgetId: Int, viewId: Int, sizeInfo: String) {
+ synchronized(InMemoryStore) {
+ InMemoryStore.removeItems(appWidgetId, viewId, sizeInfo)
+ }
+ }
+ }
+
+ /**
+ * A RemoteViewsFactory that holds items in memory and provides it to the host when requested.
+ *
+ * <p>Starts glance session if needed to reload items in memory e.g. when app process was killed
+ * and user scrolled on an existing list / grid view.
+ */
+ internal class GlanceRemoteViewsFactory(
+ private val context: Context,
+ private val appWidgetId: Int,
+ private val viewId: Int,
+ private val size: String
+ ) : RemoteViewsFactory {
+ override fun onCreate() {
+ // OnDataSetChanged is always called even onCreate, so we don't need to load data here.
+ }
+
+ override fun onDataSetChanged() = loadData()
+
+ private fun loadData() {
+ runBlocking {
+ val glanceId = AppWidgetId(appWidgetId)
+ // If session is already running, data must have already been loaded into the store
+ // during composition.
+ if (!GlanceSessionManager.isSessionRunning(context, glanceId.toSessionKey())) {
+ startSessionAndWaitUntilReady(glanceId)
+ }
+ }
+ }
+
+ private suspend fun startSessionAndWaitUntilReady(glanceId: AppWidgetId) {
+ val appWidgetManager = AppWidgetManager.getInstance(context)
+ val providerInfo = appWidgetManager.getAppWidgetInfo(appWidgetId)
+ if (providerInfo?.provider != null) {
+ val receiverClass = Class.forName(providerInfo.provider.className)
+ val glanceAppWidget =
+ (receiverClass.getDeclaredConstructor()
+ .newInstance() as GlanceAppWidgetReceiver).glanceAppWidget
+ AppWidgetSession(glanceAppWidget, glanceId)
+ .also { GlanceSessionManager.startSession(context, it) }
+ .waitForReady()
+ }
+ }
+
+ override fun onDestroy() {
+ removeItems(appWidgetId, viewId, size)
+ }
+
+ private fun items() = getItems(appWidgetId, viewId, size)
+
+ override fun getCount(): Int {
+ return items().itemCount
+ }
+
+ override fun getViewAt(position: Int): RemoteViews {
+ return items().getItemView(position)
+ }
+
+ override fun getLoadingView() = null
+
+ override fun getViewTypeCount(): Int = items().viewTypeCount
+
+ override fun getItemId(position: Int): Long = items().getItemId(position)
+
+ override fun hasStableIds(): Boolean = items().hasStableIds()
+ }
+}
+
+/**
+ * An in-memory store holding [RemoteCollectionItems] for each sized lazy view in appWidgets.
+ */
+private class RemoteCollectionItemsInMemoryStore {
+ private val items = mutableMapOf<String, RemoteCollectionItems>()
+
+ fun save(
+ appWidgetId: Int,
+ viewId: Int,
+ sizeInfo: String,
+ remoteCollectionItems: RemoteCollectionItems
+ ) {
+ items[key(appWidgetId, viewId, sizeInfo)] = remoteCollectionItems
+ }
+
+ /**
+ * Returns the collection items corresponding to the requested view in appwidget and size.
+ */
+ fun getItems(appWidgetId: Int, viewId: Int, sizeInfo: String): RemoteCollectionItems {
+ return items[key(appWidgetId, viewId, sizeInfo)] ?: RemoteCollectionItems.Empty
+ }
+
+ /**
+ * Removes the collection items corresponding to the requested view in appwidget and size.
+ */
+ fun removeItems(appWidgetId: Int, viewId: Int, sizeInfo: String) {
+ items.remove(key(appWidgetId, viewId, sizeInfo))
+ }
+
+ // A unique key for RemoteCollectionItems in the store. Including size info allows us to compose
+ // for different sizes and maintain separate collection items for each size.
+ private fun key(appWidgetId: Int, viewId: Int, sizeInfo: String): String {
+ return "$appWidgetId-$viewId-$sizeInfo"
+ }
+}
+
+/**
+ * Sets remote views adapter.
+ *
+ * <p>For SDKs higher than S, passes the items in the adapter. For S and below SDKs, connects to a
+ * GlanceRemoteViewsService using an intent.
+ */
+@Suppress("DEPRECATION")
+@DoNotInline
+internal fun RemoteViews.setRemoteAdapter(
+ context: Context,
+ appWidgetId: Int,
+ viewId: Int,
+ sizeInfo: String,
+ items: RemoteCollectionItems
+) {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S) {
+ CollectionItemsApi31Impl.setRemoteAdapter(this, viewId, items)
+ } else {
+ val intent = Intent(context, GlanceRemoteViewsService::class.java)
+ .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
+ .putExtra(GlanceRemoteViewsService.EXTRA_VIEW_ID, viewId)
+ .putExtra(GlanceRemoteViewsService.EXTRA_SIZE_INFO, sizeInfo)
+ .apply {
+ // Set a data Uri to disambiguate Intents for different widget/view ids.
+ data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME))
+ }
+ check(context.packageManager.resolveService(intent, 0) != null) {
+ "GlanceRemoteViewsService could not be resolved, check the app manifest."
+ }
+ setRemoteAdapter(viewId, intent)
+ GlanceRemoteViewsService.saveItems(
+ appWidgetId,
+ viewId,
+ sizeInfo,
+ items
+ )
+ AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, viewId)
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.S)
+private object CollectionItemsApi31Impl {
+ @DoNotInline
+ fun setRemoteAdapter(remoteViews: RemoteViews, viewId: Int, items: RemoteCollectionItems) {
+ remoteViews.setRemoteAdapter(viewId, toPlatformCollectionItems(items))
+ }
+
+ @DoNotInline
+ fun toPlatformCollectionItems(items: RemoteCollectionItems):
+ RemoteViews.RemoteCollectionItems {
+ return RemoteViews.RemoteCollectionItems.Builder()
+ .setHasStableIds(items.hasStableIds())
+ .setViewTypeCount(items.viewTypeCount)
+ .also { builder ->
+ repeat(items.itemCount) { index ->
+ builder.addItem(items.getItemId(index), items.getItemView(index))
+ }
+ }
+ .build()
+ }
+}
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LinearProgressIndicator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LinearProgressIndicator.kt
index 409413f..e314c1a 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LinearProgressIndicator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/LinearProgressIndicator.kt
@@ -17,10 +17,10 @@
package androidx.glance.appwidget
import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
import androidx.glance.Emittable
import androidx.glance.GlanceModifier
import androidx.glance.GlanceNode
-import androidx.compose.ui.graphics.Color
import androidx.glance.unit.ColorProvider
/**
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteCollectionItems.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteCollectionItems.kt
new file mode 100644
index 0000000..61c8bcb
--- /dev/null
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteCollectionItems.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.glance.appwidget
+
+import android.annotation.SuppressLint
+import android.widget.RemoteViews
+
+/** Representation of a fixed list of items to be displayed in a RemoteViews collection. */
+internal class RemoteCollectionItems private constructor(
+ private val ids: LongArray,
+ private val views: Array<RemoteViews>,
+ private val hasStableIds: Boolean,
+ private val _viewTypeCount: Int
+) {
+ init {
+ require(ids.size == views.size) {
+ "RemoteCollectionItems has different number of ids and views"
+ }
+ require(_viewTypeCount >= 1) { "View type count must be >= 1" }
+ val layoutIdCount = views.map { it.layoutId }.distinct().count()
+ require(layoutIdCount <= _viewTypeCount) {
+ "View type count is set to $_viewTypeCount, but the collection contains " +
+ "$layoutIdCount different layout ids"
+ }
+ }
+
+ /**
+ * Returns the id for [position]. See [hasStableIds] for whether this id should be
+ * considered meaningful across collection updates.
+ *
+ * @return Id for the position.
+ */
+ fun getItemId(position: Int): Long = ids[position]
+
+ /**
+ * Returns the [RemoteViews] to display at [position].
+ *
+ * @return RemoteViews for the position.
+ */
+ fun getItemView(position: Int): RemoteViews = views[position]
+
+ /**
+ * Returns the number of elements in the collection.
+ *
+ * @return Count of items.
+ */
+ val itemCount: Int
+ get() = ids.size
+
+ /**
+ * Returns the view type count for the collection when used in an adapter
+ *
+ * @return Count of view types for the collection when used in an adapter.
+ * @see android.widget.Adapter.getViewTypeCount
+ */
+ val viewTypeCount: Int
+ get() = _viewTypeCount
+
+ /**
+ * Indicates whether the item ids are stable across changes to the underlying data.
+ *
+ * @return True if the same id always refers to the same object.
+ * @see android.widget.Adapter.hasStableIds
+ */
+ fun hasStableIds(): Boolean = hasStableIds
+
+ /** Builder class for [RemoteCollectionItems] objects. */
+ class Builder {
+ private val ids = arrayListOf<Long>()
+ private val views = arrayListOf<RemoteViews>()
+ private var hasStableIds = false
+ private var viewTypeCount = 0
+
+ /**
+ * Adds a [RemoteViews] to the collection.
+ *
+ * @param id Id to associate with the row. Use [.setHasStableIds] to indicate that ids are
+ * stable across changes to the collection.
+ * @param view RemoteViews to display for the row.
+ */
+ // Covered by getItemId, getItemView, getItemCount.
+ @SuppressLint("MissingGetterMatchingBuilder")
+ fun addItem(id: Long, view: RemoteViews): Builder {
+ ids.add(id)
+ views.add(view)
+ return this
+ }
+
+ /**
+ * Sets whether the item ids are stable across changes to the underlying data.
+ *
+ * @see android.widget.Adapter.hasStableIds
+ */
+ fun setHasStableIds(hasStableIds: Boolean): Builder {
+ this.hasStableIds = hasStableIds
+ return this
+ }
+
+ /**
+ * Sets the view type count for the collection when used in an adapter. This can be set
+ * to the maximum number of different layout ids that will be used by RemoteViews in
+ * this collection.
+ *
+ * If this value is not set, then a value will be inferred from the provided items. As
+ * a result, the adapter may need to be recreated when the list is updated with
+ * previously unseen RemoteViews layouts for new items.
+ *
+ * @see android.widget.Adapter.getViewTypeCount
+ */
+ fun setViewTypeCount(viewTypeCount: Int): Builder {
+ this.viewTypeCount = viewTypeCount
+ return this
+ }
+
+ /** Creates the [RemoteCollectionItems] defined by this builder. */
+ fun build(): RemoteCollectionItems {
+ if (viewTypeCount < 1) {
+ // If a view type count wasn't specified, set it to be the number of distinct
+ // layout ids used in the items.
+ viewTypeCount = views.map { it.layoutId }.distinct().count()
+ }
+ return RemoteCollectionItems(
+ ids.toLongArray(),
+ views.toTypedArray(),
+ hasStableIds,
+ maxOf(viewTypeCount, 1)
+ )
+ }
+ }
+
+ companion object {
+ val Empty = RemoteCollectionItems(
+ ids = longArrayOf(),
+ views = emptyArray(),
+ hasStableIds = false,
+ _viewTypeCount = 1
+ )
+ }
+}
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
index e6a5fed..2618cbc 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/RemoteViewsTranslator.kt
@@ -30,6 +30,7 @@
import androidx.annotation.VisibleForTesting
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.isSpecified
import androidx.core.widget.RemoteViewsCompat.setLinearLayoutGravity
import androidx.glance.Emittable
import androidx.glance.EmittableButton
@@ -114,7 +115,10 @@
val size = (child as EmittableSizeBox).size
val remoteViewsInfo = createRootView(translationContext, child.modifier, rootViewIndex)
val rv = remoteViewsInfo.remoteViews.apply {
- translateChild(translationContext.forRoot(root = remoteViewsInfo), child)
+ translateChild(
+ translationContext.forRootAndSize(root = remoteViewsInfo, size),
+ child
+ )
}
size.toSizeF() to rv
}
@@ -146,7 +150,7 @@
else -> throw IllegalArgumentException("There must be between 1 and 2 views.")
}
-private const val LastInvalidViewId = 1
+private const val LAST_INVALID_VIEW_ID = 1
internal data class TranslationContext(
val context: Context,
@@ -155,7 +159,7 @@
val layoutConfiguration: LayoutConfiguration?,
val itemPosition: Int,
val isLazyCollectionDescendant: Boolean = false,
- val lastViewId: AtomicInteger = AtomicInteger(LastInvalidViewId),
+ val lastViewId: AtomicInteger = AtomicInteger(LAST_INVALID_VIEW_ID),
val parentContext: InsertedViewInfo = InsertedViewInfo(),
val isBackgroundSpecified: AtomicBoolean = AtomicBoolean(false),
val layoutSize: DpSize = DpSize.Zero,
@@ -174,7 +178,15 @@
forChild(pos = 0, parent = root.view)
.copy(
isBackgroundSpecified = AtomicBoolean(false),
- lastViewId = AtomicInteger(LastInvalidViewId),
+ lastViewId = AtomicInteger(LAST_INVALID_VIEW_ID),
+ )
+
+ fun forRootAndSize(root: RemoteViewsInfo, layoutSize: DpSize): TranslationContext =
+ forChild(pos = 0, parent = root.view)
+ .copy(
+ isBackgroundSpecified = AtomicBoolean(false),
+ lastViewId = AtomicInteger(LAST_INVALID_VIEW_ID),
+ layoutSize = layoutSize
)
fun resetViewId(newViewId: Int = 0) = copy(lastViewId = AtomicInteger(newViewId))
@@ -190,6 +202,14 @@
fun forActionTargetId(viewId: Int) = copy(actionTargetId = viewId)
}
+internal fun DpSize.toSizeString(): String {
+ return if (isSpecified) {
+ "${width}x$height"
+ } else {
+ "Unspecified"
+ }
+}
+
internal fun RemoteViews.translateChild(
translationContext: TranslationContext,
element: Emittable
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
index b106440..cea6860 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/Utils.kt
@@ -23,10 +23,10 @@
import android.widget.RemoteViews
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
-import androidx.core.widget.RemoteViewsCompat.setViewStubInflatedId
-import androidx.core.widget.RemoteViewsCompat.setViewStubLayoutResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.core.widget.RemoteViewsCompat.setViewStubInflatedId
+import androidx.core.widget.RemoteViewsCompat.setViewStubLayoutResource
internal fun Dp.toPixels(context: Context) = toPixels(context.resources.displayMetrics)
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
index 0efa461..77a2e9d 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/lazy/LazyVerticalGrid.kt
@@ -15,17 +15,17 @@
*/
package androidx.glance.appwidget.lazy
-import androidx.compose.runtime.Composable
-import androidx.glance.GlanceModifier
-import androidx.glance.GlanceNode
-import androidx.glance.layout.Alignment
-import androidx.glance.EmittableWithChildren
-import androidx.glance.layout.fillMaxWidth
-import androidx.glance.layout.wrapContentHeight
import androidx.annotation.RequiresApi
+import androidx.compose.runtime.Composable
import androidx.compose.runtime.key
import androidx.compose.ui.unit.Dp
import androidx.glance.Emittable
+import androidx.glance.EmittableWithChildren
+import androidx.glance.GlanceModifier
+import androidx.glance.GlanceNode
+import androidx.glance.layout.Alignment
+import androidx.glance.layout.fillMaxWidth
+import androidx.glance.layout.wrapContentHeight
/**
* The DSL implementation of a lazy grid layout. It composes only visible rows of the grid.
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
index 0d7c717..aa002f4 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/CircularProgressIndicatorTranslator.kt
@@ -16,20 +16,22 @@
package androidx.glance.appwidget.translators
+import android.content.res.ColorStateList
import android.os.Build
+import android.util.Log
import android.widget.RemoteViews
+import androidx.compose.ui.graphics.toArgb
+import androidx.core.widget.RemoteViewsCompat.setProgressBarIndeterminateTintList
+import androidx.glance.appwidget.EmittableCircularProgressIndicator
+import androidx.glance.appwidget.GlanceAppWidgetTag
import androidx.glance.appwidget.LayoutType
import androidx.glance.appwidget.TranslationContext
import androidx.glance.appwidget.applyModifiers
import androidx.glance.appwidget.insertView
-import androidx.core.widget.RemoteViewsCompat.setProgressBarIndeterminateTintList
-import androidx.compose.ui.graphics.toArgb
-import android.content.res.ColorStateList
+import androidx.glance.color.DayNightColorProvider
import androidx.glance.unit.FixedColorProvider
import androidx.glance.unit.ResourceColorProvider
-import androidx.glance.appwidget.EmittableCircularProgressIndicator
-
internal fun RemoteViews.translateEmittableCircularProgressIndicator(
translationContext: TranslationContext,
element: EmittableCircularProgressIndicator
@@ -49,9 +51,18 @@
is ResourceColorProvider -> {
setProgressBarIndeterminateTintList(
viewId = viewDef.mainViewId,
- tint = ColorStateList.valueOf(indicatorColor.resId)
+ resId = indicatorColor.resId
)
}
+ is DayNightColorProvider -> {
+ setProgressBarIndeterminateTintList(
+ viewId = viewDef.mainViewId,
+ notNightTint = ColorStateList.valueOf(indicatorColor.day.toArgb()),
+ nightTint = ColorStateList.valueOf(indicatorColor.night.toArgb())
+ )
+ }
+ else ->
+ Log.w(GlanceAppWidgetTag, "Unexpected progress indicator color: $indicatorColor")
}
}
applyModifiers(translationContext, this, element.modifier, viewDef)
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyListTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyListTranslator.kt
index 6c02991..2698f76 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyListTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyListTranslator.kt
@@ -22,9 +22,9 @@
import android.content.Intent
import android.content.Intent.FILL_IN_COMPONENT
import android.widget.RemoteViews
-import androidx.core.widget.RemoteViewsCompat
import androidx.glance.appwidget.InsertedViewInfo
import androidx.glance.appwidget.LayoutType
+import androidx.glance.appwidget.RemoteCollectionItems
import androidx.glance.appwidget.TopLevelLayoutsCount
import androidx.glance.appwidget.TranslationContext
import androidx.glance.appwidget.applyModifiers
@@ -33,6 +33,8 @@
import androidx.glance.appwidget.lazy.EmittableLazyList
import androidx.glance.appwidget.lazy.EmittableLazyListItem
import androidx.glance.appwidget.lazy.ReservedItemIdRangeEnd
+import androidx.glance.appwidget.setRemoteAdapter
+import androidx.glance.appwidget.toSizeString
import androidx.glance.appwidget.translateChild
import androidx.glance.appwidget.translateComposition
import androidx.glance.layout.Alignment
@@ -67,7 +69,7 @@
FILL_IN_COMPONENT or FLAG_MUTABLE or FLAG_UPDATE_CURRENT,
)
)
- val items = RemoteViewsCompat.RemoteCollectionItems.Builder().apply {
+ val items = RemoteCollectionItems.Builder().apply {
val childContext = translationContext.forLazyCollection(viewDef.mainViewId)
element.children.foldIndexed(false) { position, previous, itemEmittable ->
itemEmittable as EmittableLazyListItem
@@ -85,11 +87,11 @@
}.let { setHasStableIds(it) }
setViewTypeCount(TopLevelLayoutsCount)
}.build()
- RemoteViewsCompat.setRemoteAdapter(
+ setRemoteAdapter(
translationContext.context,
- this,
translationContext.appWidgetId,
viewDef.mainViewId,
+ translationContext.layoutSize.toSizeString(),
items
)
applyModifiers(translationContext, this, element.modifier, viewDef)
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyVerticalGridTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyVerticalGridTranslator.kt
index b81a8c9..805c1f7 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyVerticalGridTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LazyVerticalGridTranslator.kt
@@ -16,17 +16,17 @@
package androidx.glance.appwidget.translators
-import android.os.Build
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_MUTABLE
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Intent
import android.content.Intent.FILL_IN_COMPONENT
+import android.os.Build
import android.widget.RemoteViews
-import androidx.core.widget.RemoteViewsCompat
import androidx.core.widget.RemoteViewsCompat.setGridViewColumnWidth
import androidx.glance.appwidget.InsertedViewInfo
import androidx.glance.appwidget.LayoutType
+import androidx.glance.appwidget.RemoteCollectionItems
import androidx.glance.appwidget.TopLevelLayoutsCount
import androidx.glance.appwidget.TranslationContext
import androidx.glance.appwidget.applyModifiers
@@ -35,6 +35,8 @@
import androidx.glance.appwidget.lazy.EmittableLazyVerticalGridListItem
import androidx.glance.appwidget.lazy.GridCells
import androidx.glance.appwidget.lazy.ReservedItemIdRangeEnd
+import androidx.glance.appwidget.setRemoteAdapter
+import androidx.glance.appwidget.toSizeString
import androidx.glance.appwidget.translateChild
import androidx.glance.appwidget.translateComposition
import androidx.glance.layout.Alignment
@@ -80,7 +82,7 @@
FILL_IN_COMPONENT or FLAG_MUTABLE or FLAG_UPDATE_CURRENT,
)
)
- val items = RemoteViewsCompat.RemoteCollectionItems.Builder().apply {
+ val items = RemoteCollectionItems.Builder().apply {
val childContext = translationContext.forLazyCollection(viewDef.mainViewId)
element.children.foldIndexed(false) { position, previous, itemEmittable ->
itemEmittable as EmittableLazyVerticalGridListItem
@@ -98,11 +100,11 @@
}.let { setHasStableIds(it) }
setViewTypeCount(TopLevelLayoutsCount)
}.build()
- RemoteViewsCompat.setRemoteAdapter(
+ setRemoteAdapter(
translationContext.context,
- this,
translationContext.appWidgetId,
viewDef.mainViewId,
+ translationContext.layoutSize.toSizeString(),
items
)
if (Build.VERSION.SDK_INT >= 31 && gridCells is GridCells.Adaptive) {
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
index 0c1342b..b3d72ae 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/translators/LinearProgressIndicatorTranslator.kt
@@ -16,21 +16,23 @@
package androidx.glance.appwidget.translators
+import android.content.res.ColorStateList
import android.os.Build
+import android.util.Log
import android.widget.RemoteViews
+import androidx.compose.ui.graphics.toArgb
+import androidx.core.widget.RemoteViewsCompat.setProgressBarProgressBackgroundTintList
+import androidx.core.widget.RemoteViewsCompat.setProgressBarProgressTintList
+import androidx.glance.appwidget.EmittableLinearProgressIndicator
+import androidx.glance.appwidget.GlanceAppWidgetTag
import androidx.glance.appwidget.LayoutType
import androidx.glance.appwidget.TranslationContext
import androidx.glance.appwidget.applyModifiers
import androidx.glance.appwidget.insertView
-import androidx.core.widget.RemoteViewsCompat.setProgressBarProgressTintList
-import androidx.core.widget.RemoteViewsCompat.setProgressBarProgressBackgroundTintList
-import androidx.compose.ui.graphics.toArgb
-import android.content.res.ColorStateList
+import androidx.glance.color.DayNightColorProvider
import androidx.glance.unit.FixedColorProvider
import androidx.glance.unit.ResourceColorProvider
-import androidx.glance.appwidget.EmittableLinearProgressIndicator
-
internal fun RemoteViews.translateEmittableLinearProgressIndicator(
translationContext: TranslationContext,
element: EmittableLinearProgressIndicator
@@ -54,6 +56,15 @@
resId = indicatorColor.resId
)
}
+ is DayNightColorProvider -> {
+ setProgressBarProgressTintList(
+ viewId = viewDef.mainViewId,
+ notNightTint = ColorStateList.valueOf(indicatorColor.day.toArgb()),
+ nightTint = ColorStateList.valueOf(indicatorColor.night.toArgb())
+ )
+ }
+ else ->
+ Log.w(GlanceAppWidgetTag, "Unexpected progress indicator color: $indicatorColor")
}
when (val backgroundColor = element.backgroundColor) {
@@ -69,6 +80,16 @@
resId = backgroundColor.resId
)
}
+ is DayNightColorProvider -> {
+ setProgressBarProgressBackgroundTintList(
+ viewId = viewDef.mainViewId,
+ notNightTint = ColorStateList.valueOf(backgroundColor.day.toArgb()),
+ nightTint = ColorStateList.valueOf(backgroundColor.night.toArgb())
+ )
+ }
+ else ->
+ Log.w(GlanceAppWidgetTag,
+ "Unexpected progress indicator background color: $backgroundColor")
}
}
applyModifiers(translationContext, this, element.modifier, viewDef)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ActionCallbackBroadcastReceiverTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ActionCallbackBroadcastReceiverTest.kt
index 8cb1cda..310431e 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ActionCallbackBroadcastReceiverTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ActionCallbackBroadcastReceiverTest.kt
@@ -26,10 +26,10 @@
import androidx.glance.appwidget.action.createUniqueUri
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import java.io.Serializable
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import java.io.Serializable
@RunWith(RobolectricTestRunner::class)
class ActionCallbackBroadcastReceiverTest {
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt
index 46c84a9..378cecf 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ApplyDimensionModifierTest.kt
@@ -43,6 +43,8 @@
import androidx.glance.text.Text
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -50,8 +52,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
-import kotlin.test.assertNotNull
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
index 04e1faf..2be2889 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/TestUtils.kt
@@ -42,13 +42,13 @@
import androidx.glance.session.GlobalSnapshotManager
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.currentCoroutineContext
-import kotlinx.coroutines.launch
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.test.assertIs
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
internal suspend fun runTestingComposition(
content: @Composable @GlanceComposable () -> Unit,
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ViewSubject.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ViewSubject.kt
index d8a66f2..caf58cc 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ViewSubject.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/ViewSubject.kt
@@ -34,11 +34,11 @@
import androidx.glance.layout.Alignment
import com.google.common.truth.FailureMetadata
import com.google.common.truth.Subject
-import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertAbout
-import org.robolectric.Shadows.shadowOf
+import com.google.common.truth.Truth.assertThat
import kotlin.test.assertIs
import kotlin.test.assertNotNull
+import org.robolectric.Shadows.shadowOf
internal open class ViewSubject(
metaData: FailureMetadata,
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/LaunchActivityIntentActionTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/LaunchActivityIntentActionTest.kt
index acded2e..b07dfcf 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/LaunchActivityIntentActionTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/LaunchActivityIntentActionTest.kt
@@ -25,11 +25,11 @@
import androidx.glance.findModifier
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/RunCallbackActionTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/RunCallbackActionTest.kt
index 47f979d..cbc0ff6 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/RunCallbackActionTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/RunCallbackActionTest.kt
@@ -23,13 +23,13 @@
import androidx.glance.action.ActionParameters
import androidx.glance.action.clickable
import androidx.glance.findModifier
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/SendBroadcastActionTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/SendBroadcastActionTest.kt
index 061d7ef..303a6d6 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/SendBroadcastActionTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/SendBroadcastActionTest.kt
@@ -26,11 +26,11 @@
import androidx.glance.findModifier
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/StartServiceActionTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/StartServiceActionTest.kt
index 431e9f0..a19b0e9 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/StartServiceActionTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/action/StartServiceActionTest.kt
@@ -27,11 +27,11 @@
import androidx.glance.findModifier
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyColumnTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyColumnTest.kt
index 7da7812..22c6a6c 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyColumnTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyColumnTest.kt
@@ -28,12 +28,12 @@
import androidx.glance.text.EmittableText
import androidx.glance.text.Text
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class LazyColumnTest {
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyVerticalGridTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyVerticalGridTest.kt
index 207f899..0e686ff 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyVerticalGridTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/layout/LazyVerticalGridTest.kt
@@ -17,10 +17,11 @@
package androidx.glance.appwidget.layout
import android.annotation.TargetApi
+import androidx.compose.ui.unit.dp
import androidx.glance.appwidget.lazy.EmittableLazyVerticalGrid
import androidx.glance.appwidget.lazy.EmittableLazyVerticalGridListItem
-import androidx.glance.appwidget.lazy.LazyVerticalGrid
import androidx.glance.appwidget.lazy.GridCells
+import androidx.glance.appwidget.lazy.LazyVerticalGrid
import androidx.glance.appwidget.lazy.ReservedItemIdRangeEnd
import androidx.glance.appwidget.lazy.items
import androidx.glance.appwidget.lazy.itemsIndexed
@@ -29,14 +30,13 @@
import androidx.glance.layout.Row
import androidx.glance.text.EmittableText
import androidx.glance.text.Text
-import androidx.compose.ui.unit.dp
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class LazyVerticalGridTest {
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
index cddb9bd..cc9f17e 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/RadioButtonBackportTranslatorTest.kt
@@ -39,6 +39,7 @@
import androidx.glance.unit.ColorProvider
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -48,7 +49,6 @@
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
-import kotlin.test.assertIs
@Config(minSdk = 23, maxSdk = 30)
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
index ec11aab..fbb441e 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/translators/SwitchBackportTranslatorTest.kt
@@ -24,13 +24,13 @@
import androidx.glance.GlanceModifier
import androidx.glance.appwidget.ImageViewSubject.Companion.assertThat
import androidx.glance.appwidget.Switch
+import androidx.glance.appwidget.SwitchDefaults
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.applyRemoteViews
import androidx.glance.appwidget.configurationContext
import androidx.glance.appwidget.findView
import androidx.glance.appwidget.runAndTranslate
-import androidx.glance.appwidget.SwitchDefaults
import androidx.glance.color.ColorProvider
import androidx.glance.semantics.contentDescription
import androidx.glance.semantics.semantics
diff --git a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/unit/ColorProviderTest.kt b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/unit/ColorProviderTest.kt
index 55f242d..dfe943a 100644
--- a/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/unit/ColorProviderTest.kt
+++ b/glance/glance-appwidget/src/test/kotlin/androidx/glance/appwidget/unit/ColorProviderTest.kt
@@ -18,19 +18,19 @@
import android.content.Context
import androidx.compose.ui.graphics.Color
+import androidx.glance.appwidget.ColorSubject.Companion.assertThat
import androidx.glance.appwidget.test.R
import androidx.glance.appwidget.unit.CheckedUncheckedColorProvider.Companion.createCheckableColorProvider
+import androidx.glance.color.ColorProvider
import androidx.glance.unit.ColorProvider
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
-import androidx.glance.appwidget.ColorSubject.Companion.assertThat
-import androidx.glance.color.ColorProvider
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.robolectric.annotation.Config
-import org.robolectric.RobolectricTestRunner
import kotlin.test.assertFailsWith
import kotlin.test.assertIs
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
class ColorProviderTest {
diff --git a/glance/glance-material/build.gradle b/glance/glance-material/build.gradle
index 5a02590..17a787b 100644
--- a/glance/glance-material/build.gradle
+++ b/glance/glance-material/build.gradle
@@ -26,7 +26,7 @@
}
androidx {
- name = "Android Glance Material"
+ name = "Glance Material"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Glance Material 2 integration library." +
diff --git a/glance/glance-material3/build.gradle b/glance/glance-material3/build.gradle
index 4177903..9439749 100644
--- a/glance/glance-material3/build.gradle
+++ b/glance/glance-material3/build.gradle
@@ -26,7 +26,7 @@
}
androidx {
- name = "Android Glance Material"
+ name = "Glance Material"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Glance Material integration library." +
diff --git a/glance/glance-preview/build.gradle b/glance/glance-preview/build.gradle
index 844dcee..0857b2ee 100644
--- a/glance/glance-preview/build.gradle
+++ b/glance/glance-preview/build.gradle
@@ -24,7 +24,7 @@
}
androidx {
- name = "Android Glance Preview"
+ name = "Glance Preview"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GLANCE_PREVIEW
inceptionYear = "2022"
diff --git a/glance/glance-template/build.gradle b/glance/glance-template/build.gradle
index a74f078..331d3e2 100644
--- a/glance/glance-template/build.gradle
+++ b/glance/glance-template/build.gradle
@@ -73,7 +73,7 @@
}
androidx {
- name = "Glance Templates Library"
+ name = "Glance Templates"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GLANCE_TEMPLATE
inceptionYear = "2021"
diff --git a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
index 5ee0b7f..5c33d7e 100644
--- a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
+++ b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/DemoOverrideWidget.kt
@@ -24,15 +24,15 @@
import androidx.glance.ImageProvider
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
-import androidx.glance.template.GlanceTemplateAppWidget
-import androidx.glance.template.SingleEntityTemplate
import androidx.glance.background
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
import androidx.glance.layout.fillMaxSize
+import androidx.glance.template.GlanceTemplateAppWidget
import androidx.glance.template.HeaderBlock
import androidx.glance.template.ImageBlock
import androidx.glance.template.LocalTemplateMode
+import androidx.glance.template.SingleEntityTemplate
import androidx.glance.template.SingleEntityTemplateData
import androidx.glance.template.TemplateImageWithDescription
import androidx.glance.template.TemplateMode
diff --git a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
index 04ec6f2..18c7278 100644
--- a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
+++ b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/GalleryDemoWidget.kt
@@ -22,11 +22,11 @@
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
import androidx.glance.appwidget.action.actionRunCallback
-import androidx.glance.template.GalleryTemplate
-import androidx.glance.template.GlanceTemplateAppWidget
import androidx.glance.template.ActionBlock
import androidx.glance.template.AspectRatio
+import androidx.glance.template.GalleryTemplate
import androidx.glance.template.GalleryTemplateData
+import androidx.glance.template.GlanceTemplateAppWidget
import androidx.glance.template.HeaderBlock
import androidx.glance.template.ImageBlock
import androidx.glance.template.ImageSize
diff --git a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
index 354d8b2..0f87618 100644
--- a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
+++ b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/ListDemoWidget.kt
@@ -34,14 +34,14 @@
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.state.updateAppWidgetState
-import androidx.glance.template.GlanceTemplateAppWidget
-import androidx.glance.template.ListTemplate
import androidx.glance.currentState
import androidx.glance.template.ActionBlock
+import androidx.glance.template.GlanceTemplateAppWidget
import androidx.glance.template.HeaderBlock
import androidx.glance.template.ImageBlock
import androidx.glance.template.ImageSize
import androidx.glance.template.ListStyle
+import androidx.glance.template.ListTemplate
import androidx.glance.template.ListTemplateData
import androidx.glance.template.ListTemplateItem
import androidx.glance.template.TemplateImageButton
diff --git a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
index 36e6d78..0e297bf 100644
--- a/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
+++ b/glance/glance-template/integration-tests/template-demos/src/main/java/androidx/glance/appwidget/template/demos/SingleEntityDemoWidget.kt
@@ -29,12 +29,12 @@
import androidx.glance.appwidget.action.ActionCallback
import androidx.glance.appwidget.action.actionRunCallback
import androidx.glance.appwidget.state.updateAppWidgetState
-import androidx.glance.template.GlanceTemplateAppWidget
-import androidx.glance.template.SingleEntityTemplate
import androidx.glance.currentState
import androidx.glance.template.ActionBlock
+import androidx.glance.template.GlanceTemplateAppWidget
import androidx.glance.template.HeaderBlock
import androidx.glance.template.ImageBlock
+import androidx.glance.template.SingleEntityTemplate
import androidx.glance.template.SingleEntityTemplateData
import androidx.glance.template.TemplateImageWithDescription
import androidx.glance.template.TemplateText
diff --git a/glance/glance-template/src/main/java/androidx/glance/template/GalleryTemplateLayouts.kt b/glance/glance-template/src/main/java/androidx/glance/template/GalleryTemplateLayouts.kt
index 8d66ce0..8c81d38 100644
--- a/glance/glance-template/src/main/java/androidx/glance/template/GalleryTemplateLayouts.kt
+++ b/glance/glance-template/src/main/java/androidx/glance/template/GalleryTemplateLayouts.kt
@@ -27,7 +27,6 @@
import androidx.glance.appwidget.lazy.GridCells
import androidx.glance.appwidget.lazy.LazyVerticalGrid
import androidx.glance.appwidget.lazy.itemsIndexed
-import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeMin
import androidx.glance.background
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
@@ -40,6 +39,7 @@
import androidx.glance.layout.height
import androidx.glance.layout.padding
import androidx.glance.layout.width
+import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeMin
import kotlin.math.ceil
import kotlin.math.pow
import kotlin.math.roundToInt
diff --git a/glance/glance-template/src/main/java/androidx/glance/template/SingleEntityTemplateLayouts.kt b/glance/glance-template/src/main/java/androidx/glance/template/SingleEntityTemplateLayouts.kt
index f954264..0e17cca 100644
--- a/glance/glance-template/src/main/java/androidx/glance/template/SingleEntityTemplateLayouts.kt
+++ b/glance/glance-template/src/main/java/androidx/glance/template/SingleEntityTemplateLayouts.kt
@@ -22,8 +22,6 @@
import androidx.glance.GlanceTheme
import androidx.glance.LocalSize
import androidx.glance.appwidget.cornerRadius
-import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeMin
-import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeS
import androidx.glance.background
import androidx.glance.layout.Column
import androidx.glance.layout.ContentScale
@@ -35,6 +33,8 @@
import androidx.glance.layout.height
import androidx.glance.layout.padding
import androidx.glance.layout.width
+import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeMin
+import androidx.glance.template.GlanceTemplateAppWidget.Companion.sizeS
// TODO: Define template layouts for other surfaces
/**
diff --git a/glance/glance-wear-tiles-preview/build.gradle b/glance/glance-wear-tiles-preview/build.gradle
index a5836b4..9314528 100644
--- a/glance/glance-wear-tiles-preview/build.gradle
+++ b/glance/glance-wear-tiles-preview/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Glance Wear Tiles Preview"
+ name = "Glance Wear Tiles Preview"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GLANCE_WEAR_TILES
inceptionYear = "2022"
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt
index 94ad581..a585320 100644
--- a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/FirstGlancePreview.kt
@@ -18,9 +18,9 @@
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
-import androidx.glance.action.Action
import androidx.glance.Button
import androidx.glance.GlanceModifier
+import androidx.glance.action.Action
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
import androidx.glance.layout.Row
diff --git a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt
index 3f4b8fd..debe385 100644
--- a/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt
+++ b/glance/glance-wear-tiles-preview/src/androidAndroidTest/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapterTest.kt
@@ -16,13 +16,13 @@
package androidx.glance.wear.tiles.preview
-import androidx.glance.wear.tiles.preview.test.R
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.glance.wear.tiles.preview.test.R
import androidx.test.filters.MediumTest
import org.junit.Assert
import org.junit.Before
diff --git a/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt
index 929bfba..944d3ed 100644
--- a/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt
+++ b/glance/glance-wear-tiles-preview/src/androidMain/kotlin/androidx/glance/wear/tiles/preview/GlanceTileServiceViewAdapter.kt
@@ -27,8 +27,8 @@
import androidx.glance.wear.tiles.compose
import androidx.glance.wear.tiles.preview.ComposableInvoker.invokeComposable
import androidx.wear.tiles.TileBuilders
-import kotlinx.coroutines.runBlocking
import androidx.wear.tiles.renderer.TileRenderer
+import kotlinx.coroutines.runBlocking
private const val TOOLS_NS_URI = "http://schemas.android.com/tools"
diff --git a/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/CountTileService.kt b/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/CountTileService.kt
index b83d447..4b6af16 100644
--- a/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/CountTileService.kt
+++ b/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/CountTileService.kt
@@ -26,25 +26,25 @@
import androidx.glance.Button
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
-import androidx.glance.wear.tiles.action.ActionCallback
-import androidx.glance.wear.tiles.action.actionRunCallback
import androidx.glance.background
import androidx.glance.currentState
import androidx.glance.layout.Alignment
import androidx.glance.layout.Column
import androidx.glance.layout.Row
import androidx.glance.layout.Spacer
-import androidx.glance.layout.padding
import androidx.glance.layout.height
+import androidx.glance.layout.padding
import androidx.glance.layout.width
import androidx.glance.semantics.contentDescription
import androidx.glance.semantics.semantics
import androidx.glance.state.PreferencesGlanceStateDefinition
-import androidx.glance.wear.tiles.GlanceTileService
import androidx.glance.text.FontWeight
import androidx.glance.text.Text
import androidx.glance.text.TextStyle
import androidx.glance.unit.ColorProvider
+import androidx.glance.wear.tiles.GlanceTileService
+import androidx.glance.wear.tiles.action.ActionCallback
+import androidx.glance.wear.tiles.action.actionRunCallback
import androidx.glance.wear.tiles.state.updateWearTileState
private val prefsCountKey = intPreferencesKey("count")
diff --git a/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/TilePreviewActivity.kt b/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/TilePreviewActivity.kt
index 09c3ef0..92bff5a 100644
--- a/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/TilePreviewActivity.kt
+++ b/glance/glance-wear-tiles/integration-tests/demos/src/main/java/androidx/glance/wear/tiles/demos/TilePreviewActivity.kt
@@ -25,9 +25,9 @@
import android.widget.FrameLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
-import androidx.wear.tiles.manager.TileUiClient
-import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.adapter.FragmentStateAdapter
+import androidx.viewpager2.widget.ViewPager2
+import androidx.wear.tiles.manager.TileUiClient
private const val NUM_PAGES = 4
private val TILE_PROVIDERS_NAME = arrayOf(
diff --git a/glance/glance-wear-tiles/src/androidAndroidTest/AndroidManifest.xml b/glance/glance-wear-tiles/src/androidAndroidTest/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/glance/glance-wear-tiles/src/androidAndroidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/glance/glance-wear-tiles/src/androidMain/AndroidManifest.xml b/glance/glance-wear-tiles/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/glance/glance-wear-tiles/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/GlanceWearTiles.kt b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/GlanceWearTiles.kt
index d6dd76e..ac1bded 100644
--- a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/GlanceWearTiles.kt
+++ b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/GlanceWearTiles.kt
@@ -16,11 +16,13 @@
package androidx.glance.wear.tiles
-import androidx.glance.LocalState
import android.content.Context
import android.util.Log
import androidx.compose.runtime.BroadcastFrameClock
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Composition
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.Recomposer
import androidx.compose.ui.unit.DpSize
import androidx.glance.Applier
import androidx.glance.GlanceId
@@ -28,17 +30,15 @@
import androidx.glance.LocalContext
import androidx.glance.LocalGlanceId
import androidx.glance.LocalSize
+import androidx.glance.LocalState
import androidx.glance.layout.Alignment
import androidx.glance.layout.EmittableBox
import androidx.glance.layout.fillMaxSize
+import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import androidx.compose.runtime.Composition
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.Recomposer
-import kotlinx.coroutines.CancellationException
/**
* Object containing the result from composition of [GlanceWearTiles].
diff --git a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/curved/CurvedRow.kt b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/curved/CurvedRow.kt
index c84930b..58489b1 100644
--- a/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/curved/CurvedRow.kt
+++ b/glance/glance-wear-tiles/src/androidMain/kotlin/androidx/glance/wear/tiles/curved/CurvedRow.kt
@@ -16,12 +16,12 @@
package androidx.glance.wear.tiles.curved
-import androidx.glance.GlanceNode
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.glance.Emittable
import androidx.glance.EmittableWithChildren
import androidx.glance.GlanceModifier
+import androidx.glance.GlanceNode
import androidx.glance.unit.ColorProvider
/**
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
index 4c7486f..8018dd2 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BackgroundTest.kt
@@ -16,18 +16,18 @@
package androidx.glance.wear.tiles
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
import androidx.glance.BackgroundModifier
import androidx.glance.GlanceModifier
import androidx.glance.background
import androidx.glance.findModifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.toArgb
import androidx.glance.unit.FixedColorProvider
import androidx.glance.unit.ResourceColorProvider
import androidx.glance.wear.tiles.test.R
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import kotlin.test.assertIs
+import org.junit.Test
class BackgroundTest {
@Test
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BorderTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BorderTest.kt
index b38fd4e..6f88fd0 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BorderTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/BorderTest.kt
@@ -24,9 +24,9 @@
import androidx.glance.findModifier
import androidx.glance.unit.ColorProvider
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
-import org.junit.Test
class BorderTest {
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
index ce386f6..340ea7b 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/GlanceTileServiceTest.kt
@@ -24,39 +24,39 @@
import androidx.core.graphics.drawable.toBitmap
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.stringPreferencesKey
-import androidx.glance.currentState
import androidx.glance.GlanceModifier
import androidx.glance.Image
import androidx.glance.ImageProvider
+import androidx.glance.currentState
import androidx.glance.layout.ContentScale
import androidx.glance.layout.size
import androidx.glance.state.PreferencesGlanceStateDefinition
import androidx.glance.text.Text
import androidx.glance.wear.tiles.test.R
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.wear.tiles.RequestBuilders
import androidx.wear.tiles.testing.TestTileClient
-import androidx.test.core.app.ApplicationProvider.getApplicationContext
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.io.ByteArrayOutputStream
+import java.time.Instant
+import java.util.Arrays
+import kotlin.test.assertIs
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import org.robolectric.android.util.concurrent.InlineExecutorService
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
-import java.io.ByteArrayOutputStream
-import java.time.Instant
-import java.util.Arrays
-import kotlin.test.assertIs
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import org.junit.Ignore
+import org.robolectric.android.util.concurrent.InlineExecutorService
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalStdlibApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/TimelineModeTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/TimelineModeTest.kt
index ba8bf2b..d159631 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/TimelineModeTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/TimelineModeTest.kt
@@ -17,8 +17,8 @@
package androidx.glance.wear.tiles
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.time.Instant
+import org.junit.Test
class TimelineModeTest {
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
index b167405..306f8c1 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/WearCompositionTranslatorTest.kt
@@ -70,6 +70,10 @@
import androidx.glance.wear.tiles.test.R
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import com.google.common.truth.Truth.assertThat
+import java.io.ByteArrayOutputStream
+import java.util.Arrays
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -77,10 +81,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import java.io.ByteArrayOutputStream
-import java.util.Arrays
-import kotlin.test.assertIs
-import kotlin.test.assertNotNull
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/action/RunCallbackActionTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/action/RunCallbackActionTest.kt
index b4598ab..f0a9c37 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/action/RunCallbackActionTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/action/RunCallbackActionTest.kt
@@ -26,13 +26,13 @@
import androidx.glance.wear.tiles.curved.GlanceCurvedModifier
import androidx.glance.wear.tiles.curved.clickable
import androidx.glance.wear.tiles.curved.findModifier
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/curved/CurvedRowTest.kt b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/curved/CurvedRowTest.kt
index 3dfc764..1c6a622 100644
--- a/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/curved/CurvedRowTest.kt
+++ b/glance/glance-wear-tiles/src/test/kotlin/androidx/glance/wear/tiles/curved/CurvedRowTest.kt
@@ -30,12 +30,12 @@
import androidx.glance.unit.ColorProvider
import androidx.glance.wear.tiles.runTestingComposition
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class CurvedRowTest {
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index 68ec157..1d44a68 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -88,7 +88,7 @@
}
androidx {
- name = "Glance Core Library"
+ name = "Glance"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Glance allows developers to build layouts for remote surfaces using a Jetpack " +
diff --git a/glance/glance/src/androidMain/AndroidManifest.xml b/glance/glance/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/glance/glance/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/glance/glance/src/test/kotlin/androidx/glance/ApplierTest.kt b/glance/glance/src/test/kotlin/androidx/glance/ApplierTest.kt
index 3536a0d..2fb71b2 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/ApplierTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/ApplierTest.kt
@@ -17,9 +17,9 @@
package androidx.glance
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
-import kotlin.test.assertFailsWith
@OptIn(ExperimentalCoroutinesApi::class)
class ApplierTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/ImageTest.kt b/glance/glance/src/test/kotlin/androidx/glance/ImageTest.kt
index 95473a6..07f00f1 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/ImageTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/ImageTest.kt
@@ -26,13 +26,13 @@
import androidx.glance.semantics.SemanticsProperties
import androidx.glance.unit.ColorProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
-import kotlin.test.assertNotNull
@OptIn(ExperimentalCoroutinesApi::class)
class ImageTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/action/ActionParametersTest.kt b/glance/glance/src/test/kotlin/androidx/glance/action/ActionParametersTest.kt
index 450a8b4..fcf114d 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/action/ActionParametersTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/action/ActionParametersTest.kt
@@ -17,10 +17,10 @@
package androidx.glance.action
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import org.junit.Test
class ActionParametersTest {
@Test
diff --git a/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt b/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
index 6100675..763fe17 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/action/ActionTest.kt
@@ -22,6 +22,8 @@
import androidx.glance.findModifier
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
+import kotlin.test.assertNotNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
@@ -29,8 +31,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertIs
-import kotlin.test.assertNotNull
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/BoxTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/BoxTest.kt
index 85c4897..aefe11d 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/BoxTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/BoxTest.kt
@@ -20,12 +20,12 @@
import androidx.glance.GlanceModifier
import androidx.glance.findModifier
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class BoxTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/ColumnTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/ColumnTest.kt
index 72455c3..7f72a59 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/ColumnTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/ColumnTest.kt
@@ -21,12 +21,12 @@
import androidx.glance.findModifier
import androidx.glance.unit.Dimension
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class ColumnTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/PaddingTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/PaddingTest.kt
index 8b6a366..f8f75be 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/PaddingTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/PaddingTest.kt
@@ -21,9 +21,9 @@
import androidx.glance.GlanceModifier
import androidx.glance.findModifier
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
-import org.junit.Test
class PaddingTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/RowTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/RowTest.kt
index 0078c36..7ee121e 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/RowTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/RowTest.kt
@@ -21,12 +21,12 @@
import androidx.glance.findModifier
import androidx.glance.unit.Dimension
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class RowTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/SizeModifiersTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/SizeModifiersTest.kt
index 7dedee8..706ce82 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/SizeModifiersTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/SizeModifiersTest.kt
@@ -21,8 +21,8 @@
import androidx.glance.findModifier
import androidx.glance.unit.Dimension
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import kotlin.test.assertIs
+import org.junit.Test
class SizeModifiersTest {
@Test
diff --git a/glance/glance/src/test/kotlin/androidx/glance/layout/SpacerTest.kt b/glance/glance/src/test/kotlin/androidx/glance/layout/SpacerTest.kt
index c301c0e..9ebc68a 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/layout/SpacerTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/layout/SpacerTest.kt
@@ -21,12 +21,12 @@
import androidx.glance.findModifier
import androidx.glance.unit.Dimension
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class SpacerTest {
diff --git a/glance/glance/src/test/kotlin/androidx/glance/state/StateDefinitionTest.kt b/glance/glance/src/test/kotlin/androidx/glance/state/StateDefinitionTest.kt
index 91a054a..7082643 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/state/StateDefinitionTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/state/StateDefinitionTest.kt
@@ -21,12 +21,12 @@
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertNotNull
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.test.assertNotNull
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(RobolectricTestRunner::class)
diff --git a/glance/glance/src/test/kotlin/androidx/glance/text/TextTest.kt b/glance/glance/src/test/kotlin/androidx/glance/text/TextTest.kt
index 2c08b78..9b7516d 100644
--- a/glance/glance/src/test/kotlin/androidx/glance/text/TextTest.kt
+++ b/glance/glance/src/test/kotlin/androidx/glance/text/TextTest.kt
@@ -24,12 +24,12 @@
import androidx.glance.layout.runTestingComposition
import androidx.glance.unit.Dimension
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertIs
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
-import kotlin.test.assertIs
@OptIn(ExperimentalCoroutinesApi::class)
class TextTest {
diff --git a/graphics/graphics-core/build.gradle b/graphics/graphics-core/build.gradle
index f20971b..b99b3c8 100644
--- a/graphics/graphics-core/build.gradle
+++ b/graphics/graphics-core/build.gradle
@@ -61,7 +61,7 @@
}
androidx {
- name = "Android Graphics Core"
+ name = "Graphics Core"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GRAPHICS_CORE
inceptionYear = "2021"
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/BufferTransformHintResolverTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/BufferTransformHintResolverTest.kt
index 067f6ba..ff5d80f 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/BufferTransformHintResolverTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/BufferTransformHintResolverTest.kt
@@ -27,8 +27,8 @@
import androidx.graphics.lowlatency.BufferTransformHintResolver.Companion.ORIENTATION_90
import androidx.graphics.lowlatency.BufferTransformHintResolver.Companion.UNKNOWN_TRANSFORM
import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_IDENTITY
-import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_270
import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_180
+import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_270
import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_90
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
index ba81a87..b2c764d 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/GLFrontBufferedRendererTest.kt
@@ -753,7 +753,9 @@
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
fun testUsageFlagContainsFrontBufferUsage() {
val usageFlags = FrontBufferUtils.obtainHardwareBufferUsageFlags()
- if (UsageFlagsVerificationHelper.isSupported(HardwareBuffer.USAGE_FRONT_BUFFER)) {
+ // See b/280866371
+ if (UsageFlagsVerificationHelper.isSupported(HardwareBuffer.USAGE_FRONT_BUFFER) &&
+ !Build.MODEL.contains("Cuttlefish")) {
assertNotEquals(0, usageFlags and HardwareBuffer.USAGE_FRONT_BUFFER)
} else {
assertEquals(0, usageFlags and HardwareBuffer.USAGE_FRONT_BUFFER)
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SampleInkViewActivity.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SampleInkViewActivity.kt
index 56ffdec..458ad0c 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SampleInkViewActivity.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/lowlatency/SampleInkViewActivity.kt
@@ -21,9 +21,9 @@
import android.os.Bundle
import android.view.Gravity
import android.view.View
-import android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
import android.widget.Button
import android.widget.FrameLayout
+import android.widget.FrameLayout.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout.LayoutParams.MATCH_PARENT
import androidx.annotation.RequiresApi
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
index 43f1de6..8d31c50 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/GLRendererTest.kt
@@ -43,11 +43,11 @@
import androidx.graphics.isAllColor
import androidx.graphics.lowlatency.LineRenderer
import androidx.graphics.lowlatency.Rectangle
-import androidx.hardware.SyncFenceCompat
import androidx.graphics.opengl.egl.EGLManager
import androidx.graphics.opengl.egl.EGLSpec
import androidx.graphics.opengl.egl.supportsNativeAndroidFence
import androidx.graphics.verifyQuadrants
+import androidx.hardware.SyncFenceCompat
import androidx.lifecycle.Lifecycle.State
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
index d2a9139..8a8486e 100644
--- a/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
+++ b/graphics/graphics-core/src/androidTest/java/androidx/graphics/opengl/egl/EGLManagerTest.kt
@@ -32,11 +32,6 @@
import androidx.opengl.EGLBindings
import androidx.opengl.EGLExt
import androidx.opengl.EGLExt.Companion.EGL_ANDROID_CLIENT_BUFFER
-import androidx.opengl.EGLExt.Companion.EGL_SYNC_CONDITION_KHR
-import androidx.opengl.EGLExt.Companion.EGL_SYNC_FENCE_KHR
-import androidx.opengl.EGLExt.Companion.EGL_SYNC_NATIVE_FENCE_ANDROID
-import androidx.opengl.EGLExt.Companion.EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
-import androidx.opengl.EGLExt.Companion.EGL_SYNC_TYPE_KHR
import androidx.opengl.EGLExt.Companion.EGL_ANDROID_IMAGE_NATIVE_BUFFER
import androidx.opengl.EGLExt.Companion.EGL_ANDROID_NATIVE_FENCE_SYNC
import androidx.opengl.EGLExt.Companion.EGL_FOREVER_KHR
@@ -44,8 +39,13 @@
import androidx.opengl.EGLExt.Companion.EGL_KHR_IMAGE
import androidx.opengl.EGLExt.Companion.EGL_KHR_IMAGE_BASE
import androidx.opengl.EGLExt.Companion.EGL_KHR_SURFACELESS_CONTEXT
+import androidx.opengl.EGLExt.Companion.EGL_SYNC_CONDITION_KHR
+import androidx.opengl.EGLExt.Companion.EGL_SYNC_FENCE_KHR
import androidx.opengl.EGLExt.Companion.EGL_SYNC_FLUSH_COMMANDS_BIT_KHR
+import androidx.opengl.EGLExt.Companion.EGL_SYNC_NATIVE_FENCE_ANDROID
+import androidx.opengl.EGLExt.Companion.EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
import androidx.opengl.EGLExt.Companion.EGL_SYNC_STATUS_KHR
+import androidx.opengl.EGLExt.Companion.EGL_SYNC_TYPE_KHR
import androidx.opengl.EGLSyncKHR
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferUtils.kt b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferUtils.kt
index 5b00170..7321a55 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferUtils.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/lowlatency/FrontBufferUtils.kt
@@ -93,7 +93,11 @@
fun obtainUsageFlagsV33(): Long {
// First verify if the front buffer usage flag is supported along with the
// "usage composer overlay" flag that was introduced in API level 33
- return if (isSupported(HardwareBuffer.USAGE_FRONT_BUFFER)) {
+ // SF Seems to log errors when configuring HardwareBuffer instances with the
+ // front buffer usage flag on Cuttlefish, so only include it for actual devices.
+ // See b/280866371
+ return if (isSupported(HardwareBuffer.USAGE_FRONT_BUFFER) &&
+ !Build.MODEL.contains("Cuttlefish")) {
FrontBufferUtils.BaseFlags or HardwareBuffer.USAGE_FRONT_BUFFER
} else {
FrontBufferUtils.BaseFlags
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
index 19a3ed5..bafcff8 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/opengl/FrameBufferRenderer.kt
@@ -25,13 +25,13 @@
import android.util.Log
import android.view.Surface
import androidx.annotation.RequiresApi
-import androidx.hardware.SyncFenceCompat
import androidx.graphics.opengl.egl.EGLManager
import androidx.graphics.opengl.egl.EGLSpec
+import androidx.hardware.SyncFenceCompat
import androidx.opengl.EGLExt
-import java.util.concurrent.atomic.AtomicBoolean
import androidx.opengl.EGLExt.Companion.EGL_ANDROID_NATIVE_FENCE_SYNC
import androidx.opengl.EGLExt.Companion.EGL_KHR_FENCE_SYNC
+import java.util.concurrent.atomic.AtomicBoolean
/**
* [GLRenderer.RenderCallback] implementation that renders content into a frame buffer object
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
index 9d8af62..460f50a 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlImpl.kt
@@ -25,9 +25,9 @@
import android.view.SurfaceControl
import android.view.SurfaceView
import androidx.annotation.RequiresApi
+import androidx.graphics.surface.SurfaceControlCompat.TransactionCommittedListener
import androidx.hardware.SyncFenceCompat
import androidx.hardware.SyncFenceImpl
-import androidx.graphics.surface.SurfaceControlCompat.TransactionCommittedListener
import java.util.concurrent.Executor
/**
diff --git a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
index c1e1701..8a303de 100644
--- a/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
+++ b/graphics/graphics-core/src/main/java/androidx/graphics/surface/SurfaceControlV29.kt
@@ -26,9 +26,9 @@
import androidx.annotation.RequiresApi
import androidx.graphics.lowlatency.BufferTransformHintResolver.Companion.UNKNOWN_TRANSFORM
import androidx.graphics.lowlatency.FrontBufferUtils
-import androidx.hardware.SyncFenceImpl
import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_270
import androidx.graphics.surface.SurfaceControlCompat.Companion.BUFFER_TRANSFORM_ROTATE_90
+import androidx.hardware.SyncFenceImpl
import androidx.hardware.SyncFenceV19
import java.util.concurrent.Executor
diff --git a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
index 29bc952..2b17fc6 100644
--- a/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
+++ b/graphics/graphics-core/src/main/java/androidx/hardware/SyncFenceCompat.kt
@@ -22,8 +22,8 @@
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.graphics.lowlatency.FrontBufferUtils
-import androidx.opengl.EGLExt
import androidx.graphics.surface.SurfaceControlCompat
+import androidx.opengl.EGLExt
import androidx.opengl.EGLSyncKHR
/**
diff --git a/graphics/graphics-shapes/build.gradle b/graphics/graphics-shapes/build.gradle
index f04e619..5e5dfc1 100644
--- a/graphics/graphics-shapes/build.gradle
+++ b/graphics/graphics-shapes/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Graphics Shapes"
+ name = "Graphics Shapes"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.GRAPHICS_SHAPES
inceptionYear = "2022"
diff --git a/gridlayout/gridlayout/api/1.1.0-beta01.txt b/gridlayout/gridlayout/api/1.1.0-beta01.txt
new file mode 100644
index 0000000..abbe71f
--- /dev/null
+++ b/gridlayout/gridlayout/api/1.1.0-beta01.txt
@@ -0,0 +1,71 @@
+// Signature format: 4.0
+package androidx.gridlayout.widget {
+
+ public class GridLayout extends android.view.ViewGroup {
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!, int);
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!);
+ ctor public GridLayout(android.content.Context!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateDefaultLayoutParams();
+ method public androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+ method public int getAlignmentMode();
+ method public int getColumnCount();
+ method public int getOrientation();
+ method public android.util.Printer! getPrinter();
+ method public int getRowCount();
+ method public boolean getUseDefaultMargins();
+ method public boolean isColumnOrderPreserved();
+ method public boolean isRowOrderPreserved();
+ method public void setAlignmentMode(int);
+ method public void setColumnCount(int);
+ method public void setColumnOrderPreserved(boolean);
+ method public void setOrientation(int);
+ method public void setPrinter(android.util.Printer!);
+ method public void setRowCount(int);
+ method public void setRowOrderPreserved(boolean);
+ method public void setUseDefaultMargins(boolean);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int);
+ field public static final int ALIGN_BOUNDS = 0; // 0x0
+ field public static final int ALIGN_MARGINS = 1; // 0x1
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BASELINE;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BOTTOM;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! CENTER;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! END;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! FILL;
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! LEFT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! RIGHT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! START;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! TOP;
+ field public static final int UNDEFINED = -2147483648; // 0x80000000
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public abstract static class GridLayout.Alignment {
+ }
+
+ public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.Spec!, androidx.gridlayout.widget.GridLayout.Spec!);
+ ctor public GridLayout.LayoutParams();
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+ method public void setGravity(int);
+ field public androidx.gridlayout.widget.GridLayout.Spec! columnSpec;
+ field public androidx.gridlayout.widget.GridLayout.Spec! rowSpec;
+ }
+
+ public static class GridLayout.Spec {
+ method public androidx.gridlayout.widget.GridLayout.Alignment! getAbsoluteAlignment(boolean);
+ }
+
+}
+
diff --git a/gridlayout/gridlayout/api/public_plus_experimental_1.1.0-beta01.txt b/gridlayout/gridlayout/api/public_plus_experimental_1.1.0-beta01.txt
new file mode 100644
index 0000000..abbe71f
--- /dev/null
+++ b/gridlayout/gridlayout/api/public_plus_experimental_1.1.0-beta01.txt
@@ -0,0 +1,71 @@
+// Signature format: 4.0
+package androidx.gridlayout.widget {
+
+ public class GridLayout extends android.view.ViewGroup {
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!, int);
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!);
+ ctor public GridLayout(android.content.Context!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateDefaultLayoutParams();
+ method public androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+ method public int getAlignmentMode();
+ method public int getColumnCount();
+ method public int getOrientation();
+ method public android.util.Printer! getPrinter();
+ method public int getRowCount();
+ method public boolean getUseDefaultMargins();
+ method public boolean isColumnOrderPreserved();
+ method public boolean isRowOrderPreserved();
+ method public void setAlignmentMode(int);
+ method public void setColumnCount(int);
+ method public void setColumnOrderPreserved(boolean);
+ method public void setOrientation(int);
+ method public void setPrinter(android.util.Printer!);
+ method public void setRowCount(int);
+ method public void setRowOrderPreserved(boolean);
+ method public void setUseDefaultMargins(boolean);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int);
+ field public static final int ALIGN_BOUNDS = 0; // 0x0
+ field public static final int ALIGN_MARGINS = 1; // 0x1
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BASELINE;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BOTTOM;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! CENTER;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! END;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! FILL;
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! LEFT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! RIGHT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! START;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! TOP;
+ field public static final int UNDEFINED = -2147483648; // 0x80000000
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public abstract static class GridLayout.Alignment {
+ }
+
+ public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.Spec!, androidx.gridlayout.widget.GridLayout.Spec!);
+ ctor public GridLayout.LayoutParams();
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+ method public void setGravity(int);
+ field public androidx.gridlayout.widget.GridLayout.Spec! columnSpec;
+ field public androidx.gridlayout.widget.GridLayout.Spec! rowSpec;
+ }
+
+ public static class GridLayout.Spec {
+ method public androidx.gridlayout.widget.GridLayout.Alignment! getAbsoluteAlignment(boolean);
+ }
+
+}
+
diff --git a/gridlayout/gridlayout/api/res-1.1.0-beta01.txt b/gridlayout/gridlayout/api/res-1.1.0-beta01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/gridlayout/gridlayout/api/res-1.1.0-beta01.txt
diff --git a/gridlayout/gridlayout/api/restricted_1.1.0-beta01.txt b/gridlayout/gridlayout/api/restricted_1.1.0-beta01.txt
new file mode 100644
index 0000000..abbe71f
--- /dev/null
+++ b/gridlayout/gridlayout/api/restricted_1.1.0-beta01.txt
@@ -0,0 +1,71 @@
+// Signature format: 4.0
+package androidx.gridlayout.widget {
+
+ public class GridLayout extends android.view.ViewGroup {
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!, int);
+ ctor public GridLayout(android.content.Context!, android.util.AttributeSet!);
+ ctor public GridLayout(android.content.Context!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateDefaultLayoutParams();
+ method public androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.util.AttributeSet!);
+ method protected androidx.gridlayout.widget.GridLayout.LayoutParams! generateLayoutParams(android.view.ViewGroup.LayoutParams!);
+ method public int getAlignmentMode();
+ method public int getColumnCount();
+ method public int getOrientation();
+ method public android.util.Printer! getPrinter();
+ method public int getRowCount();
+ method public boolean getUseDefaultMargins();
+ method public boolean isColumnOrderPreserved();
+ method public boolean isRowOrderPreserved();
+ method public void setAlignmentMode(int);
+ method public void setColumnCount(int);
+ method public void setColumnOrderPreserved(boolean);
+ method public void setOrientation(int);
+ method public void setPrinter(android.util.Printer!);
+ method public void setRowCount(int);
+ method public void setRowOrderPreserved(boolean);
+ method public void setUseDefaultMargins(boolean);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, float);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, androidx.gridlayout.widget.GridLayout.Alignment!);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int, int);
+ method public static androidx.gridlayout.widget.GridLayout.Spec! spec(int);
+ field public static final int ALIGN_BOUNDS = 0; // 0x0
+ field public static final int ALIGN_MARGINS = 1; // 0x1
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BASELINE;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! BOTTOM;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! CENTER;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! END;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! FILL;
+ field public static final int HORIZONTAL = 0; // 0x0
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! LEFT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! RIGHT;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! START;
+ field public static final androidx.gridlayout.widget.GridLayout.Alignment! TOP;
+ field public static final int UNDEFINED = -2147483648; // 0x80000000
+ field public static final int VERTICAL = 1; // 0x1
+ }
+
+ public abstract static class GridLayout.Alignment {
+ }
+
+ public static class GridLayout.LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.Spec!, androidx.gridlayout.widget.GridLayout.Spec!);
+ ctor public GridLayout.LayoutParams();
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.view.ViewGroup.MarginLayoutParams!);
+ ctor public GridLayout.LayoutParams(androidx.gridlayout.widget.GridLayout.LayoutParams!);
+ ctor public GridLayout.LayoutParams(android.content.Context!, android.util.AttributeSet!);
+ method public void setGravity(int);
+ field public androidx.gridlayout.widget.GridLayout.Spec! columnSpec;
+ field public androidx.gridlayout.widget.GridLayout.Spec! rowSpec;
+ }
+
+ public static class GridLayout.Spec {
+ method public androidx.gridlayout.widget.GridLayout.Alignment! getAbsoluteAlignment(boolean);
+ }
+
+}
+
diff --git a/gridlayout/gridlayout/build.gradle b/gridlayout/gridlayout/build.gradle
index 44db995..9fdbcdb 100644
--- a/gridlayout/gridlayout/build.gradle
+++ b/gridlayout/gridlayout/build.gradle
@@ -17,7 +17,7 @@
}
androidx {
- name = "Android Support Grid Layout"
+ name = "Grid Layout"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2013"
description = "Android Support Grid Layout"
diff --git a/gridlayout/gridlayout/src/main/AndroidManifest.xml b/gridlayout/gridlayout/src/main/AndroidManifest.xml
deleted file mode 100644
index bd7af07..0000000
--- a/gridlayout/gridlayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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 />
diff --git a/health/connect/connect-client-proto/build.gradle b/health/connect/connect-client-proto/build.gradle
index 0458446..0ed136e 100644
--- a/health/connect/connect-client-proto/build.gradle
+++ b/health/connect/connect-client-proto/build.gradle
@@ -78,7 +78,7 @@
artifacts.add(jarjarConf.name, preferencesProtoJarJarTask.flatMap { it.archiveFile })
androidx {
- name = "AndroidX Health Connect Client Proto"
+ name = "Health Connect Client Proto"
publish = Publish.NONE
inceptionYear = "2022"
description = "Proto files for health-connect-client"
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index 0a8378c..a5bd664 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -421,21 +421,119 @@
public static final class ElevationGainedRecord.Companion {
}
+ public final class ExerciseLap {
+ ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+ method public java.time.Instant getEndTime();
+ method public androidx.health.connect.client.units.Length? getLength();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final androidx.health.connect.client.units.Length? length;
+ property public final java.time.Instant startTime;
+ }
+
+ public final class ExerciseSegment {
+ ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+ method public java.time.Instant getEndTime();
+ method public int getRepetitions();
+ method public int getSegmentType();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int repetitions;
+ property public final int segmentType;
+ property public final java.time.Instant startTime;
+ field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+ field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+ field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+ field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+ field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+ field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+ field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+ field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+ field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+ field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+ field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+ field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+ field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+ field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+ field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+ field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+ field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+ field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+ field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+ field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+ field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+ field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+ field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+ field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+ field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+ field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+ field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+ field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+ field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+ field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+ field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+ field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+ field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+ field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+ field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+ field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+ field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+ field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+ }
+
+ public static final class ExerciseSegment.Companion {
+ }
+
public final class ExerciseSessionRecord implements androidx.health.connect.client.records.Record {
- ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public int getExerciseType();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
property public java.time.Instant endTime;
property public java.time.ZoneOffset? endZoneOffset;
property public final int exerciseType;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
@@ -944,11 +1042,12 @@
}
public final class SleepSessionRecord implements androidx.health.connect.client.records.Record {
- ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
@@ -956,32 +1055,14 @@
property public java.time.ZoneOffset? endZoneOffset;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
- }
-
- public static final class SleepSessionRecord.Companion {
- }
-
- public final class SleepStageRecord implements androidx.health.connect.client.records.Record {
- ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public java.time.Instant getEndTime();
- method public java.time.ZoneOffset? getEndZoneOffset();
- method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
- method public int getStage();
- method public java.time.Instant getStartTime();
- method public java.time.ZoneOffset? getStartZoneOffset();
- property public java.time.Instant endTime;
- property public java.time.ZoneOffset? endZoneOffset;
- property public androidx.health.connect.client.records.metadata.Metadata metadata;
- property public final int stage;
- property public java.time.Instant startTime;
- property public java.time.ZoneOffset? startZoneOffset;
- field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+ field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
field public static final int STAGE_TYPE_DEEP = 5; // 0x5
field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -990,7 +1071,17 @@
field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
}
- public static final class SleepStageRecord.Companion {
+ public static final class SleepSessionRecord.Companion {
+ }
+
+ public static final class SleepSessionRecord.Stage {
+ ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+ method public java.time.Instant getEndTime();
+ method public int getStage();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int stage;
+ property public final java.time.Instant startTime;
}
public final class SpeedRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/public_plus_experimental_current.txt b/health/connect/connect-client/api/public_plus_experimental_current.txt
index 0a8378c..a5bd664 100644
--- a/health/connect/connect-client/api/public_plus_experimental_current.txt
+++ b/health/connect/connect-client/api/public_plus_experimental_current.txt
@@ -421,21 +421,119 @@
public static final class ElevationGainedRecord.Companion {
}
+ public final class ExerciseLap {
+ ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+ method public java.time.Instant getEndTime();
+ method public androidx.health.connect.client.units.Length? getLength();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final androidx.health.connect.client.units.Length? length;
+ property public final java.time.Instant startTime;
+ }
+
+ public final class ExerciseSegment {
+ ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+ method public java.time.Instant getEndTime();
+ method public int getRepetitions();
+ method public int getSegmentType();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int repetitions;
+ property public final int segmentType;
+ property public final java.time.Instant startTime;
+ field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+ field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+ field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+ field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+ field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+ field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+ field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+ field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+ field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+ field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+ field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+ field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+ field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+ field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+ field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+ field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+ field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+ field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+ field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+ field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+ field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+ field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+ field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+ field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+ field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+ field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+ field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+ field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+ field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+ field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+ field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+ field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+ field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+ field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+ field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+ field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+ field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+ field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+ }
+
+ public static final class ExerciseSegment.Companion {
+ }
+
public final class ExerciseSessionRecord implements androidx.health.connect.client.records.Record {
- ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public int getExerciseType();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
property public java.time.Instant endTime;
property public java.time.ZoneOffset? endZoneOffset;
property public final int exerciseType;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
@@ -944,11 +1042,12 @@
}
public final class SleepSessionRecord implements androidx.health.connect.client.records.Record {
- ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
@@ -956,32 +1055,14 @@
property public java.time.ZoneOffset? endZoneOffset;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
- }
-
- public static final class SleepSessionRecord.Companion {
- }
-
- public final class SleepStageRecord implements androidx.health.connect.client.records.Record {
- ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public java.time.Instant getEndTime();
- method public java.time.ZoneOffset? getEndZoneOffset();
- method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
- method public int getStage();
- method public java.time.Instant getStartTime();
- method public java.time.ZoneOffset? getStartZoneOffset();
- property public java.time.Instant endTime;
- property public java.time.ZoneOffset? endZoneOffset;
- property public androidx.health.connect.client.records.metadata.Metadata metadata;
- property public final int stage;
- property public java.time.Instant startTime;
- property public java.time.ZoneOffset? startZoneOffset;
- field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+ field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
field public static final int STAGE_TYPE_DEEP = 5; // 0x5
field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -990,7 +1071,17 @@
field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
}
- public static final class SleepStageRecord.Companion {
+ public static final class SleepSessionRecord.Companion {
+ }
+
+ public static final class SleepSessionRecord.Stage {
+ ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+ method public java.time.Instant getEndTime();
+ method public int getStage();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int stage;
+ property public final java.time.Instant startTime;
}
public final class SpeedRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 970eb61..fbce104 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -421,21 +421,119 @@
public static final class ElevationGainedRecord.Companion {
}
+ public final class ExerciseLap {
+ ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+ method public java.time.Instant getEndTime();
+ method public androidx.health.connect.client.units.Length? getLength();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final androidx.health.connect.client.units.Length? length;
+ property public final java.time.Instant startTime;
+ }
+
+ public final class ExerciseSegment {
+ ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+ method public java.time.Instant getEndTime();
+ method public int getRepetitions();
+ method public int getSegmentType();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int repetitions;
+ property public final int segmentType;
+ property public final java.time.Instant startTime;
+ field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+ field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+ field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+ field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+ field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+ field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+ field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+ field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+ field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+ field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+ field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+ field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+ field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+ field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+ field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+ field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+ field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+ field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+ field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+ field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+ field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+ field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+ field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+ field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+ field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+ field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+ field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+ field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+ field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+ field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+ field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+ field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+ field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+ field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+ field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+ field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+ field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+ field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+ field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+ field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+ field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+ field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+ field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+ field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+ field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+ field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+ }
+
+ public static final class ExerciseSegment.Companion {
+ }
+
public final class ExerciseSessionRecord implements androidx.health.connect.client.records.IntervalRecord {
- ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public int getExerciseType();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
property public java.time.Instant endTime;
property public java.time.ZoneOffset? endZoneOffset;
property public final int exerciseType;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
@@ -967,11 +1065,12 @@
}
public final class SleepSessionRecord implements androidx.health.connect.client.records.IntervalRecord {
- ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+ ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
method public java.time.Instant getEndTime();
method public java.time.ZoneOffset? getEndZoneOffset();
method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
method public String? getNotes();
+ method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
method public java.time.Instant getStartTime();
method public java.time.ZoneOffset? getStartZoneOffset();
method public String? getTitle();
@@ -979,32 +1078,14 @@
property public java.time.ZoneOffset? endZoneOffset;
property public androidx.health.connect.client.records.metadata.Metadata metadata;
property public final String? notes;
+ property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
property public java.time.Instant startTime;
property public java.time.ZoneOffset? startZoneOffset;
property public final String? title;
field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
- }
-
- public static final class SleepSessionRecord.Companion {
- }
-
- public final class SleepStageRecord implements androidx.health.connect.client.records.IntervalRecord {
- ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
- method public java.time.Instant getEndTime();
- method public java.time.ZoneOffset? getEndZoneOffset();
- method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
- method public int getStage();
- method public java.time.Instant getStartTime();
- method public java.time.ZoneOffset? getStartZoneOffset();
- property public java.time.Instant endTime;
- property public java.time.ZoneOffset? endZoneOffset;
- property public androidx.health.connect.client.records.metadata.Metadata metadata;
- property public final int stage;
- property public java.time.Instant startTime;
- property public java.time.ZoneOffset? startZoneOffset;
- field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+ field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
field public static final int STAGE_TYPE_DEEP = 5; // 0x5
field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -1013,7 +1094,17 @@
field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
}
- public static final class SleepStageRecord.Companion {
+ public static final class SleepSessionRecord.Companion {
+ }
+
+ public static final class SleepSessionRecord.Stage {
+ ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+ method public java.time.Instant getEndTime();
+ method public int getStage();
+ method public java.time.Instant getStartTime();
+ property public final java.time.Instant endTime;
+ property public final int stage;
+ property public final java.time.Instant startTime;
}
public final class SpeedRecord implements androidx.health.connect.client.records.SeriesRecord<androidx.health.connect.client.records.SpeedRecord.Sample> {
diff --git a/health/connect/connect-client/build.gradle b/health/connect/connect-client/build.gradle
index 06b657b..f3b4530 100644
--- a/health/connect/connect-client/build.gradle
+++ b/health/connect/connect-client/build.gradle
@@ -73,7 +73,7 @@
}
androidx {
- name = "AndroidX Health Connect Client Library"
+ name = "Health Connect Client"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "read or write user's health and fitness records."
diff --git a/health/connect/connect-client/samples/build.gradle b/health/connect/connect-client/samples/build.gradle
index 2d8bd45..b1b2388 100644
--- a/health/connect/connect-client/samples/build.gradle
+++ b/health/connect/connect-client/samples/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Health Connect Library Samples"
+ name = "Health Connect Samples"
type = LibraryType.SAMPLES
inceptionYear = "2022"
description = "Contains the sample code for the Androidx Health Connect Library"
diff --git a/health/connect/connect-client/samples/src/main/AndroidManifest.xml b/health/connect/connect-client/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 676b645..0000000
--- a/health/connect/connect-client/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- 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.
- -->
-
-<manifest />
\ No newline at end of file
diff --git a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/AggregationSamples.kt b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/AggregationSamples.kt
index 829941f5..e6a48dc 100644
--- a/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/AggregationSamples.kt
+++ b/health/connect/connect-client/samples/src/main/java/androidx/health/connect/client/samples/AggregationSamples.kt
@@ -23,9 +23,9 @@
import androidx.health.connect.client.records.DistanceRecord
import androidx.health.connect.client.records.HeartRateRecord
import androidx.health.connect.client.records.StepsRecord
-import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.request.AggregateGroupByDurationRequest
import androidx.health.connect.client.request.AggregateGroupByPeriodRequest
+import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Duration
import java.time.Instant
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordUtils.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordUtils.kt
index 57b0fba..f2fa0f4 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordUtils.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/impl/converters/records/ProtoToRecordUtils.kt
@@ -18,12 +18,12 @@
package androidx.health.connect.client.impl.converters.records
import androidx.annotation.RestrictTo
-import androidx.health.connect.client.records.SleepSessionRecord
-import androidx.health.connect.client.records.SleepSessionRecord.Companion.STAGE_TYPE_STRING_TO_INT_MAP
import androidx.health.connect.client.records.ExerciseLap
import androidx.health.connect.client.records.ExerciseRoute
import androidx.health.connect.client.records.ExerciseSegment
import androidx.health.connect.client.records.ExerciseSegment.Companion.EXERCISE_SEGMENT_TYPE_UNKNOWN
+import androidx.health.connect.client.records.SleepSessionRecord
+import androidx.health.connect.client.records.SleepSessionRecord.Companion.STAGE_TYPE_STRING_TO_INT_MAP
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.records.metadata.Device
import androidx.health.connect.client.records.metadata.Metadata
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
index 08aa1fc..290feb0 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
@@ -16,21 +16,19 @@
package androidx.health.connect.client.records
-import androidx.annotation.RestrictTo
import androidx.health.connect.client.units.Length
import java.time.Instant
/**
* Captures the time of a lap within an exercise session.
*
- * <p>Each lap contains the start and end time and optional [Length] of the lap (e.g. pool
- * length while swimming or a track lap while running). There may or may not be direct correlation
- * with [ExerciseSegment] start and end times, e.g. [ExerciseSessionRecord] of type
- * running without any segments can be divided into laps of different lengths.
+ * <p>Each lap contains the start and end time and optional [Length] of the lap (e.g. pool length
+ * while swimming or a track lap while running). There may or may not be direct correlation with
+ * [ExerciseSegment] start and end times, e.g. [ExerciseSessionRecord] of type running without any
+ * segments can be divided into laps of different lengths.
*
* @see ExerciseSessionRecord
*/
-@RestrictTo(RestrictTo.Scope.LIBRARY)
public class ExerciseLap(
public val startTime: Instant,
public val endTime: Instant,
@@ -62,4 +60,4 @@
result = 31 * result + length.hashCode()
return result
}
-}
\ No newline at end of file
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
index 67cf876..6afd2ee 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
@@ -28,7 +28,6 @@
*
* @see ExerciseSessionRecord
*/
-@RestrictTo(RestrictTo.Scope.LIBRARY)
public class ExerciseSegment(
public val startTime: Instant,
public val endTime: Instant,
@@ -70,10 +69,7 @@
if (UNIVERSAL_SEGMENTS.contains(segmentType)) {
return true
}
- if (!SESSION_TO_SEGMENTS_MAPPING.contains(sessionType)) {
- return false
- }
- return SESSION_TO_SEGMENTS_MAPPING[sessionType]!!.contains(segmentType)
+ return SESSION_TO_SEGMENTS_MAPPING[sessionType]?.contains(segmentType) ?: false
}
companion object {
@@ -280,179 +276,48 @@
/** Use this type for yoga. */
const val EXERCISE_SEGMENT_TYPE_YOGA = 67
- internal val UNIVERSAL_SESSION_TYPES = setOf(
- ExerciseSessionRecord.EXERCISE_TYPE_BOOT_CAMP,
- ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
- ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT,
- )
+ internal val UNIVERSAL_SESSION_TYPES =
+ setOf(
+ ExerciseSessionRecord.EXERCISE_TYPE_BOOT_CAMP,
+ ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+ ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT,
+ )
- internal val UNIVERSAL_SEGMENTS = setOf(
- EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
- EXERCISE_SEGMENT_TYPE_PAUSE,
- EXERCISE_SEGMENT_TYPE_REST,
- EXERCISE_SEGMENT_TYPE_STRETCHING,
- EXERCISE_SEGMENT_TYPE_UNKNOWN,
- )
-
- internal val EXERCISE_SEGMENTS = setOf(
- EXERCISE_SEGMENT_TYPE_ARM_CURL,
- EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
- EXERCISE_SEGMENT_TYPE_BALL_SLAM,
- EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
- EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
- EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
- EXERCISE_SEGMENT_TYPE_BURPEE,
- EXERCISE_SEGMENT_TYPE_CRUNCH,
- EXERCISE_SEGMENT_TYPE_DEADLIFT,
- EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
- EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
- EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
- EXERCISE_SEGMENT_TYPE_HIP_THRUST,
- EXERCISE_SEGMENT_TYPE_HULA_HOOP,
- EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
- EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
- EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
- EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
- EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
- EXERCISE_SEGMENT_TYPE_LEG_CURL,
- EXERCISE_SEGMENT_TYPE_LEG_EXTENSION,
- EXERCISE_SEGMENT_TYPE_LEG_PRESS,
- EXERCISE_SEGMENT_TYPE_LEG_RAISE,
- EXERCISE_SEGMENT_TYPE_LUNGE,
- EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER,
- EXERCISE_SEGMENT_TYPE_PLANK,
- EXERCISE_SEGMENT_TYPE_PULL_UP,
- EXERCISE_SEGMENT_TYPE_PUNCH,
- EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS,
- EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
- EXERCISE_SEGMENT_TYPE_SIT_UP,
- EXERCISE_SEGMENT_TYPE_SQUAT,
- EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
- EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING
- )
- internal val SWIMMING_SEGMENTS = setOf(
- EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
- EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
- EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
- EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
- EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
- EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER
- )
-
- private val SESSION_TO_SEGMENTS_MAPPING = mapOf(
- ExerciseSessionRecord.EXERCISE_TYPE_BIKING to setOf(EXERCISE_SEGMENT_TYPE_BIKING),
- ExerciseSessionRecord.EXERCISE_TYPE_BIKING_STATIONARY to setOf(
- EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS to EXERCISE_SEGMENTS,
- ExerciseSessionRecord.EXERCISE_TYPE_ELLIPTICAL
- to setOf(EXERCISE_SEGMENT_TYPE_ELLIPTICAL),
- ExerciseSessionRecord.EXERCISE_TYPE_EXERCISE_CLASS to setOf(
- EXERCISE_SEGMENT_TYPE_YOGA,
- EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
- EXERCISE_SEGMENT_TYPE_PILATES,
- EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_GYMNASTICS to EXERCISE_SEGMENTS,
- ExerciseSessionRecord.EXERCISE_TYPE_HIKING to setOf(
- EXERCISE_SEGMENT_TYPE_WALKING,
- EXERCISE_SEGMENT_TYPE_WHEELCHAIR
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_PILATES to setOf(EXERCISE_SEGMENT_TYPE_PILATES),
- ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE to setOf(
- EXERCISE_SEGMENT_TYPE_ROWING_MACHINE
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_RUNNING to setOf(
- EXERCISE_SEGMENT_TYPE_RUNNING,
- EXERCISE_SEGMENT_TYPE_WALKING
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_RUNNING_TREADMILL to setOf(
- EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING to EXERCISE_SEGMENTS,
- ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING to setOf(
- EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING_MACHINE to setOf(
- EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE
- ),
- ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER to buildSet {
- add(EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER)
- addAll(SWIMMING_SEGMENTS)
- },
- ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL to buildSet {
- add(EXERCISE_SEGMENT_TYPE_SWIMMING_POOL)
- addAll(SWIMMING_SEGMENTS)
- },
- ExerciseSessionRecord.EXERCISE_TYPE_WALKING to setOf(EXERCISE_SEGMENT_TYPE_WALKING),
- ExerciseSessionRecord.EXERCISE_TYPE_WHEELCHAIR
- to setOf(EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
- ExerciseSessionRecord.EXERCISE_TYPE_WEIGHTLIFTING to EXERCISE_SEGMENTS,
- ExerciseSessionRecord.EXERCISE_TYPE_YOGA to setOf(EXERCISE_SEGMENT_TYPE_YOGA),
- )
-
- /**
- * List of supported segment types on Health Platform.
- *
- * @suppress
- */
- @Retention(AnnotationRetention.SOURCE)
- @RestrictTo(RestrictTo.Scope.LIBRARY)
- @IntDef(
- value =
- [
- EXERCISE_SEGMENT_TYPE_UNKNOWN,
- EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
- EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
- EXERCISE_SEGMENT_TYPE_BIKING,
- EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
- EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
- EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
- EXERCISE_SEGMENT_TYPE_ELLIPTICAL,
- EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
- EXERCISE_SEGMENT_TYPE_PILATES,
- EXERCISE_SEGMENT_TYPE_ROWING_MACHINE,
- EXERCISE_SEGMENT_TYPE_RUNNING,
- EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL,
- EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING,
- EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE,
- EXERCISE_SEGMENT_TYPE_STRETCHING,
- EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER,
- EXERCISE_SEGMENT_TYPE_SWIMMING_POOL,
- EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
- EXERCISE_SEGMENT_TYPE_WALKING,
- EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING,
- EXERCISE_SEGMENT_TYPE_WHEELCHAIR,
+ internal val UNIVERSAL_SEGMENTS =
+ setOf(
EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
- EXERCISE_SEGMENT_TYPE_YOGA,
+ EXERCISE_SEGMENT_TYPE_PAUSE,
+ EXERCISE_SEGMENT_TYPE_REST,
+ EXERCISE_SEGMENT_TYPE_STRETCHING,
+ EXERCISE_SEGMENT_TYPE_UNKNOWN,
+ )
+
+ internal val EXERCISE_SEGMENTS =
+ setOf(
EXERCISE_SEGMENT_TYPE_ARM_CURL,
EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
EXERCISE_SEGMENT_TYPE_BALL_SLAM,
+ EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
+ EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
EXERCISE_SEGMENT_TYPE_BURPEE,
EXERCISE_SEGMENT_TYPE_CRUNCH,
EXERCISE_SEGMENT_TYPE_DEADLIFT,
EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
+ EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
EXERCISE_SEGMENT_TYPE_HIP_THRUST,
EXERCISE_SEGMENT_TYPE_HULA_HOOP,
- EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
+ EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
@@ -469,16 +334,146 @@
EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
EXERCISE_SEGMENT_TYPE_SIT_UP,
EXERCISE_SEGMENT_TYPE_SQUAT,
- EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
+ EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
+ EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING
+ )
+ internal val SWIMMING_SEGMENTS =
+ setOf(
EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
- EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER,
- EXERCISE_SEGMENT_TYPE_REST,
- EXERCISE_SEGMENT_TYPE_PAUSE,
- ]
+ EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER
+ )
+
+ private val SESSION_TO_SEGMENTS_MAPPING =
+ mapOf(
+ ExerciseSessionRecord.EXERCISE_TYPE_BIKING to setOf(EXERCISE_SEGMENT_TYPE_BIKING),
+ ExerciseSessionRecord.EXERCISE_TYPE_BIKING_STATIONARY to
+ setOf(EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY),
+ ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS to EXERCISE_SEGMENTS,
+ ExerciseSessionRecord.EXERCISE_TYPE_ELLIPTICAL to
+ setOf(EXERCISE_SEGMENT_TYPE_ELLIPTICAL),
+ ExerciseSessionRecord.EXERCISE_TYPE_EXERCISE_CLASS to
+ setOf(
+ EXERCISE_SEGMENT_TYPE_YOGA,
+ EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
+ EXERCISE_SEGMENT_TYPE_PILATES,
+ EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
+ ),
+ ExerciseSessionRecord.EXERCISE_TYPE_GYMNASTICS to EXERCISE_SEGMENTS,
+ ExerciseSessionRecord.EXERCISE_TYPE_HIKING to
+ setOf(EXERCISE_SEGMENT_TYPE_WALKING, EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
+ ExerciseSessionRecord.EXERCISE_TYPE_PILATES to setOf(EXERCISE_SEGMENT_TYPE_PILATES),
+ ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE to
+ setOf(EXERCISE_SEGMENT_TYPE_ROWING_MACHINE),
+ ExerciseSessionRecord.EXERCISE_TYPE_RUNNING to
+ setOf(EXERCISE_SEGMENT_TYPE_RUNNING, EXERCISE_SEGMENT_TYPE_WALKING),
+ ExerciseSessionRecord.EXERCISE_TYPE_RUNNING_TREADMILL to
+ setOf(EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL),
+ ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING to EXERCISE_SEGMENTS,
+ ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING to
+ setOf(EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING),
+ ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING_MACHINE to
+ setOf(EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE),
+ ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER to
+ buildSet {
+ add(EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER)
+ addAll(SWIMMING_SEGMENTS)
+ },
+ ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL to
+ buildSet {
+ add(EXERCISE_SEGMENT_TYPE_SWIMMING_POOL)
+ addAll(SWIMMING_SEGMENTS)
+ },
+ ExerciseSessionRecord.EXERCISE_TYPE_WALKING to setOf(EXERCISE_SEGMENT_TYPE_WALKING),
+ ExerciseSessionRecord.EXERCISE_TYPE_WHEELCHAIR to
+ setOf(EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
+ ExerciseSessionRecord.EXERCISE_TYPE_WEIGHTLIFTING to EXERCISE_SEGMENTS,
+ ExerciseSessionRecord.EXERCISE_TYPE_YOGA to setOf(EXERCISE_SEGMENT_TYPE_YOGA),
+ )
+
+ /**
+ * List of supported segment types on Health Platform.
+ *
+ * @suppress
+ */
+ @Retention(AnnotationRetention.SOURCE)
+ @RestrictTo(RestrictTo.Scope.LIBRARY)
+ @IntDef(
+ value =
+ [
+ EXERCISE_SEGMENT_TYPE_UNKNOWN,
+ EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
+ EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
+ EXERCISE_SEGMENT_TYPE_BIKING,
+ EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
+ EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
+ EXERCISE_SEGMENT_TYPE_ELLIPTICAL,
+ EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+ EXERCISE_SEGMENT_TYPE_PILATES,
+ EXERCISE_SEGMENT_TYPE_ROWING_MACHINE,
+ EXERCISE_SEGMENT_TYPE_RUNNING,
+ EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL,
+ EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING,
+ EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE,
+ EXERCISE_SEGMENT_TYPE_STRETCHING,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_POOL,
+ EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
+ EXERCISE_SEGMENT_TYPE_WALKING,
+ EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING,
+ EXERCISE_SEGMENT_TYPE_WHEELCHAIR,
+ EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
+ EXERCISE_SEGMENT_TYPE_YOGA,
+ EXERCISE_SEGMENT_TYPE_ARM_CURL,
+ EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
+ EXERCISE_SEGMENT_TYPE_BALL_SLAM,
+ EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
+ EXERCISE_SEGMENT_TYPE_BURPEE,
+ EXERCISE_SEGMENT_TYPE_CRUNCH,
+ EXERCISE_SEGMENT_TYPE_DEADLIFT,
+ EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
+ EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
+ EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
+ EXERCISE_SEGMENT_TYPE_HIP_THRUST,
+ EXERCISE_SEGMENT_TYPE_HULA_HOOP,
+ EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
+ EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
+ EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
+ EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
+ EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
+ EXERCISE_SEGMENT_TYPE_LEG_CURL,
+ EXERCISE_SEGMENT_TYPE_LEG_EXTENSION,
+ EXERCISE_SEGMENT_TYPE_LEG_PRESS,
+ EXERCISE_SEGMENT_TYPE_LEG_RAISE,
+ EXERCISE_SEGMENT_TYPE_LUNGE,
+ EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER,
+ EXERCISE_SEGMENT_TYPE_PLANK,
+ EXERCISE_SEGMENT_TYPE_PULL_UP,
+ EXERCISE_SEGMENT_TYPE_PUNCH,
+ EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS,
+ EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
+ EXERCISE_SEGMENT_TYPE_SIT_UP,
+ EXERCISE_SEGMENT_TYPE_SQUAT,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
+ EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER,
+ EXERCISE_SEGMENT_TYPE_REST,
+ EXERCISE_SEGMENT_TYPE_PAUSE,
+ ]
)
annotation class ExerciseSegmentTypes
}
-}
\ No newline at end of file
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
index 4c9cb06..1709165 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
@@ -34,7 +34,9 @@
*
* @sample androidx.health.connect.client.samples.ReadExerciseSessions
*/
-public class ExerciseSessionRecord @RestrictTo(RestrictTo.Scope.LIBRARY) constructor(
+public class ExerciseSessionRecord
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+constructor(
override val startTime: Instant,
override val startZoneOffset: ZoneOffset?,
override val endTime: Instant,
@@ -46,22 +48,23 @@
/** Additional notes for the session. Optional field. */
public val notes: String? = null,
override val metadata: Metadata = Metadata.EMPTY,
- @get:RestrictTo(RestrictTo.Scope.LIBRARY)
- /** [ExerciseSegment]s of the session. Optional field.
- * Time in segments should be within the parent session, and should not overlap with each other.
+ /**
+ * [ExerciseSegment]s of the session. Optional field. Time in segments should be within the
+ * parent session, and should not overlap with each other.
*/
public val segments: List<ExerciseSegment> = emptyList(),
- @get:RestrictTo(RestrictTo.Scope.LIBRARY)
- /** [ExerciseLap]s of the session. Optional field.
- * Time in laps should be within the parent session, and should not overlap with each other.
+ /**
+ * [ExerciseLap]s of the session. Optional field. Time in laps should be within the parent
+ * session, and should not overlap with each other.
*/
public val laps: List<ExerciseLap> = emptyList(),
@get:RestrictTo(RestrictTo.Scope.LIBRARY)
/** [ExerciseRoute]s of the session. Optional field. */
public val route: ExerciseRoute? = null,
@get:RestrictTo(RestrictTo.Scope.LIBRARY)
- /** Indicates whether or not the underlying [ExerciseSessionRecord] has a route, even it's not
- * present because lack of permission.
+ /**
+ * Indicates whether or not the underlying [ExerciseSessionRecord] has a route, even it's not
+ * present because lack of permission.
*/
public val hasRoute: Boolean = false,
) : IntervalRecord {
@@ -78,6 +81,8 @@
/** Additional notes for the session. Optional field. */
notes: String? = null,
metadata: Metadata = Metadata.EMPTY,
+ segments: List<ExerciseSegment> = emptyList(),
+ laps: List<ExerciseLap> = emptyList(),
) : this(
startTime,
startZoneOffset,
@@ -87,10 +92,9 @@
title,
notes,
metadata,
- emptyList(),
- emptyList(),
- null,
- false
+ segments,
+ laps,
+ null
)
@RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -163,12 +167,9 @@
}
require(route == null || hasRoute) { "hasRoute must be true if the route is not null" }
if (route != null) {
- require(
- route.isWithin(
- startTime,
- endTime
- )
- ) { "route can not be out of parent time range." }
+ require(route.isWithin(startTime, endTime)) {
+ "route can not be out of parent time range."
+ }
}
}
@@ -396,69 +397,69 @@
@RestrictTo(RestrictTo.Scope.LIBRARY)
@IntDef(
value =
- [
- EXERCISE_TYPE_BADMINTON,
- EXERCISE_TYPE_BASEBALL,
- EXERCISE_TYPE_BASKETBALL,
- EXERCISE_TYPE_BIKING,
- EXERCISE_TYPE_BIKING_STATIONARY,
- EXERCISE_TYPE_BOOT_CAMP,
- EXERCISE_TYPE_BOXING,
- EXERCISE_TYPE_CALISTHENICS,
- EXERCISE_TYPE_CRICKET,
- EXERCISE_TYPE_DANCING,
- EXERCISE_TYPE_ELLIPTICAL,
- EXERCISE_TYPE_EXERCISE_CLASS,
- EXERCISE_TYPE_FENCING,
- EXERCISE_TYPE_FOOTBALL_AMERICAN,
- EXERCISE_TYPE_FOOTBALL_AUSTRALIAN,
- EXERCISE_TYPE_FRISBEE_DISC,
- EXERCISE_TYPE_GOLF,
- EXERCISE_TYPE_GUIDED_BREATHING,
- EXERCISE_TYPE_GYMNASTICS,
- EXERCISE_TYPE_HANDBALL,
- EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
- EXERCISE_TYPE_HIKING,
- EXERCISE_TYPE_ICE_HOCKEY,
- EXERCISE_TYPE_ICE_SKATING,
- EXERCISE_TYPE_MARTIAL_ARTS,
- EXERCISE_TYPE_PADDLING,
- EXERCISE_TYPE_PARAGLIDING,
- EXERCISE_TYPE_PILATES,
- EXERCISE_TYPE_RACQUETBALL,
- EXERCISE_TYPE_ROCK_CLIMBING,
- EXERCISE_TYPE_ROLLER_HOCKEY,
- EXERCISE_TYPE_ROWING,
- EXERCISE_TYPE_ROWING_MACHINE,
- EXERCISE_TYPE_RUGBY,
- EXERCISE_TYPE_RUNNING,
- EXERCISE_TYPE_RUNNING_TREADMILL,
- EXERCISE_TYPE_SAILING,
- EXERCISE_TYPE_SCUBA_DIVING,
- EXERCISE_TYPE_SKATING,
- EXERCISE_TYPE_SKIING,
- EXERCISE_TYPE_SNOWBOARDING,
- EXERCISE_TYPE_SNOWSHOEING,
- EXERCISE_TYPE_SOCCER,
- EXERCISE_TYPE_SOFTBALL,
- EXERCISE_TYPE_SQUASH,
- EXERCISE_TYPE_STAIR_CLIMBING,
- EXERCISE_TYPE_STAIR_CLIMBING_MACHINE,
- EXERCISE_TYPE_STRENGTH_TRAINING,
- EXERCISE_TYPE_STRETCHING,
- EXERCISE_TYPE_SURFING,
- EXERCISE_TYPE_SWIMMING_OPEN_WATER,
- EXERCISE_TYPE_SWIMMING_POOL,
- EXERCISE_TYPE_TABLE_TENNIS,
- EXERCISE_TYPE_TENNIS,
- EXERCISE_TYPE_VOLLEYBALL,
- EXERCISE_TYPE_WALKING,
- EXERCISE_TYPE_WATER_POLO,
- EXERCISE_TYPE_WEIGHTLIFTING,
- EXERCISE_TYPE_WHEELCHAIR,
- EXERCISE_TYPE_OTHER_WORKOUT,
- EXERCISE_TYPE_YOGA,
- ]
+ [
+ EXERCISE_TYPE_BADMINTON,
+ EXERCISE_TYPE_BASEBALL,
+ EXERCISE_TYPE_BASKETBALL,
+ EXERCISE_TYPE_BIKING,
+ EXERCISE_TYPE_BIKING_STATIONARY,
+ EXERCISE_TYPE_BOOT_CAMP,
+ EXERCISE_TYPE_BOXING,
+ EXERCISE_TYPE_CALISTHENICS,
+ EXERCISE_TYPE_CRICKET,
+ EXERCISE_TYPE_DANCING,
+ EXERCISE_TYPE_ELLIPTICAL,
+ EXERCISE_TYPE_EXERCISE_CLASS,
+ EXERCISE_TYPE_FENCING,
+ EXERCISE_TYPE_FOOTBALL_AMERICAN,
+ EXERCISE_TYPE_FOOTBALL_AUSTRALIAN,
+ EXERCISE_TYPE_FRISBEE_DISC,
+ EXERCISE_TYPE_GOLF,
+ EXERCISE_TYPE_GUIDED_BREATHING,
+ EXERCISE_TYPE_GYMNASTICS,
+ EXERCISE_TYPE_HANDBALL,
+ EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+ EXERCISE_TYPE_HIKING,
+ EXERCISE_TYPE_ICE_HOCKEY,
+ EXERCISE_TYPE_ICE_SKATING,
+ EXERCISE_TYPE_MARTIAL_ARTS,
+ EXERCISE_TYPE_PADDLING,
+ EXERCISE_TYPE_PARAGLIDING,
+ EXERCISE_TYPE_PILATES,
+ EXERCISE_TYPE_RACQUETBALL,
+ EXERCISE_TYPE_ROCK_CLIMBING,
+ EXERCISE_TYPE_ROLLER_HOCKEY,
+ EXERCISE_TYPE_ROWING,
+ EXERCISE_TYPE_ROWING_MACHINE,
+ EXERCISE_TYPE_RUGBY,
+ EXERCISE_TYPE_RUNNING,
+ EXERCISE_TYPE_RUNNING_TREADMILL,
+ EXERCISE_TYPE_SAILING,
+ EXERCISE_TYPE_SCUBA_DIVING,
+ EXERCISE_TYPE_SKATING,
+ EXERCISE_TYPE_SKIING,
+ EXERCISE_TYPE_SNOWBOARDING,
+ EXERCISE_TYPE_SNOWSHOEING,
+ EXERCISE_TYPE_SOCCER,
+ EXERCISE_TYPE_SOFTBALL,
+ EXERCISE_TYPE_SQUASH,
+ EXERCISE_TYPE_STAIR_CLIMBING,
+ EXERCISE_TYPE_STAIR_CLIMBING_MACHINE,
+ EXERCISE_TYPE_STRENGTH_TRAINING,
+ EXERCISE_TYPE_STRETCHING,
+ EXERCISE_TYPE_SURFING,
+ EXERCISE_TYPE_SWIMMING_OPEN_WATER,
+ EXERCISE_TYPE_SWIMMING_POOL,
+ EXERCISE_TYPE_TABLE_TENNIS,
+ EXERCISE_TYPE_TENNIS,
+ EXERCISE_TYPE_VOLLEYBALL,
+ EXERCISE_TYPE_WALKING,
+ EXERCISE_TYPE_WATER_POLO,
+ EXERCISE_TYPE_WEIGHTLIFTING,
+ EXERCISE_TYPE_WHEELCHAIR,
+ EXERCISE_TYPE_OTHER_WORKOUT,
+ EXERCISE_TYPE_YOGA,
+ ]
)
annotation class ExerciseTypes
}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
index 2337212..4aafec9 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
@@ -32,14 +32,15 @@
* continuous but shouldn't overlap.
*
* Example code demonstrate how to read sleep session with stages:
+ *
* @sample androidx.health.connect.client.samples.ReadSleepSessions
*
* When deleting a session, associated sleep stage records need to be deleted separately:
- * @sample androidx.health.connect.client.samples.DeleteSleepSession
*
+ * @sample androidx.health.connect.client.samples.DeleteSleepSession
* @see SleepStageRecord
*/
-public class SleepSessionRecord @RestrictTo(RestrictTo.Scope.LIBRARY) constructor(
+public class SleepSessionRecord(
override val startTime: Instant,
override val startZoneOffset: ZoneOffset?,
override val endTime: Instant,
@@ -48,30 +49,9 @@
public val title: String? = null,
/** Additional notes for the session. Optional field. */
public val notes: String? = null,
- @get:RestrictTo(RestrictTo.Scope.LIBRARY)
public val stages: List<Stage> = emptyList(),
override val metadata: Metadata = Metadata.EMPTY,
) : IntervalRecord {
- public constructor(
- startTime: Instant,
- startZoneOffset: ZoneOffset?,
- endTime: Instant,
- endZoneOffset: ZoneOffset?,
- /** Title of the session. Optional field. */
- title: String? = null,
- /** Additional notes for the session. Optional field. */
- notes: String? = null,
- metadata: Metadata = Metadata.EMPTY,
- ) : this(
- startTime,
- startZoneOffset,
- endTime,
- endZoneOffset,
- title,
- notes,
- emptyList(),
- metadata
- )
init {
require(startTime.isBefore(endTime)) { "startTime must be before endTime." }
@@ -124,38 +104,30 @@
AggregateMetric.durationMetric("SleepSession")
/** Use this type if the stage of sleep is unknown. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_UNKNOWN = 0
/**
* The user is awake and either known to be in bed, or it is unknown whether they are in bed
* or not.
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_AWAKE = 1
/** The user is asleep but the particular stage of sleep (light, deep or REM) is unknown. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_SLEEPING = 2
/** The user is out of bed and assumed to be awake. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_OUT_OF_BED = 3
/** The user is in a light sleep stage. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_LIGHT = 4
/** The user is in a deep sleep stage. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_DEEP = 5
/** The user is in a REM sleep stage. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_REM = 6
/** The user is awake and in bed. */
- @RestrictTo(RestrictTo.Scope.LIBRARY)
const val STAGE_TYPE_AWAKE_IN_BED = 7
@RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -180,21 +152,22 @@
/**
* Type of sleep stage.
+ *
* @suppress
*/
@Retention(AnnotationRetention.SOURCE)
@IntDef(
value =
- [
- STAGE_TYPE_UNKNOWN,
- STAGE_TYPE_AWAKE,
- STAGE_TYPE_SLEEPING,
- STAGE_TYPE_OUT_OF_BED,
- STAGE_TYPE_LIGHT,
- STAGE_TYPE_DEEP,
- STAGE_TYPE_REM,
- STAGE_TYPE_AWAKE_IN_BED,
- ]
+ [
+ STAGE_TYPE_UNKNOWN,
+ STAGE_TYPE_AWAKE,
+ STAGE_TYPE_SLEEPING,
+ STAGE_TYPE_OUT_OF_BED,
+ STAGE_TYPE_LIGHT,
+ STAGE_TYPE_DEEP,
+ STAGE_TYPE_REM,
+ STAGE_TYPE_AWAKE_IN_BED,
+ ]
)
@RestrictTo(RestrictTo.Scope.LIBRARY)
annotation class StageTypes
@@ -204,7 +177,6 @@
*
* @see SleepSessionRecord
*/
- @RestrictTo(RestrictTo.Scope.LIBRARY)
public class Stage(
val startTime: Instant,
val endTime: Instant,
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
index 1a566d9..f1af1da 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
@@ -26,6 +26,7 @@
*
* @see SleepSessionRecord
*/
+@RestrictTo(RestrictTo.Scope.LIBRARY)
public class SleepStageRecord(
override val startTime: Instant,
override val startZoneOffset: ZoneOffset?,
@@ -94,6 +95,7 @@
/**
* Type of sleep stage.
+ *
* @suppress
*/
@Retention(AnnotationRetention.SOURCE)
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/request/AggregateRequest.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/request/AggregateRequest.kt
index a8984a6..e6d96bb 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/request/AggregateRequest.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/request/AggregateRequest.kt
@@ -15,10 +15,10 @@
*/
package androidx.health.connect.client.request
+import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.aggregate.AggregateMetric
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.time.TimeRangeFilter
-import androidx.health.connect.client.HealthConnectClient
/**
* Request object to read aggregations for given [AggregateMetric]s in Android Health Platform.
diff --git a/health/health-services-client/build.gradle b/health/health-services-client/build.gradle
index 65a44a0..a0df417 100644
--- a/health/health-services-client/build.gradle
+++ b/health/health-services-client/build.gradle
@@ -79,7 +79,7 @@
}
androidx {
- name = "AndroidX Health Services Client Library"
+ name = "Health Services Client"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.HEALTH_SERVICES_CLIENT
inceptionYear = "2021"
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
index e1b58d7..080b83a 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/ExerciseClient.kt
@@ -21,10 +21,10 @@
import androidx.health.services.client.data.DataType
import androidx.health.services.client.data.ExerciseCapabilities
import androidx.health.services.client.data.ExerciseConfig
+import androidx.health.services.client.data.ExerciseEndReason
import androidx.health.services.client.data.ExerciseGoal
import androidx.health.services.client.data.ExerciseInfo
import androidx.health.services.client.data.ExerciseState
-import androidx.health.services.client.data.ExerciseEndReason
import androidx.health.services.client.data.ExerciseType
import androidx.health.services.client.data.ExerciseTypeConfig
import androidx.health.services.client.data.ExerciseUpdate
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseEndReason.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseEndReason.kt
index b0ac3ad..6072b1d9 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseEndReason.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseEndReason.kt
@@ -18,8 +18,8 @@
import androidx.annotation.IntDef
import androidx.annotation.RestrictTo
-import androidx.health.services.client.proto.DataProto
import androidx.health.services.client.ExerciseClient
+import androidx.health.services.client.proto.DataProto
import kotlin.annotation.AnnotationRetention.SOURCE
/**
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseUpdate.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseUpdate.kt
index 456443a..bf9b12f 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseUpdate.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/ExerciseUpdate.kt
@@ -16,13 +16,13 @@
package androidx.health.services.client.data
-import androidx.health.services.client.proto.DataProto.ExerciseUpdate.LatestMetricsEntry as LatestMetricsEntryProto
import androidx.annotation.RestrictTo
import androidx.annotation.RestrictTo.Scope
import androidx.health.services.client.data.ExerciseEndReason.Companion.toProto
import androidx.health.services.client.data.ExerciseUpdate.ActiveDurationCheckpoint
import androidx.health.services.client.proto.DataProto
import androidx.health.services.client.proto.DataProto.AchievedExerciseGoal
+import androidx.health.services.client.proto.DataProto.ExerciseUpdate.LatestMetricsEntry as LatestMetricsEntryProto
import java.time.Duration
import java.time.Instant
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/LocationAccuracy.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/LocationAccuracy.kt
index 25aa2a8..4d5edbf 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/LocationAccuracy.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/LocationAccuracy.kt
@@ -16,10 +16,10 @@
package androidx.health.services.client.data
-import androidx.health.services.client.proto.DataProto
-import androidx.health.services.client.proto.DataProto.DataPointAccuracy.LocationAccuracy as LocationAccuracyProto
import android.util.Log
import androidx.annotation.FloatRange
+import androidx.health.services.client.proto.DataProto
+import androidx.health.services.client.proto.DataProto.DataPointAccuracy.LocationAccuracy as LocationAccuracyProto
/** Accuracy for a [DataType.LOCATION] data point. */
@Suppress("ParcelCreator")
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveGoal.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveGoal.kt
index bfb1d9a..71c64a0 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveGoal.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveGoal.kt
@@ -16,10 +16,10 @@
package androidx.health.services.client.data
-import androidx.health.services.client.proto.DataProto.PassiveGoal as PassiveGoalProto
import androidx.annotation.IntDef
import androidx.annotation.RestrictTo
import androidx.health.services.client.data.PassiveGoal.TriggerFrequency.Companion.toProto
+import androidx.health.services.client.proto.DataProto.PassiveGoal as PassiveGoalProto
/**
* Defines a passive goal that will be triggered when the specified condition is met which will
diff --git a/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveMonitoringUpdate.kt b/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveMonitoringUpdate.kt
index 61b74cb..1f262f7 100644
--- a/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveMonitoringUpdate.kt
+++ b/health/health-services-client/src/main/java/androidx/health/services/client/data/PassiveMonitoringUpdate.kt
@@ -16,8 +16,8 @@
package androidx.health.services.client.data
-import androidx.health.services.client.proto.DataProto.PassiveMonitoringUpdate as PassiveMonitoringUpdateProto
import androidx.health.services.client.proto.DataProto
+import androidx.health.services.client.proto.DataProto.PassiveMonitoringUpdate as PassiveMonitoringUpdateProto
/**
* Represents an update from Passive tracking.
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/data/DataTypeTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/data/DataTypeTest.kt
index 3d9858c..6ab8729 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/data/DataTypeTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/data/DataTypeTest.kt
@@ -20,14 +20,14 @@
import androidx.health.services.client.data.DataType.Companion.ABSOLUTE_ELEVATION_STATS
import androidx.health.services.client.data.DataType.Companion.ACTIVE_EXERCISE_DURATION_TOTAL
import androidx.health.services.client.data.DataType.Companion.CALORIES
-import androidx.health.services.client.data.DataType.Companion.CALORIES_TOTAL
import androidx.health.services.client.data.DataType.Companion.CALORIES_DAILY
+import androidx.health.services.client.data.DataType.Companion.CALORIES_TOTAL
import androidx.health.services.client.data.DataType.Companion.DISTANCE_DAILY
import androidx.health.services.client.data.DataType.Companion.FLOORS_DAILY
-import androidx.health.services.client.data.DataType.Companion.STEPS_DAILY
import androidx.health.services.client.data.DataType.Companion.FORMAT_BYTE_ARRAY
import androidx.health.services.client.data.DataType.Companion.LOCATION
import androidx.health.services.client.data.DataType.Companion.STEPS
+import androidx.health.services.client.data.DataType.Companion.STEPS_DAILY
import androidx.health.services.client.data.DataType.Companion.SWIMMING_LAP_COUNT
import androidx.health.services.client.data.DataType.TimeType.Companion.INTERVAL
import androidx.health.services.client.data.DataType.TimeType.Companion.UNKNOWN
@@ -36,11 +36,11 @@
import androidx.health.services.client.proto.DataProto.DataType.TimeType.TIME_TYPE_UNKNOWN
import com.google.common.truth.Truth.assertThat
import kotlin.reflect.KVisibility
+import kotlin.reflect.full.declaredMemberProperties
+import kotlin.reflect.jvm.javaField
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
-import kotlin.reflect.full.declaredMemberProperties
-import kotlin.reflect.jvm.javaField
@RunWith(RobolectricTestRunner::class)
internal class DataTypeTest {
diff --git a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
index 1164cbf..c918351 100644
--- a/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
+++ b/health/health-services-client/src/test/java/androidx/health/services/client/impl/ServiceBackedExerciseClientTest.kt
@@ -31,8 +31,8 @@
import androidx.health.services.client.data.ExerciseLapSummary
import androidx.health.services.client.data.ExerciseType
import androidx.health.services.client.data.ExerciseUpdate
-import androidx.health.services.client.data.WarmUpConfig
import androidx.health.services.client.data.GolfExerciseTypeConfig
+import androidx.health.services.client.data.WarmUpConfig
import androidx.health.services.client.impl.event.ExerciseUpdateListenerEvent
import androidx.health.services.client.impl.internal.IExerciseInfoCallback
import androidx.health.services.client.impl.internal.IStatusCallback
diff --git a/heifwriter/heifwriter/build.gradle b/heifwriter/heifwriter/build.gradle
index 7bffa1a..3e8ff02 100644
--- a/heifwriter/heifwriter/build.gradle
+++ b/heifwriter/heifwriter/build.gradle
@@ -23,7 +23,7 @@
}
androidx {
- name = "Android Support HeifWriter"
+ name = "HeifWriter"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Support HeifWriter for writing HEIF still images"
diff --git a/heifwriter/heifwriter/src/main/AndroidManifest.xml b/heifwriter/heifwriter/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/heifwriter/heifwriter/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/hilt/hilt-common/build.gradle b/hilt/hilt-common/build.gradle
index 24537d9..4737307 100644
--- a/hilt/hilt-common/build.gradle
+++ b/hilt/hilt-common/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "AndroidX Hilt Extension Annotations"
+ name = "Hilt Common"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.HILT
inceptionYear = "2020"
diff --git a/hilt/hilt-compiler/build.gradle b/hilt/hilt-compiler/build.gradle
index eb22d1c..e6b2f0e 100644
--- a/hilt/hilt-compiler/build.gradle
+++ b/hilt/hilt-compiler/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "AndroidX Hilt Extension Compiler"
+ name = "Hilt Extension Compiler"
type = LibraryType.ANNOTATION_PROCESSOR
mavenVersion = LibraryVersions.HILT
inceptionYear = "2020"
diff --git a/hilt/hilt-compiler/src/main/kotlin/androidx/hilt/AndroidXHiltProcessor.kt b/hilt/hilt-compiler/src/main/kotlin/androidx/hilt/AndroidXHiltProcessor.kt
index 668af93..277140b 100644
--- a/hilt/hilt-compiler/src/main/kotlin/androidx/hilt/AndroidXHiltProcessor.kt
+++ b/hilt/hilt-compiler/src/main/kotlin/androidx/hilt/AndroidXHiltProcessor.kt
@@ -18,14 +18,14 @@
import androidx.hilt.work.WorkerStep
import com.google.auto.service.AutoService
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessor
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.Processor
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.SourceVersion
import javax.lang.model.element.Element
import javax.lang.model.element.TypeElement
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING
/**
* Annotation processor for the various AndroidX Hilt extensions.
diff --git a/hilt/hilt-navigation-compose/samples/src/main/AndroidManifest.xml b/hilt/hilt-navigation-compose/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 20af317..0000000
--- a/hilt/hilt-navigation-compose/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/hilt/hilt-navigation-compose/src/androidTest/java/androidx/hilt/navigation/compose/HiltViewModelComposeTest.kt b/hilt/hilt-navigation-compose/src/androidTest/java/androidx/hilt/navigation/compose/HiltViewModelComposeTest.kt
index 9ca7c4d..ad8f010 100644
--- a/hilt/hilt-navigation-compose/src/androidTest/java/androidx/hilt/navigation/compose/HiltViewModelComposeTest.kt
+++ b/hilt/hilt-navigation-compose/src/androidTest/java/androidx/hilt/navigation/compose/HiltViewModelComposeTest.kt
@@ -48,10 +48,10 @@
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
+import javax.inject.Inject
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import javax.inject.Inject
@LargeTest
@HiltAndroidTest
diff --git a/hilt/hilt-navigation-compose/src/main/AndroidManifest.xml b/hilt/hilt-navigation-compose/src/main/AndroidManifest.xml
deleted file mode 100644
index 38e6839..0000000
--- a/hilt/hilt-navigation-compose/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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.
- -->
-
-<manifest />
diff --git a/hilt/hilt-navigation-fragment/build.gradle b/hilt/hilt-navigation-fragment/build.gradle
index 22eea96..814229f 100644
--- a/hilt/hilt-navigation-fragment/build.gradle
+++ b/hilt/hilt-navigation-fragment/build.gradle
@@ -56,7 +56,7 @@
}
androidx {
- name = "Android Navigation Fragment Hilt Extension"
+ name = "Navigation Fragment Hilt Extension"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.HILT
inceptionYear = "2021"
diff --git a/hilt/hilt-navigation-fragment/src/androidTest/java/androidx/hilt/navigation/fragment/HiltNavGraphViewModelLazyTest.kt b/hilt/hilt-navigation-fragment/src/androidTest/java/androidx/hilt/navigation/fragment/HiltNavGraphViewModelLazyTest.kt
index 06352ae..6cc6dc8 100644
--- a/hilt/hilt-navigation-fragment/src/androidTest/java/androidx/hilt/navigation/fragment/HiltNavGraphViewModelLazyTest.kt
+++ b/hilt/hilt-navigation-fragment/src/androidTest/java/androidx/hilt/navigation/fragment/HiltNavGraphViewModelLazyTest.kt
@@ -38,10 +38,10 @@
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
+import javax.inject.Inject
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import javax.inject.Inject
/*
* Copyright 2021 The Android Open Source Project
diff --git a/hilt/hilt-navigation-fragment/src/main/AndroidManifest.xml b/hilt/hilt-navigation-fragment/src/main/AndroidManifest.xml
deleted file mode 100644
index 38e6839..0000000
--- a/hilt/hilt-navigation-fragment/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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.
- -->
-
-<manifest />
diff --git a/hilt/hilt-navigation/build.gradle b/hilt/hilt-navigation/build.gradle
index ad4e41a..6539c86 100644
--- a/hilt/hilt-navigation/build.gradle
+++ b/hilt/hilt-navigation/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Navigation Hilt Extension"
+ name = "Navigation Hilt Extension"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.HILT
inceptionYear = "2021"
diff --git a/hilt/hilt-navigation/src/main/AndroidManifest.xml b/hilt/hilt-navigation/src/main/AndroidManifest.xml
deleted file mode 100644
index 38e6839..0000000
--- a/hilt/hilt-navigation/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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.
- -->
-
-<manifest />
diff --git a/hilt/hilt-work/build.gradle b/hilt/hilt-work/build.gradle
index 46f258b..abe1186 100644
--- a/hilt/hilt-work/build.gradle
+++ b/hilt/hilt-work/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Lifecycle WorkManager Hilt Extension"
+ name = "WorkManager Hilt Extension"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.HILT
inceptionYear = "2020"
diff --git a/hilt/integration-tests/workerapp/src/androidTest/java/androidx/hilt/integration/workerapp/SimpleTest.kt b/hilt/integration-tests/workerapp/src/androidTest/java/androidx/hilt/integration/workerapp/SimpleTest.kt
index 477c46b..46cc51c 100644
--- a/hilt/integration-tests/workerapp/src/androidTest/java/androidx/hilt/integration/workerapp/SimpleTest.kt
+++ b/hilt/integration-tests/workerapp/src/androidTest/java/androidx/hilt/integration/workerapp/SimpleTest.kt
@@ -27,12 +27,12 @@
import com.google.common.truth.Truth.assertThat
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
+import javax.inject.Inject
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import javax.inject.Inject
@SmallTest
@HiltAndroidTest
diff --git a/input/input-motionprediction/build.gradle b/input/input-motionprediction/build.gradle
index c630796..e5e6f105 100644
--- a/input/input-motionprediction/build.gradle
+++ b/input/input-motionprediction/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "Android Motion Prediction"
+ name = "Motion Prediction"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.INPUT_MOTIONPREDICTION
inceptionYear = "2022"
diff --git a/input/input-motionprediction/src/main/AndroidManifest.xml b/input/input-motionprediction/src/main/AndroidManifest.xml
deleted file mode 100644
index e4e6dc1f..0000000
--- a/input/input-motionprediction/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<manifest />
\ No newline at end of file
diff --git a/inspection/inspection-gradle-plugin/build.gradle b/inspection/inspection-gradle-plugin/build.gradle
index 4589093..bddd9ff 100644
--- a/inspection/inspection-gradle-plugin/build.gradle
+++ b/inspection/inspection-gradle-plugin/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "Android Inspection Gradle Plugin"
+ name = "Inspection Gradle Plugin"
type = LibraryType.GRADLE_PLUGIN
publish = Publish.NONE
inceptionYear = "2019"
diff --git a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateInspectionPlatformVersionTask.kt b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateInspectionPlatformVersionTask.kt
index 84a7b25..97c3fc0 100644
--- a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateInspectionPlatformVersionTask.kt
+++ b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateInspectionPlatformVersionTask.kt
@@ -17,6 +17,7 @@
package androidx.inspection.gradle
import com.android.build.api.variant.Variant
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
@@ -36,7 +37,6 @@
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.work.DisableCachingByDefault
-import java.io.File
/**
* Generates a file into META-INF/ folder that has version of androidx.inspection used
diff --git a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateProguardDetectionFileTask.kt b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateProguardDetectionFileTask.kt
index 9801f3c..aa6d722 100644
--- a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateProguardDetectionFileTask.kt
+++ b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/GenerateProguardDetectionFileTask.kt
@@ -16,6 +16,7 @@
package androidx.inspection.gradle
+import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
@@ -25,7 +26,6 @@
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
-import java.io.File
/**
* Task purposely empty, unused class that would be removed by proguard. See javadoc below for more
* information.
diff --git a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/InspectionPlugin.kt b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/InspectionPlugin.kt
index 8a3832e..48c5da5 100644
--- a/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/InspectionPlugin.kt
+++ b/inspection/inspection-gradle-plugin/src/main/kotlin/androidx/inspection/gradle/InspectionPlugin.kt
@@ -22,19 +22,19 @@
import com.google.protobuf.gradle.GenerateProtoTask
import com.google.protobuf.gradle.ProtobufExtension
import com.google.protobuf.gradle.ProtobufPlugin
+import java.io.File
+import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
+import org.gradle.api.artifacts.MinimalExternalModuleDependency
+import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.api.artifacts.type.ArtifactTypeDefinition
import org.gradle.api.attributes.Attribute
import org.gradle.api.tasks.StopExecutionException
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.dependencies
-import java.io.File
-import org.gradle.api.GradleException
-import org.gradle.api.artifacts.MinimalExternalModuleDependency
-import org.gradle.api.artifacts.VersionCatalogsExtension
/**
* A plugin which, when present, ensures that intermediate inspector
diff --git a/inspection/inspection-gradle-plugin/src/test/kotlin/androidx/inspection/gradle/InspectionPluginTest.kt b/inspection/inspection-gradle-plugin/src/test/kotlin/androidx/inspection/gradle/InspectionPluginTest.kt
index 0ed2418..00b6f06 100644
--- a/inspection/inspection-gradle-plugin/src/test/kotlin/androidx/inspection/gradle/InspectionPluginTest.kt
+++ b/inspection/inspection-gradle-plugin/src/test/kotlin/androidx/inspection/gradle/InspectionPluginTest.kt
@@ -17,6 +17,11 @@
package androidx.inspection.gradle
import androidx.testutils.gradle.ProjectSetupRule
+import java.io.BufferedReader
+import java.io.File
+import java.io.InputStreamReader
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Before
@@ -25,11 +30,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.BufferedReader
-import java.io.File
-import java.io.InputStreamReader
-import kotlin.test.assertEquals
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class InspectionPluginTest {
diff --git a/inspection/inspection-testing/build.gradle b/inspection/inspection-testing/build.gradle
index 7f51b57..f7b000e 100644
--- a/inspection/inspection-testing/build.gradle
+++ b/inspection/inspection-testing/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Inspection Testing"
+ name = "Inspection Testing"
type = LibraryType.INTERNAL_TEST_LIBRARY
publish = Publish.NONE
inceptionYear = "2019"
diff --git a/inspection/inspection-testing/src/androidTest/java/androidx/inspection/testing/echo/EchoInspector.kt b/inspection/inspection-testing/src/androidTest/java/androidx/inspection/testing/echo/EchoInspector.kt
index 0af1c8d..a1d4bb3 100644
--- a/inspection/inspection-testing/src/androidTest/java/androidx/inspection/testing/echo/EchoInspector.kt
+++ b/inspection/inspection-testing/src/androidTest/java/androidx/inspection/testing/echo/EchoInspector.kt
@@ -20,12 +20,12 @@
import androidx.inspection.Inspector
import androidx.inspection.InspectorEnvironment
import androidx.inspection.InspectorFactory
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
-import java.util.concurrent.Executor
/**
* An inspector for test purposes, it echoes on commands and sends events once
diff --git a/inspection/inspection-testing/src/main/AndroidManifest.xml b/inspection/inspection-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/inspection/inspection-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/inspection/inspection-testing/src/main/java/androidx/inspection/testing/InspectorTester.kt b/inspection/inspection-testing/src/main/java/androidx/inspection/testing/InspectorTester.kt
index 0ee526c..ee96110 100644
--- a/inspection/inspection-testing/src/main/java/androidx/inspection/testing/InspectorTester.kt
+++ b/inspection/inspection-testing/src/main/java/androidx/inspection/testing/InspectorTester.kt
@@ -23,6 +23,11 @@
import androidx.inspection.InspectorEnvironment
import androidx.inspection.InspectorExecutors
import androidx.inspection.InspectorFactory
+import java.util.ServiceLoader
+import java.util.concurrent.CancellationException
+import java.util.concurrent.Executor
+import kotlin.coroutines.coroutineContext
+import kotlin.coroutines.resume
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
@@ -35,11 +40,6 @@
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
-import java.util.ServiceLoader
-import java.util.concurrent.CancellationException
-import java.util.concurrent.Executor
-import kotlin.coroutines.coroutineContext
-import kotlin.coroutines.resume
// TODO: should be non suspend function with CoroutineScope receiver, that would automatically
// dispose inspector;
diff --git a/inspection/inspection-testing/src/main/java/androidx/inspection/testing/TestInspectorExecutors.kt b/inspection/inspection-testing/src/main/java/androidx/inspection/testing/TestInspectorExecutors.kt
index 96adc63..645cea9 100644
--- a/inspection/inspection-testing/src/main/java/androidx/inspection/testing/TestInspectorExecutors.kt
+++ b/inspection/inspection-testing/src/main/java/androidx/inspection/testing/TestInspectorExecutors.kt
@@ -19,10 +19,10 @@
import android.os.Handler
import android.os.HandlerThread
import androidx.inspection.InspectorExecutors
-import kotlinx.coroutines.Job
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.concurrent.RejectedExecutionException
+import kotlinx.coroutines.Job
/**
* Test Inspector Executors.
diff --git a/inspection/inspection/build.gradle b/inspection/inspection/build.gradle
index 5c35b71..a142722 100644
--- a/inspection/inspection/build.gradle
+++ b/inspection/inspection/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Inspection"
+ name = "Inspection"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Experimental AndroidX Inspection Project"
diff --git a/inspection/inspection/src/androidTest/java/androidx/inspection/rules/JvmtiRule.kt b/inspection/inspection/src/androidTest/java/androidx/inspection/rules/JvmtiRule.kt
index cccfd9a..3a93a310 100644
--- a/inspection/inspection/src/androidTest/java/androidx/inspection/rules/JvmtiRule.kt
+++ b/inspection/inspection/src/androidTest/java/androidx/inspection/rules/JvmtiRule.kt
@@ -18,8 +18,8 @@
import android.os.Debug
import androidx.annotation.RequiresApi
-import org.junit.rules.ExternalResource
import java.io.IOException
+import org.junit.rules.ExternalResource
@RequiresApi(28)
class JvmtiRule : ExternalResource() {
diff --git a/inspection/inspection/src/main/AndroidManifest.xml b/inspection/inspection/src/main/AndroidManifest.xml
deleted file mode 100644
index 873a38a..0000000
--- a/inspection/inspection/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
- <!-- Copyright (C) 2014 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 />
diff --git a/interpolator/interpolator/build.gradle b/interpolator/interpolator/build.gradle
index 524e14e..00cd919 100644
--- a/interpolator/interpolator/build.gradle
+++ b/interpolator/interpolator/build.gradle
@@ -10,7 +10,7 @@
}
androidx {
- name = "Android Support Library Interpolators"
+ name = "Interpolators"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/interpolator/interpolator/src/main/AndroidManifest.xml b/interpolator/interpolator/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/interpolator/interpolator/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java b/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
index 8a7e238..1619734 100644
--- a/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
+++ b/javascriptengine/javascriptengine/src/androidTest/java/androidx/javascriptengine/WebViewJavaScriptSandboxTest.java
@@ -17,9 +17,12 @@
package androidx.javascriptengine;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.webkit.WebView;
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
+import androidx.core.content.pm.PackageInfoCompat;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
@@ -30,6 +33,7 @@
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -53,6 +57,18 @@
Assume.assumeTrue(JavaScriptSandbox.isSupported());
}
+ // Get the current WebView provider version. In a versionCode of AAAABBBCD, AAAA is the build
+ // number and BBB is the patch number. C and D may usually be ignored.
+ //
+ // Strongly prefer using feature flags over version checks if possible.
+ public long getWebViewVersion() {
+ PackageInfo systemWebViewPackage = WebView.getCurrentWebViewPackage();
+ if (systemWebViewPackage == null) {
+ Assert.fail("No current WebView provider");
+ }
+ return PackageInfoCompat.getLongVersionCode(systemWebViewPackage);
+ }
+
@Test
@MediumTest
public void testSimpleJsEvaluation() throws Throwable {
@@ -193,6 +209,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testInfiniteLoop() throws Throwable {
final String code = "while(true){}";
Context context = ApplicationProvider.getApplicationContext();
@@ -221,6 +238,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testMultipleInfiniteLoops() throws Throwable {
final String code = "while(true){}";
final int num_of_evaluations = 10;
@@ -255,6 +273,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testSimpleArrayBuffer() throws Throwable {
final String provideString = "Hello World";
final byte[] bytes = provideString.getBytes(StandardCharsets.US_ASCII);
@@ -286,6 +305,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testArrayBufferWasmCompilation() throws Throwable {
final String success = "success";
// The bytes of a minimal WebAssembly module, courtesy of v8/test/cctest/test-api-wasm.cc
@@ -319,6 +339,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testPromiseReturn() throws Throwable {
final String code = "Promise.resolve(\"PASS\")";
final String expected = "PASS";
@@ -339,6 +360,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testPromiseReturnLaterResolve() throws Throwable {
final String code1 = "var promiseResolve, promiseReject;"
+ "new Promise(function(resolve, reject){"
@@ -366,6 +388,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testNestedConsumeNamedDataAsArrayBuffer() throws Throwable {
final String success = "success";
// The bytes of a minimal WebAssembly module, courtesy of v8/test/cctest/test-api-wasm.cc
@@ -409,6 +432,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testPromiseEvaluationThrow() throws Throwable {
final String provideString = "Hello World";
final byte[] bytes = provideString.getBytes(StandardCharsets.US_ASCII);
@@ -531,6 +555,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testHeapSizeAdjustment() throws Throwable {
final String code = "\"PASS\"";
final String expected = "PASS";
@@ -570,7 +595,16 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testHeapSizeEnforced() throws Throwable {
+ // WebView versions < 110.0.5438.0 do not contain OOM crashes to a single isolate and
+ // instead crash the whole sandbox process. This change is not tracked in a feature flag.
+ // Versions < 110.0.5438.0 are not considered to be broken, but their behavior is not
+ // of interest for this test.
+ // See Chromium change: https://chromium-review.googlesource.com/c/chromium/src/+/4047785
+ Assume.assumeTrue("WebView version does not support per-isolate OOM handling",
+ getWebViewVersion() >= 5438_000_00L);
+
final long maxHeapSize = REASONABLE_HEAP_SIZE;
// We need to beat the v8 optimizer to ensure it really allocates the required memory. Note
// that we're allocating an array of elements - not bytes. Filling will ensure that the
@@ -587,6 +621,7 @@
try (JavaScriptSandbox jsSandbox = jsSandboxFuture1.get(5, TimeUnit.SECONDS)) {
Assume.assumeTrue(jsSandbox.isFeatureSupported(
JavaScriptSandbox.JS_FEATURE_ISOLATE_MAX_HEAP_SIZE));
+
Assume.assumeTrue(
jsSandbox.isFeatureSupported(JavaScriptSandbox.JS_FEATURE_PROMISE_RETURN));
IsolateStartupParameters isolateStartupParameters = new IsolateStartupParameters();
@@ -656,7 +691,16 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testIsolateCreationAfterCrash() throws Throwable {
+ // WebView versions < 110.0.5438.0 do not contain OOM crashes to a single isolate and
+ // instead crash the whole sandbox process. This change is not tracked in a feature flag.
+ // Versions < 110.0.5438.0 are not considered to be broken, but their behavior is not
+ // of interest for this test.
+ // See Chromium change: https://chromium-review.googlesource.com/c/chromium/src/+/4047785
+ Assume.assumeTrue("WebView version does not support per-isolate OOM handling",
+ getWebViewVersion() >= 5438_000_00L);
+
final long maxHeapSize = REASONABLE_HEAP_SIZE;
// We need to beat the v8 optimizer to ensure it really allocates the required memory. Note
// that we're allocating an array of elements - not bytes. Filling will ensure that the
@@ -727,6 +771,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testAsyncPromiseCallbacks() throws Throwable {
// Unlike testPromiseReturn and testPromiseEvaluationThrow, this test is guaranteed to
// exercise promises in an asynchronous way, rather than in ways which cause a promise to
@@ -795,6 +840,7 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testLargeScriptJsEvaluation() throws Throwable {
String longString = "a".repeat(2000000);
final String code = ""
@@ -819,6 +865,7 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testLargeScriptByteArrayJsEvaluation() throws Throwable {
final String longString = "a".repeat(2000000);
final String codeString = ""
@@ -844,6 +891,7 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testLargeReturn() throws Throwable {
final String longString = "a".repeat(2000000);
final String code = "'a'.repeat(2000000);";
@@ -866,6 +914,7 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testLargeError() throws Throwable {
final String longString = "a".repeat(2000000);
final String code = "throw \"" + longString + "\");";
@@ -892,6 +941,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testResultSizeEnforced() throws Throwable {
final int maxSize = 100;
Context context = ApplicationProvider.getApplicationContext();
@@ -942,6 +992,7 @@
@Test
@LargeTest
+ @Ignore("b/268212217")
public void testConsoleLogging() throws Throwable {
final class LoggingJavaScriptConsoleCallback implements JavaScriptConsoleCallback {
private final Object mLock = new Object();
@@ -1094,6 +1145,7 @@
@Test
@MediumTest
+ @Ignore("b/268212217")
public void testConsoleCallbackCanCallService() throws Throwable {
// This checks that there is nothing intrinsically wrong with calling service APIs from a
// console client. Note that, in theory, Binder will reuse the same threads if code recurses
diff --git a/javascriptengine/javascriptengine/src/main/AndroidManifest.xml b/javascriptengine/javascriptengine/src/main/AndroidManifest.xml
deleted file mode 100644
index 8e90956..0000000
--- a/javascriptengine/javascriptengine/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
- -->
-<manifest />
diff --git a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/IsolateStartupParameters.java b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/IsolateStartupParameters.java
index df70280..75655f4 100644
--- a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/IsolateStartupParameters.java
+++ b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/IsolateStartupParameters.java
@@ -46,7 +46,11 @@
* The applied limit may not be exact. For example, the limit may internally be rounded up to
* some multiple of bytes, be increased to some minimum value, or reduced to some maximum
* supported value.
- *
+ * <p>
+ * Exceeding this limit will usually result in a {@link MemoryLimitExceededException},
+ * but beware that not all JavaScript sandbox service implementations (particularly older ones)
+ * handle memory exhaustion equally gracefully, and may crash the entire sandbox (see
+ * {@link SandboxDeadException}).
* @param size heap size in bytes
*/
@RequiresFeature(name = JavaScriptSandbox.JS_FEATURE_ISOLATE_MAX_HEAP_SIZE,
diff --git a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/JavaScriptIsolate.java b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/JavaScriptIsolate.java
index 00afeb8..a4432f0 100644
--- a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/JavaScriptIsolate.java
+++ b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/JavaScriptIsolate.java
@@ -162,13 +162,23 @@
@Override
public void reportResult(String result) {
Objects.requireNonNull(result);
- handleEvaluationResult(mCompleter, result);
+ final long identityToken = Binder.clearCallingIdentity();
+ try {
+ handleEvaluationResult(mCompleter, result);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
}
@Override
public void reportError(@ExecutionErrorTypes int type, String error) {
Objects.requireNonNull(error);
- handleEvaluationError(mCompleter, type, error);
+ final long identityToken = Binder.clearCallingIdentity();
+ try {
+ handleEvaluationError(mCompleter, type, error);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
}
}
diff --git a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/MemoryLimitExceededException.java b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/MemoryLimitExceededException.java
index f3690ee..a0eee81 100644
--- a/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/MemoryLimitExceededException.java
+++ b/javascriptengine/javascriptengine/src/main/java/androidx/javascriptengine/MemoryLimitExceededException.java
@@ -20,11 +20,11 @@
/**
* Indicates that a JavaScriptIsolate's evaluation failed due to exceeding its heap size limit.
- *
- * This exception is thrown when exceeding the heap size limit configured for the isolate via
- * {@link IsolateStartupParameters}, or the default limit. It is not guaranteed to be thrown if the
- * Android system as a whole has run out of memory before the JavaScript environment has reached its
- * configured heap limit.
+ * <p>
+ * This exception may be thrown when exceeding the heap size limit configured for the isolate via
+ * {@link IsolateStartupParameters}, or the default limit. Beware that it will not be thrown if the
+ * Android system as a whole has run out of memory before the JavaScript environment has reached
+ * its configured heap limit.
* <p>
* The isolate may not continue to be used after this exception has been thrown, and other pending
* evalutions for the isolate will fail. The isolate may continue to hold onto resources (even if
@@ -32,6 +32,10 @@
* sandbox be restarted at the earliest opportunity in order to reclaim these resources.
* <p>
* Other isolates within the same sandbox may continue to be used, created, and closed as normal.
+ * <p>
+ * Beware that not all JavaScript sandbox service implementations (particularly older ones)
+ * handle memory exhaustion equally gracefully, and may instead crash the entire sandbox (see
+ * {@link SandboxDeadException}).
*/
public final class MemoryLimitExceededException extends JavaScriptException {
public MemoryLimitExceededException(@NonNull String error) {
diff --git a/leanback/leanback-grid/build.gradle b/leanback/leanback-grid/build.gradle
index 36a1965..b6171c8 100644
--- a/leanback/leanback-grid/build.gradle
+++ b/leanback/leanback-grid/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "AndroidX Leanback Grid"
+ name = "Leanback Grid"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.LEANBACK_GRID
inceptionYear = "2021"
diff --git a/leanback/leanback-grid/src/main/AndroidManifest.xml b/leanback/leanback-grid/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/leanback/leanback-grid/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/leanback/leanback-paging/build.gradle b/leanback/leanback-paging/build.gradle
index 6c51eec..0b19679 100644
--- a/leanback/leanback-paging/build.gradle
+++ b/leanback/leanback-paging/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "AndroidX Leanback Paging"
+ name = "Leanback Paging"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.LEANBACK_PAGING
inceptionYear = "2020"
diff --git a/leanback/leanback-paging/src/androidTest/java/androidx/leanback/paging/PagingDataAdapterTest.kt b/leanback/leanback-paging/src/androidTest/java/androidx/leanback/paging/PagingDataAdapterTest.kt
index 9b2d05e..2cda1ef 100644
--- a/leanback/leanback-paging/src/androidTest/java/androidx/leanback/paging/PagingDataAdapterTest.kt
+++ b/leanback/leanback-paging/src/androidTest/java/androidx/leanback/paging/PagingDataAdapterTest.kt
@@ -28,6 +28,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.testutils.MainDispatcherRule
+import kotlin.coroutines.ContinuationInterceptor
+import kotlin.test.assertEquals
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -40,8 +42,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.coroutines.ContinuationInterceptor
-import kotlin.test.assertEquals
@OptIn(ExperimentalCoroutinesApi::class)
@MediumTest
diff --git a/leanback/leanback-paging/src/main/AndroidManifest.xml b/leanback/leanback-paging/src/main/AndroidManifest.xml
deleted file mode 100644
index 95dabe9..0000000
--- a/leanback/leanback-paging/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
\ No newline at end of file
diff --git a/leanback/leanback-preference/build.gradle b/leanback/leanback-preference/build.gradle
index d64a337..8af0e9d 100644
--- a/leanback/leanback-preference/build.gradle
+++ b/leanback/leanback-preference/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "AndroidX Leanback Preference"
+ name = "Leanback Preference"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.LEANBACK_PREFERENCE
inceptionYear = "2015"
diff --git a/leanback/leanback-preference/src/main/AndroidManifest.xml b/leanback/leanback-preference/src/main/AndroidManifest.xml
deleted file mode 100644
index 107b553..0000000
--- a/leanback/leanback-preference/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2015 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 />
diff --git a/leanback/leanback-tab/build.gradle b/leanback/leanback-tab/build.gradle
index 1c0b1cb..b38819a 100644
--- a/leanback/leanback-tab/build.gradle
+++ b/leanback/leanback-tab/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "AndroidX Leanback Tab"
+ name = "Leanback Tab"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.LEANBACK_TAB
inceptionYear = "2020"
diff --git a/leanback/leanback-tab/src/main/AndroidManifest.xml b/leanback/leanback-tab/src/main/AndroidManifest.xml
deleted file mode 100644
index a297096..0000000
--- a/leanback/leanback-tab/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
\ No newline at end of file
diff --git a/leanback/leanback/api/current.ignore b/leanback/leanback/api/current.ignore
index 27e9b7a..bd85f68 100644
--- a/leanback/leanback/api/current.ignore
+++ b/leanback/leanback/api/current.ignore
@@ -21,9 +21,3 @@
Removed deprecated class androidx.leanback.widget.OnChildSelectedListener
RemovedInterface: androidx.leanback.widget.ViewHolderTask:
Removed class androidx.leanback.widget.ViewHolderTask
-
-
-RemovedMethod: androidx.leanback.widget.FacetProvider#getFacet(Class<?>):
- Removed method androidx.leanback.widget.FacetProvider.getFacet(Class<?>)
-RemovedMethod: androidx.leanback.widget.FacetProviderAdapter#getFacetProvider(int):
- Removed method androidx.leanback.widget.FacetProviderAdapter.getFacetProvider(int)
diff --git a/leanback/leanback/api/restricted_current.ignore b/leanback/leanback/api/restricted_current.ignore
index 2ac34c7..3295f54 100644
--- a/leanback/leanback/api/restricted_current.ignore
+++ b/leanback/leanback/api/restricted_current.ignore
@@ -23,9 +23,3 @@
Removed deprecated class androidx.leanback.widget.OnChildSelectedListener
RemovedInterface: androidx.leanback.widget.ViewHolderTask:
Removed class androidx.leanback.widget.ViewHolderTask
-
-
-RemovedMethod: androidx.leanback.widget.FacetProvider#getFacet(Class<?>):
- Removed method androidx.leanback.widget.FacetProvider.getFacet(Class<?>)
-RemovedMethod: androidx.leanback.widget.FacetProviderAdapter#getFacetProvider(int):
- Removed method androidx.leanback.widget.FacetProviderAdapter.getFacetProvider(int)
diff --git a/leanback/leanback/build.gradle b/leanback/leanback/build.gradle
index 1a3152a..d22458a 100644
--- a/leanback/leanback/build.gradle
+++ b/leanback/leanback/build.gradle
@@ -55,7 +55,7 @@
}
androidx {
- name = "Android Support Leanback v17"
+ name = "Leanback"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.LEANBACK
inceptionYear = "2014"
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
index 02e6d11..50f2fee 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/BrowseFragmentTest.java
@@ -59,6 +59,7 @@
import androidx.test.rule.ActivityTestRule;
import org.junit.After;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -190,6 +191,7 @@
}
@Test
+ @Ignore("b/281082608")
public void testPressRightBeforeMainFragmentCreated() throws Throwable {
final long dataLoadingDelay = 1000;
Intent intent = new Intent();
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
index cd4bca8..897d008 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchFragmentTest.java
@@ -30,6 +30,7 @@
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import org.junit.Ignore;
import android.app.Fragment;
import androidx.leanback.test.R;
@@ -190,6 +191,7 @@
}
@Test
+ @Ignore("b/281082608")
public void testFocusWithSpeechRecognizerEnabled() throws Exception {
// Skip the test for devices which do not have SpeechRecognizer
diff --git a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
index 804ffa3..32d6e59 100644
--- a/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
+++ b/leanback/leanback/src/androidTest/java/androidx/leanback/app/SearchSupportFragmentTest.java
@@ -27,6 +27,7 @@
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import org.junit.Ignore;
import androidx.fragment.app.Fragment;
import androidx.leanback.test.R;
@@ -187,6 +188,7 @@
}
@Test
+ @Ignore("b/281082608")
public void testFocusWithSpeechRecognizerEnabled() throws Exception {
// Skip the test for devices which do not have SpeechRecognizer
diff --git a/leanback/leanback/src/main/AndroidManifest.xml b/leanback/leanback/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/leanback/leanback/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/leanback/leanback/src/main/res/values-or/strings.xml b/leanback/leanback/src/main/res/values-or/strings.xml
index d5269f5..a7f2365 100644
--- a/leanback/leanback/src/main/res/values-or/strings.xml
+++ b/leanback/leanback/src/main/res/values-or/strings.xml
@@ -26,7 +26,7 @@
<string name="lb_control_display_fast_forward_multiplier" msgid="4657191930956702614">"%1$dX"</string>
<string name="lb_control_display_rewind_multiplier" msgid="4597148235912710942">"%1$dX"</string>
<string name="lb_playback_controls_play" msgid="7088090604803481121">"ଚଲାନ୍ତୁ"</string>
- <string name="lb_playback_controls_pause" msgid="917331776961802657">"ପଜ୍ କରନ୍ତୁ"</string>
+ <string name="lb_playback_controls_pause" msgid="917331776961802657">"ବିରତ କରନ୍ତୁ"</string>
<string name="lb_playback_controls_fast_forward" msgid="740570111678243493">"ଫାଷ୍ଟ ଫର୍ୱାର୍ଡ"</string>
<string name="lb_playback_controls_fast_forward_multiplier" msgid="5734614175721471329">"%1$dX ବେଗରେ ଫାଷ୍ଟ ଫରୱାର୍ଡ"</string>
<string name="lb_playback_controls_rewind" msgid="2866333981131020771">"ରିୱାଇଣ୍ଡ"</string>
diff --git a/libraryversions.toml b/libraryversions.toml
index d5eb02a..413f3f3 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -21,7 +21,7 @@
COLLECTION = "1.3.0-alpha05"
COMPOSE = "1.5.0-alpha04"
COMPOSE_COMPILER = "1.4.7"
-COMPOSE_MATERIAL3 = "1.2.0-alpha01"
+COMPOSE_MATERIAL3 = "1.2.0-alpha02"
COMPOSE_MATERIAL3_ADAPTIVE = "1.0.0-alpha01"
COMPOSE_RUNTIME_TRACING = "1.0.0-alpha03"
CONSTRAINTLAYOUT = "2.2.0-alpha10"
@@ -64,7 +64,7 @@
GRAPHICS_CORE = "1.0.0-alpha04"
GRAPHICS_FILTERS = "1.0.0-alpha01"
GRAPHICS_SHAPES = "1.0.0-alpha03"
-GRIDLAYOUT = "1.1.0-alpha02"
+GRIDLAYOUT = "1.1.0-beta01"
HEALTH_CONNECT = "1.0.0-alpha11"
HEALTH_SERVICES_CLIENT = "1.0.0-beta04"
HEIFWRITER = "1.1.0-alpha02"
diff --git a/lifecycle/integration-tests/incrementality/src/test/kotlin/androidx/lifecycle/IncrementalAnnotationProcessingTest.kt b/lifecycle/integration-tests/incrementality/src/test/kotlin/androidx/lifecycle/IncrementalAnnotationProcessingTest.kt
index d23d266..b7f7648 100644
--- a/lifecycle/integration-tests/incrementality/src/test/kotlin/androidx/lifecycle/IncrementalAnnotationProcessingTest.kt
+++ b/lifecycle/integration-tests/incrementality/src/test/kotlin/androidx/lifecycle/IncrementalAnnotationProcessingTest.kt
@@ -18,15 +18,15 @@
import androidx.testutils.gradle.ProjectSetupRule
import com.google.common.truth.Truth.assertThat
+import java.io.File
+import java.nio.file.Files
+import java.nio.file.Path
import org.gradle.testkit.runner.GradleRunner
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.File
-import java.nio.file.Files
-import java.nio.file.Path
@RunWith(JUnit4::class)
class IncrementalAnnotationProcessingTest {
diff --git a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt b/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
index 5b4d60d..61bece9 100644
--- a/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
+++ b/lifecycle/integration-tests/kotlintestapp/src/test-common/java/androidx.lifecycle/LifecycleCoroutineScopeTestBase.kt
@@ -18,6 +18,7 @@
import androidx.lifecycle.testing.TestLifecycleOwner
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CancellationException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
@@ -25,10 +26,9 @@
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.withContext
import org.junit.Test
-import java.util.concurrent.CancellationException
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
@OptIn(ExperimentalCoroutinesApi::class)
abstract class LifecycleCoroutineScopeTestBase {
diff --git a/lifecycle/integration-tests/kotlintestapp/src/test/java/androidx/lifecycle/LifecycleCoroutineScopeTest.kt b/lifecycle/integration-tests/kotlintestapp/src/test/java/androidx/lifecycle/LifecycleCoroutineScopeTest.kt
index a2af184..19d71e3 100644
--- a/lifecycle/integration-tests/kotlintestapp/src/test/java/androidx/lifecycle/LifecycleCoroutineScopeTest.kt
+++ b/lifecycle/integration-tests/kotlintestapp/src/test/java/androidx/lifecycle/LifecycleCoroutineScopeTest.kt
@@ -18,6 +18,8 @@
package androidx.lifecycle
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.test.resetMain
@@ -26,8 +28,6 @@
import org.junit.Before
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
/**
* To ensure consistent behavior, we run these tests both on androidTest and test
diff --git a/lifecycle/lifecycle-common-java8/build.gradle b/lifecycle/lifecycle-common-java8/build.gradle
index cbab42e..88e4bc1 100644
--- a/lifecycle/lifecycle-common-java8/build.gradle
+++ b/lifecycle/lifecycle-common-java8/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "Android Lifecycle-Common for Java 8 Language"
+ name = "Lifecycle-Common for Java 8"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle-Common for Java 8 Language"
diff --git a/lifecycle/lifecycle-common/build.gradle b/lifecycle/lifecycle-common/build.gradle
index fcd8ba4..1aeacc3 100644
--- a/lifecycle/lifecycle-common/build.gradle
+++ b/lifecycle/lifecycle-common/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Lifecycle-Common"
+ name = "Lifecycle-Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle-Common"
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DispatchQueue.kt b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DispatchQueue.kt
index 1f51438..13f6bd8 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DispatchQueue.kt
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DispatchQueue.kt
@@ -18,10 +18,10 @@
import androidx.annotation.AnyThread
import androidx.annotation.MainThread
-import kotlinx.coroutines.Dispatchers
import java.util.ArrayDeque
import java.util.Queue
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.Dispatchers
/**
* Helper class for [PausingDispatcher] that tracks runnables which are enqueued to the dispatcher
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.kt b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.kt
index ac586d8..f69c624 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.kt
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.kt
@@ -25,7 +25,6 @@
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
-import kotlinx.coroutines.launch
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -33,6 +32,7 @@
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.launch
/**
* Defines an object that has an Android Lifecycle. [Fragment][androidx.fragment.app.Fragment]
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/PausingDispatcher.kt b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/PausingDispatcher.kt
index 70dc54d..7b388ed 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/PausingDispatcher.kt
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/PausingDispatcher.kt
@@ -16,13 +16,13 @@
package androidx.lifecycle
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.Runnable
import kotlinx.coroutines.withContext
-import kotlin.coroutines.CoroutineContext
/**
* Runs the given block when the [LifecycleOwner]'s [Lifecycle] is at least in
diff --git a/lifecycle/lifecycle-compiler/build.gradle b/lifecycle/lifecycle-compiler/build.gradle
index 60945b2..b5ac1f6 100644
--- a/lifecycle/lifecycle-compiler/build.gradle
+++ b/lifecycle/lifecycle-compiler/build.gradle
@@ -53,7 +53,7 @@
}
androidx {
- name = "Android Lifecycles Compiler"
+ name = "Lifecycles Compiler"
type = LibraryType.ANNOTATION_PROCESSOR
inceptionYear = "2017"
description = "Android Lifecycles annotation processor"
diff --git a/lifecycle/lifecycle-compiler/src/test/kotlin/androidx/lifecycle/ValidCasesTest.kt b/lifecycle/lifecycle-compiler/src/test/kotlin/androidx/lifecycle/ValidCasesTest.kt
index 4c36341..1889a41 100644
--- a/lifecycle/lifecycle-compiler/src/test/kotlin/androidx/lifecycle/ValidCasesTest.kt
+++ b/lifecycle/lifecycle-compiler/src/test/kotlin/androidx/lifecycle/ValidCasesTest.kt
@@ -20,11 +20,11 @@
import androidx.lifecycle.utils.processClass
import com.google.testing.compile.CompileTester
import com.google.testing.compile.JavaSourcesSubject
+import java.io.File
+import javax.tools.StandardLocation
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.io.File
-import javax.tools.StandardLocation
@RunWith(JUnit4::class)
class ValidCasesTest {
diff --git a/lifecycle/lifecycle-extensions/build.gradle b/lifecycle/lifecycle-extensions/build.gradle
index b729d31..b8c4e04 100644
--- a/lifecycle/lifecycle-extensions/build.gradle
+++ b/lifecycle/lifecycle-extensions/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Lifecycle Extensions"
+ name = "Lifecycle Extensions"
publish = Publish.NONE
runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
inceptionYear = "2017"
diff --git a/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle b/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
index 6bb81f4..59c894a 100644
--- a/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
+++ b/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "Android LiveData Kotlin Lint Checks"
+ name = "LiveData Kotlin Lint Checks"
type = LibraryType.LINT
inceptionYear = "2019"
description = "Lint Checks for LiveData Kotlin Extensions"
diff --git a/lifecycle/lifecycle-livedata-core-ktx/src/main/AndroidManifest.xml b/lifecycle/lifecycle-livedata-core-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/lifecycle/lifecycle-livedata-core-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/lifecycle/lifecycle-livedata-core-truth/src/main/AndroidManifest.xml b/lifecycle/lifecycle-livedata-core-truth/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/lifecycle/lifecycle-livedata-core-truth/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/lifecycle/lifecycle-livedata-core/build.gradle b/lifecycle/lifecycle-livedata-core/build.gradle
index 1947720d..58101b7 100644
--- a/lifecycle/lifecycle-livedata-core/build.gradle
+++ b/lifecycle/lifecycle-livedata-core/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Lifecycle LiveData Core"
+ name = "Lifecycle LiveData Core"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle LiveData Core"
diff --git a/lifecycle/lifecycle-livedata-ktx/src/main/AndroidManifest.xml b/lifecycle/lifecycle-livedata-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/lifecycle/lifecycle-livedata-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/lifecycle/lifecycle-livedata/build.gradle b/lifecycle/lifecycle-livedata/build.gradle
index 824c7f0..898e7b1 100644
--- a/lifecycle/lifecycle-livedata/build.gradle
+++ b/lifecycle/lifecycle-livedata/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Lifecycle LiveData"
+ name = "Lifecycle LiveData"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle LiveData"
diff --git a/lifecycle/lifecycle-process/build.gradle b/lifecycle/lifecycle-process/build.gradle
index 09a4076..2c59ba1f5 100644
--- a/lifecycle/lifecycle-process/build.gradle
+++ b/lifecycle/lifecycle-process/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "Android Lifecycle Process"
+ name = "Lifecycle Process"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Lifecycle Process"
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
index 79856f6..2fef830 100644
--- a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Lifecycle ReactiveStreams KTX"
+ name = "Lifecycle ReactiveStreams KTX"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for Lifecycle ReactiveStreams"
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/src/main/AndroidManifest.xml b/lifecycle/lifecycle-reactivestreams-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 29b496b..0000000
--- a/lifecycle/lifecycle-reactivestreams-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/lifecycle/lifecycle-reactivestreams/build.gradle b/lifecycle/lifecycle-reactivestreams/build.gradle
index e47bb63..e73e520b 100644
--- a/lifecycle/lifecycle-reactivestreams/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "Android Lifecycle Reactivestreams"
+ name = "Lifecycle Reactivestreams"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle Reactivestreams"
diff --git a/lifecycle/lifecycle-runtime-compose/api/current.txt b/lifecycle/lifecycle-runtime-compose/api/current.txt
index 5b19f2b..41aee87c 100644
--- a/lifecycle/lifecycle-runtime-compose/api/current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/current.txt
@@ -10,11 +10,31 @@
public final class LifecycleEffectKt {
method @androidx.compose.runtime.Composable public static void LifecycleEventEffect(androidx.lifecycle.Lifecycle.Event event, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function0<kotlin.Unit> onEvent);
+ method @androidx.compose.runtime.Composable public static void LifecycleResumeEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleResumePauseEffectScope,? extends androidx.lifecycle.compose.LifecyclePauseEffectResult> effects);
+ method @androidx.compose.runtime.Composable public static void LifecycleStartEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleStartStopEffectScope,? extends androidx.lifecycle.compose.LifecycleStopEffectResult> effects);
}
public final class LifecycleExtKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.lifecycle.Lifecycle.State> currentStateAsState(androidx.lifecycle.Lifecycle);
}
+ public interface LifecyclePauseEffectResult {
+ method public void runPauseEffect();
+ }
+
+ public final class LifecycleResumePauseEffectScope {
+ ctor public LifecycleResumePauseEffectScope();
+ method public inline androidx.lifecycle.compose.LifecyclePauseEffectResult onPause(kotlin.jvm.functions.Function0<kotlin.Unit> onPauseEffect);
+ }
+
+ public final class LifecycleStartStopEffectScope {
+ ctor public LifecycleStartStopEffectScope();
+ method public inline androidx.lifecycle.compose.LifecycleStopEffectResult onStop(kotlin.jvm.functions.Function0<kotlin.Unit> onStopEffect);
+ }
+
+ public interface LifecycleStopEffectResult {
+ method public void runStopEffect();
+ }
+
}
diff --git a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
index 5b19f2b..41aee87c 100644
--- a/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/public_plus_experimental_current.txt
@@ -10,11 +10,31 @@
public final class LifecycleEffectKt {
method @androidx.compose.runtime.Composable public static void LifecycleEventEffect(androidx.lifecycle.Lifecycle.Event event, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function0<kotlin.Unit> onEvent);
+ method @androidx.compose.runtime.Composable public static void LifecycleResumeEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleResumePauseEffectScope,? extends androidx.lifecycle.compose.LifecyclePauseEffectResult> effects);
+ method @androidx.compose.runtime.Composable public static void LifecycleStartEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleStartStopEffectScope,? extends androidx.lifecycle.compose.LifecycleStopEffectResult> effects);
}
public final class LifecycleExtKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.lifecycle.Lifecycle.State> currentStateAsState(androidx.lifecycle.Lifecycle);
}
+ public interface LifecyclePauseEffectResult {
+ method public void runPauseEffect();
+ }
+
+ public final class LifecycleResumePauseEffectScope {
+ ctor public LifecycleResumePauseEffectScope();
+ method public inline androidx.lifecycle.compose.LifecyclePauseEffectResult onPause(kotlin.jvm.functions.Function0<kotlin.Unit> onPauseEffect);
+ }
+
+ public final class LifecycleStartStopEffectScope {
+ ctor public LifecycleStartStopEffectScope();
+ method public inline androidx.lifecycle.compose.LifecycleStopEffectResult onStop(kotlin.jvm.functions.Function0<kotlin.Unit> onStopEffect);
+ }
+
+ public interface LifecycleStopEffectResult {
+ method public void runStopEffect();
+ }
+
}
diff --git a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
index 5b19f2b..41aee87c 100644
--- a/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
+++ b/lifecycle/lifecycle-runtime-compose/api/restricted_current.txt
@@ -10,11 +10,31 @@
public final class LifecycleEffectKt {
method @androidx.compose.runtime.Composable public static void LifecycleEventEffect(androidx.lifecycle.Lifecycle.Event event, optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function0<kotlin.Unit> onEvent);
+ method @androidx.compose.runtime.Composable public static void LifecycleResumeEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleResumePauseEffectScope,? extends androidx.lifecycle.compose.LifecyclePauseEffectResult> effects);
+ method @androidx.compose.runtime.Composable public static void LifecycleStartEffect(optional androidx.lifecycle.LifecycleOwner lifecycleOwner, kotlin.jvm.functions.Function1<? super androidx.lifecycle.compose.LifecycleStartStopEffectScope,? extends androidx.lifecycle.compose.LifecycleStopEffectResult> effects);
}
public final class LifecycleExtKt {
method @androidx.compose.runtime.Composable public static androidx.compose.runtime.State<androidx.lifecycle.Lifecycle.State> currentStateAsState(androidx.lifecycle.Lifecycle);
}
+ public interface LifecyclePauseEffectResult {
+ method public void runPauseEffect();
+ }
+
+ public final class LifecycleResumePauseEffectScope {
+ ctor public LifecycleResumePauseEffectScope();
+ method public inline androidx.lifecycle.compose.LifecyclePauseEffectResult onPause(kotlin.jvm.functions.Function0<kotlin.Unit> onPauseEffect);
+ }
+
+ public final class LifecycleStartStopEffectScope {
+ ctor public LifecycleStartStopEffectScope();
+ method public inline androidx.lifecycle.compose.LifecycleStopEffectResult onStop(kotlin.jvm.functions.Function0<kotlin.Unit> onStopEffect);
+ }
+
+ public interface LifecycleStopEffectResult {
+ method public void runStopEffect();
+ }
+
}
diff --git a/lifecycle/lifecycle-runtime-compose/samples/build.gradle b/lifecycle/lifecycle-runtime-compose/samples/build.gradle
index b1f8730..334768e 100644
--- a/lifecycle/lifecycle-runtime-compose/samples/build.gradle
+++ b/lifecycle/lifecycle-runtime-compose/samples/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "AndroidX Lifecycle Runtime Compose Integration Samples"
+ name = "Lifecycle Runtime Compose Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Samples for Compose integration with Lifecycle Runtime"
diff --git a/lifecycle/lifecycle-runtime-compose/src/androidTest/java/androidx/lifecycle/compose/LifecycleEffectTest.kt b/lifecycle/lifecycle-runtime-compose/src/androidTest/java/androidx/lifecycle/compose/LifecycleEffectTest.kt
index 3d7e9fe..482c851 100644
--- a/lifecycle/lifecycle-runtime-compose/src/androidTest/java/androidx/lifecycle/compose/LifecycleEffectTest.kt
+++ b/lifecycle/lifecycle-runtime-compose/src/androidTest/java/androidx/lifecycle/compose/LifecycleEffectTest.kt
@@ -110,4 +110,78 @@
.isEqualTo(1)
}
}
+
+ @Test
+ fun lifecycleStartEffectTest() {
+ lifecycleOwner = TestLifecycleOwner(
+ Lifecycle.State.INITIALIZED,
+ dispatcher
+ )
+ var startCount = 0
+ var stopCount = 0
+
+ composeTestRule.waitForIdle()
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalLifecycleOwner provides lifecycleOwner) {
+ LifecycleStartEffect {
+ startCount++
+
+ onStop {
+ stopCount++
+ }
+ }
+ }
+ }
+
+ composeTestRule.runOnIdle {
+ assertWithMessage("Lifecycle should not be started (or stopped)")
+ .that(startCount)
+ .isEqualTo(0)
+
+ lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
+ assertWithMessage("Lifecycle should have been started")
+ .that(startCount)
+ .isEqualTo(1)
+
+ lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
+ assertWithMessage("Lifecycle should have been stopped")
+ .that(stopCount)
+ .isEqualTo(1)
+ }
+ }
+
+ @Test
+ fun lifecycleResumeEffectTest() {
+ var resumeCount = 0
+ var pauseCount = 0
+
+ composeTestRule.waitForIdle()
+ composeTestRule.setContent {
+ CompositionLocalProvider(LocalLifecycleOwner provides lifecycleOwner) {
+ LifecycleResumeEffect {
+ resumeCount++
+
+ onPause {
+ pauseCount++
+ }
+ }
+ }
+ }
+
+ composeTestRule.runOnIdle {
+ assertWithMessage("Lifecycle should not be resumed (or paused)")
+ .that(resumeCount)
+ .isEqualTo(0)
+
+ lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
+ assertWithMessage("Lifecycle should have been resumed")
+ .that(resumeCount)
+ .isEqualTo(1)
+
+ lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
+ assertWithMessage("Lifecycle should have been paused")
+ .that(pauseCount)
+ .isEqualTo(1)
+ }
+ }
}
\ No newline at end of file
diff --git a/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt b/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt
index 7ee6398..f1b633c 100644
--- a/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt
+++ b/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/FlowExt.kt
@@ -23,11 +23,11 @@
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.withContext
-import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.EmptyCoroutineContext
/**
* Collects values from this [StateFlow] and represents its latest value via [State] in a
diff --git a/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/LifecycleEffect.kt b/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/LifecycleEffect.kt
index c9e47ae..245b1a5 100644
--- a/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/LifecycleEffect.kt
+++ b/lifecycle/lifecycle-runtime-compose/src/main/java/androidx/lifecycle/compose/LifecycleEffect.kt
@@ -75,4 +75,176 @@
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
-}
\ No newline at end of file
+}
+
+/**
+ * Schedule a pair of effects to run when the [Lifecycle] receives either a
+ * [Lifecycle.Event.ON_START] or [Lifecycle.Event.ON_STOP]. The ON_START effect will
+ * be the body of the [effects] block and the ON_STOP effect will be within the
+ * (onStop clause)[LifecycleStartStopEffectScope.onStop]:
+ *
+ * LifecycleStartEffect(lifecycleOwner) {
+ * // add ON_START effect work here
+ *
+ * onStop {
+ * // add ON_STOP effect work here
+ * }
+ * }
+ *
+ * A [LifecycleStartEffect] **must** include an [onStop][LifecycleStartStopEffectScope.onStop]
+ * clause as the final statement in its [effects] block. If your operation does not require
+ * an effect for both ON_START and ON_STOP, a [LifecycleEventEffect] should be used instead.
+ *
+ * This function uses a [LifecycleEventObserver] to listen for when [LifecycleStartEffect]
+ * enters the composition and the effects will be launched when receiving a
+ * [Lifecycle.Event.ON_START] or [Lifecycle.Event.ON_STOP] event, respectively.
+ *
+ * This function should **not** be used to launch tasks in response to callback
+ * events by way of storing callback data as a [Lifecycle.State] in a [MutableState].
+ * Instead, see [currentStateAsState] to obtain a [State<Lifecycle.State>][State]
+ * that may be used to launch jobs in response to state changes.
+ *
+ * @param lifecycleOwner The lifecycle owner to attach an observer
+ * @param effects The effects to be launched when we receive the respective event callbacks
+ */
+@Composable
+fun LifecycleStartEffect(
+ lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
+ effects: LifecycleStartStopEffectScope.() -> LifecycleStopEffectResult
+) {
+ val lifecycleStartStopEffectScope = LifecycleStartStopEffectScope()
+ // Safely update the current `onStart` lambda when a new one is provided
+ val currentEffects by rememberUpdatedState(effects)
+ DisposableEffect(lifecycleOwner) {
+ val observer = LifecycleEventObserver { _, event ->
+ when (event) {
+ Lifecycle.Event.ON_START ->
+ lifecycleStartStopEffectScope.currentEffects()
+
+ Lifecycle.Event.ON_STOP ->
+ lifecycleStartStopEffectScope.currentEffects().runStopEffect()
+
+ else -> {}
+ }
+ }
+
+ lifecycleOwner.lifecycle.addObserver(observer)
+
+ onDispose {
+ lifecycleOwner.lifecycle.removeObserver(observer)
+ }
+ }
+}
+
+/**
+ * Interface used for [LifecycleStartEffect] to run the effect within the onStop
+ * clause when an (ON_STOP)[Lifecycle.Event.ON_STOP] event is received.
+ */
+interface LifecycleStopEffectResult {
+ fun runStopEffect()
+}
+
+/**
+ * Receiver scope for [LifecycleStartEffect] that offers the [onStop] clause to
+ * couple the ON_START effect. This should be the last statement in any call to
+ * [LifecycleStartEffect].
+ */
+class LifecycleStartStopEffectScope {
+ /**
+ * Provide the [onStopEffect] to the [LifecycleStartEffect] to run when the observer
+ * receives an (ON_STOP)[Lifecycle.Event.ON_STOP] event.
+ */
+ inline fun onStop(
+ crossinline onStopEffect: () -> Unit
+ ): LifecycleStopEffectResult = object : LifecycleStopEffectResult {
+ override fun runStopEffect() {
+ onStopEffect()
+ }
+ }
+}
+
+/**
+ * Schedule a pair of effects to run when the [Lifecycle] receives either a
+ * [Lifecycle.Event.ON_RESUME] or [Lifecycle.Event.ON_PAUSE]. The ON_RESUME effect
+ * will be the body of the [effects] block and the ON_PAUSE effect will be within the
+ * (onPause clause)[LifecycleResumePauseEffectScope.onPause]:
+ *
+ * LifecycleResumeEffect(lifecycleOwner) {
+ * // add ON_RESUME effect work here
+ *
+ * onPause {
+ * // add ON_PAUSE effect work here
+ * }
+ * }
+ *
+ * A [LifecycleResumeEffect] **must** include an [onPause][LifecycleResumePauseEffectScope.onPause]
+ * clause as the final statement in its [effects] block. If your operation does not require
+ * an effect for both ON_RESUME and ON_PAUSE, a [LifecycleEventEffect] should be used instead.
+ *
+ * This function uses a [LifecycleEventObserver] to listen for when [LifecycleResumeEffect]
+ * enters the composition and the effects will be launched when receiving a
+ * [Lifecycle.Event.ON_RESUME] or [Lifecycle.Event.ON_PAUSE] event, respectively.
+ *
+ * This function should **not** be used to launch tasks in response to callback
+ * events by way of storing callback data as a [Lifecycle.State] in a [MutableState].
+ * Instead, see [currentStateAsState] to obtain a [State<Lifecycle.State>][State]
+ * that may be used to launch jobs in response to state changes.
+ *
+ * @param lifecycleOwner The lifecycle owner to attach an observer
+ * @param effects The effects to be launched when we receive the respective event callbacks
+ */
+@Composable
+fun LifecycleResumeEffect(
+ lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
+ effects: LifecycleResumePauseEffectScope.() -> LifecyclePauseEffectResult
+) {
+ val lifecycleResumePauseEffectScope = LifecycleResumePauseEffectScope()
+ // Safely update the current `onResume` lambda when a new one is provided
+ val currentEffects by rememberUpdatedState(effects)
+ DisposableEffect(lifecycleOwner) {
+ val observer = LifecycleEventObserver { _, event ->
+ when (event) {
+ Lifecycle.Event.ON_RESUME ->
+ lifecycleResumePauseEffectScope.currentEffects()
+
+ Lifecycle.Event.ON_PAUSE ->
+ lifecycleResumePauseEffectScope.currentEffects().runPauseEffect()
+
+ else -> {}
+ }
+ }
+
+ lifecycleOwner.lifecycle.addObserver(observer)
+
+ onDispose {
+ lifecycleOwner.lifecycle.removeObserver(observer)
+ }
+ }
+}
+
+/**
+ * Interface used for [LifecycleResumeEffect] to run the effect within the onPause
+ * clause when an (ON_PAUSE)[Lifecycle.Event.ON_PAUSE] event is received.
+ */
+interface LifecyclePauseEffectResult {
+ fun runPauseEffect()
+}
+
+/**
+ * Receiver scope for [LifecycleResumeEffect] that offers the [onPause] clause to
+ * couple the ON_RESUME effect. This should be the last statement in any call to
+ * [LifecycleResumeEffect].
+ */
+class LifecycleResumePauseEffectScope {
+ /**
+ * Provide the [onPauseEffect] to the [LifecycleResumeEffect] to run when the observer
+ * receives an (ON_PAUSE)[Lifecycle.Event.ON_PAUSE] event.
+ */
+ inline fun onPause(
+ crossinline onPauseEffect: () -> Unit
+ ): LifecyclePauseEffectResult = object : LifecyclePauseEffectResult {
+ override fun runPauseEffect() {
+ onPauseEffect()
+ }
+ }
+}
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/build.gradle b/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
index 3761f26..e10aea4 100644
--- a/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
+++ b/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "Android Lifecycles Lint Checks"
+ name = "Lifecycles Lint Checks"
type = LibraryType.LINT
inceptionYear = "2019"
description = "Android Lifecycles Lint Checks"
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleWhenChecks.kt b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleWhenChecks.kt
index f863f3c..dce48e7 100644
--- a/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleWhenChecks.kt
+++ b/lifecycle/lifecycle-runtime-ktx-lint/src/main/java/androidx/lifecycle/lint/LifecycleWhenChecks.kt
@@ -33,6 +33,7 @@
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiWildcardType
import com.intellij.psi.util.PsiTypesUtil
+import java.util.ArrayDeque
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.uast.UCallExpression
@@ -49,7 +50,6 @@
import org.jetbrains.uast.tryResolve
import org.jetbrains.uast.visitor.AbstractUastVisitor
import org.jetbrains.uast.visitor.UastVisitor
-import java.util.ArrayDeque
// both old and new ones
private val CONTINUATION_NAMES = setOf(
diff --git a/lifecycle/lifecycle-runtime-ktx/build.gradle b/lifecycle/lifecycle-runtime-ktx/build.gradle
index e394b0b..554d287 100644
--- a/lifecycle/lifecycle-runtime-ktx/build.gradle
+++ b/lifecycle/lifecycle-runtime-ktx/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "Android Lifecycle Kotlin Extensions"
+ name = "Lifecycle Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Kotlin extensions for 'lifecycle' artifact"
diff --git a/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/PausingDispatcherTest.kt b/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/PausingDispatcherTest.kt
index 4d2f2d6..4cadb0a 100644
--- a/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/PausingDispatcherTest.kt
+++ b/lifecycle/lifecycle-runtime-ktx/src/androidTest/java/androidx/lifecycle/PausingDispatcherTest.kt
@@ -20,10 +20,15 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Delay
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.InternalCoroutinesApi
@@ -46,11 +51,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.Delay
@Suppress("DEPRECATION")
@InternalCoroutinesApi
diff --git a/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/RepeatOnLifecycle.kt b/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/RepeatOnLifecycle.kt
index 45b0f53..a3b6d45b 100644
--- a/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/RepeatOnLifecycle.kt
+++ b/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/RepeatOnLifecycle.kt
@@ -16,6 +16,7 @@
package androidx.lifecycle
+import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@@ -25,7 +26,6 @@
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
-import kotlin.coroutines.resume
/**
* Runs the given [block] in a new coroutine when `this` [Lifecycle] is at least at [state] and
diff --git a/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/WithLifecycleState.kt b/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/WithLifecycleState.kt
index 9f3dd21..e8f63d7 100644
--- a/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/WithLifecycleState.kt
+++ b/lifecycle/lifecycle-runtime-ktx/src/main/java/androidx/lifecycle/WithLifecycleState.kt
@@ -16,13 +16,13 @@
package androidx.lifecycle
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.coroutines.coroutineContext
+import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
-import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.coroutines.coroutineContext
-import kotlin.coroutines.resumeWithException
/**
* A [CancellationException] that indicates that the [Lifecycle] associated with an operation
diff --git a/lifecycle/lifecycle-runtime-testing/build.gradle b/lifecycle/lifecycle-runtime-testing/build.gradle
index 4e59db92..3c7aca3 100644
--- a/lifecycle/lifecycle-runtime-testing/build.gradle
+++ b/lifecycle/lifecycle-runtime-testing/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "Android Lifecycle Runtime Testing"
+ name = "Lifecycle Runtime Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Testing utilities for 'lifecycle' artifact"
diff --git a/lifecycle/lifecycle-runtime/build.gradle b/lifecycle/lifecycle-runtime/build.gradle
index 5199df9..3e06c78 100644
--- a/lifecycle/lifecycle-runtime/build.gradle
+++ b/lifecycle/lifecycle-runtime/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name "Android Lifecycle Runtime"
+ name = "Lifecycle Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear "2017"
description "Android Lifecycle Runtime"
diff --git a/lifecycle/lifecycle-service/build.gradle b/lifecycle/lifecycle-service/build.gradle
index 690553f..7ab4fc2 100644
--- a/lifecycle/lifecycle-service/build.gradle
+++ b/lifecycle/lifecycle-service/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "Android Lifecycle Service"
+ name = "Lifecycle Service"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Lifecycle Service"
diff --git a/lifecycle/lifecycle-service/src/main/AndroidManifest.xml b/lifecycle/lifecycle-service/src/main/AndroidManifest.xml
deleted file mode 100644
index 1f3367f..0000000
--- a/lifecycle/lifecycle-service/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2016 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 />
diff --git a/lifecycle/lifecycle-viewmodel-compose/integration-tests/lifecycle-viewmodel-demos/src/main/AndroidManifest.xml b/lifecycle/lifecycle-viewmodel-compose/integration-tests/lifecycle-viewmodel-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index 20af317..0000000
--- a/lifecycle/lifecycle-viewmodel-compose/integration-tests/lifecycle-viewmodel-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle b/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
index 195fb57..f812410 100644
--- a/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "AndroidX Lifecycle ViewModel Compose Integration Samples"
+ name = "Lifecycle ViewModel Compose Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Samples for Compose integration with Lifecycle ViewModel"
diff --git a/lifecycle/lifecycle-viewmodel-compose/samples/src/main/AndroidManifest.xml b/lifecycle/lifecycle-viewmodel-compose/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index 20af317..0000000
--- a/lifecycle/lifecycle-viewmodel-compose/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/lifecycle/lifecycle-viewmodel-compose/samples/src/main/java/androidx/lifecycle/viewmodel/compose/samples/LifecycleViewModelSamples.kt b/lifecycle/lifecycle-viewmodel-compose/samples/src/main/java/androidx/lifecycle/viewmodel/compose/samples/LifecycleViewModelSamples.kt
index 750d2ff..126cd46 100644
--- a/lifecycle/lifecycle-viewmodel-compose/samples/src/main/java/androidx/lifecycle/viewmodel/compose/samples/LifecycleViewModelSamples.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/samples/src/main/java/androidx/lifecycle/viewmodel/compose/samples/LifecycleViewModelSamples.kt
@@ -18,13 +18,13 @@
import androidx.annotation.Sampled
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.listSaver
+import androidx.compose.runtime.setValue
import androidx.compose.runtime.toMutableStateList
import androidx.compose.runtime.toMutableStateMap
import androidx.core.os.bundleOf
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInAppCompatActivityTest.kt b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInAppCompatActivityTest.kt
index 7681326..e5ee149 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInAppCompatActivityTest.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInAppCompatActivityTest.kt
@@ -23,14 +23,14 @@
import androidx.lifecycle.LifecycleOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInComponentActivityTest.kt b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInComponentActivityTest.kt
index 594a2e2..50f06f9 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInComponentActivityTest.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInComponentActivityTest.kt
@@ -24,14 +24,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInFragmentTest.kt b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInFragmentTest.kt
index a6ba005..cb4e6a5 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInFragmentTest.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/androidTest/java/androidx/lifecycle/viewmodel/compose/ViewModelInFragmentTest.kt
@@ -25,14 +25,14 @@
import androidx.fragment.app.FragmentContainerView
import androidx.lifecycle.ViewModel
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(Parameterized::class)
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/main/AndroidManifest.xml b/lifecycle/lifecycle-viewmodel-compose/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/lifecycle/lifecycle-viewmodel-compose/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/SavedStateHandleSaver.kt b/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/SavedStateHandleSaver.kt
index 8c70d69..9620449 100644
--- a/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/SavedStateHandleSaver.kt
+++ b/lifecycle/lifecycle-viewmodel-compose/src/main/java/androidx/lifecycle/viewmodel/compose/SavedStateHandleSaver.kt
@@ -21,9 +21,9 @@
import androidx.compose.runtime.SnapshotMutationPolicy
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.saveable.autoSaver
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.SaverScope
+import androidx.compose.runtime.saveable.autoSaver
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotMutableState
import androidx.core.os.bundleOf
diff --git a/lifecycle/lifecycle-viewmodel-ktx/build.gradle b/lifecycle/lifecycle-viewmodel-ktx/build.gradle
index efaa638..dfb7838 100644
--- a/lifecycle/lifecycle-viewmodel-ktx/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-ktx/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "Android Lifecycle ViewModel Kotlin Extensions"
+ name = "Lifecycle ViewModel Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for 'viewmodel' artifact"
diff --git a/lifecycle/lifecycle-viewmodel-ktx/src/main/AndroidManifest.xml b/lifecycle/lifecycle-viewmodel-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/lifecycle/lifecycle-viewmodel-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt b/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt
index 2078226..ffc77f9 100644
--- a/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt
+++ b/lifecycle/lifecycle-viewmodel-ktx/src/main/java/androidx/lifecycle/ViewModel.kt
@@ -16,12 +16,12 @@
package androidx.lifecycle
+import java.io.Closeable
+import kotlin.coroutines.CoroutineContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
-import java.io.Closeable
-import kotlin.coroutines.CoroutineContext
private const val JOB_KEY = "androidx.lifecycle.ViewModelCoroutineScope.JOB_KEY"
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
index ec45470..c2144f0 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Lifecycle ViewModel with SavedState"
+ name = "Lifecycle ViewModel with SavedState"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Lifecycle ViewModel"
diff --git a/lifecycle/lifecycle-viewmodel/build.gradle b/lifecycle/lifecycle-viewmodel/build.gradle
index 125c988..4c2db52 100644
--- a/lifecycle/lifecycle-viewmodel/build.gradle
+++ b/lifecycle/lifecycle-viewmodel/build.gradle
@@ -48,7 +48,7 @@
}
androidx {
- name = "Android Lifecycle ViewModel"
+ name = "Lifecycle ViewModel"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Lifecycle ViewModel"
diff --git a/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt b/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
index ba62b11..7beaf03 100644
--- a/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
+++ b/lifecycle/lifecycle-viewmodel/src/main/java/androidx/lifecycle/ViewModelProvider.kt
@@ -22,9 +22,9 @@
import androidx.annotation.RestrictTo
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.DEFAULT_KEY
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.defaultFactory
-import androidx.lifecycle.viewmodel.CreationExtras.Key
import androidx.lifecycle.ViewModelProvider.NewInstanceFactory.Companion.VIEW_MODEL_KEY
import androidx.lifecycle.viewmodel.CreationExtras
+import androidx.lifecycle.viewmodel.CreationExtras.Key
import androidx.lifecycle.viewmodel.InitializerViewModelFactory
import androidx.lifecycle.viewmodel.MutableCreationExtras
import androidx.lifecycle.viewmodel.ViewModelInitializer
diff --git a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
index f05b834..7de1624 100644
--- a/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/AndroidXIssueRegistry.kt
@@ -75,6 +75,7 @@
// MissingJvmDefaultWithCompatibilityDetector is intentionally left out of the
// registry, see comments on the class for more details.
BanVisibleForTestingParams.ISSUE,
+ PrereleaseSdkCoreDependencyDetector.ISSUE
)
}
}
diff --git a/lint-checks/src/main/java/androidx/build/lint/BanKeepAnnotation.kt b/lint-checks/src/main/java/androidx/build/lint/BanKeepAnnotation.kt
index 8bcfd3a..6c5d65d 100644
--- a/lint-checks/src/main/java/androidx/build/lint/BanKeepAnnotation.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/BanKeepAnnotation.kt
@@ -19,7 +19,6 @@
package androidx.build.lint
import com.android.tools.lint.client.api.UElementHandler
-
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Implementation
diff --git a/lint-checks/src/main/java/androidx/build/lint/BanParcelableUsage.kt b/lint-checks/src/main/java/androidx/build/lint/BanParcelableUsage.kt
index ff4de6a..b2253c69 100644
--- a/lint-checks/src/main/java/androidx/build/lint/BanParcelableUsage.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/BanParcelableUsage.kt
@@ -27,9 +27,9 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.intellij.psi.PsiModifier
+import java.util.Collections
import org.jetbrains.uast.UAnonymousClass
import org.jetbrains.uast.UClass
-import java.util.Collections
const val PARCELABLE_INTERFACE_CANONICAL_NAME = "android.os.Parcelable"
diff --git a/lint-checks/src/main/java/androidx/build/lint/MetadataTagInsideApplicationTagDetector.kt b/lint-checks/src/main/java/androidx/build/lint/MetadataTagInsideApplicationTagDetector.kt
index 3a13a9f..9bef39f 100644
--- a/lint-checks/src/main/java/androidx/build/lint/MetadataTagInsideApplicationTagDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/MetadataTagInsideApplicationTagDetector.kt
@@ -27,7 +27,6 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.XmlContext
import com.android.xml.AndroidManifest.NODE_APPLICATION
-
import org.w3c.dom.Element
class MetadataTagInsideApplicationTagDetector : Detector(), Detector.XmlScanner {
diff --git a/lint-checks/src/main/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetector.kt b/lint-checks/src/main/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetector.kt
new file mode 100644
index 0000000..fc50974
--- /dev/null
+++ b/lint-checks/src/main/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetector.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.build.lint
+
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Incident
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.model.LintModelAndroidLibrary
+import com.android.tools.lint.model.LintModelLibrary
+import org.jetbrains.uast.UCallExpression
+
+class PrereleaseSdkCoreDependencyDetector : Detector(), Detector.UastScanner {
+
+ override fun getApplicableUastTypes() = listOf(UCallExpression::class.java)
+
+ override fun createUastHandler(context: JavaContext): UElementHandler {
+ return CallChecker(context)
+ }
+
+ private inner class CallChecker(val context: JavaContext) : UElementHandler() {
+ override fun visitCallExpression(node: UCallExpression) {
+ // Check that this is a prerelease SDK check
+ val method = node.resolve() ?: return
+ val containingClass = method.containingClass ?: return
+ if (containingClass.qualifiedName != BUILD_COMPAT) return
+
+ if (method.annotations.none { it.hasQualifiedName(PRERELEASE_SDK_CHECK) }) return
+
+ // Check if the project is using a versioned dependency on core
+ val dependencies = context.project.buildVariant.mainArtifact.dependencies.getAll()
+ if (dependencies.any { it.isInvalidCoreDependency() }) {
+ val incident = Incident(context)
+ .issue(ISSUE)
+ .location(context.getLocation(node))
+ .message(
+ "Prelease SDK check ${method.name} cannot be called as this project has " +
+ "a versioned dependency on androidx.core:core"
+ )
+ .scope(node)
+ context.report(incident)
+ }
+ }
+
+ /**
+ * Checks whether this library is a dependency on a specific version of androidx.core:core
+ */
+ private fun LintModelLibrary.isInvalidCoreDependency(): Boolean {
+ val library = this as? LintModelAndroidLibrary ?: return false
+ val coordinates = library.resolvedCoordinates
+ return coordinates.artifactId == "core" &&
+ coordinates.groupId == "androidx.core" &&
+ coordinates.version != "unspecified"
+ }
+ }
+
+ companion object {
+ val ISSUE = Issue.create(
+ "PrereleaseSdkCoreDependency",
+ "Prerelease SDK checks can only be used by projects with a TOT dependency on " +
+ "androidx.core:core",
+ """
+ The implementation of a prerelease SDK check will change when the SDK is finalized,
+ so projects using these checks must have a tip-of-tree dependency on core to ensure
+ the check stays up-to-date.
+
+ This error means that the `androidx.core:core` dependency in this project's
+ `build.gradle` file should be replaced with `implementation(project(":core:core"))`
+
+ See go/androidx-api-guidelines#compat-sdk for more information.
+ """,
+ Category.CORRECTNESS, 5, Severity.ERROR,
+ Implementation(
+ PrereleaseSdkCoreDependencyDetector::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+
+ private const val BUILD_COMPAT = "androidx.core.os.BuildCompat"
+ private const val PRERELEASE_SDK_CHECK = "$BUILD_COMPAT.PrereleaseSdkCheck"
+ }
+}
diff --git a/lint-checks/src/main/java/androidx/build/lint/TargetApiAnnotationUsageDetector.kt b/lint-checks/src/main/java/androidx/build/lint/TargetApiAnnotationUsageDetector.kt
index e96d19d9..048054d 100644
--- a/lint-checks/src/main/java/androidx/build/lint/TargetApiAnnotationUsageDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/TargetApiAnnotationUsageDetector.kt
@@ -19,7 +19,6 @@
package androidx.build.lint
import com.android.tools.lint.client.api.UElementHandler
-
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Implementation
diff --git a/lint-checks/src/main/java/androidx/build/lint/TestSizeAnnotationEnforcer.kt b/lint-checks/src/main/java/androidx/build/lint/TestSizeAnnotationEnforcer.kt
index a6b34e6..0777c76 100644
--- a/lint-checks/src/main/java/androidx/build/lint/TestSizeAnnotationEnforcer.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/TestSizeAnnotationEnforcer.kt
@@ -28,11 +28,11 @@
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
+import java.util.Collections
+import java.util.EnumSet
import org.jetbrains.uast.UClass
import org.jetbrains.uast.UClassLiteralExpression
import org.jetbrains.uast.UElement
-import java.util.Collections
-import java.util.EnumSet
/**
* Lint check to enforce that every device side test (tests in the androidTest dir) has correct
diff --git a/lint-checks/src/main/java/androidx/build/lint/aidl/AidlDefinitionDetector.kt b/lint-checks/src/main/java/androidx/build/lint/aidl/AidlDefinitionDetector.kt
index a365b00..16e56b7 100644
--- a/lint-checks/src/main/java/androidx/build/lint/aidl/AidlDefinitionDetector.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/aidl/AidlDefinitionDetector.kt
@@ -44,19 +44,32 @@
override fun getApplicableFiles() = Scope.OTHER_SCOPE
override fun beforeCheckEachProject(context: Context) {
- LanguageParserDefinitions.INSTANCE.apply {
+ // Neither LanguageParserDefinitions nor CoreFileTypeRegistry are thread-safe, so this is a
+ // best-effort to avoid a race condition during our own access across multiple lint worker
+ // threads.
+ synchronized(intellijCoreLock) {
+ val aidlFileType = AidlFileType.INSTANCE
+
// When we run from CLI, the IntelliJ parser (which does not support lexing AIDL) will
// already be set. Only the first parser will be used, so we need to remove that parser
// before we add our own.
- allForLanguage(AidlFileType.INSTANCE.language).forEach { parser ->
- removeExplicitExtension(AidlFileType.INSTANCE.language, parser)
+ val languageParserDefinitions = LanguageParserDefinitions.INSTANCE
+ languageParserDefinitions.apply {
+ allForLanguage(aidlFileType.language).forEach { parser ->
+ removeExplicitExtension(aidlFileType.language, parser)
+ }
+ addExplicitExtension(aidlFileType.language, AidlParserDefinition())
}
- addExplicitExtension(AidlFileType.INSTANCE.language, AidlParserDefinition())
+
+ // Register our parser for the AIDL file type. Files may be registered more than once to
+ // overwrite the associated extension, but only the first call to `registerFileType`
+ // will associate the file with the name returned by `FileType.getName()`.
+ val coreFileTypeRegistry = CoreFileTypeRegistry.getInstance() as CoreFileTypeRegistry
+ coreFileTypeRegistry.registerFileType(
+ aidlFileType,
+ aidlFileType.defaultExtension
+ )
}
- (CoreFileTypeRegistry.getInstance() as CoreFileTypeRegistry).registerFileType(
- AidlFileType.INSTANCE,
- AidlFileType.INSTANCE.defaultExtension
- )
}
override fun run(context: Context) {
@@ -125,4 +138,10 @@
containingFile.text,
textRange.startOffset,
textRange.endOffset
-)
\ No newline at end of file
+)
+
+/**
+ * Lock object used to synchronize access to IntelliJ registries which are not thread-safe,
+ * including [LanguageParserDefinitions] and [CoreFileTypeRegistry].
+ */
+private val intellijCoreLock = Any()
diff --git a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
index 706cd32..781c1fd5 100644
--- a/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
+++ b/lint-checks/src/test/java/androidx/build/lint/ClassVerificationFailureDetectorTest.kt
@@ -19,8 +19,8 @@
package androidx.build.lint
import androidx.build.lint.Stubs.Companion.DoNotInline
-import androidx.build.lint.Stubs.Companion.RequiresApi
import androidx.build.lint.Stubs.Companion.IntRange
+import androidx.build.lint.Stubs.Companion.RequiresApi
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/lint-checks/src/test/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetectorTest.kt b/lint-checks/src/test/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetectorTest.kt
new file mode 100644
index 0000000..b6d3422
--- /dev/null
+++ b/lint-checks/src/test/java/androidx/build/lint/PrereleaseSdkCoreDependencyDetectorTest.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.build.lint
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class PrereleaseSdkCoreDependencyDetectorTest : AbstractLintDetectorTest(
+ useDetector = PrereleaseSdkCoreDependencyDetector(),
+ useIssues = listOf(PrereleaseSdkCoreDependencyDetector.ISSUE),
+ stubs = arrayOf(
+ Stubs.BuildCompat,
+ Stubs.ChecksSdkIntAtLeast,
+ Stubs.JetpackRequiresOptIn,
+ Stubs.RestrictTo
+ )
+) {
+ @Test
+ fun `Versioned dependency with isAtLeastU is flagged`() {
+ val input = arrayOf(
+ kotlin(
+ """
+ package androidx.test
+
+ import androidx.core.os.BuildCompat
+
+ fun callIsAtLeastU() {
+ return BuildCompat.isAtLeastU()
+ }
+ """.trimIndent()
+ ),
+ gradle("""
+ dependencies {
+ implementation("androidx.core:core:1.9.0")
+ }
+ """.trimIndent()),
+ )
+
+ /* ktlint-disable max-line-length */
+ val expected = """
+ src/main/kotlin/androidx/test/test.kt:6: Error: Prelease SDK check isAtLeastU cannot be called as this project has a versioned dependency on androidx.core:core [PrereleaseSdkCoreDependency]
+ return BuildCompat.isAtLeastU()
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """.trimIndent()
+ /* ktlint-enable max-line-length */
+
+ check(*input).expect(expected)
+ }
+
+ @Test
+ fun `Tip-of-tree dependency with isAtLeastU is not flagged`() {
+ val input = arrayOf(
+ kotlin(
+ """
+ package androidx.test
+
+ import androidx.core.os.BuildCompat
+
+ fun callIsAtLeastU() {
+ return BuildCompat.isAtLeastU()
+ }
+ """.trimIndent()
+ ),
+ gradle("""
+ dependencies {
+ implementation(project(":core:core"))
+ }
+ """.trimIndent()),
+ )
+
+ check(*input).expectClean()
+ }
+
+ @Test
+ fun `Versioned dependency with isAtLeastSv2 is flagged`() {
+ val input = arrayOf(
+ kotlin(
+ """
+ package androidx.test
+
+ import androidx.core.os.BuildCompat
+
+ fun callIsAtLeastSv2() {
+ return BuildCompat.isAtLeastSv2()
+ }
+ """.trimIndent()
+ ),
+ gradle("""
+ dependencies {
+ implementation("androidx.core:core:1.9.0")
+ }
+ """.trimIndent()),
+ )
+
+ /* ktlint-disable max-line-length */
+ val expected = """
+ src/main/kotlin/androidx/test/test.kt:6: Error: Prelease SDK check isAtLeastSv2 cannot be called as this project has a versioned dependency on androidx.core:core [PrereleaseSdkCoreDependency]
+ return BuildCompat.isAtLeastSv2()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 1 errors, 0 warnings
+ """.trimIndent()
+ /* ktlint-enable max-line-length */
+
+ check(*input).expect(expected)
+ }
+
+ @Test
+ fun `Versioned dependency with non-annotated isAtLeastN is not flagged`() {
+ val input = arrayOf(
+ kotlin(
+ """
+ package androidx.test
+
+ import androidx.core.os.BuildCompat
+
+ fun callIsAtLeastN() {
+ return BuildCompat.isAtLeastN()
+ }
+ """.trimIndent()
+ ),
+ gradle("""
+ dependencies {
+ implementation("androidx.core:core:1.9.0")
+ }
+ """.trimIndent()),
+ )
+
+ check(*input).expectClean()
+ }
+}
diff --git a/lint-checks/src/test/java/androidx/build/lint/Stubs.kt b/lint-checks/src/test/java/androidx/build/lint/Stubs.kt
index c4aad8a..108e776 100644
--- a/lint-checks/src/test/java/androidx/build/lint/Stubs.kt
+++ b/lint-checks/src/test/java/androidx/build/lint/Stubs.kt
@@ -386,6 +386,59 @@
}
""".trimIndent()
)
+
+ /**
+ * Contains only a few of the isAtLeastX implementations from BuildCompat for testing
+ */
+ val BuildCompat: TestFile = LintDetectorTest.java("""
+package androidx.core.os;
+
+import android.os.Build;
+import android.os.Build.VERSION;
+
+import androidx.annotation.ChecksSdkIntAtLeast;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresOptIn;
+import androidx.annotation.RestrictTo;
+
+import java.util.Locale;
+
+public class BuildCompat {
+ private BuildCompat() {}
+
+ @RestrictTo(RestrictTo.Scope.TESTS)
+ protected static boolean isAtLeastPreReleaseCodename(@NonNull String codename, @NonNull String buildCodename) {
+ if ("REL".equals(buildCodename)) {
+ return false;
+ }
+ final String buildCodenameUpper = buildCodename.toUpperCase(Locale.ROOT);
+ final String codenameUpper = codename.toUpperCase(Locale.ROOT);
+ return buildCodenameUpper.compareTo(codenameUpper) >= 0;
+ }
+
+ @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.N)
+ @Deprecated
+ public static boolean isAtLeastN() {
+ return VERSION.SDK_INT >= 24;
+ }
+
+ @PrereleaseSdkCheck
+ @ChecksSdkIntAtLeast(api = 32, codename = "Sv2")
+ @Deprecated
+ public static boolean isAtLeastSv2() {
+ return VERSION.SDK_INT >= 32 || (VERSION.SDK_INT >= 31 && isAtLeastPreReleaseCodename("Sv2", VERSION.CODENAME));
+ }
+
+ @PrereleaseSdkCheck
+ @ChecksSdkIntAtLeast(codename = "UpsideDownCake")
+ public static boolean isAtLeastU() {
+ return VERSION.SDK_INT >= 33 && isAtLeastPreReleaseCodename("UpsideDownCake", VERSION.CODENAME);
+ }
+
+ @RequiresOptIn
+ public @interface PrereleaseSdkCheck { }
+}
+ """.trimIndent())
/* ktlint-enable max-line-length */
}
}
diff --git a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt b/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
index 809d8b8..e83c552 100644
--- a/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
+++ b/loader/loader-ktx/src/androidTest/java/androidx/loader/app/LoaderManagerTest.kt
@@ -24,12 +24,12 @@
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/loader/loader-ktx/src/main/AndroidManifest.xml b/loader/loader-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index b47339d..0000000
--- a/loader/loader-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2019 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 />
diff --git a/loader/loader/build.gradle b/loader/loader/build.gradle
index e9ff426..5b46db6 100644
--- a/loader/loader/build.gradle
+++ b/loader/loader/build.gradle
@@ -23,7 +23,7 @@
}
androidx {
- name = "Android Support Library loader"
+ name = "loader"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2011"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/loader/loader/src/main/AndroidManifest.xml b/loader/loader/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/loader/loader/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/media/media/build.gradle b/media/media/build.gradle
index 91a6177..783d543 100644
--- a/media/media/build.gradle
+++ b/media/media/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Support Library media compat"
+ name = "Media"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.MEDIA
inceptionYear = "2011"
diff --git a/media/media/src/main/AndroidManifest.xml b/media/media/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/media/media/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/media2/media2-common/build.gradle b/media2/media2-common/build.gradle
index 8c0570f..46c5577 100644
--- a/media2/media2-common/build.gradle
+++ b/media2/media2-common/build.gradle
@@ -62,7 +62,7 @@
}
androidx {
- name = "AndroidX media2 common library"
+ name = "Media2 Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Media2 Common"
diff --git a/media2/media2-common/src/main/AndroidManifest.xml b/media2/media2-common/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/media2/media2-common/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/media2/media2-exoplayer/build.gradle b/media2/media2-exoplayer/build.gradle
index 291a8bc..c7873df 100644
--- a/media2/media2-exoplayer/build.gradle
+++ b/media2/media2-exoplayer/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "Media2 repackaged ExoPlayer dependency"
+ name = "Media2 ExoPlayer"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Repackaged ExoPlayer for 'media2' artifact"
diff --git a/media2/media2-exoplayer/src/main/AndroidManifest.xml b/media2/media2-exoplayer/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/media2/media2-exoplayer/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/media2/media2-player/build.gradle b/media2/media2-player/build.gradle
index c11da0f..ca8a752 100644
--- a/media2/media2-player/build.gradle
+++ b/media2/media2-player/build.gradle
@@ -49,7 +49,7 @@
}
androidx {
- name = "AndroidX media2 player library"
+ name = "Media2 Player"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Media2 Player"
diff --git a/media2/media2-player/src/main/AndroidManifest.xml b/media2/media2-player/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/media2/media2-player/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/media2/media2-session/build.gradle b/media2/media2-session/build.gradle
index 8830b4f..66b502d 100644
--- a/media2/media2-session/build.gradle
+++ b/media2/media2-session/build.gradle
@@ -56,7 +56,7 @@
}
androidx {
- name = "AndroidX media2 session library"
+ name = "Media2 Session"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Media2 Session"
diff --git a/media2/media2-session/src/main/AndroidManifest.xml b/media2/media2-session/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/media2/media2-session/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/media2/media2-widget/build.gradle b/media2/media2-widget/build.gradle
index d4452b3..ceee35f 100644
--- a/media2/media2-widget/build.gradle
+++ b/media2/media2-widget/build.gradle
@@ -56,7 +56,7 @@
}
androidx {
- name = "AndroidX media2 widget library"
+ name = "Media2 Widget"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "AndroidX Media2 Widget"
diff --git a/media2/media2-widget/src/main/AndroidManifest.xml b/media2/media2-widget/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/media2/media2-widget/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/mediarouter/mediarouter-testing/build.gradle b/mediarouter/mediarouter-testing/build.gradle
index 5d2fbf6..0e39af2 100644
--- a/mediarouter/mediarouter-testing/build.gradle
+++ b/mediarouter/mediarouter-testing/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "AndroidX MediaRouter Testing"
+ name = "MediaRouter Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2021"
description = "Test utilities for AndroidX MediaRouter"
diff --git a/mediarouter/mediarouter-testing/src/main/AndroidManifest.xml b/mediarouter/mediarouter-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/mediarouter/mediarouter-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/mediarouter/mediarouter/build.gradle b/mediarouter/mediarouter/build.gradle
index 2cb2454..46de044 100644
--- a/mediarouter/mediarouter/build.gradle
+++ b/mediarouter/mediarouter/build.gradle
@@ -57,7 +57,7 @@
}
androidx {
- name = "Android MediaRouter Support Library"
+ name = "MediaRouter"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2013"
description = "Android MediaRouter Support Library"
diff --git a/mediarouter/mediarouter/src/main/AndroidManifest.xml b/mediarouter/mediarouter/src/main/AndroidManifest.xml
deleted file mode 100644
index bd7af07..0000000
--- a/mediarouter/mediarouter/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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 />
diff --git a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteChooserDialog.java b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteChooserDialog.java
index 2f7f395..51e6cb0 100644
--- a/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteChooserDialog.java
+++ b/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteChooserDialog.java
@@ -28,6 +28,7 @@
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -35,11 +36,16 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialog;
@@ -50,6 +56,8 @@
import java.io.IOException;
import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -69,7 +77,12 @@
// Do not update the route list immediately to avoid unnatural dialog change.
private static final long UPDATE_ROUTES_DELAY_MS = 300L;
- static final int MSG_UPDATE_ROUTES = 1;
+ private static final int MSG_UPDATE_ROUTES = 1;
+ private static final int MSG_SHOW_WIFI_HINT = 2;
+ private static final int MSG_SHOW_NO_ROUTES = 3;
+
+ private static final int SHOW_WIFI_HINT_DELAY_MS = 5000;
+ private static final int SHOW_NO_ROUTES_DELAY_MS = 15000;
private final MediaRouter mRouter;
private final MediaRouterCallback mCallback;
@@ -79,6 +92,11 @@
private ArrayList<MediaRouter.RouteInfo> mRoutes;
private RouteAdapter mAdapter;
private ListView mListView;
+ private RelativeLayout mEmptyView;
+ private LinearLayout mSearchingRoutesView;
+ private FrameLayout mNoRoutesView;
+ private FrameLayout mWifiWarningView;
+ private FrameLayout mFooterView;
private boolean mAttachedToWindow;
private long mLastUpdateTime;
@SuppressWarnings({"unchecked", "deprecation"})
@@ -87,12 +105,28 @@
public void handleMessage(Message message) {
switch (message.what) {
case MSG_UPDATE_ROUTES:
- updateRoutes((List<MediaRouter.RouteInfo>) message.obj);
+ handleUpdateRoutes((List<MediaRouter.RouteInfo>) message.obj);
+ break;
+ case MSG_SHOW_WIFI_HINT:
+ handleShowNoWifiWarning();
+ break;
+ case MSG_SHOW_NO_ROUTES:
+ handleShowNoRoutes();
break;
}
}
};
+ private static final int FINDING_DEVICES = 0;
+ private static final int SHOWING_ROUTES = 1;
+ private static final int NO_DEVICES_NO_WIFI_HINT = 2;
+ private static final int NO_ROUTES = 3;
+
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({FINDING_DEVICES, SHOWING_ROUTES, NO_DEVICES_NO_WIFI_HINT, NO_ROUTES})
+ private @interface MediaRouterChooserDialogState {}
+
public MediaRouteChooserDialog(@NonNull Context context) {
this(context, 0);
}
@@ -196,6 +230,20 @@
mListView.setEmptyView(findViewById(android.R.id.empty));
mTitleView = findViewById(R.id.mr_chooser_title);
+ mEmptyView = findViewById(R.id.mr_empty_view);
+ mSearchingRoutesView = findViewById(R.id.mr_chooser_searching);
+ mNoRoutesView = findViewById(R.id.mr_chooser_no_routes);
+ mWifiWarningView = findViewById(R.id.mr_chooser_wifi_warning);
+ mFooterView = findViewById(R.id.mr_chooser_footer);
+
+ TextView zeroRoutesDescription = findViewById(R.id.mr_chooser_zero_routes_description);
+ TextView wifiWarningDescription = findViewById(R.id.mr_chooser_wifi_warning_description);
+ Button doneButton = findViewById(R.id.mr_chooser_done_button);
+
+ zeroRoutesDescription.setMovementMethod(LinkMovementMethod.getInstance());
+ wifiWarningDescription.setMovementMethod(LinkMovementMethod.getInstance());
+ doneButton.setOnClickListener(view -> dismiss());
+
updateLayout();
}
@@ -210,17 +258,26 @@
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
-
mAttachedToWindow = true;
mRouter.addCallback(mSelector, mCallback, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
refreshRoutes();
+
+ mHandler.removeMessages(MSG_SHOW_WIFI_HINT);
+ mHandler.removeMessages(MSG_SHOW_NO_ROUTES);
+ mHandler.removeMessages(MSG_UPDATE_ROUTES);
+
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_SHOW_WIFI_HINT), SHOW_WIFI_HINT_DELAY_MS);
}
@Override
public void onDetachedFromWindow() {
mAttachedToWindow = false;
+
mRouter.removeCallback(mCallback);
mHandler.removeMessages(MSG_UPDATE_ROUTES);
+ mHandler.removeMessages(MSG_SHOW_WIFI_HINT);
+ mHandler.removeMessages(MSG_SHOW_NO_ROUTES);
super.onDetachedFromWindow();
}
@@ -234,7 +291,7 @@
onFilterRoutes(routes);
Collections.sort(routes, RouteComparator.sInstance);
if (SystemClock.uptimeMillis() - mLastUpdateTime >= UPDATE_ROUTES_DELAY_MS) {
- updateRoutes(routes);
+ handleUpdateRoutes(routes);
} else {
mHandler.removeMessages(MSG_UPDATE_ROUTES);
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ROUTES, routes),
@@ -243,11 +300,105 @@
}
}
- void updateRoutes(List<MediaRouter.RouteInfo> routes) {
+ void handleUpdateRoutes(List<MediaRouter.RouteInfo> routes) {
mLastUpdateTime = SystemClock.uptimeMillis();
mRoutes.clear();
mRoutes.addAll(routes);
mAdapter.notifyDataSetChanged();
+
+ mHandler.removeMessages(MSG_SHOW_NO_ROUTES);
+ mHandler.removeMessages(MSG_SHOW_WIFI_HINT);
+
+ if (routes.isEmpty()) {
+ // When all routes are removed or disconnected
+ updateViewForState(FINDING_DEVICES);
+
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_SHOW_WIFI_HINT), SHOW_WIFI_HINT_DELAY_MS);
+ } else {
+ updateViewForState(SHOWING_ROUTES);
+ }
+ }
+
+ void handleShowNoWifiWarning() {
+ if (mRoutes.isEmpty()) {
+ updateViewForState(NO_DEVICES_NO_WIFI_HINT);
+ mHandler.removeMessages(MSG_SHOW_WIFI_HINT);
+ mHandler.removeMessages(MSG_SHOW_NO_ROUTES);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_NO_ROUTES),
+ SHOW_NO_ROUTES_DELAY_MS);
+ }
+ }
+
+ void handleShowNoRoutes() {
+ if (mRoutes.isEmpty()) {
+ updateViewForState(NO_ROUTES);
+ mHandler.removeMessages(MSG_SHOW_WIFI_HINT);
+ mHandler.removeMessages(MSG_SHOW_NO_ROUTES);
+ mHandler.removeMessages(MSG_UPDATE_ROUTES);
+ mRouter.removeCallback(mCallback);
+ }
+ }
+
+ void updateViewForState(@MediaRouterChooserDialogState int state) {
+ switch (state) {
+ case NO_ROUTES:
+ updateViewForNoRoutes();
+ break;
+ case NO_DEVICES_NO_WIFI_HINT:
+ updateViewForNoDevicesNoWifiHint();
+ break;
+ case SHOWING_ROUTES:
+ updateViewForShowingRoutes();
+ break;
+ case FINDING_DEVICES:
+ updateViewForFindingDevices();
+ break;
+ }
+ }
+
+ private void updateViewForNoRoutes() {
+ setTitle(R.string.mr_chooser_zero_routes_found_title);
+ mTitleView.setVisibility(View.VISIBLE);
+ mListView.setVisibility(View.GONE);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mFooterView.setVisibility(View.VISIBLE);
+ mNoRoutesView.setVisibility(View.VISIBLE);
+ mSearchingRoutesView.setVisibility(View.GONE);
+ mWifiWarningView.setVisibility(View.GONE);
+ }
+
+ private void updateViewForNoDevicesNoWifiHint() {
+ setTitle(R.string.mr_chooser_title);
+ mTitleView.setVisibility(View.VISIBLE);
+ mListView.setVisibility(View.GONE);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mFooterView.setVisibility(View.GONE);
+ mNoRoutesView.setVisibility(View.GONE);
+ mSearchingRoutesView.setVisibility(View.VISIBLE);
+ mWifiWarningView.setVisibility(View.VISIBLE);
+ }
+
+ private void updateViewForShowingRoutes() {
+ setTitle(R.string.mr_chooser_title);
+ mTitleView.setVisibility(View.VISIBLE);
+ mListView.setVisibility(View.VISIBLE);
+ mEmptyView.setVisibility(View.GONE);
+ mFooterView.setVisibility(View.GONE);
+ mNoRoutesView.setVisibility(View.GONE);
+ mSearchingRoutesView.setVisibility(View.GONE);
+ mWifiWarningView.setVisibility(View.GONE);
+ }
+
+ private void updateViewForFindingDevices() {
+ setTitle(R.string.mr_chooser_title);
+ mTitleView.setVisibility(View.VISIBLE);
+ mListView.setVisibility(View.GONE);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mFooterView.setVisibility(View.GONE);
+ mNoRoutesView.setVisibility(View.GONE);
+ mSearchingRoutesView.setVisibility(View.VISIBLE);
+ mWifiWarningView.setVisibility(View.GONE);
}
private static final class RouteAdapter extends ArrayAdapter<MediaRouter.RouteInfo>
@@ -288,8 +439,9 @@
return getItem(position).isEnabled();
}
+ @NonNull
@Override
- public View getView(int position, View convertView, ViewGroup parent) {
+ public View getView(int position, View convertView, @NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.mr_chooser_list_item, parent, false);
@@ -356,7 +508,7 @@
private Drawable getDefaultIconDrawable(MediaRouter.RouteInfo route) {
// If the type of the receiver device is specified, use it.
switch (route.getDeviceType()) {
- case MediaRouter.RouteInfo.DEVICE_TYPE_TV:
+ case MediaRouter.RouteInfo.DEVICE_TYPE_TV:
return mTvIcon;
case MediaRouter.RouteInfo.DEVICE_TYPE_SPEAKER:
return mSpeakerIcon;
@@ -407,4 +559,4 @@
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
}
-}
+}
\ No newline at end of file
diff --git a/mediarouter/mediarouter/src/main/res/layout/mr_chooser_dialog.xml b/mediarouter/mediarouter/src/main/res/layout/mr_chooser_dialog.xml
index 966e42c..c8978f7 100644
--- a/mediarouter/mediarouter/src/main/res/layout/mr_chooser_dialog.xml
+++ b/mediarouter/mediarouter/src/main/res/layout/mr_chooser_dialog.xml
@@ -15,44 +15,111 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <TextView android:id="@+id/mr_chooser_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:minHeight="52dp"
- android:paddingTop="12dp"
- android:paddingLeft="24dp"
- android:paddingRight="24dp"
- android:gravity="center_vertical"
- android:text="@string/mr_chooser_title"
- android:singleLine="true"
- android:ellipsize="end"
- android:textAppearance="@style/TextAppearance.MediaRouter.Title" />
- <ListView android:id="@+id/mr_chooser_list"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="24dp"
- android:divider="@android:color/transparent"
- android:dividerHeight="0dp" />
- <LinearLayout android:id="@android:id/empty"
- android:layout_width="fill_parent"
- android:layout_height="240dp"
- android:orientation="vertical"
- android:paddingTop="90dp"
- android:paddingLeft="16dp"
- android:paddingRight="16dp"
- android:visibility="gone">
- <TextView android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:text="@string/mr_chooser_searching"
- android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
- <ProgressBar android:layout_width="150dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminate="true"
- style="?android:attr/progressBarStyleHorizontal" />
- </LinearLayout>
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="24dp">
+
+ <TextView
+ android:id="@+id/mr_chooser_title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:ellipsize="end"
+ android:gravity="center_vertical"
+ android:singleLine="true"
+ android:text="@string/mr_chooser_title"
+ android:textAppearance="@style/TextAppearance.MediaRouter.Title" />
+
+ <ListView
+ android:id="@+id/mr_chooser_list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="0dp"
+ android:visibility="gone" />
+
+ <RelativeLayout
+ android:id="@+id/mr_empty_view"
+ android:layout_width="fill_parent"
+ android:layout_height="240dp"
+ android:visibility="visible">
+
+ <LinearLayout
+ android:id="@+id/mr_chooser_searching"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerInParent="true"
+ android:orientation="vertical"
+ android:visibility="visible">
+
+ <ProgressBar
+ android:id="@+id/mr_chooser_search_progress_bar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="150dp"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:indeterminate="true" />
+
+ <TextView
+ android:id="@+id/mr_chooser_search_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/mr_chooser_searching"
+ android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
+
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/mr_chooser_no_routes"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+
+ <TextView
+ android:id="@+id/mr_chooser_zero_routes_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/mr_chooser_zero_routes_description"
+ android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/mr_chooser_wifi_warning"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone">
+
+ <TextView
+ android:id="@+id/mr_chooser_wifi_warning_description"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/mr_chooser_wifi_warning_description"
+ android:textAppearance="@style/TextAppearance.MediaRouter.SecondaryText" />
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/mr_chooser_footer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:gravity="bottom"
+ android:visibility="gone">
+
+ <Button
+ android:id="@+id/mr_chooser_done_button"
+ style="?android:attr/borderlessButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|right"
+ android:text="@string/mr_chooser_done_button_label" />
+
+ </FrameLayout>
+
+ </RelativeLayout>
+
</LinearLayout>
diff --git a/mediarouter/mediarouter/src/main/res/values-af/strings.xml b/mediarouter/mediarouter/src/main/res/values-af/strings.xml
index adcb678..d92200d 100644
--- a/mediarouter/mediarouter/src/main/res/values-af/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-af/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Voeg \'n toestel by"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Speel op \'n groep"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Geen inligting beskikbaar nie"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-am/strings.xml b/mediarouter/mediarouter/src/main/res/values-am/strings.xml
index a0ca4d46..b68b906 100644
--- a/mediarouter/mediarouter/src/main/res/values-am/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-am/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"መሣሪያ ያክሉ"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"በቡድን ላይ ያጫውቱ"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ምንም መረጃ አይገኝም"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ar/strings.xml b/mediarouter/mediarouter/src/main/res/values-ar/strings.xml
index 49d12dc..360dd7b 100644
--- a/mediarouter/mediarouter/src/main/res/values-ar/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ar/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"إضافة جهاز"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"تشغيل على مجموعة من الأجهزة"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"لا تتوفر أي معلومات"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-as/strings.xml b/mediarouter/mediarouter/src/main/res/values-as/strings.xml
index 37a0be4..ed65579 100644
--- a/mediarouter/mediarouter/src/main/res/values-as/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-as/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"কোনো এটা ডিভাইচ যোগ কৰক"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"কোনো এটা গোটত প্লে’ কৰক"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"কোনো তথ্য নাই"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-az/strings.xml b/mediarouter/mediarouter/src/main/res/values-az/strings.xml
index 62cadf4..f178a7ee 100644
--- a/mediarouter/mediarouter/src/main/res/values-az/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-az/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Cihaz əlavə edin"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Qrupda oxudun"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Əlçatan məlumat yoxdur"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-b+sr+Latn/strings.xml b/mediarouter/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
index 18bcd14..482284d 100644
--- a/mediarouter/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-b+sr+Latn/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Dodajte uređaj"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Puštajte u grupi"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nema dostupnih informacija"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-be/strings.xml b/mediarouter/mediarouter/src/main/res/values-be/strings.xml
index 1801a8c..9edfde2 100644
--- a/mediarouter/mediarouter/src/main/res/values-be/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-be/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Дадаць прыладу"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Прайграць на групе прылад"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Інфармацыя адсутнічае"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-bg/strings.xml b/mediarouter/mediarouter/src/main/res/values-bg/strings.xml
index 1afa5c6..497a794 100644
--- a/mediarouter/mediarouter/src/main/res/values-bg/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-bg/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Добавяне на устройство"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Възпроизвеждане в група"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Няма налична информация"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-bn/strings.xml b/mediarouter/mediarouter/src/main/res/values-bn/strings.xml
index 3f4883fe..7966f96 100644
--- a/mediarouter/mediarouter/src/main/res/values-bn/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-bn/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"একটি ডিভাইস যোগ করুন"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"গ্রুপে প্লে করুন"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"কোনও তথ্য নেই"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-bs/strings.xml b/mediarouter/mediarouter/src/main/res/values-bs/strings.xml
index 458cce8..3182fd5 100644
--- a/mediarouter/mediarouter/src/main/res/values-bs/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-bs/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Dodajte uređaj"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproduciranje u grupi"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nema dostupnih informacija"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ca/strings.xml b/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
index 5b56248..d0641a2 100644
--- a/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ca/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Afegeix un dispositiu"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reprodueix en un grup"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No hi ha informació disponible"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-cs/strings.xml b/mediarouter/mediarouter/src/main/res/values-cs/strings.xml
index c8bb66e..1385da1 100644
--- a/mediarouter/mediarouter/src/main/res/values-cs/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-cs/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Přidání zařízení"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Přehrávání ve skupině"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nejsou k dispozici žádné informace"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-da/strings.xml b/mediarouter/mediarouter/src/main/res/values-da/strings.xml
index a11ce83..b385462 100644
--- a/mediarouter/mediarouter/src/main/res/values-da/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-da/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Tilføj en enhed"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Afspil på en gruppe"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Der er ingen tilgængelige oplysninger"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-de/strings.xml b/mediarouter/mediarouter/src/main/res/values-de/strings.xml
index 16e64fd..65cdfe6 100644
--- a/mediarouter/mediarouter/src/main/res/values-de/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-de/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Gerät hinzufügen"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Auf einem Gruppengerät abspielen"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Keine Informationen verfügbar"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-el/strings.xml b/mediarouter/mediarouter/src/main/res/values-el/strings.xml
index b44c8351..6d2abc3 100644
--- a/mediarouter/mediarouter/src/main/res/values-el/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-el/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Προσθήκη συσκευής"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Αναπαραγωγή σε κάποια ομάδα"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Δεν υπάρχουν διαθέσιμες πληροφορίες"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-en-rAU/strings.xml b/mediarouter/mediarouter/src/main/res/values-en-rAU/strings.xml
index 9de7198..0af3fbc 100644
--- a/mediarouter/mediarouter/src/main/res/values-en-rAU/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-en-rAU/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Add a device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Play on a group"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No info available"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-en-rCA/strings.xml b/mediarouter/mediarouter/src/main/res/values-en-rCA/strings.xml
index 9de7198..68cb38b 100644
--- a/mediarouter/mediarouter/src/main/res/values-en-rCA/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-en-rCA/strings.xml
@@ -41,4 +41,8 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Add a device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Play on a group"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No info available"</string>
+ <string name="mr_chooser_zero_routes_found_title" msgid="5213435473397442608">"No devices available"</string>
+ <string name="mr_chooser_zero_routes_description" msgid="5123320430013505927">"Unable to find devices, make sure your device and the Cast device are on the same Wi-Fi network and try again."</string>
+ <string name="mr_chooser_wifi_warning_description" msgid="337903053432238985">"Make sure your device and the Cast device are on the same Wi-Fi network."</string>
+ <string name="mr_chooser_done_button_label" msgid="7897288652928484627">"Done"</string>
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-en-rGB/strings.xml b/mediarouter/mediarouter/src/main/res/values-en-rGB/strings.xml
index 9de7198..0af3fbc 100644
--- a/mediarouter/mediarouter/src/main/res/values-en-rGB/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-en-rGB/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Add a device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Play on a group"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No info available"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-en-rIN/strings.xml b/mediarouter/mediarouter/src/main/res/values-en-rIN/strings.xml
index 9de7198..0af3fbc 100644
--- a/mediarouter/mediarouter/src/main/res/values-en-rIN/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-en-rIN/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Add a device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Play on a group"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No info available"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-en-rXC/strings.xml b/mediarouter/mediarouter/src/main/res/values-en-rXC/strings.xml
index 974ce7b..4d254b2 100644
--- a/mediarouter/mediarouter/src/main/res/values-en-rXC/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-en-rXC/strings.xml
@@ -41,4 +41,8 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Add a device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Play on a group"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No info available"</string>
+ <string name="mr_chooser_zero_routes_found_title" msgid="5213435473397442608">"No devices available"</string>
+ <string name="mr_chooser_zero_routes_description" msgid="5123320430013505927">"Unable to find devices, make sure your device and the Cast device are on the same Wi-Fi network and try again."</string>
+ <string name="mr_chooser_wifi_warning_description" msgid="337903053432238985">"Make sure your device and the Cast device are on the same Wi-Fi network."</string>
+ <string name="mr_chooser_done_button_label" msgid="7897288652928484627">"Done"</string>
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-es-rUS/strings.xml b/mediarouter/mediarouter/src/main/res/values-es-rUS/strings.xml
index d55c633..1aad2e0 100644
--- a/mediarouter/mediarouter/src/main/res/values-es-rUS/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-es-rUS/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Agregar un dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproducir en un grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Sin información disponible"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-es/strings.xml b/mediarouter/mediarouter/src/main/res/values-es/strings.xml
index 4986046..1352bcd 100644
--- a/mediarouter/mediarouter/src/main/res/values-es/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-es/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Añadir un dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproducir en un grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"No hay información disponible"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-et/strings.xml b/mediarouter/mediarouter/src/main/res/values-et/strings.xml
index fe2d2c8..e616867 100644
--- a/mediarouter/mediarouter/src/main/res/values-et/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-et/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Seadme lisamine"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Grupis esitamine"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Teave puudub"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-eu/strings.xml b/mediarouter/mediarouter/src/main/res/values-eu/strings.xml
index d58c241..5a8f9ee 100644
--- a/mediarouter/mediarouter/src/main/res/values-eu/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-eu/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Gehitu gailu bat"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Erreproduzitu talde batean"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Ez dago informaziorik"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-fa/strings.xml b/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
index cfeb662..a89fa74 100644
--- a/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fa/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"افزودن دستگاه"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"بازی در گروه"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"اطلاعاتی در دسترس نیست"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-fi/strings.xml b/mediarouter/mediarouter/src/main/res/values-fi/strings.xml
index 168a5b3..16ecc20 100644
--- a/mediarouter/mediarouter/src/main/res/values-fi/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fi/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Lisää laite"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Toista ryhmässä"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Ei tietoja saatavilla"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-fr-rCA/strings.xml b/mediarouter/mediarouter/src/main/res/values-fr-rCA/strings.xml
index 28c763a9..738aae0 100644
--- a/mediarouter/mediarouter/src/main/res/values-fr-rCA/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fr-rCA/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Ajouter un appareil"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Faire jouer sur un groupe d\'appareils"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Aucune donnée trouvée"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-fr/strings.xml b/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
index cb9d9a0..6646d65 100644
--- a/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-fr/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Ajouter un appareil"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Lire sur un groupe d\'appareils"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Aucune information disponible"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-gl/strings.xml b/mediarouter/mediarouter/src/main/res/values-gl/strings.xml
index e91bed7..6117f73 100644
--- a/mediarouter/mediarouter/src/main/res/values-gl/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-gl/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Engadir un dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproducir nun grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Non hai información dispoñible"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-gu/strings.xml b/mediarouter/mediarouter/src/main/res/values-gu/strings.xml
index 0067904..5d12ade 100644
--- a/mediarouter/mediarouter/src/main/res/values-gu/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-gu/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ડિવાઇસ ઉમેરો"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"જૂથમાં રમો"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"કોઈ માહિતી ઉપલબ્ધ નથી"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-hi/strings.xml b/mediarouter/mediarouter/src/main/res/values-hi/strings.xml
index b179584..edd8c71 100644
--- a/mediarouter/mediarouter/src/main/res/values-hi/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-hi/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"कोई डिवाइस जोड़ें"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"समूह में खेलें"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"कोई जानकारी मौजूद नहीं है"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-hr/strings.xml b/mediarouter/mediarouter/src/main/res/values-hr/strings.xml
index 1f63f98..a5d9a4a 100644
--- a/mediarouter/mediarouter/src/main/res/values-hr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-hr/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Dodavanje uređaja"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reprodukcija u grupi"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Informacije nisu dostupne"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-hu/strings.xml b/mediarouter/mediarouter/src/main/res/values-hu/strings.xml
index 3b525c0..e71a892 100644
--- a/mediarouter/mediarouter/src/main/res/values-hu/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-hu/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Eszköz hozzáadása"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Lejátszás eszközcsoportban"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nincs információ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-hy/strings.xml b/mediarouter/mediarouter/src/main/res/values-hy/strings.xml
index 1800c00..609fc37 100644
--- a/mediarouter/mediarouter/src/main/res/values-hy/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-hy/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Ավելացրեք սարք"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Նվագարկեք սարքերի խմբում"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Հասանելի տեղեկություններ չկան"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-in/strings.xml b/mediarouter/mediarouter/src/main/res/values-in/strings.xml
index 3aa6597..7c89622 100644
--- a/mediarouter/mediarouter/src/main/res/values-in/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-in/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Tambahkan perangkat"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Putar di grup"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Info tidak tersedia"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-is/strings.xml b/mediarouter/mediarouter/src/main/res/values-is/strings.xml
index 64217f3..8e7c465 100644
--- a/mediarouter/mediarouter/src/main/res/values-is/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-is/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Bæta tæki við"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Spila í hóp"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Engar upplýsingar í boði"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-it/strings.xml b/mediarouter/mediarouter/src/main/res/values-it/strings.xml
index b86336a..61fab4b 100644
--- a/mediarouter/mediarouter/src/main/res/values-it/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-it/strings.xml
@@ -33,7 +33,7 @@
<string name="mr_controller_expand_group" msgid="4521419834052044261">"Espandi"</string>
<string name="mr_controller_collapse_group" msgid="2585048604188129749">"Comprimi"</string>
<string name="mr_controller_album_art" msgid="3330502667672708728">"Copertina dell\'album"</string>
- <string name="mr_controller_volume_slider" msgid="2955862765169128170">"Dispositivo di scorrimento del volume"</string>
+ <string name="mr_controller_volume_slider" msgid="2955862765169128170">"Cursore del volume"</string>
<string name="mr_controller_no_media_selected" msgid="5495452265246139458">"Nessun contenuto multimediale selezionato"</string>
<string name="mr_controller_no_info_available" msgid="855271725131981086">"Nessuna informazione disponibile"</string>
<string name="mr_controller_casting_screen" msgid="9171231064758955152">"Trasmissione dello schermo attiva"</string>
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Aggiungi un dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Riproduci su un gruppo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nessuna informazione disponibile"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-iw/strings.xml b/mediarouter/mediarouter/src/main/res/values-iw/strings.xml
index eda57a80..57e4a8b 100644
--- a/mediarouter/mediarouter/src/main/res/values-iw/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-iw/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"הוספת מכשיר"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"הפעלה בקבוצה"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"אין מידע זמין"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ja/strings.xml b/mediarouter/mediarouter/src/main/res/values-ja/strings.xml
index 61a726c..2b81561 100644
--- a/mediarouter/mediarouter/src/main/res/values-ja/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ja/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"デバイスの追加"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"グループで再生"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"情報がありません"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ka/strings.xml b/mediarouter/mediarouter/src/main/res/values-ka/strings.xml
index 315aa64e..27f748c 100644
--- a/mediarouter/mediarouter/src/main/res/values-ka/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ka/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"მოწყობილობის დამატება"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ჯგუფში დაკვრა"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ინფორმაცია მიუწვდომელია"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-kk/strings.xml b/mediarouter/mediarouter/src/main/res/values-kk/strings.xml
index 7a7907a..8cc0255 100644
--- a/mediarouter/mediarouter/src/main/res/values-kk/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-kk/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Құрылғы енгізу"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Топта ойнату"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Ешқандай ақпарат жоқ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-km/strings.xml b/mediarouter/mediarouter/src/main/res/values-km/strings.xml
index 8b9d27f..5c7cc84 100644
--- a/mediarouter/mediarouter/src/main/res/values-km/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-km/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"បញ្ចូលឧបករណ៍"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"លេងនៅលើក្រុម"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"មិនមានព័ត៌មានទេ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-kn/strings.xml b/mediarouter/mediarouter/src/main/res/values-kn/strings.xml
index b6933ee..152904b 100644
--- a/mediarouter/mediarouter/src/main/res/values-kn/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-kn/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ಸಾಧನವನ್ನು ಸೇರಿಸಿ"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ಗುಂಪಿನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ಯಾವುದೇ ಮಾಹಿತಿ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ko/strings.xml b/mediarouter/mediarouter/src/main/res/values-ko/strings.xml
index f5fe7b9..a3a9163 100644
--- a/mediarouter/mediarouter/src/main/res/values-ko/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ko/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"기기 추가"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"그룹에서 재생"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"사용할 수 있는 정보 없음"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ky/strings.xml b/mediarouter/mediarouter/src/main/res/values-ky/strings.xml
index 33e6806..e51e3d0 100644
--- a/mediarouter/mediarouter/src/main/res/values-ky/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ky/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="mr_system_route_name" msgid="7449553026175453403">"Тутум"</string>
+ <string name="mr_system_route_name" msgid="7449553026175453403">"Система"</string>
<string name="mr_user_route_category_name" msgid="4088331695424166162">"Түзмөктөр"</string>
<string name="mr_button_content_description" msgid="2939063992730535343">"Тышкы экранга чыгаруу"</string>
<string name="mr_cast_button_disconnected" msgid="8071109333469380363">"Тышкы экранга чыгаруу. Ажыратылды"</string>
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Түзмөк кошуу"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Топто ойнотуу"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Эч маалымат жок"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-lo/strings.xml b/mediarouter/mediarouter/src/main/res/values-lo/strings.xml
index 889ff75..9fad7af 100644
--- a/mediarouter/mediarouter/src/main/res/values-lo/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-lo/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ເພີ່ມອຸປະກອນ"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ຫຼິ້ນຢູ່ກຸ່ມ"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ບໍ່ມີຂໍ້ມູນ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-lt/strings.xml b/mediarouter/mediarouter/src/main/res/values-lt/strings.xml
index 91f6e5b..aca94fe 100644
--- a/mediarouter/mediarouter/src/main/res/values-lt/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-lt/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Įrenginio pridėjimas"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Leidimas grupėje"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nėra jokios informacijos"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-lv/strings.xml b/mediarouter/mediarouter/src/main/res/values-lv/strings.xml
index 468cdeb..c3bbe2c 100644
--- a/mediarouter/mediarouter/src/main/res/values-lv/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-lv/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Pievienot ierīci"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Atskaņošana grupā"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nav informācijas"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-mk/strings.xml b/mediarouter/mediarouter/src/main/res/values-mk/strings.xml
index 73e2bb9..aa622b2 100644
--- a/mediarouter/mediarouter/src/main/res/values-mk/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-mk/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Додајте уред"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Пуштете на група"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Нема достапни информации"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ml/strings.xml b/mediarouter/mediarouter/src/main/res/values-ml/strings.xml
index 9721e13..225af4b 100644
--- a/mediarouter/mediarouter/src/main/res/values-ml/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ml/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ഒരു ഉപകരണം ചേർക്കുക"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ഒരു ഗ്രൂപ്പിൽ പ്ലേ ചെയ്യുക"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"വിവരങ്ങളൊന്നും ലഭ്യമല്ല"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-mn/strings.xml b/mediarouter/mediarouter/src/main/res/values-mn/strings.xml
index 4d15aa8..17670e2 100644
--- a/mediarouter/mediarouter/src/main/res/values-mn/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-mn/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Төхөөрөмж нэмэх"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Бүлэгт тоглуулах"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Мэдээлэл алга"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-mr/strings.xml b/mediarouter/mediarouter/src/main/res/values-mr/strings.xml
index 895b020..69cae09 100644
--- a/mediarouter/mediarouter/src/main/res/values-mr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-mr/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"डिव्हाइस जोडा"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"गटावर प्ले करा"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"कोणतीही माहिती उपलब्ध नाही"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ms/strings.xml b/mediarouter/mediarouter/src/main/res/values-ms/strings.xml
index bdbe265..a6a76ee 100644
--- a/mediarouter/mediarouter/src/main/res/values-ms/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ms/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Tambah peranti"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Mainkan pada kumpulan"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Maklumat tidak tersedia"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-my/strings.xml b/mediarouter/mediarouter/src/main/res/values-my/strings.xml
index 43a59ac..1f00f1a 100644
--- a/mediarouter/mediarouter/src/main/res/values-my/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-my/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"စက်ပစ္စည်း ထည့်ခြင်း"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"အုပ်စုလိုက် ဖွင့်ခြင်း"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"အချက်အလက် မရရှိနိုင်ပါ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-nb/strings.xml b/mediarouter/mediarouter/src/main/res/values-nb/strings.xml
index 311a537..43be34f 100644
--- a/mediarouter/mediarouter/src/main/res/values-nb/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-nb/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Legg til en enhet"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Spill i en gruppe"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Ingen informasjon er tilgjengelig"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ne/strings.xml b/mediarouter/mediarouter/src/main/res/values-ne/strings.xml
index 8f025d1..aef78a2 100644
--- a/mediarouter/mediarouter/src/main/res/values-ne/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ne/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"डिभाइस थप्नुहोस्"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"कुनै समूहमा प्ले गर्नुहोस्"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"कुनै पनि जानकारी उपलब्ध छैन"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-nl/strings.xml b/mediarouter/mediarouter/src/main/res/values-nl/strings.xml
index 4a3ad87..41e6dec 100644
--- a/mediarouter/mediarouter/src/main/res/values-nl/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-nl/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Een apparaat toevoegen"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Afspelen in een groep"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Geen informatie beschikbaar"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-or/strings.xml b/mediarouter/mediarouter/src/main/res/values-or/strings.xml
index f02c6fc..dcef71d 100644
--- a/mediarouter/mediarouter/src/main/res/values-or/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-or/strings.xml
@@ -28,7 +28,7 @@
<string name="mr_controller_stop_casting" msgid="804210341192624074">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="mr_controller_close_description" msgid="5684434439232634509">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="mr_controller_play" msgid="1253345086594430054">"ଚଲାନ୍ତୁ"</string>
- <string name="mr_controller_pause" msgid="747801650871398383">"ପଜ୍ କରନ୍ତୁ"</string>
+ <string name="mr_controller_pause" msgid="747801650871398383">"ବିରତ କରନ୍ତୁ"</string>
<string name="mr_controller_stop" msgid="5497722768305745508">"ରୋକନ୍ତୁ"</string>
<string name="mr_controller_expand_group" msgid="4521419834052044261">"ବିସ୍ତାର କରନ୍ତୁ"</string>
<string name="mr_controller_collapse_group" msgid="2585048604188129749">"ସଂକୁଚିତ କରନ୍ତୁ"</string>
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ଏକ ଡିଭାଇସ୍ ଯୋଗ କରନ୍ତୁ"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ଏକ ଗ୍ରୁପ୍ରେ ପ୍ଲେ କରନ୍ତୁ"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"କୌଣସି ସୂଚନା ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-pa/strings.xml b/mediarouter/mediarouter/src/main/res/values-pa/strings.xml
index e0c2c29..8396b1f 100644
--- a/mediarouter/mediarouter/src/main/res/values-pa/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-pa/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"ਕੋਈ ਡੀਵਾਈਸ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"ਕਿਸੇ ਗਰੁੱਪ ਵਿੱਚ ਖੇਡੋ"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ਕੋਈ ਜਾਣਕਾਰੀ ਉਪਲਬਧ ਨਹੀਂ"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-pl/strings.xml b/mediarouter/mediarouter/src/main/res/values-pl/strings.xml
index 1f552eb..fd06cce 100644
--- a/mediarouter/mediarouter/src/main/res/values-pl/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-pl/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Dodaj urządzenie"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Odtwórz w grupie"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Brak informacji"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-pt-rBR/strings.xml b/mediarouter/mediarouter/src/main/res/values-pt-rBR/strings.xml
index 20c5ae5..1c15e96 100644
--- a/mediarouter/mediarouter/src/main/res/values-pt-rBR/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-pt-rBR/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Adicionar um dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproduzir em um grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nenhuma informação disponível"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-pt-rPT/strings.xml b/mediarouter/mediarouter/src/main/res/values-pt-rPT/strings.xml
index f9c5870..c4a9b98 100644
--- a/mediarouter/mediarouter/src/main/res/values-pt-rPT/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-pt-rPT/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Adicionar um dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproduzir num grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nenhuma informação disponível"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-pt/strings.xml b/mediarouter/mediarouter/src/main/res/values-pt/strings.xml
index 20c5ae5..1c15e96 100644
--- a/mediarouter/mediarouter/src/main/res/values-pt/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-pt/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Adicionar um dispositivo"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Reproduzir em um grupo"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nenhuma informação disponível"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ro/strings.xml b/mediarouter/mediarouter/src/main/res/values-ro/strings.xml
index c8e5f3c..bf4841e 100644
--- a/mediarouter/mediarouter/src/main/res/values-ro/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ro/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Adaugă un dispozitiv"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Redă într-un grup"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nu sunt informații disponibile"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ru/strings.xml b/mediarouter/mediarouter/src/main/res/values-ru/strings.xml
index beca097..99c5462 100644
--- a/mediarouter/mediarouter/src/main/res/values-ru/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ru/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Добавление устройства"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Воспроизведение в группе"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Данных нет"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-si/strings.xml b/mediarouter/mediarouter/src/main/res/values-si/strings.xml
index e2e473a..d9054f7 100644
--- a/mediarouter/mediarouter/src/main/res/values-si/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-si/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"උපාංගයක් එක් කරන්න"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"සමූහයක ධාවනය කරන්න"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ලබා ගත හැකි තොරතුරු නොමැත"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sk/strings.xml b/mediarouter/mediarouter/src/main/res/values-sk/strings.xml
index 449e9a9..0283410 100644
--- a/mediarouter/mediarouter/src/main/res/values-sk/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sk/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Pridanie zariadenia"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Prehrávanie v skupine"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nie sú k dispozícii žiadne informácie"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sl/strings.xml b/mediarouter/mediarouter/src/main/res/values-sl/strings.xml
index 33a4f9e..5889dfb 100644
--- a/mediarouter/mediarouter/src/main/res/values-sl/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sl/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Dodajanje naprave"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Predvajanje v skupini"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Ni podatkov"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sq/strings.xml b/mediarouter/mediarouter/src/main/res/values-sq/strings.xml
index 3fa9667..8b7c925 100644
--- a/mediarouter/mediarouter/src/main/res/values-sq/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sq/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Shto një pajisje"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Luaj në një grup"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Nuk jepet asnjë informacion"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sr/strings.xml b/mediarouter/mediarouter/src/main/res/values-sr/strings.xml
index 6bd1e34..ad33c85 100644
--- a/mediarouter/mediarouter/src/main/res/values-sr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sr/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Додајте уређај"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Пуштајте у групи"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Нема доступних информација"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sv/strings.xml b/mediarouter/mediarouter/src/main/res/values-sv/strings.xml
index de428a1..f1716ad 100644
--- a/mediarouter/mediarouter/src/main/res/values-sv/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sv/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Lägga till en enhet"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Spela upp på en grupp enheter"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Det finns ingen tillgänglig information"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-sw/strings.xml b/mediarouter/mediarouter/src/main/res/values-sw/strings.xml
index db3915f..6c73e06 100644
--- a/mediarouter/mediarouter/src/main/res/values-sw/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-sw/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Ongeza kifaa"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Cheza kwenye kikundi"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Hakuna maelezo yaliyopatikana"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ta/strings.xml b/mediarouter/mediarouter/src/main/res/values-ta/strings.xml
index 5f0dcc3..61fdf59 100644
--- a/mediarouter/mediarouter/src/main/res/values-ta/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ta/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"சாதனத்தைச் சேர்த்தல்"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"குழுவில் இயக்கு"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"தகவல் எதுவுமில்லை"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-te/strings.xml b/mediarouter/mediarouter/src/main/res/values-te/strings.xml
index 81f0b97..e3a416b 100644
--- a/mediarouter/mediarouter/src/main/res/values-te/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-te/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"పరికరాన్ని జోడించండి"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"గ్రూప్లో ప్లే చేయండి"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"సమాచారం అందుబాటులో లేదు"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-th/strings.xml b/mediarouter/mediarouter/src/main/res/values-th/strings.xml
index 36971c5..6128c15 100644
--- a/mediarouter/mediarouter/src/main/res/values-th/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-th/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"เพิ่มอุปกรณ์"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"เล่นในกลุ่ม"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"ไม่มีข้อมูล"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-tl/strings.xml b/mediarouter/mediarouter/src/main/res/values-tl/strings.xml
index bbc61d1..09d27ab 100644
--- a/mediarouter/mediarouter/src/main/res/values-tl/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-tl/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Magdagdag ng device"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"I-play sa isang pangkat"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Walang available na impormasyon"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-tr/strings.xml b/mediarouter/mediarouter/src/main/res/values-tr/strings.xml
index 5d4b340..a2848f8 100644
--- a/mediarouter/mediarouter/src/main/res/values-tr/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-tr/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Cihaz ekleyin"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Bir grupta oynatın"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Bilgi yok"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-uk/strings.xml b/mediarouter/mediarouter/src/main/res/values-uk/strings.xml
index cd76c28..c52083d 100644
--- a/mediarouter/mediarouter/src/main/res/values-uk/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-uk/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Додати пристрій"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Увімкнути на групі пристроїв"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Немає інформації"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-ur/strings.xml b/mediarouter/mediarouter/src/main/res/values-ur/strings.xml
index 322a94a..4491aec 100644
--- a/mediarouter/mediarouter/src/main/res/values-ur/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-ur/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"کوئی آلہ شامل کریں"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"گروپ پر چلائیں"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"کوئی معلومات دستیاب نہیں"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-uz/strings.xml b/mediarouter/mediarouter/src/main/res/values-uz/strings.xml
index a2b411e..6bd6c65 100644
--- a/mediarouter/mediarouter/src/main/res/values-uz/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-uz/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Qurilma qo‘shish"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Guruhda ijro qilish"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Hech narsa topilmadi"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-vi/strings.xml b/mediarouter/mediarouter/src/main/res/values-vi/strings.xml
index 28b6e62..01c6a1c 100644
--- a/mediarouter/mediarouter/src/main/res/values-vi/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-vi/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Thêm thiết bị"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Phát trên nhóm"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Không có thông tin nào"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-zh-rCN/strings.xml b/mediarouter/mediarouter/src/main/res/values-zh-rCN/strings.xml
index bae9baf..912d9ea 100644
--- a/mediarouter/mediarouter/src/main/res/values-zh-rCN/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-zh-rCN/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"添加设备"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"在一组设备上播放"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"没有任何相关信息"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-zh-rHK/strings.xml b/mediarouter/mediarouter/src/main/res/values-zh-rHK/strings.xml
index c641c28..90d792c 100644
--- a/mediarouter/mediarouter/src/main/res/values-zh-rHK/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-zh-rHK/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"新增裝置"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"在群組裝置中播放"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"沒有資料可以提供"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-zh-rTW/strings.xml b/mediarouter/mediarouter/src/main/res/values-zh-rTW/strings.xml
index c7588a4..36e2645 100644
--- a/mediarouter/mediarouter/src/main/res/values-zh-rTW/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-zh-rTW/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"新增裝置"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"在群組上播放"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"沒有可用的資訊"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values-zu/strings.xml b/mediarouter/mediarouter/src/main/res/values-zu/strings.xml
index 5335450..c8774f2 100644
--- a/mediarouter/mediarouter/src/main/res/values-zu/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values-zu/strings.xml
@@ -41,4 +41,12 @@
<string name="mr_dialog_groupable_header" msgid="4307018456678388936">"Engeza idivayisi"</string>
<string name="mr_dialog_transferable_header" msgid="6068257520605505468">"Dlala eqenjini"</string>
<string name="mr_cast_dialog_title_view_placeholder" msgid="2175930138959078155">"Alukho ulwazi olutholakalayo"</string>
+ <!-- no translation found for mr_chooser_zero_routes_found_title (5213435473397442608) -->
+ <skip />
+ <!-- no translation found for mr_chooser_zero_routes_description (5123320430013505927) -->
+ <skip />
+ <!-- no translation found for mr_chooser_wifi_warning_description (337903053432238985) -->
+ <skip />
+ <!-- no translation found for mr_chooser_done_button_label (7897288652928484627) -->
+ <skip />
</resources>
diff --git a/mediarouter/mediarouter/src/main/res/values/strings.xml b/mediarouter/mediarouter/src/main/res/values/strings.xml
index 42d088d..8b54407 100644
--- a/mediarouter/mediarouter/src/main/res/values/strings.xml
+++ b/mediarouter/mediarouter/src/main/res/values/strings.xml
@@ -94,4 +94,16 @@
<!-- Placeholder text for cast dialog title view [CHAR LIMIT=50] -->
<string name="mr_cast_dialog_title_view_placeholder">No info available</string>
+
+ <!-- Title of the media route chooser dialog when zero routes have been found after searching. [CHAR_LIMIT=NONE] -->
+ <string name="mr_chooser_zero_routes_found_title">No devices available</string>
+
+ <!-- Text displayed when no routes have been found after searching. [CHAR_LIMIT=NONE] -->
+ <string name="mr_chooser_zero_routes_description">Unable to find devices, make sure your device and the Cast device are on the same Wi-Fi network and try again.</string>
+
+ <!-- Text displayed to hint making sure device and cast device are connected to the same Wi-Fi. [CHAR_LIMIT=NONE] -->
+ <string name="mr_chooser_wifi_warning_description">Make sure your device and the Cast device are on the same Wi-Fi network.</string>
+
+ <!-- The label of the Done button that closes the Cast media route chooser dialog when tapped. [CHAR_LIMIT=30] -->
+ <string name="mr_chooser_done_button_label">Done</string>
</resources>
diff --git a/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankAggregatorActivity.kt b/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankAggregatorActivity.kt
index e293c37..d280f43 100644
--- a/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankAggregatorActivity.kt
+++ b/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankAggregatorActivity.kt
@@ -20,8 +20,8 @@
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
-import androidx.metrics.performance.PerformanceMetricsState
import androidx.metrics.performance.FrameData
+import androidx.metrics.performance.PerformanceMetricsState
import androidx.metrics.performance.janktest.databinding.ActivityMainBinding
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
diff --git a/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankLoggingActivity.kt b/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankLoggingActivity.kt
index e3c0087..08826f4 100644
--- a/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankLoggingActivity.kt
+++ b/metrics/integration-tests/janktest/src/main/java/androidx/metrics/performance/janktest/JankLoggingActivity.kt
@@ -20,9 +20,9 @@
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
-import androidx.metrics.performance.PerformanceMetricsState
import androidx.metrics.performance.FrameData
import androidx.metrics.performance.JankStats
+import androidx.metrics.performance.PerformanceMetricsState
import androidx.metrics.performance.janktest.databinding.ActivityMainBinding
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
diff --git a/metrics/metrics-benchmark/src/main/AndroidManifest.xml b/metrics/metrics-benchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 29b496b..0000000
--- a/metrics/metrics-benchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/metrics/metrics-performance/build.gradle b/metrics/metrics-performance/build.gradle
index 94fcacb..8c474b0 100644
--- a/metrics/metrics-performance/build.gradle
+++ b/metrics/metrics-performance/build.gradle
@@ -59,7 +59,7 @@
androidx {
- name = "AndroidX Metrics"
+ name = "Metrics"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2021"
description = "Library for tracking and reporting various runtime metrics for applications"
diff --git a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
index f447748..0129f1f 100644
--- a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
+++ b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/DelayedView.kt
@@ -2,6 +2,8 @@
import android.content.Context
import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Paint
import android.os.Build
import android.util.AttributeSet
import android.view.View
@@ -15,6 +17,11 @@
var repetitions: Int = 0
var maxReps: Int = 0
var perFrameStateData: List<JankStatsTest.FrameStateInputData> = listOf()
+ val textPaint = Paint()
+
+ init {
+ textPaint.textSize = 50f
+ }
@RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
override fun onDraw(canvas: Canvas) {
@@ -29,8 +36,10 @@
(((Math.random() * 127) + 128).toInt() shl 16) or
(((Math.random() * 127) + 128).toInt() shl 8) or
((Math.random() * 127) + 128).toInt()
+ textPaint.setColor(Color.BLACK)
canvas.drawColor(randomColor)
+ canvas.drawText("Frame ${repetitions - 1}", 200f, 200f, textPaint)
if (perFrameStateData.isNotEmpty()) {
val metricsState = PerformanceMetricsState.getHolderForHierarchy(this).state!!
val stateData = perFrameStateData[repetitions - 1]
diff --git a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
index 5351167..a933cfc 100644
--- a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
+++ b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
@@ -35,8 +35,8 @@
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.math.max
-import org.hamcrest.Matchers
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
@@ -185,15 +185,11 @@
jankStats.jankHeuristicMultiplier = 0f
runDelayTest(frameDelay, NUM_FRAMES, latchedListener)
// FrameMetrics sometimes drops a frame, so the total number of
- // jankData items might be less than NUM_FRAMES
+ // jankData items might be less than NUM_FRAMES. Check against actual
+ // number of frames received instead.
assertEquals(
- "jank frames != NUMFRAMES",
- NUM_FRAMES, latchedListener.numJankFrames
- )
- assertTrue(
- "With heuristicMultiplier 0, should be at least ${NUM_FRAMES - 1} " +
- "frames with jank data, not ${latchedListener.numJankFrames}",
- latchedListener.numJankFrames >= (NUM_FRAMES - 1)
+ "numJankFrames != numFrames",
+ latchedListener.numFrames, latchedListener.numJankFrames
)
}
@@ -275,12 +271,12 @@
frameInit.initFramePipeline()
runDelayTest(frameDelay, NUM_FRAMES, latchedListener)
+
// FrameMetrics sometimes drops a frame, so the total number of
// jankData items might be less than NUM_FRAMES
- assertTrue(
- "There should be at least ${NUM_FRAMES - 1} frames with jank data, " +
- "not ${latchedListener.jankData.size}",
- latchedListener.jankData.size >= (NUM_FRAMES - 1)
+ assertEquals("There should be ${latchedListener.numFrames} frames " +
+ "with jank data, not ${latchedListener.jankData.size}",
+ latchedListener.numFrames, latchedListener.jankData.size
)
latchedListener.reset()
@@ -307,8 +303,8 @@
metricsState.putSingleFrameState(state2.key, state2.value)
runDelayTest(frameDelay, NUM_FRAMES, latchedListener)
assertEquals(
- "frameDelay 100: There should be $NUM_FRAMES frames with jank data", NUM_FRAMES,
- latchedListener.jankData.size
+ "frameDelay 100: There should be ${latchedListener.numFrames} frames with" +
+ "jank data", latchedListener.numFrames, latchedListener.jankData.size
)
var item0: FrameData = latchedListener.jankData[0]
assertEquals("There should be 3 states at frame 0", 3,
@@ -323,7 +319,7 @@
assertThat(state2, Matchers.isIn(item0.states))
// Now test the rest of the frames, which should not include singleFrameState state2
- for (i in 1 until NUM_FRAMES) {
+ for (i in 1 until latchedListener.numFrames) {
val item = latchedListener.jankData[i]
assertEquals("There should be 2 states at frame $i", 2,
item.states.size)
@@ -503,18 +499,46 @@
runDelayTest(frameDelay = 0, numFrames = perFrameStateData.size,
latchedListener, perFrameStateData)
- assertEquals("There should be ${expectedResults.size} frames of data",
- expectedResults.size, latchedListener.jankData.size)
- for (i in 0 until expectedResults.size) {
- val testResultStates = latchedListener.jankData[i].states
- val expectedResult = expectedResults[i]
- assertEquals("There should be ${expectedResult.size} states",
- expectedResult.size, testResultStates.size)
- for (state in testResultStates) {
- assertEquals("State value not correct",
- state.value, expectedResult.get(state.key))
+ // There might be one or two dropped frames, check that we have nearly the number
+ // expected
+ assertTrue("There should be at least ${expectedResults.size - 2} frames of data",
+ (latchedListener.jankData.size > expectedResults.size - 2))
+
+ /*
+ Ideally, we would check each frame's result states against the expected results.
+ But the system sometimes drops frames, causing the jankData to be a subset of
+ the expectedResults set from above. This is fine, for testing purposes, but that
+ means we should check the current result against the expected result of this and
+ the next frame, to account for these skips. when this happens, we increment the
+ expected index since all results will be offset by that skip.
+ */
+ var expectedIndex = 0
+ var resultIndex = 0
+ while (expectedIndex < expectedResults.size) {
+ val testResultStates = latchedListener.jankData[resultIndex].states
+ // Test against this and next expected result, in case system skipped a frame
+ var matched = checkFrameStates(expectedResults[expectedIndex], testResultStates)
+ if (!matched) {
+ expectedIndex++
+ matched = checkFrameStates(expectedResults[expectedIndex], testResultStates)
+ }
+ assertTrue("States do not match at frame $expectedIndex", matched)
+ expectedIndex++
+ resultIndex++
+ }
+ }
+
+ private fun checkFrameStates(
+ expectedResult: Map<String, String>,
+ testResultStates: List<StateInfo>
+ ): Boolean {
+ if (expectedResult.size != testResultStates.size) return false
+ for (state in testResultStates) {
+ if (state.value != expectedResult.get(state.key)) {
+ return false
}
}
+ return true
}
private fun runDelayTest(
diff --git a/metrics/metrics-performance/src/main/AndroidManifest.xml b/metrics/metrics-performance/src/main/AndroidManifest.xml
deleted file mode 100644
index 6a68baf..0000000
--- a/metrics/metrics-performance/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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.
--->
-<manifest />
diff --git a/navigation/CHANGELOG.md b/navigation/CHANGELOG.md
index 5c13fd8..e80842d 100644
--- a/navigation/CHANGELOG.md
+++ b/navigation/CHANGELOG.md
@@ -14,9 +14,15 @@
# Behavior Change
# External Contributions
-# Unreleased
+## Unreleased
+
+### Bug Fixes
+
+- Updated the error message and exception type when navigating on a NavController with no
+ navigation graph set.
### Dependency Updates
-* Changed dependency of Activity library from version 1.6.1 to version 1.7.1.
+- Changed dependency of Activity library from version 1.6.1 to version 1.7.1.
+
diff --git a/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/MainFragment.kt b/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/MainFragment.kt
index 083d17d..e820bfe 100644
--- a/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/MainFragment.kt
+++ b/navigation/integration-tests/testapp/src/main/java/androidx/navigation/testapp/MainFragment.kt
@@ -18,6 +18,7 @@
import android.graphics.Color
import android.os.Bundle
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -27,6 +28,7 @@
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
+import androidx.transition.Slide
/**
* Fragment used to show how to navigate to another destination
@@ -38,6 +40,8 @@
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
+ enterTransition = Slide(Gravity.RIGHT)
+ exitTransition = Slide(Gravity.LEFT)
return inflater.inflate(R.layout.main_fragment, container, false)
}
diff --git a/navigation/integration-tests/testapp/src/main/res/navigation/nav_main.xml b/navigation/integration-tests/testapp/src/main/res/navigation/nav_main.xml
index cea98bd..4db4d1d 100644
--- a/navigation/integration-tests/testapp/src/main/res/navigation/nav_main.xml
+++ b/navigation/integration-tests/testapp/src/main/res/navigation/nav_main.xml
@@ -23,31 +23,19 @@
android:name=".MainFragment"
android:label="@string/home">
<argument android:name="myarg" android:defaultValue="Home" />
- <action android:id="@+id/next" app:destination="@+id/first_screen"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/first_screen"/>
</fragment>
<fragment android:id="@+id/first_screen"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/first">
<argument android:name="myarg" android:defaultValue="one" />
- <action android:id="@+id/next" app:destination="@+id/next_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/next_fragment"/>
</fragment>
<fragment android:id="@+id/next_fragment"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/second">
<argument android:name="myarg" android:defaultValue="two" />
- <action android:id="@+id/next" app:destination="@+id/first_screen"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/first_screen"/>
</fragment>
</navigation>
<dialog
diff --git a/navigation/integration-tests/testapp/src/main/res/navigation/two_pane_navigation.xml b/navigation/integration-tests/testapp/src/main/res/navigation/two_pane_navigation.xml
index f7eb4da..63261cbf 100644
--- a/navigation/integration-tests/testapp/src/main/res/navigation/two_pane_navigation.xml
+++ b/navigation/integration-tests/testapp/src/main/res/navigation/two_pane_navigation.xml
@@ -20,51 +20,31 @@
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/first">
<argument android:name="myarg" android:defaultValue="one" />
- <action android:id="@+id/next" app:destination="@+id/second_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/second_fragment"/>
</fragment>
<fragment android:id="@+id/second_fragment"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/second">
<argument android:name="myarg" android:defaultValue="two" />
- <action android:id="@+id/next" app:destination="@+id/third_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/third_fragment"/>
</fragment>
<fragment android:id="@+id/third_fragment"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/third">
<argument android:name="myarg" android:defaultValue="three" />
- <action android:id="@+id/next" app:destination="@+id/fourth_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/fourth_fragment"/>
</fragment>
<fragment android:id="@+id/fourth_fragment"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/fourth">
<argument android:name="myarg" android:defaultValue="four" />
- <action android:id="@+id/next" app:destination="@+id/fifth_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/fifth_fragment"/>
</fragment>
<fragment android:id="@+id/fifth_fragment"
android:name="androidx.navigation.testapp.MainFragment"
android:label="@string/fifth">
<argument android:name="myarg" android:defaultValue="five" />
- <action android:id="@+id/next" app:destination="@+id/first_fragment"
- app:enterAnim="@anim/nav_default_enter_anim"
- app:exitAnim="@anim/nav_default_exit_anim"
- app:popEnterAnim="@anim/nav_default_pop_enter_anim"
- app:popExitAnim="@anim/nav_default_pop_exit_anim"/>
+ <action android:id="@+id/next" app:destination="@+id/first_fragment"/>
</fragment>
<dialog
android:id="@+id/learn_more"
diff --git a/navigation/navigation-common-ktx/build.gradle b/navigation/navigation-common-ktx/build.gradle
index 03904c3..b2f94223 100644
--- a/navigation/navigation-common-ktx/build.gradle
+++ b/navigation/navigation-common-ktx/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Navigation Common Kotlin Extensions"
+ name = "Navigation Common Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Navigation-Common-Ktx"
diff --git a/navigation/navigation-common-ktx/src/main/AndroidManifest.xml b/navigation/navigation-common-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index fdfdce5..0000000
--- a/navigation/navigation-common-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index 954e0da..91a97ad3 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -67,7 +67,7 @@
}
androidx {
- name = "Android Navigation Common"
+ name = "Navigation Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Navigation-Common"
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
index a4da5ed..c893818 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavDeepLinkTest.kt
@@ -24,9 +24,9 @@
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.io.UnsupportedEncodingException
import kotlin.test.assertFailsWith
import org.junit.Test
-import java.io.UnsupportedEncodingException
@SmallTest
class NavDeepLinkTest {
diff --git a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
index 91be8b2..457e530 100644
--- a/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
+++ b/navigation/navigation-common/src/androidTest/java/androidx/navigation/NavTypeTest.kt
@@ -23,8 +23,8 @@
import androidx.navigation.common.test.R
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
import java.io.Serializable
+import org.junit.Test
@SmallTest
class NavTypeTest {
diff --git a/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt b/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
index 5577ac2..9cbe30e 100644
--- a/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
+++ b/navigation/navigation-common/src/main/java/androidx/navigation/NavigatorState.kt
@@ -20,11 +20,11 @@
import androidx.annotation.CallSuper
import androidx.annotation.RestrictTo
import androidx.lifecycle.Lifecycle
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
/**
* The NavigatorState encapsulates the state shared between the [Navigator] and the
diff --git a/navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt b/navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt
index 97ceb0f..c422999 100644
--- a/navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt
+++ b/navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt
@@ -24,8 +24,8 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
@RunWith(JUnit4::class)
class NavDestinationTest {
diff --git a/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt b/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt
index 5bba39e..0978c5b 100644
--- a/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt
+++ b/navigation/navigation-compose-lint/src/main/java/androidx/navigation/compose/lint/ComposableDestinationInComposeScopeDetector.kt
@@ -31,8 +31,8 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
/**
* [Detector] that checks `composable` calls to make sure that they are not called inside a
diff --git a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/AndroidManifest.xml b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/BasicNavDemo.kt b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/BasicNavDemo.kt
index aef7393..105717b 100644
--- a/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/BasicNavDemo.kt
+++ b/navigation/navigation-compose/integration-tests/navigation-demos/src/main/java/androidx/navigation/compose/demos/BasicNavDemo.kt
@@ -16,8 +16,8 @@
package androidx.navigation.compose.demos
-import androidx.navigation.compose.samples.BasicNav
import androidx.compose.runtime.Composable
+import androidx.navigation.compose.samples.BasicNav
@Composable
fun BasicNavDemo() {
diff --git a/navigation/navigation-compose/samples/build.gradle b/navigation/navigation-compose/samples/build.gradle
index b71e29c..b229762 100644
--- a/navigation/navigation-compose/samples/build.gradle
+++ b/navigation/navigation-compose/samples/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "AndroidX Compose UI Navigation Integration Samples"
+ name = "Compose UI Navigation Integration Samples"
type = LibraryType.SAMPLES
inceptionYear = "2020"
description = "Samples for Compose integration with Navigation"
diff --git a/navigation/navigation-compose/samples/src/main/AndroidManifest.xml b/navigation/navigation-compose/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/navigation/navigation-compose/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/navigation/navigation-compose/src/androidTest/AndroidManifest.xml b/navigation/navigation-compose/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/navigation/navigation-compose/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavGraphBuilderTest.kt b/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavGraphBuilderTest.kt
index 3634fee..619b7db 100644
--- a/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavGraphBuilderTest.kt
+++ b/navigation/navigation-compose/src/androidTest/java/androidx/navigation/compose/NavGraphBuilderTest.kt
@@ -20,8 +20,8 @@
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.core.net.toUri
-import androidx.navigation.contains
import androidx.navigation.NavDeepLinkRequest
+import androidx.navigation.contains
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
import androidx.navigation.navigation
diff --git a/navigation/navigation-compose/src/main/AndroidManifest.xml b/navigation/navigation-compose/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/navigation/navigation-compose/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/navigation/navigation-dynamic-features-fragment/build.gradle b/navigation/navigation-dynamic-features-fragment/build.gradle
index 80119e7..931ddb1 100644
--- a/navigation/navigation-dynamic-features-fragment/build.gradle
+++ b/navigation/navigation-dynamic-features-fragment/build.gradle
@@ -64,7 +64,7 @@
}
androidx {
- name = "Android Dynamic Feature Navigation Fragment"
+ name = "Dynamic Feature Navigation Fragment"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android Dynamic Feature Navigation Fragment"
diff --git a/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/ui/DefaultProgressFragmentTest.kt b/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/ui/DefaultProgressFragmentTest.kt
index 99c67e7..b05a6cc 100644
--- a/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/ui/DefaultProgressFragmentTest.kt
+++ b/navigation/navigation-dynamic-features-fragment/src/androidTest/java/androidx/navigation/dynamicfeatures/fragment/ui/DefaultProgressFragmentTest.kt
@@ -16,13 +16,13 @@
package androidx.navigation.dynamicfeatures.fragment.ui
-import androidx.navigation.dynamicfeatures.fragment.R as mainR
-import androidx.navigation.dynamicfeatures.fragment.test.R as testR
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
import androidx.navigation.dynamicfeatures.fragment.NavigationActivity
+import androidx.navigation.dynamicfeatures.fragment.R as mainR
+import androidx.navigation.dynamicfeatures.fragment.test.R as testR
import androidx.navigation.fragment.findNavController
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/navigation/navigation-dynamic-features-runtime/build.gradle b/navigation/navigation-dynamic-features-runtime/build.gradle
index e722e52..497c5ea 100644
--- a/navigation/navigation-dynamic-features-runtime/build.gradle
+++ b/navigation/navigation-dynamic-features-runtime/build.gradle
@@ -60,7 +60,7 @@
}
androidx {
- name = "Android Dynamic Feature Navigation Runtime"
+ name = "Dynamic Feature Navigation Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android Dynamic Feature Navigation Runtime"
diff --git a/navigation/navigation-fragment-ktx/build.gradle b/navigation/navigation-fragment-ktx/build.gradle
index 2cb0659..bd96b86 100644
--- a/navigation/navigation-fragment-ktx/build.gradle
+++ b/navigation/navigation-fragment-ktx/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "Android Navigation Fragment Kotlin Extensions"
+ name = "Navigation Fragment Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Navigation-Fragment-Ktx"
diff --git a/navigation/navigation-fragment-ktx/src/androidTest/AndroidManifest.xml b/navigation/navigation-fragment-ktx/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 8358852..0000000
--- a/navigation/navigation-fragment-ktx/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 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 />
diff --git a/navigation/navigation-fragment-ktx/src/main/AndroidManifest.xml b/navigation/navigation-fragment-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 0e03c43..0000000
--- a/navigation/navigation-fragment-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/navigation/navigation-fragment/build.gradle b/navigation/navigation-fragment/build.gradle
index f8284f5..5edeaf7 100644
--- a/navigation/navigation-fragment/build.gradle
+++ b/navigation/navigation-fragment/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "Android Navigation Fragment"
+ name = "Navigation Fragment"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Navigation-Fragment"
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
index 22cded3..b434bcf 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/DialogFragmentNavigatorTest.kt
@@ -35,11 +35,11 @@
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlin.reflect.KClass
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.reflect.KClass
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/ImmediateNavigationTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/ImmediateNavigationTest.kt
index 8d3b01b10..fdad624 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/ImmediateNavigationTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/ImmediateNavigationTest.kt
@@ -27,11 +27,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.testutils.withActivity
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt
index 1a72855..eb54237 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/MultiNavHostFragmentTest.kt
@@ -26,10 +26,10 @@
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Test
+import org.junit.runner.RunWith
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavControllerWithFragmentTest.kt b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavControllerWithFragmentTest.kt
index 15a2734..d000958 100644
--- a/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavControllerWithFragmentTest.kt
+++ b/navigation/navigation-fragment/src/androidTest/java/androidx/navigation/fragment/NavControllerWithFragmentTest.kt
@@ -300,6 +300,60 @@
assertThat(navController.currentBackStackEntry?.destination?.route).isEqualTo("first")
}
+ @LargeTest
+ @Test
+ fun testSystemBackPressAfterPopUpToStartDestinationOffBackStack() = withNavigationActivity {
+ navController.graph = navController.createGraph("first") {
+ fragment<EmptyFragment>("first")
+ fragment<EmptyFragment>("second")
+ fragment<EmptyFragment>("third")
+ }
+ navController.navigate("second")
+ val fm = supportFragmentManager.findFragmentById(R.id.nav_host)?.childFragmentManager
+ fm?.executePendingTransactions()
+
+ navController.navigate("third", navOptions {
+ popUpTo("first") { inclusive = true }
+ })
+ fm?.executePendingTransactions()
+
+ navController.navigate("first")
+ fm?.executePendingTransactions()
+
+ onBackPressedDispatcher.onBackPressed()
+
+ assertThat(navController.currentBackStackEntry?.destination?.route).isEqualTo("third")
+ }
+
+ @LargeTest
+ @Test
+ fun testSystemBackPressAfterPopUpToOffBackStack() = withNavigationActivity {
+ navController.graph = navController.createGraph("first") {
+ fragment<EmptyFragment>("first")
+ fragment<EmptyFragment>("second")
+ fragment<EmptyFragment>("third")
+ fragment<EmptyFragment>("fourth")
+ }
+ navController.navigate("second")
+ val fm = supportFragmentManager.findFragmentById(R.id.nav_host)?.childFragmentManager
+ fm?.executePendingTransactions()
+
+ navController.navigate("third")
+ fm?.executePendingTransactions()
+
+ navController.navigate("fourth", navOptions {
+ popUpTo("second") { inclusive = true }
+ })
+ fm?.executePendingTransactions()
+
+ navController.navigate("second")
+ fm?.executePendingTransactions()
+
+ onBackPressedDispatcher.onBackPressed()
+
+ assertThat(navController.currentBackStackEntry?.destination?.route).isEqualTo("fourth")
+ }
+
private fun withNavigationActivity(
block: NavigationActivity.() -> Unit
) {
diff --git a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
index f92e322..8bb7b8c 100644
--- a/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
+++ b/navigation/navigation-fragment/src/main/java/androidx/navigation/fragment/FragmentNavigator.kt
@@ -67,7 +67,10 @@
/**
* List of entries that were popped by direct calls to popBackStack (i.e. from NavController)
*/
- private val entriesToPop = mutableSetOf<String>()
+ internal val entriesToPop: Set<String>
+ get() = (state.transitionsInProgress.value - state.backStack.value.toSet())
+ .map { it.id }
+ .toSet()
/**
* Get the back stack from the [state].
@@ -81,7 +84,6 @@
entry.id == fragment.tag
}
if (entry != null) {
- entriesToPop.remove(entry.id)
if (!state.backStack.value.contains(entry)) {
state.markTransitionComplete(entry)
}
@@ -99,7 +101,6 @@
// Once the lifecycle reaches DESTROYED, if the entry is not in the back stack, we can
// mark the transition complete
if (event == Lifecycle.Event.ON_DESTROY) {
- entriesToPop.remove(entry.id)
if (!state.backStack.value.contains(entry)) {
state.markTransitionComplete(entry)
}
@@ -150,16 +151,10 @@
// we need to make sure we still return the entries to their proper final state.
attachClearViewModel(fragment, entry, state)
if (pop) {
- // The entry has already been removed from the back stack so just remove it
- // from the list
- if (!state.backStack.value.contains(entry)) {
- // remove it so we don't falsely identify a direct call to popBackStack
- entriesToPop.remove(entry.id)
- }
// This is the case of system back where we will need to make the call to
// popBackStack. Otherwise, popBackStack was called directly and this should
// end up being a no-op.
- else if (entriesToPop.isEmpty() && fragment.isRemoving) {
+ if (entriesToPop.isEmpty() && fragment.isRemoving) {
state.popWithTransition(entry, false)
}
}
@@ -249,10 +244,6 @@
FragmentManager.POP_BACK_STACK_INCLUSIVE
)
}
- // Add all of the entries that are going to be popped to our set of entries to pop
- poppedList.forEach {
- entriesToPop.add(it.id)
- }
state.popWithTransition(popUpTo, savedState)
}
diff --git a/navigation/navigation-runtime-ktx/build.gradle b/navigation/navigation-runtime-ktx/build.gradle
index 1b497c7..4663086 100644
--- a/navigation/navigation-runtime-ktx/build.gradle
+++ b/navigation/navigation-runtime-ktx/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "Android Navigation Runtime Kotlin Extensions"
+ name = "Navigation Runtime Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Navigation-Runtime-Ktx"
diff --git a/navigation/navigation-runtime-ktx/src/androidTest/AndroidManifest.xml b/navigation/navigation-runtime-ktx/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 8358852..0000000
--- a/navigation/navigation-runtime-ktx/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 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 />
diff --git a/navigation/navigation-runtime-ktx/src/main/AndroidManifest.xml b/navigation/navigation-runtime-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index fdfdce5..0000000
--- a/navigation/navigation-runtime-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/navigation/navigation-runtime-truth/build.gradle b/navigation/navigation-runtime-truth/build.gradle
index dfc5054..4ff4554f 100644
--- a/navigation/navigation-runtime-truth/build.gradle
+++ b/navigation/navigation-runtime-truth/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android Navigation Runtime Truth"
+ name = "Navigation Runtime Truth"
publish = Publish.NONE
inceptionYear = "2019"
description = "Android Navigation-Runtime-Truth"
diff --git a/navigation/navigation-runtime-truth/src/androidTest/java/androidx/navigation/truth/NavControllerSubjectTest.kt b/navigation/navigation-runtime-truth/src/androidTest/java/androidx/navigation/truth/NavControllerSubjectTest.kt
index 15499c8..10caf31 100644
--- a/navigation/navigation-runtime-truth/src/androidTest/java/androidx/navigation/truth/NavControllerSubjectTest.kt
+++ b/navigation/navigation-runtime-truth/src/androidTest/java/androidx/navigation/truth/NavControllerSubjectTest.kt
@@ -18,8 +18,8 @@
import androidx.navigation.NavController
import androidx.navigation.plusAssign
-import androidx.navigation.truth.test.R
import androidx.navigation.truth.NavControllerSubject.Companion.assertThat
+import androidx.navigation.truth.test.R
import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.SmallTest
diff --git a/navigation/navigation-runtime-truth/src/main/AndroidManifest.xml b/navigation/navigation-runtime-truth/src/main/AndroidManifest.xml
deleted file mode 100644
index fdfdce5..0000000
--- a/navigation/navigation-runtime-truth/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/navigation/navigation-runtime/build.gradle b/navigation/navigation-runtime/build.gradle
index c7ebc80..ff856e6 100644
--- a/navigation/navigation-runtime/build.gradle
+++ b/navigation/navigation-runtime/build.gradle
@@ -60,7 +60,7 @@
}
androidx {
- name = "Android Navigation Runtime"
+ name = "Navigation Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Navigation-Runtime"
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
index 8b35f7b..3b662ee 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -54,8 +54,8 @@
import androidx.test.filters.MediumTest
import androidx.test.filters.SdkSuppress
import androidx.testutils.TestNavigator
-import androidx.testutils.withActivity
import androidx.testutils.test
+import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlin.test.assertFailsWith
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerViewModelTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerViewModelTest.kt
index d786d7a..2ff68ee9 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerViewModelTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerViewModelTest.kt
@@ -20,9 +20,9 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import java.util.UUID
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.UUID
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
index 7d97f4e..18a7e32 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
@@ -16,16 +16,16 @@
package androidx.navigation
-import androidx.navigation.test.R
import android.content.Context
import android.os.Bundle
+import androidx.core.os.bundleOf
+import androidx.navigation.test.R
import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.testutils.TestNavigator
import androidx.testutils.test
-import androidx.core.os.bundleOf
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Test
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
index be6eafb..4176c33 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
@@ -42,6 +42,8 @@
import androidx.navigation.NavDestination.Companion.createRoute
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
+import java.util.concurrent.CopyOnWriteArrayList
+import java.util.concurrent.atomic.AtomicInteger
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -49,8 +51,6 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
-import java.util.concurrent.CopyOnWriteArrayList
-import java.util.concurrent.atomic.AtomicInteger
/**
* NavController manages app navigation within a [NavHost].
@@ -1605,7 +1605,7 @@
* @param navOptions special options for this navigation operation
* @param navigatorExtras extras to pass to the Navigator
*
- * @throws IllegalStateException if there is no current navigation node
+ * @throws IllegalStateException if navigation graph has not been set for this NavController
* @throws IllegalArgumentException if the desired destination cannot be found from the
* current destination
*/
@@ -1622,7 +1622,10 @@
_graph
else
backQueue.last().destination
- ) ?: throw IllegalStateException("no current navigation node")
+ ) ?: throw IllegalStateException(
+ "No current destination found. Ensure a navigation graph has been set for " +
+ "NavController $this."
+ )
@IdRes
var destId = resId
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt
index 4c8f16b..2b624ea 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt
@@ -16,10 +16,10 @@
package androidx.navigation
import android.app.Activity
-import android.content.Intent
-import android.content.ComponentName
import android.app.PendingIntent
+import android.content.ComponentName
import android.content.Context
+import android.content.Intent
import android.os.Bundle
import androidx.annotation.IdRes
import androidx.annotation.NavigationRes
diff --git a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavInflater.kt b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavInflater.kt
index 4754d62..7722bba 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavInflater.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavInflater.kt
@@ -29,9 +29,9 @@
import androidx.core.content.res.use
import androidx.core.content.withStyledAttributes
import androidx.navigation.common.R
+import java.io.IOException
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
-import java.io.IOException
/**
* Class which translates a navigation XML file into a [NavGraph]
diff --git a/navigation/navigation-safe-args-generator/build.gradle b/navigation/navigation-safe-args-generator/build.gradle
index 4b4c91f..988bc00 100644
--- a/navigation/navigation-safe-args-generator/build.gradle
+++ b/navigation/navigation-safe-args-generator/build.gradle
@@ -60,7 +60,7 @@
androidx {
- name = "Android Navigation TypeSafe Arguments Generator"
+ name = "Navigation TypeSafe Arguments Generator"
type = LibraryType.OTHER_CODE_PROCESSOR
inceptionYear = "2017"
description = "Android Navigation TypeSafe Arguments Generator"
diff --git a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/XmlPositionParser.kt b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/XmlPositionParser.kt
index 305c54f..d0e29bc 100644
--- a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/XmlPositionParser.kt
+++ b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/XmlPositionParser.kt
@@ -16,9 +16,9 @@
package androidx.navigation.safe.args.generator
+import java.io.Reader
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
-import java.io.Reader
internal class XmlPositionParser(private val name: String, reader: Reader, val logger: NavLogger) {
private var startLine = 0
diff --git a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/java/JavaTypes.kt b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/java/JavaTypes.kt
index fb886bb..0ec5e48 100644
--- a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/java/JavaTypes.kt
+++ b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/java/JavaTypes.kt
@@ -35,13 +35,13 @@
import androidx.navigation.safe.args.generator.ObjectType
import androidx.navigation.safe.args.generator.ReferenceArrayType
import androidx.navigation.safe.args.generator.ReferenceType
+import androidx.navigation.safe.args.generator.ReferenceValue
import androidx.navigation.safe.args.generator.StringArrayType
import androidx.navigation.safe.args.generator.StringType
-import androidx.navigation.safe.args.generator.models.Argument
-import androidx.navigation.safe.args.generator.ReferenceValue
import androidx.navigation.safe.args.generator.StringValue
import androidx.navigation.safe.args.generator.WritableValue
import androidx.navigation.safe.args.generator.ext.toClassNameParts
+import androidx.navigation.safe.args.generator.models.Argument
import androidx.navigation.safe.args.generator.models.ResReference
import com.squareup.javapoet.ArrayTypeName
import com.squareup.javapoet.ClassName
diff --git a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinTypes.kt b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinTypes.kt
index 5a42e74..4a3a9dd 100644
--- a/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinTypes.kt
+++ b/navigation/navigation-safe-args-generator/src/main/kotlin/androidx/navigation/safe/args/generator/kotlin/KotlinTypes.kt
@@ -52,8 +52,8 @@
import com.squareup.kotlinpoet.INT
import com.squareup.kotlinpoet.LONG
import com.squareup.kotlinpoet.ParameterizedTypeName
-import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
+import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.asTypeName
import java.lang.UnsupportedOperationException
diff --git a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/JavaNavWriterTest.kt b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/JavaNavWriterTest.kt
index bcd9829..9723d49 100644
--- a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/JavaNavWriterTest.kt
+++ b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/JavaNavWriterTest.kt
@@ -29,13 +29,13 @@
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.TypeSpec
+import javax.tools.JavaFileObject
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import javax.tools.JavaFileObject
@RunWith(JUnit4::class)
class JavaNavWriterTest {
diff --git a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavArgumentResolverTest.kt b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavArgumentResolverTest.kt
index 915faaf..29c9fbf 100644
--- a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavArgumentResolverTest.kt
+++ b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavArgumentResolverTest.kt
@@ -16,19 +16,19 @@
package androidx.navigation.safe.args.generator
+import androidx.navigation.safe.args.generator.ext.capitalize
import androidx.navigation.safe.args.generator.models.Action
import androidx.navigation.safe.args.generator.models.Argument
import androidx.navigation.safe.args.generator.models.Destination
import androidx.navigation.safe.args.generator.models.ResReference
-import androidx.navigation.safe.args.generator.ext.capitalize
import com.squareup.javapoet.ClassName
+import java.util.Locale
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.Locale
@RunWith(JUnit4::class)
class NavArgumentResolverTest {
diff --git a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavGeneratorTest.kt b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavGeneratorTest.kt
index 7f29cd0..cb2cb9f 100644
--- a/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavGeneratorTest.kt
+++ b/navigation/navigation-safe-args-generator/src/test/kotlin/androidx/navigation/safe/args/generator/NavGeneratorTest.kt
@@ -20,6 +20,8 @@
import androidx.navigation.safe.args.generator.kotlin.KotlinCodeFile
import com.google.common.truth.Truth
import com.google.testing.compile.JavaSourcesSubject
+import java.io.File
+import java.lang.IllegalStateException
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Rule
@@ -27,8 +29,6 @@
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.io.File
-import java.lang.IllegalStateException
@RunWith(Parameterized::class)
class NavGeneratorTest(private val generateKotlin: Boolean) {
diff --git a/navigation/navigation-safe-args-gradle-plugin/build.gradle b/navigation/navigation-safe-args-gradle-plugin/build.gradle
index 1d740b2..08697dc 100644
--- a/navigation/navigation-safe-args-gradle-plugin/build.gradle
+++ b/navigation/navigation-safe-args-gradle-plugin/build.gradle
@@ -50,7 +50,7 @@
}
androidx {
- name = "Android Navigation TypeSafe Arguments Gradle Plugin"
+ name = "Navigation TypeSafe Arguments Gradle Plugin"
type = LibraryType.GRADLE_PLUGIN
inceptionYear = "2017"
description = "Android Navigation TypeSafe Arguments Gradle Plugin"
diff --git a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
index 279f78a..b08f9fd 100644
--- a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
+++ b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
@@ -20,6 +20,8 @@
import androidx.navigation.safe.args.generator.SafeArgsGenerator
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
+import java.io.File
+import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
@@ -36,8 +38,6 @@
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
-import java.io.File
-import javax.inject.Inject
private const val MAPPING_FILE = "file_mappings.json"
diff --git a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/SafeArgsPlugin.kt b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/SafeArgsPlugin.kt
index a50222b..47edf23 100644
--- a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/SafeArgsPlugin.kt
+++ b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/SafeArgsPlugin.kt
@@ -23,6 +23,9 @@
import com.android.build.gradle.AppExtension
import com.android.build.gradle.BaseExtension
import com.android.build.gradle.LibraryExtension
+import java.io.File
+import java.util.Locale
+import javax.inject.Inject
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
@@ -30,9 +33,6 @@
import org.gradle.api.provider.Provider
import org.gradle.api.provider.ProviderFactory
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
-import java.io.File
-import java.util.Locale
-import javax.inject.Inject
private const val PLUGIN_DIRNAME = "navigation-args"
internal const val GENERATED_PATH = "generated/source/$PLUGIN_DIRNAME"
diff --git a/navigation/navigation-safe-args-gradle-plugin/src/test/kotlin/androidx/navigation/safeargs/gradle/BasePluginTest.kt b/navigation/navigation-safe-args-gradle-plugin/src/test/kotlin/androidx/navigation/safeargs/gradle/BasePluginTest.kt
index c3e20c9..5f0e351 100644
--- a/navigation/navigation-safe-args-gradle-plugin/src/test/kotlin/androidx/navigation/safeargs/gradle/BasePluginTest.kt
+++ b/navigation/navigation-safe-args-gradle-plugin/src/test/kotlin/androidx/navigation/safeargs/gradle/BasePluginTest.kt
@@ -17,13 +17,13 @@
package androidx.navigation.safeargs.gradle
import androidx.testutils.gradle.ProjectSetupRule
+import java.io.File
import org.gradle.testkit.runner.BuildResult
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Rule
-import java.io.File
internal const val MAIN_DIR = "androidx/navigation/testapp"
diff --git a/navigation/navigation-testing/build.gradle b/navigation/navigation-testing/build.gradle
index d30a3fc..4008f8e 100644
--- a/navigation/navigation-testing/build.gradle
+++ b/navigation/navigation-testing/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android Navigation Testing"
+ name = "Navigation Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Navigation-Testing"
diff --git a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
index 76aa369..3d9ca21 100644
--- a/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
+++ b/navigation/navigation-testing/src/androidTest/java/androidx/navigation/testing/TestNavHostControllerTest.kt
@@ -17,7 +17,6 @@
package androidx.navigation.testing
import android.os.Bundle
-import androidx.test.annotation.UiThreadTest
import androidx.navigation.ActivityNavigator
import androidx.navigation.NavOptions
import androidx.navigation.Navigator
@@ -25,6 +24,7 @@
import androidx.navigation.createGraph
import androidx.navigation.plusAssign
import androidx.navigation.testing.test.R
+import androidx.test.annotation.UiThreadTest
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.truth.os.BundleSubject.assertThat
diff --git a/navigation/navigation-ui-ktx/build.gradle b/navigation/navigation-ui-ktx/build.gradle
index 3cbe68b..23f6129 100644
--- a/navigation/navigation-ui-ktx/build.gradle
+++ b/navigation/navigation-ui-ktx/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "Android Navigation UI Kotlin Extensions"
+ name = "Navigation UI Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Navigation-UI-Ktx"
diff --git a/navigation/navigation-ui-ktx/src/main/AndroidManifest.xml b/navigation/navigation-ui-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index fdfdce5..0000000
--- a/navigation/navigation-ui-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/navigation/navigation-ui/build.gradle b/navigation/navigation-ui/build.gradle
index 5dd6cca..4877297 100644
--- a/navigation/navigation-ui/build.gradle
+++ b/navigation/navigation-ui/build.gradle
@@ -55,7 +55,7 @@
}
androidx {
- name = "Android Navigation UI"
+ name = "Navigation UI"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Navigation-UI"
diff --git a/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt b/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
index a615eb5..2a9c625 100644
--- a/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
+++ b/paging/integration-tests/testapp/src/androidTest/kotlin/androidx/paging/integration/testapp/v3/OnPagesUpdatedTest.kt
@@ -22,6 +22,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.assertTrue
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -36,11 +38,10 @@
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.test.assertTrue
@LargeTest
@RunWith(AndroidJUnit4::class)
@@ -50,6 +51,7 @@
@OptIn(ExperimentalCoroutinesApi::class)
@Test
+ @Ignore("b/278918559")
fun onPagesUpdatedFlow() = runBlocking {
val scenario = scenarioRule.scenario
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
index a107d6e..cbefb66 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/ItemDataSource.kt
@@ -20,8 +20,8 @@
import androidx.annotation.ColorInt
import androidx.paging.PagingSource
import androidx.paging.PagingState
-import kotlinx.coroutines.delay
import java.util.concurrent.atomic.AtomicBoolean
+import kotlinx.coroutines.delay
val dataSourceError = AtomicBoolean(false)
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/ItemPagingSource.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/ItemPagingSource.kt
index e7f4e4a..fd4b1bf 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/ItemPagingSource.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/ItemPagingSource.kt
@@ -20,8 +20,8 @@
import androidx.annotation.ColorInt
import androidx.paging.PagingSource
import androidx.paging.PagingState
-import kotlinx.coroutines.delay
import java.util.concurrent.atomic.AtomicBoolean
+import kotlinx.coroutines.delay
val dataSourceError = AtomicBoolean(false)
diff --git a/paging/paging-common-ktx/build.gradle b/paging/paging-common-ktx/build.gradle
index bab41ca..f5a7a7e 100644
--- a/paging/paging-common-ktx/build.gradle
+++ b/paging/paging-common-ktx/build.gradle
@@ -26,7 +26,7 @@
}
androidx {
- name = "Android Paging-Common Kotlin Extensions"
+ name = "Paging-Common Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for 'paging-common' artifact"
diff --git a/paging/paging-common/api/current.txt b/paging/paging-common/api/current.txt
index 10ec13b..2070710 100644
--- a/paging/paging-common/api/current.txt
+++ b/paging/paging-common/api/current.txt
@@ -46,7 +46,7 @@
method @AnyThread public void onInvalidated();
}
- public final class InvalidatingPagingSourceFactory<Key, Value> implements kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ public final class InvalidatingPagingSourceFactory<Key, Value> implements androidx.paging.PagingSourceFactory<Key,Value> {
ctor public InvalidatingPagingSourceFactory(kotlin.jvm.functions.Function0<? extends androidx.paging.PagingSource<Key,Value>> pagingSourceFactory);
method public void invalidate();
method public androidx.paging.PagingSource<Key,Value> invoke();
@@ -411,6 +411,10 @@
public static final class PagingSource.LoadResult.Page.Companion {
}
+ public fun interface PagingSourceFactory<Key, Value> extends kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ method public operator androidx.paging.PagingSource<Key,Value> invoke();
+ }
+
public final class PagingState<Key, Value> {
ctor public PagingState(java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>> pages, Integer? anchorPosition, androidx.paging.PagingConfig config, @IntRange(from=0L) int leadingPlaceholderCount);
method public Value? closestItemToPosition(int anchorPosition);
diff --git a/paging/paging-common/api/public_plus_experimental_current.txt b/paging/paging-common/api/public_plus_experimental_current.txt
index 07e6471..a5d3d01 100644
--- a/paging/paging-common/api/public_plus_experimental_current.txt
+++ b/paging/paging-common/api/public_plus_experimental_current.txt
@@ -49,7 +49,7 @@
@kotlin.RequiresOptIn @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalPagingApi {
}
- public final class InvalidatingPagingSourceFactory<Key, Value> implements kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ public final class InvalidatingPagingSourceFactory<Key, Value> implements androidx.paging.PagingSourceFactory<Key,Value> {
ctor public InvalidatingPagingSourceFactory(kotlin.jvm.functions.Function0<? extends androidx.paging.PagingSource<Key,Value>> pagingSourceFactory);
method public void invalidate();
method public androidx.paging.PagingSource<Key,Value> invoke();
@@ -415,6 +415,10 @@
public static final class PagingSource.LoadResult.Page.Companion {
}
+ public fun interface PagingSourceFactory<Key, Value> extends kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ method public operator androidx.paging.PagingSource<Key,Value> invoke();
+ }
+
public final class PagingState<Key, Value> {
ctor public PagingState(java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>> pages, Integer? anchorPosition, androidx.paging.PagingConfig config, @IntRange(from=0L) int leadingPlaceholderCount);
method public Value? closestItemToPosition(int anchorPosition);
diff --git a/paging/paging-common/api/restricted_current.txt b/paging/paging-common/api/restricted_current.txt
index 10ec13b..2070710 100644
--- a/paging/paging-common/api/restricted_current.txt
+++ b/paging/paging-common/api/restricted_current.txt
@@ -46,7 +46,7 @@
method @AnyThread public void onInvalidated();
}
- public final class InvalidatingPagingSourceFactory<Key, Value> implements kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ public final class InvalidatingPagingSourceFactory<Key, Value> implements androidx.paging.PagingSourceFactory<Key,Value> {
ctor public InvalidatingPagingSourceFactory(kotlin.jvm.functions.Function0<? extends androidx.paging.PagingSource<Key,Value>> pagingSourceFactory);
method public void invalidate();
method public androidx.paging.PagingSource<Key,Value> invoke();
@@ -411,6 +411,10 @@
public static final class PagingSource.LoadResult.Page.Companion {
}
+ public fun interface PagingSourceFactory<Key, Value> extends kotlin.jvm.functions.Function0<androidx.paging.PagingSource<Key,Value>> {
+ method public operator androidx.paging.PagingSource<Key,Value> invoke();
+ }
+
public final class PagingState<Key, Value> {
ctor public PagingState(java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>> pages, Integer? anchorPosition, androidx.paging.PagingConfig config, @IntRange(from=0L) int leadingPlaceholderCount);
method public Value? closestItemToPosition(int anchorPosition);
diff --git a/paging/paging-common/build.gradle b/paging/paging-common/build.gradle
index 00ad658..bbc62bf 100644
--- a/paging/paging-common/build.gradle
+++ b/paging/paging-common/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Paging-Common"
+ name = "Paging-Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Paging-Common"
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/FlowExt.kt b/paging/paging-common/src/main/kotlin/androidx/paging/FlowExt.kt
index 9cd5e14..d6b55b8 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/FlowExt.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/FlowExt.kt
@@ -22,6 +22,7 @@
import androidx.paging.CombineSource.INITIAL
import androidx.paging.CombineSource.OTHER
import androidx.paging.CombineSource.RECEIVER
+import java.util.concurrent.atomic.AtomicInteger
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.SendChannel
@@ -35,7 +36,6 @@
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.yield
-import java.util.concurrent.atomic.AtomicInteger
/**
* This File includes custom flow operators that we implement to avoid using experimental APIs
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/HintHandler.kt b/paging/paging-common/src/main/kotlin/androidx/paging/HintHandler.kt
index cefabc2..8c81e2e 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/HintHandler.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/HintHandler.kt
@@ -21,11 +21,11 @@
import androidx.annotation.RestrictTo
import androidx.paging.LoadType.APPEND
import androidx.paging.LoadType.PREPEND
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
/**
* Helper class to handle UI hints.
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/InvalidatingPagingSourceFactory.kt b/paging/paging-common/src/main/kotlin/androidx/paging/InvalidatingPagingSourceFactory.kt
index 93ddb2d..3f74d54 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/InvalidatingPagingSourceFactory.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/InvalidatingPagingSourceFactory.kt
@@ -32,7 +32,7 @@
*/
public class InvalidatingPagingSourceFactory<Key : Any, Value : Any>(
private val pagingSourceFactory: () -> PagingSource<Key, Value>
-) : () -> PagingSource<Key, Value> {
+) : PagingSourceFactory<Key, Value> {
@VisibleForTesting
internal val pagingSources = CopyOnWriteArrayList<PagingSource<Key, Value>>()
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/ItemKeyedDataSource.kt b/paging/paging-common/src/main/kotlin/androidx/paging/ItemKeyedDataSource.kt
index 68a85be..8aeb85a 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/ItemKeyedDataSource.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/ItemKeyedDataSource.kt
@@ -19,9 +19,9 @@
import androidx.annotation.VisibleForTesting
import androidx.arch.core.util.Function
import androidx.paging.DataSource.KeyType.ITEM_KEYED
+import kotlin.coroutines.resume
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
-import kotlin.coroutines.resume
/**
* Incremental data loader for paging keyed content, where loaded content uses previously loaded
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPageFetcher.kt b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPageFetcher.kt
index 868af5e..d923015 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPageFetcher.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/LegacyPageFetcher.kt
@@ -19,10 +19,10 @@
import androidx.paging.LoadState.Loading
import androidx.paging.LoadState.NotLoading
import androidx.paging.PagingSource.LoadParams
+import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
-import java.util.concurrent.atomic.AtomicBoolean
internal class LegacyPageFetcher<K : Any, V : Any>(
private val pagedListScope: CoroutineScope,
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/MutableCombinedLoadStateCollection.kt b/paging/paging-common/src/main/kotlin/androidx/paging/MutableCombinedLoadStateCollection.kt
index 964433b..0b12735 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/MutableCombinedLoadStateCollection.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/MutableCombinedLoadStateCollection.kt
@@ -19,8 +19,8 @@
import androidx.paging.LoadState.Error
import androidx.paging.LoadState.Loading
import androidx.paging.LoadState.NotLoading
-import kotlinx.coroutines.flow.MutableStateFlow
import java.util.concurrent.CopyOnWriteArrayList
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PageFetcherSnapshotState.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PageFetcherSnapshotState.kt
index 209142b..e72df74 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PageFetcherSnapshotState.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PageFetcherSnapshotState.kt
@@ -17,8 +17,8 @@
package androidx.paging
import androidx.annotation.CheckResult
-import androidx.paging.LoadState.NotLoading
import androidx.paging.LoadState.Loading
+import androidx.paging.LoadState.NotLoading
import androidx.paging.LoadType.APPEND
import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.REFRESH
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PageKeyedDataSource.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PageKeyedDataSource.kt
index e3d0fd8..5c98360 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PageKeyedDataSource.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PageKeyedDataSource.kt
@@ -18,9 +18,9 @@
import androidx.arch.core.util.Function
import androidx.paging.DataSource.KeyType.PAGE_KEYED
+import kotlin.coroutines.resume
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
-import kotlin.coroutines.resume
/**
* Incremental data loader for page-keyed content, where requests return keys for next/previous
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
index ac60b3d..23f7ebe 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PagedList.kt
@@ -19,6 +19,9 @@
import androidx.annotation.IntRange
import androidx.annotation.MainThread
import androidx.annotation.RestrictTo
+import java.lang.ref.WeakReference
+import java.util.AbstractList
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -27,9 +30,6 @@
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import java.lang.ref.WeakReference
-import java.util.AbstractList
-import java.util.concurrent.Executor
/**
* Lazy loading list that pages in immutable content from a [PagingSource].
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PagingDataTransforms.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PagingDataTransforms.kt
index 9fcf71a..0a31f4e 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PagingDataTransforms.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PagingDataTransforms.kt
@@ -20,10 +20,10 @@
import androidx.annotation.CheckResult
import androidx.paging.TerminalSeparatorType.FULLY_COMPLETE
+import java.util.concurrent.Executor
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
-import java.util.concurrent.Executor
private inline fun <T : Any, R : Any> PagingData<T>.transform(
crossinline transform: suspend (PageEvent<T>) -> PageEvent<R>
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PagingSourceFactory.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PagingSourceFactory.kt
new file mode 100644
index 0000000..4ed3c7f
--- /dev/null
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PagingSourceFactory.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.paging
+
+/**
+ * Interface for a factory that generates [PagingSource].
+ *
+ * The factory extending this interface can be used to instantiate a [Pager] as the
+ * pagingSourceFactory.
+ */
+public fun interface PagingSourceFactory<Key : Any, Value : Any> : () -> PagingSource<Key, Value> {
+ /**
+ * Returns a new PagingSource instance.
+ *
+ * This function can be invoked by calling pagingSourceFactory() or pagingSourceFactory::invoke.
+ */
+ public override operator fun invoke(): PagingSource<Key, Value>
+}
\ No newline at end of file
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/PositionalDataSource.kt b/paging/paging-common/src/main/kotlin/androidx/paging/PositionalDataSource.kt
index 1b84ad3..134a223 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/PositionalDataSource.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/PositionalDataSource.kt
@@ -22,8 +22,8 @@
import androidx.arch.core.util.Function
import androidx.paging.DataSource.KeyType.POSITIONAL
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
-import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Position-based data loader for a fixed-size, countable data set, supporting fixed-size loads at
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/RemoteMediatorAccessor.kt b/paging/paging-common/src/main/kotlin/androidx/paging/RemoteMediatorAccessor.kt
index 358f194..17b923c 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/RemoteMediatorAccessor.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/RemoteMediatorAccessor.kt
@@ -20,12 +20,12 @@
import androidx.paging.AccessorState.BlockState.REQUIRES_REFRESH
import androidx.paging.AccessorState.BlockState.UNBLOCKED
import androidx.paging.RemoteMediator.MediatorResult
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
/**
* Interface provided to the snapshot to trigger load events.
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/SimpleChannelFlow.kt b/paging/paging-common/src/main/kotlin/androidx/paging/SimpleChannelFlow.kt
index 75ab293..1c8ae24 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/SimpleChannelFlow.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/SimpleChannelFlow.kt
@@ -19,6 +19,7 @@
package androidx.paging
import androidx.annotation.RestrictTo
+import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
@@ -30,7 +31,6 @@
import kotlinx.coroutines.flow.internal.FusibleFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
-import kotlin.coroutines.resume
/**
* This is a simplified channelFlow implementation as a temporary measure until channel flow
diff --git a/paging/paging-common/src/main/kotlin/androidx/paging/multicast/StoreRealActor.kt b/paging/paging-common/src/main/kotlin/androidx/paging/multicast/StoreRealActor.kt
index 74c7fc1..60c962a 100644
--- a/paging/paging-common/src/main/kotlin/androidx/paging/multicast/StoreRealActor.kt
+++ b/paging/paging-common/src/main/kotlin/androidx/paging/multicast/StoreRealActor.kt
@@ -15,6 +15,7 @@
*/
package androidx.paging.multicast
+import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
@@ -22,7 +23,6 @@
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
-import java.util.concurrent.atomic.AtomicBoolean
/**
* Simple actor implementation abstracting away Coroutine.actor since it is deprecated.
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt
index 1948415..cffc528 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowLeakTest.kt
@@ -16,6 +16,9 @@
package androidx.paging
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.Ignore
+import kotlin.test.Test
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
@@ -25,11 +28,8 @@
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import org.junit.Ignore
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.coroutines.EmptyCoroutineContext
/**
* reproduces b/203594733
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowTest.kt
index 77e0ce1..1f3cda9 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/CachedPageEventFlowTest.kt
@@ -17,6 +17,7 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
@@ -32,7 +33,6 @@
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/CachingTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/CachingTest.kt
index 5eb154c..977255e 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/CachingTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/CachingTest.kt
@@ -19,6 +19,8 @@
import androidx.paging.ActiveFlowTracker.FlowType.PAGED_DATA_FLOW
import androidx.paging.ActiveFlowTracker.FlowType.PAGE_EVENT_FLOW
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicInteger
+import kotlin.test.Test
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -36,15 +38,13 @@
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.yield
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import java.util.concurrent.atomic.AtomicInteger
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.yield
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/ConflatedEventBusTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/ConflatedEventBusTest.kt
index c5bde13..174df10 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/ConflatedEventBusTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/ConflatedEventBusTest.kt
@@ -17,12 +17,12 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
-import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class)
class ConflatedEventBusTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
index 1a4637b..79c02d1 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/ContiguousPagedListTest.kt
@@ -29,18 +29,18 @@
import androidx.paging.PagedList.Config
import androidx.paging.PagingSource.LoadResult.Page
import androidx.testutils.TestDispatcher
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertSame
+import kotlin.test.assertTrue
+import kotlinx.coroutines.runBlocking
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
import org.mockito.kotlin.mock
import org.mockito.kotlin.reset
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
-import kotlinx.coroutines.runBlocking
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertSame
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import kotlin.test.assertFailsWith
-import kotlin.test.assertTrue
@RunWith(Parameterized::class)
class ContiguousPagedListTest(private val placeholdersEnabled: Boolean) {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/DataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/DataSourceTest.kt
index bd2a9fb..b5635bb 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/DataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/DataSourceTest.kt
@@ -17,7 +17,7 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
+import kotlin.test.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/FailDispatcher.kt b/paging/paging-common/src/test/kotlin/androidx/paging/FailDispatcher.kt
index 9e41203..0642f31 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/FailDispatcher.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/FailDispatcher.kt
@@ -16,10 +16,10 @@
package androidx.paging
+import kotlin.coroutines.CoroutineContext
+import kotlin.test.fail
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Runnable
-import org.junit.Assert.fail
-import kotlin.coroutines.CoroutineContext
class FailDispatcher(
val string: String = "Executor expected to be unused"
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/FlattenedPageEventStorageTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/FlattenedPageEventStorageTest.kt
index 35cf04d..44bd3bb 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/FlattenedPageEventStorageTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/FlattenedPageEventStorageTest.kt
@@ -25,7 +25,7 @@
import androidx.paging.PageEvent.Drop
import androidx.paging.PageEvent.StaticList
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
+import kotlin.test.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/FlowExtTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/FlowExtTest.kt
index 5073e746..b298a75 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/FlowExtTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/FlowExtTest.kt
@@ -20,6 +20,8 @@
import androidx.paging.CombineSource.OTHER
import androidx.paging.CombineSource.RECEIVER
import com.google.common.truth.Truth.assertThat
+import kotlin.random.Random
+import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.BUFFERED
@@ -38,8 +40,6 @@
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
-import org.junit.Test
-import kotlin.random.Random
@OptIn(ExperimentalCoroutinesApi::class)
class FlowExtTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/HeaderFooterTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/HeaderFooterTest.kt
index 4af5089..44e227c 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/HeaderFooterTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/HeaderFooterTest.kt
@@ -18,15 +18,15 @@
import androidx.paging.LoadState.NotLoading
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.single
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
/**
* Prepend and append are both Done, so that headers will appear
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/HintHandlerTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/HintHandlerTest.kt
index 6ab268b..16bc08f 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/HintHandlerTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/HintHandlerTest.kt
@@ -20,6 +20,7 @@
import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.REFRESH
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
@@ -30,7 +31,6 @@
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/InvalidatingPagingSourceFactoryTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/InvalidatingPagingSourceFactoryTest.kt
index a3b431a..28b9cb4 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/InvalidatingPagingSourceFactoryTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/InvalidatingPagingSourceFactoryTest.kt
@@ -16,7 +16,7 @@
package androidx.paging
-import org.junit.Test
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
index dc2c9fb..786c4c6 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/ItemKeyedDataSourceTest.kt
@@ -17,21 +17,21 @@
package androidx.paging
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
-import org.mockito.kotlin.capture
-import org.mockito.kotlin.mock
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
+import kotlin.test.fail
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import kotlin.random.Random
-import kotlin.test.assertFailsWith
+import org.mockito.kotlin.capture
+import org.mockito.kotlin.mock
@Suppress("DEPRECATION")
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/ItemSnapshotListTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/ItemSnapshotListTest.kt
index 7b6d6f9..4688ad0 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/ItemSnapshotListTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/ItemSnapshotListTest.kt
@@ -16,7 +16,7 @@
package androidx.paging
-import org.junit.Test
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPageFetcherTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPageFetcherTest.kt
index 78598f9..536e5d4 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPageFetcherTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPageFetcherTest.kt
@@ -28,14 +28,14 @@
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingSource.LoadResult.Page
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.StandardTestDispatcher
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
index 1ffe862..6123476 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/LegacyPagingSourceTest.kt
@@ -18,8 +18,15 @@
import androidx.paging.PagingSource.LoadResult.Page
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executors
import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import kotlin.test.fail
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filter
@@ -27,15 +34,8 @@
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.StandardTestDispatcher
-import org.junit.Assert
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.Executors
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
@@ -93,21 +93,21 @@
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<String>
) {
- Assert.fail("loadInitial not expected")
+ fail("loadInitial not expected")
}
override fun loadAfter(
params: LoadParams<Int>,
callback: LoadCallback<String>
) {
- Assert.fail("loadAfter not expected")
+ fail("loadAfter not expected")
}
override fun loadBefore(
params: LoadParams<Int>,
callback: LoadCallback<String>
) {
- Assert.fail("loadBefore not expected")
+ fail("loadBefore not expected")
}
override fun getKey(item: String) = item.hashCode()
@@ -141,21 +141,21 @@
params: LoadInitialParams<Int>,
callback: LoadInitialCallback<Int, String>
) {
- Assert.fail("loadInitial not expected")
+ fail("loadInitial not expected")
}
override fun loadBefore(
params: LoadParams<Int>,
callback: LoadCallback<Int, String>
) {
- Assert.fail("loadBefore not expected")
+ fail("loadBefore not expected")
}
override fun loadAfter(
params: LoadParams<Int>,
callback: LoadCallback<Int, String>
) {
- Assert.fail("loadAfter not expected")
+ fail("loadAfter not expected")
}
}
val pagingSource = LegacyPagingSource(
@@ -391,14 +391,14 @@
callback: LoadInitialCallback<String>
) {
if (!expectInitialLoad) {
- Assert.fail("loadInitial not expected")
+ fail("loadInitial not expected")
} else {
callback.onResult(listOf(), 0)
}
}
override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback<String>) {
- Assert.fail("loadRange not expected")
+ fail("loadRange not expected")
}
}
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
index 20a1116..414824a 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageEventTest.kt
@@ -20,17 +20,17 @@
import androidx.paging.LoadType.REFRESH
import androidx.paging.PageEvent.Drop
import kotlin.coroutines.EmptyCoroutineContext
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.junit.runners.Parameterized
+import kotlin.test.BeforeTest
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertSame
-import org.junit.Before
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.runners.Parameterized
internal fun <T : Any> adjacentInsertEvent(
isPrepend: Boolean,
@@ -293,7 +293,7 @@
private val differ = TestPagingDataDiffer<String>(EmptyCoroutineContext)
private lateinit var pagingData: PagingData<String>
- @Before
+ @BeforeTest
fun init() {
pagingData = if (data.isNotEmpty()) {
PagingData.from(data)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotStateTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotStateTest.kt
index 5006894..ffd9a01 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotStateTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotStateTest.kt
@@ -24,13 +24,13 @@
import androidx.paging.PagingSource.LoadResult.Page
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt
index 62ffbb6..f02de71 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherSnapshotTest.kt
@@ -29,6 +29,7 @@
import androidx.paging.RemoteMediatorMock.LoadEvent
import androidx.paging.TestPagingSource.Companion.LOAD_ERROR
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
@@ -66,7 +67,6 @@
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext
import kotlinx.coroutines.yield
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherTest.kt
index 1a3a4c4..5f75646 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageFetcherTest.kt
@@ -26,6 +26,7 @@
import androidx.paging.RemoteMediator.InitializeAction.LAUNCH_INITIAL_REFRESH
import androidx.paging.RemoteMediator.InitializeAction.SKIP_INITIAL_REFRESH
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotEquals
@@ -51,7 +52,6 @@
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
index 6f89ef0..9c044ef 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PageKeyedDataSourceTest.kt
@@ -16,23 +16,23 @@
package androidx.paging
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import kotlin.test.fail
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.test.assertFailsWith
-import kotlinx.coroutines.test.StandardTestDispatcher
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagePresenterTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagePresenterTest.kt
index e979bcc..13d0b94 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagePresenterTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagePresenterTest.kt
@@ -22,12 +22,12 @@
import androidx.paging.PagePresenter.ProcessPageEventCallback
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.fail
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@Suppress("TestFunctionName")
internal fun <T : Any> PagePresenter(
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
index ad107b9..c830172 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
@@ -16,8 +16,8 @@
package androidx.paging
-import org.junit.Assert
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertEquals
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -29,12 +29,12 @@
val config = PagedList.Config.Builder()
.setPageSize(10)
.build()
- Assert.assertEquals(10, config.pageSize)
- Assert.assertEquals(30, config.initialLoadSizeHint)
- Assert.assertEquals(true, config.enablePlaceholders)
- Assert.assertEquals(10, config.prefetchDistance)
+ assertEquals(10, config.pageSize)
+ assertEquals(30, config.initialLoadSizeHint)
+ assertEquals(true, config.enablePlaceholders)
+ assertEquals(10, config.prefetchDistance)
@Suppress("DEPRECATION")
- Assert.assertEquals(PagedList.Config.MAX_SIZE_UNBOUNDED, config.maxSize)
+ assertEquals(PagedList.Config.MAX_SIZE_UNBOUNDED, config.maxSize)
}
@Test(expected = IllegalArgumentException::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigTest.kt
index 6746965..c34f7bf 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListConfigTest.kt
@@ -16,8 +16,8 @@
package androidx.paging
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertEquals
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListTest.kt
index 3d7479b..b053726 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagedListTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagedListTest.kt
@@ -21,19 +21,19 @@
import androidx.testutils.TestDispatcher
import androidx.testutils.TestExecutor
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import java.util.concurrent.Executor
import kotlin.concurrent.thread
import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
import kotlin.test.fail
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class PagedListTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagedStorageTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagedStorageTest.kt
index 88d8315..5bc9b07 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagedStorageTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagedStorageTest.kt
@@ -17,17 +17,17 @@
package androidx.paging
import androidx.paging.PagingSource.LoadResult.Page
-import org.junit.Assert.assertArrayEquals
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertFalse
-import org.junit.Assert.assertTrue
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertContentEquals
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import kotlin.test.assertNotNull
@RunWith(JUnit4::class)
class PagedStorageTest {
@@ -41,7 +41,7 @@
fun construct() {
val storage = PagedStorage(2, pageOf("a", "b"), 2)
- assertArrayEquals(arrayOf(null, null, "a", "b", null, null), storage.toArray())
+ assertContentEquals(arrayOf(null, null, "a", "b", null, null), storage.toArray())
assertEquals(6, storage.size)
}
@@ -52,7 +52,7 @@
val storage = PagedStorage(2, pageOf("a", "b"), 2)
storage.appendPage(pageOf("c", "d"), callback)
- assertArrayEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
+ assertContentEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
verify(callback).onPageAppended(4, 2, 0)
verifyNoMoreInteractions(callback)
}
@@ -64,7 +64,7 @@
val storage = PagedStorage(2, pageOf("a", "b"), 0)
storage.appendPage(pageOf("c", "d"), callback)
- assertArrayEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
+ assertContentEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
verify(callback).onPageAppended(4, 0, 2)
verifyNoMoreInteractions(callback)
}
@@ -78,14 +78,14 @@
// change 2 nulls into c, d
storage.appendPage(pageOf("c", "d"), callback)
- assertArrayEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
+ assertContentEquals(arrayOf(null, null, "a", "b", "c", "d"), storage.toArray())
verify(callback).onPageAppended(4, 2, 0)
verifyNoMoreInteractions(callback)
// append e, f
storage.appendPage(pageOf("e", "f"), callback)
- assertArrayEquals(arrayOf(null, null, "a", "b", "c", "d", "e", "f"), storage.toArray())
+ assertContentEquals(arrayOf(null, null, "a", "b", "c", "d", "e", "f"), storage.toArray())
verify(callback).onPageAppended(6, 0, 2)
verifyNoMoreInteractions(callback)
}
@@ -97,7 +97,7 @@
val storage = PagedStorage(2, pageOf("c", "d"), 2)
storage.prependPage(pageOf("a", "b"), callback)
- assertArrayEquals(arrayOf("a", "b", "c", "d", null, null), storage.toArray())
+ assertContentEquals(arrayOf("a", "b", "c", "d", null, null), storage.toArray())
verify(callback).onPagePrepended(0, 2, 0)
verifyNoMoreInteractions(callback)
}
@@ -109,7 +109,7 @@
val storage = PagedStorage(0, pageOf("c", "d"), 2)
storage.prependPage(pageOf("a", "b"), callback)
- assertArrayEquals(arrayOf("a", "b", "c", "d", null, null), storage.toArray())
+ assertContentEquals(arrayOf("a", "b", "c", "d", null, null), storage.toArray())
verify(callback).onPagePrepended(0, 0, 2)
verifyNoMoreInteractions(callback)
}
@@ -123,14 +123,14 @@
// change 2 nulls into c, d
storage.prependPage(pageOf("c", "d"), callback)
- assertArrayEquals(arrayOf("c", "d", "e", "f", null, null), storage.toArray())
+ assertContentEquals(arrayOf("c", "d", "e", "f", null, null), storage.toArray())
verify(callback).onPagePrepended(0, 2, 0)
verifyNoMoreInteractions(callback)
// prepend a, b
storage.prependPage(pageOf("a", "b"), callback)
- assertArrayEquals(arrayOf("a", "b", "c", "d", "e", "f", null, null), storage.toArray())
+ assertContentEquals(arrayOf("a", "b", "c", "d", "e", "f", null, null), storage.toArray())
verify(callback).onPagePrepended(0, 0, 2)
verifyNoMoreInteractions(callback)
}
@@ -141,7 +141,7 @@
val storage = PagedStorage(1, pageOf("a"), 6)
storage.appendPage(pageOf("b", "c"), callback)
storage.appendPage(pageOf("d", "e", "f"), callback)
- assertArrayEquals(arrayOf(null, "a", "b", "c", "d", "e", "f", null), storage.toArray())
+ assertContentEquals(arrayOf(null, "a", "b", "c", "d", "e", "f", null), storage.toArray())
}
@Test
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingConfigTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingConfigTest.kt
index fa70f64..e8eb9179 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingConfigTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingConfigTest.kt
@@ -17,11 +17,11 @@
package androidx.paging
import androidx.paging.PagingConfig.Companion.MAX_SIZE_UNBOUNDED
-import org.junit.Assert.assertEquals
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
class PagingConfigTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
index 893b89c..1ee318c 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingDataDifferTest.kt
@@ -24,6 +24,7 @@
import androidx.testutils.MainDispatcherRule
import com.google.common.truth.Truth.assertThat
import kotlin.coroutines.ContinuationInterceptor
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
@@ -56,7 +57,6 @@
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext
import org.junit.Rule
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingSourceTest.kt
index bf9b097..7effb00 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingSourceTest.kt
@@ -20,14 +20,14 @@
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
import com.google.common.truth.Truth.assertThat
+import kotlin.random.Random
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
import kotlinx.coroutines.runBlocking
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.random.Random
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
class PagingSourceTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PagingStateTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PagingStateTest.kt
index 23a69fc..c2a4bff 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PagingStateTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PagingStateTest.kt
@@ -17,12 +17,12 @@
package androidx.paging
import androidx.paging.PagingSource.LoadResult.Page
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class PagingStateTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/PositionalDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/PositionalDataSourceTest.kt
index 3c428c1..036e255 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/PositionalDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/PositionalDataSourceTest.kt
@@ -16,21 +16,21 @@
package androidx.paging
+import java.util.concurrent.Executor
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Assert.fail
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import java.util.concurrent.Executor
@Suppress("DEPRECATION")
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/RemoteMediatorAccessorTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/RemoteMediatorAccessorTest.kt
index c59ebc0..5e27e87 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/RemoteMediatorAccessorTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/RemoteMediatorAccessorTest.kt
@@ -25,22 +25,22 @@
import androidx.paging.RemoteMediatorMock.LoadEvent
import androidx.paging.TestPagingSource.Companion.LOAD_ERROR
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.atomic.AtomicBoolean
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runCurrent
-import org.junit.Test
+import kotlinx.coroutines.test.runTest
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.atomic.AtomicBoolean
-import kotlin.test.assertEquals
-import kotlin.test.fail
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsTest.kt
index 88e807e..bff6c35 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsTest.kt
@@ -16,22 +16,22 @@
package androidx.paging
-import androidx.paging.LoadState.NotLoading
import androidx.paging.LoadState.Loading
+import androidx.paging.LoadState.NotLoading
import androidx.paging.LoadType.APPEND
import androidx.paging.LoadType.PREPEND
import androidx.paging.PageEvent.Drop
import androidx.paging.TerminalSeparatorType.FULLY_COMPLETE
import androidx.paging.TerminalSeparatorType.SOURCE_COMPLETE
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
private fun <T : Any> List<PageEvent<T>>.getItems() = mapNotNull { event ->
when (event) {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsWithRemoteMediatorTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsWithRemoteMediatorTest.kt
index ec78e09..15c3097 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsWithRemoteMediatorTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/SeparatorsWithRemoteMediatorTest.kt
@@ -21,14 +21,14 @@
import androidx.paging.TerminalSeparatorType.FULLY_COMPLETE
import androidx.paging.TerminalSeparatorType.SOURCE_COMPLETE
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertFailsWith
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/SimpleChannelFlowTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/SimpleChannelFlowTest.kt
index 237e540..4971df3 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/SimpleChannelFlowTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/SimpleChannelFlowTest.kt
@@ -17,9 +17,12 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlin.test.fail
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.channels.ProducerScope
@@ -35,15 +38,12 @@
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch
-import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.test.fail
@RunWith(Parameterized::class)
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/SimpleTransformLatestTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/SimpleTransformLatestTest.kt
index 7cc311e..624b8c4 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/SimpleTransformLatestTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/SimpleTransformLatestTest.kt
@@ -17,6 +17,7 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.delay
@@ -28,7 +29,6 @@
import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/SingleRunnerTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/SingleRunnerTest.kt
index 9e80ac8..1e29a83c 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/SingleRunnerTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/SingleRunnerTest.kt
@@ -17,6 +17,13 @@
package androidx.paging
import com.google.common.truth.Truth.assertThat
+import java.util.Collections
+import java.util.concurrent.CountDownLatch
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
+import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -32,15 +39,8 @@
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
-import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.Collections
-import java.util.concurrent.CountDownLatch
-import kotlin.test.assertEquals
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
-import kotlin.time.Duration.Companion.seconds
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedItemKeyedDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedItemKeyedDataSourceTest.kt
index f642d6c..e794949 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedItemKeyedDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedItemKeyedDataSourceTest.kt
@@ -16,10 +16,10 @@
package androidx.paging
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertTrue
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class WrappedItemKeyedDataSourceTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPageKeyedDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPageKeyedDataSourceTest.kt
index cf4ef24..4202070 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPageKeyedDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPageKeyedDataSourceTest.kt
@@ -16,10 +16,10 @@
package androidx.paging
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertTrue
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class WrappedPageKeyedDataSourceTest {
diff --git a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPositionalDataSourceTest.kt b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPositionalDataSourceTest.kt
index b56fe139..d3a54237 100644
--- a/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPositionalDataSourceTest.kt
+++ b/paging/paging-common/src/test/kotlin/androidx/paging/WrappedPositionalDataSourceTest.kt
@@ -16,10 +16,10 @@
package androidx.paging
-import org.junit.Test
+import kotlin.test.Test
+import kotlin.test.assertTrue
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
@RunWith(JUnit4::class)
class WrappedPositionalDataSourceTest {
diff --git a/paging/paging-compose/build.gradle b/paging/paging-compose/build.gradle
index d31e914..8affe5a 100644
--- a/paging/paging-compose/build.gradle
+++ b/paging/paging-compose/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "Android Paging-Compose"
+ name = "Paging-Compose"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.PAGING_COMPOSE
inceptionYear = "2020"
diff --git a/paging/paging-compose/integration-tests/paging-demos/src/main/AndroidManifest.xml b/paging/paging-compose/integration-tests/paging-demos/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/paging/paging-compose/integration-tests/paging-demos/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/paging/paging-compose/integration-tests/paging-demos/src/main/java/androidx/paging/compose/demos/room/PagingRoomSample.kt b/paging/paging-compose/integration-tests/paging-demos/src/main/java/androidx/paging/compose/demos/room/PagingRoomSample.kt
index e16c7b7..868b4b3 100644
--- a/paging/paging-compose/integration-tests/paging-demos/src/main/java/androidx/paging/compose/demos/room/PagingRoomSample.kt
+++ b/paging/paging-compose/integration-tests/paging-demos/src/main/java/androidx/paging/compose/demos/room/PagingRoomSample.kt
@@ -23,7 +23,7 @@
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
@@ -35,9 +35,9 @@
import androidx.paging.PagingConfig
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.compose.itemKey
+import kotlin.random.Random
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
-import kotlin.random.Random
@Composable
fun PagingRoomDemo() {
@@ -118,7 +118,7 @@
key = lazyPagingItems.itemKey { user -> user.id },
) { index ->
val user = lazyPagingItems[index]
- var counter by rememberSaveable { mutableStateOf(0) }
+ var counter by rememberSaveable { mutableIntStateOf(0) }
Text(
text = "counter=$counter index=$index ${user?.name} ${user?.id}",
fontSize = 50.sp,
diff --git a/paging/paging-compose/samples/build.gradle b/paging/paging-compose/samples/build.gradle
index 6fd15b4..753063b 100644
--- a/paging/paging-compose/samples/build.gradle
+++ b/paging/paging-compose/samples/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Paging Compose Samples"
+ name = "Paging Compose Samples"
type = LibraryType.SAMPLES
mavenVersion = LibraryVersions.PAGING_COMPOSE
inceptionYear = "2020"
diff --git a/paging/paging-compose/samples/src/main/AndroidManifest.xml b/paging/paging-compose/samples/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/paging/paging-compose/samples/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/paging/paging-compose/src/androidTest/AndroidManifest.xml b/paging/paging-compose/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/paging/paging-compose/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt b/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt
index f3ae0ae..f112c3f 100644
--- a/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt
+++ b/paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsTest.kt
@@ -51,9 +51,9 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.isActive
import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
diff --git a/paging/paging-compose/src/main/AndroidManifest.xml b/paging/paging-compose/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/paging/paging-compose/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
index 5b28b9f..bb24cb0 100644
--- a/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
+++ b/paging/paging-compose/src/main/java/androidx/paging/compose/LazyFoundationExtensions.kt
@@ -16,8 +16,8 @@
package androidx.paging.compose
-import androidx.paging.PagingConfig
import androidx.compose.foundation.lazy.grid.LazyGridScope
+import androidx.paging.PagingConfig
/**
* Returns a factory of stable and unique keys representing the item.
diff --git a/paging/paging-guava/build.gradle b/paging/paging-guava/build.gradle
index 041702f..f0151c2 100644
--- a/paging/paging-guava/build.gradle
+++ b/paging/paging-guava/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "Android Paging Guava"
+ name = "Paging Guava"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android Paging Guava"
diff --git a/paging/paging-guava/src/main/java/androidx/paging/ListenableFuturePagingData.kt b/paging/paging-guava/src/main/java/androidx/paging/ListenableFuturePagingData.kt
index 9a0d0bd..4ce7253 100644
--- a/paging/paging-guava/src/main/java/androidx/paging/ListenableFuturePagingData.kt
+++ b/paging/paging-guava/src/main/java/androidx/paging/ListenableFuturePagingData.kt
@@ -20,10 +20,10 @@
import androidx.annotation.CheckResult
import com.google.common.util.concurrent.AsyncFunction
+import java.util.concurrent.Executor
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.guava.await
import kotlinx.coroutines.withContext
-import java.util.concurrent.Executor
/**
* Returns a [PagingData] containing the result of applying the given [transform] to each
diff --git a/paging/paging-guava/src/test/java/androidx/paging/ListenableFuturePagingSourceTest.kt b/paging/paging-guava/src/test/java/androidx/paging/ListenableFuturePagingSourceTest.kt
index 747310e..ae8a63a 100644
--- a/paging/paging-guava/src/test/java/androidx/paging/ListenableFuturePagingSourceTest.kt
+++ b/paging/paging-guava/src/test/java/androidx/paging/ListenableFuturePagingSourceTest.kt
@@ -20,12 +20,12 @@
import androidx.paging.PagingSource.LoadResult.Page
import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.SettableFuture
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
class ListenableFuturePagingSourceTest {
diff --git a/paging/paging-guava/src/test/java/androidx/paging/ListenableFutureRemoteMediatorTest.kt b/paging/paging-guava/src/test/java/androidx/paging/ListenableFutureRemoteMediatorTest.kt
index e062eb5..2bf2473 100644
--- a/paging/paging-guava/src/test/java/androidx/paging/ListenableFutureRemoteMediatorTest.kt
+++ b/paging/paging-guava/src/test/java/androidx/paging/ListenableFutureRemoteMediatorTest.kt
@@ -20,13 +20,13 @@
import androidx.paging.RemoteMediator.InitializeAction.SKIP_INITIAL_REFRESH
import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture
+import kotlin.test.assertEquals
+import kotlin.test.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.fail
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-runtime-ktx/build.gradle b/paging/paging-runtime-ktx/build.gradle
index 3f2e05d..f674b7e 100644
--- a/paging/paging-runtime-ktx/build.gradle
+++ b/paging/paging-runtime-ktx/build.gradle
@@ -29,7 +29,7 @@
}
androidx {
- name = "Android Paging-Runtime Kotlin Extensions"
+ name = "Paging-Runtime Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for 'paging-runtime' artifact"
diff --git a/paging/paging-runtime-ktx/src/main/AndroidManifest.xml b/paging/paging-runtime-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/paging/paging-runtime-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/paging/paging-runtime/build.gradle b/paging/paging-runtime/build.gradle
index 47fdac8..de64d71 100644
--- a/paging/paging-runtime/build.gradle
+++ b/paging/paging-runtime/build.gradle
@@ -61,7 +61,7 @@
}
androidx {
- name = "Android Paging-Runtime"
+ name = "Paging-Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Paging-Runtime"
diff --git a/paging/paging-runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt b/paging/paging-runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
index 65537a6..23de20f 100644
--- a/paging/paging-runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
+++ b/paging/paging-runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
@@ -31,6 +31,9 @@
import androidx.test.filters.SmallTest
import androidx.testutils.TestExecutor
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlin.test.assertFalse
+import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import org.junit.Assert.assertEquals
@@ -39,9 +42,6 @@
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.test.assertFalse
-import kotlin.test.assertTrue
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/paging/paging-runtime/src/androidTest/java/androidx/paging/LivePagedListTest.kt b/paging/paging-runtime/src/androidTest/java/androidx/paging/LivePagedListTest.kt
index 5affe1c..7d0442c 100644
--- a/paging/paging-runtime/src/androidTest/java/androidx/paging/LivePagedListTest.kt
+++ b/paging/paging-runtime/src/androidTest/java/androidx/paging/LivePagedListTest.kt
@@ -28,6 +28,8 @@
import androidx.test.filters.SmallTest
import androidx.testutils.TestDispatcher
import com.google.common.truth.Truth.assertThat
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
@@ -35,14 +37,12 @@
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.test.TestCoroutineScope
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Assert.assertNotNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertTrue
-import kotlinx.coroutines.test.advanceUntilIdle
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/paging/paging-runtime/src/androidTest/java/androidx/paging/LoadFullListTest.kt b/paging/paging-runtime/src/androidTest/java/androidx/paging/LoadFullListTest.kt
index 9c9c120..5bce270 100644
--- a/paging/paging-runtime/src/androidTest/java/androidx/paging/LoadFullListTest.kt
+++ b/paging/paging-runtime/src/androidTest/java/androidx/paging/LoadFullListTest.kt
@@ -20,6 +20,7 @@
import androidx.test.filters.MediumTest
import androidx.testutils.MainDispatcherRule
import com.google.common.truth.Truth.assertThat
+import kotlin.coroutines.ContinuationInterceptor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -33,7 +34,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import kotlin.coroutines.ContinuationInterceptor
@OptIn(ExperimentalCoroutinesApi::class)
@MediumTest
diff --git a/paging/paging-runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffWithRecyclerViewTest.kt b/paging/paging-runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffWithRecyclerViewTest.kt
index a1093bf..edfa92a 100644
--- a/paging/paging-runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffWithRecyclerViewTest.kt
+++ b/paging/paging-runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffWithRecyclerViewTest.kt
@@ -30,10 +30,10 @@
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlin.random.Random
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.random.Random
/**
* For some tests, this test uses a real recyclerview with a real adapter to serve as an
diff --git a/paging/paging-runtime/src/androidTest/java/androidx/paging/StateRestorationTest.kt b/paging/paging-runtime/src/androidTest/java/androidx/paging/StateRestorationTest.kt
index 338644c..f608c44 100644
--- a/paging/paging-runtime/src/androidTest/java/androidx/paging/StateRestorationTest.kt
+++ b/paging/paging-runtime/src/androidTest/java/androidx/paging/StateRestorationTest.kt
@@ -35,6 +35,9 @@
import androidx.test.filters.SdkSuppress
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlin.coroutines.ContinuationInterceptor
+import kotlin.coroutines.CoroutineContext
+import kotlin.time.ExperimentalTime
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.Job
@@ -45,17 +48,14 @@
import kotlinx.coroutines.internal.ThreadSafeHeap
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestCoroutineDispatcher
+import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.withContext
import org.junit.Before
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.coroutines.ContinuationInterceptor
-import kotlin.coroutines.CoroutineContext
-import kotlin.time.ExperimentalTime
-import kotlinx.coroutines.test.TestCoroutineScheduler
-import org.junit.Ignore
/**
* We are only capable of restoring state if one the two is valid:
diff --git a/paging/paging-runtime/src/main/AndroidManifest.xml b/paging/paging-runtime/src/main/AndroidManifest.xml
deleted file mode 100644
index 7b5bc6e..0000000
--- a/paging/paging-runtime/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- ~ Copyright (C) 2017 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 />
diff --git a/paging/paging-runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt b/paging/paging-runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
index 031e056..5ed8435 100644
--- a/paging/paging-runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
+++ b/paging/paging-runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
@@ -19,9 +19,9 @@
import androidx.annotation.VisibleForTesting
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.lifecycle.LiveData
-import androidx.paging.LoadType.REFRESH
-import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.APPEND
+import androidx.paging.LoadType.PREPEND
+import androidx.paging.LoadType.REFRESH
import androidx.recyclerview.widget.AdapterListUpdateCallback
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
diff --git a/paging/paging-runtime/src/main/java/androidx/paging/LivePagedList.kt b/paging/paging-runtime/src/main/java/androidx/paging/LivePagedList.kt
index ea2f8d1f..f4826a1 100644
--- a/paging/paging-runtime/src/main/java/androidx/paging/LivePagedList.kt
+++ b/paging/paging-runtime/src/main/java/androidx/paging/LivePagedList.kt
@@ -21,6 +21,7 @@
import androidx.paging.LoadState.Error
import androidx.paging.LoadState.Loading
import androidx.paging.LoadType.REFRESH
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
@@ -29,7 +30,6 @@
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import java.util.concurrent.Executor
@Suppress("DEPRECATION")
internal class LivePagedList<Key : Any, Value : Any>(
diff --git a/paging/paging-runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt b/paging/paging-runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
index c770466..34a64c7 100644
--- a/paging/paging-runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
+++ b/paging/paging-runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
@@ -18,11 +18,11 @@
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.lifecycle.LiveData
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.asCoroutineDispatcher
-import java.util.concurrent.Executor
/**
* Builder for `LiveData<PagedList>` for Java users, given a [androidx.paging.DataSource.Factory]
diff --git a/paging/paging-runtime/src/main/java/androidx/paging/NullPaddedListDiffHelper.kt b/paging/paging-runtime/src/main/java/androidx/paging/NullPaddedListDiffHelper.kt
index af09d964..08550a5 100644
--- a/paging/paging-runtime/src/main/java/androidx/paging/NullPaddedListDiffHelper.kt
+++ b/paging/paging-runtime/src/main/java/androidx/paging/NullPaddedListDiffHelper.kt
@@ -90,27 +90,6 @@
)
}
-private class OffsettingListUpdateCallback internal constructor(
- private val offset: Int,
- private val callback: ListUpdateCallback
-) : ListUpdateCallback {
- override fun onInserted(position: Int, count: Int) {
- callback.onInserted(position + offset, count)
- }
-
- override fun onRemoved(position: Int, count: Int) {
- callback.onRemoved(position + offset, count)
- }
-
- override fun onMoved(fromPosition: Int, toPosition: Int) {
- callback.onMoved(fromPosition + offset, toPosition + offset)
- }
-
- override fun onChanged(position: Int, count: Int, payload: Any?) {
- callback.onChanged(position + offset, count, payload)
- }
-}
-
/**
* See NullPaddedDiffing.md for how this works and why it works that way :).
*
diff --git a/paging/paging-runtime/src/main/java/androidx/paging/PagedListAdapter.kt b/paging/paging-runtime/src/main/java/androidx/paging/PagedListAdapter.kt
index ba7fec9..b0dbec5 100644
--- a/paging/paging-runtime/src/main/java/androidx/paging/PagedListAdapter.kt
+++ b/paging/paging-runtime/src/main/java/androidx/paging/PagedListAdapter.kt
@@ -18,8 +18,8 @@
import androidx.recyclerview.widget.AdapterListUpdateCallback
import androidx.recyclerview.widget.AsyncDifferConfig
-import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ConcatAdapter
+import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
/**
diff --git a/paging/paging-rxjava2-ktx/build.gradle b/paging/paging-rxjava2-ktx/build.gradle
index a355219..b53bd80 100644
--- a/paging/paging-rxjava2-ktx/build.gradle
+++ b/paging/paging-rxjava2-ktx/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Android Paging RxJava2 Kotlin Extensions"
+ name = "Paging RxJava2 Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for 'paging-rxjava2' artifact"
diff --git a/paging/paging-rxjava2-ktx/src/main/AndroidManifest.xml b/paging/paging-rxjava2-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/paging/paging-rxjava2-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/paging/paging-rxjava2/build.gradle b/paging/paging-rxjava2/build.gradle
index c830a91..5f779d0 100644
--- a/paging/paging-rxjava2/build.gradle
+++ b/paging/paging-rxjava2/build.gradle
@@ -47,7 +47,7 @@
}
androidx {
- name = "Android Paging-RXJava2"
+ name = "Paging-RXJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Paging-RXJava2"
diff --git a/paging/paging-rxjava2/src/androidTest/AndroidManifest.xml b/paging/paging-rxjava2/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/paging/paging-rxjava2/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagedListBuilderTest.kt b/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
index 3d3c5c2..0c02a18 100644
--- a/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
+++ b/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
@@ -22,20 +22,20 @@
import androidx.paging.LoadType.REFRESH
import androidx.testutils.DirectDispatcher
import androidx.testutils.TestDispatcher
+import com.google.common.truth.Truth.assertThat
import io.reactivex.Observable
import io.reactivex.observers.TestObserver
import io.reactivex.schedulers.Schedulers
import io.reactivex.schedulers.TestScheduler
+import kotlin.test.assertTrue
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.withContext
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.asExecutor
-import kotlinx.coroutines.withContext
@Suppress("DEPRECATION")
@RunWith(JUnit4::class)
@@ -329,10 +329,10 @@
// execute first load, represents load attempt on first paging source
//
- // using poll().run() instead of executeAll(), because executeAll() + immediate schedulers
+ // using removeFirst().run() instead of executeAll(), because executeAll() + immediate schedulers
// result in first load + subsequent loads executing immediately and we won't be able to
// assert the pagedLists/loads incrementally
- loadDispatcher.queue.poll()?.run()
+ loadDispatcher.queue.removeFirst().run()
// the load failed so there should still be only one PagedList, but the first
// pagingSource should invalidated, and the second pagingSource is created
@@ -354,7 +354,7 @@
)
// execute the load attempt on second pagingSource which succeeds
- loadDispatcher.queue.poll()?.run()
+ loadDispatcher.queue.removeFirst().run()
// ensure second pagedList created with the correct data loaded
observer.assertValueCount(2)
diff --git a/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagingSourceTest.kt b/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagingSourceTest.kt
index d64a55f..ca231a9 100644
--- a/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagingSourceTest.kt
+++ b/paging/paging-rxjava2/src/test/java/androidx/paging/RxPagingSourceTest.kt
@@ -19,12 +19,12 @@
import androidx.paging.PagingSource.LoadResult.Page
import androidx.paging.rxjava2.RxPagingSource
import io.reactivex.Single
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
class RxPagingSourceTest {
diff --git a/paging/paging-rxjava2/src/test/java/androidx/paging/RxRemoteMediatorTest.kt b/paging/paging-rxjava2/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
index 7ef9953..4816060 100644
--- a/paging/paging-rxjava2/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
+++ b/paging/paging-rxjava2/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
@@ -20,13 +20,13 @@
import androidx.paging.RemoteMediator.InitializeAction.SKIP_INITIAL_REFRESH
import androidx.paging.rxjava2.RxRemoteMediator
import io.reactivex.Single
+import kotlin.test.assertEquals
+import kotlin.test.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.fail
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-rxjava3/build.gradle b/paging/paging-rxjava3/build.gradle
index dc27213..05d795c 100644
--- a/paging/paging-rxjava3/build.gradle
+++ b/paging/paging-rxjava3/build.gradle
@@ -45,7 +45,7 @@
}
androidx {
- name = "Android Paging-RxJava3"
+ name = "Paging-RxJava3"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Paging-RxJava3"
diff --git a/paging/paging-rxjava3/src/androidTest/AndroidManifest.xml b/paging/paging-rxjava3/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/paging/paging-rxjava3/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagedListBuilderTest.kt b/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
index 0a3317b..3bd051e 100644
--- a/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
+++ b/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagedListBuilderTest.kt
@@ -25,20 +25,20 @@
import androidx.paging.rxjava3.RxPagedListBuilder
import androidx.testutils.DirectDispatcher
import androidx.testutils.TestDispatcher
+import com.google.common.truth.Truth.assertThat
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.observers.TestObserver
import io.reactivex.rxjava3.schedulers.Schedulers
import io.reactivex.rxjava3.schedulers.TestScheduler
+import kotlin.test.assertTrue
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.asExecutor
+import kotlinx.coroutines.withContext
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertTrue
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.asExecutor
-import kotlinx.coroutines.withContext
@RunWith(JUnit4::class)
class RxPagedListBuilderTest {
@@ -331,10 +331,10 @@
// execute first load, represents load attempt on first paging source
//
- // using poll().run() instead of executeAll(), because executeAll() + immediate schedulers
+ // using removeFirst().run() instead of executeAll(), because executeAll() + immediate schedulers
// result in first load + subsequent loads executing immediately and we won't be able to
// assert the pagedLists/loads incrementally
- loadDispatcher.queue.poll()?.run()
+ loadDispatcher.queue.removeFirst().run()
// the load failed so there should still be only one PagedList, but the first
// pagingSource should invalidated, and the second pagingSource is created
@@ -356,7 +356,7 @@
)
// execute the load attempt on second pagingSource which succeeds
- loadDispatcher.queue.poll()?.run()
+ loadDispatcher.queue.removeFirst().run()
// ensure second pagedList created with the correct data loaded
observer.assertValueCount(2)
diff --git a/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagingSourceTest.kt b/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagingSourceTest.kt
index 15bc792..9d40b9d 100644
--- a/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagingSourceTest.kt
+++ b/paging/paging-rxjava3/src/test/java/androidx/paging/RxPagingSourceTest.kt
@@ -19,12 +19,12 @@
import androidx.paging.PagingSource.LoadResult.Page
import androidx.paging.rxjava3.RxPagingSource
import io.reactivex.rxjava3.core.Single
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.assertFailsWith
@RunWith(JUnit4::class)
class RxPagingSourceTest {
diff --git a/paging/paging-rxjava3/src/test/java/androidx/paging/RxRemoteMediatorTest.kt b/paging/paging-rxjava3/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
index 9cd7890..1861c8f 100644
--- a/paging/paging-rxjava3/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
+++ b/paging/paging-rxjava3/src/test/java/androidx/paging/RxRemoteMediatorTest.kt
@@ -20,13 +20,13 @@
import androidx.paging.RemoteMediator.InitializeAction.SKIP_INITIAL_REFRESH
import androidx.paging.rxjava3.RxRemoteMediator
import io.reactivex.rxjava3.core.Single
+import kotlin.test.assertEquals
+import kotlin.test.fail
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.test.assertEquals
-import kotlin.test.fail
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalPagingApi::class)
@RunWith(JUnit4::class)
diff --git a/paging/paging-testing/api/current.txt b/paging/paging-testing/api/current.txt
index 066939a..62159d25 100644
--- a/paging/paging-testing/api/current.txt
+++ b/paging/paging-testing/api/current.txt
@@ -26,11 +26,12 @@
}
public final class StaticListPagingSourceFactoryKt {
- method public static <Value> kotlin.jvm.functions.Function0<androidx.paging.PagingSource<java.lang.Integer,Value>> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(java.util.List<? extends Value>);
}
public final class TestPager<Key, Value> {
- ctor public TestPager(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingConfig config);
+ ctor public TestPager(androidx.paging.PagingConfig config, androidx.paging.PagingSource<Key,Value> pagingSource);
method public suspend Object? append(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult<Key,Value>>);
method public suspend Object? getLastLoadedPage(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>);
method public suspend Object? getPages(kotlin.coroutines.Continuation<java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>>);
diff --git a/paging/paging-testing/api/public_plus_experimental_current.txt b/paging/paging-testing/api/public_plus_experimental_current.txt
index 066939a..62159d25 100644
--- a/paging/paging-testing/api/public_plus_experimental_current.txt
+++ b/paging/paging-testing/api/public_plus_experimental_current.txt
@@ -26,11 +26,12 @@
}
public final class StaticListPagingSourceFactoryKt {
- method public static <Value> kotlin.jvm.functions.Function0<androidx.paging.PagingSource<java.lang.Integer,Value>> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(java.util.List<? extends Value>);
}
public final class TestPager<Key, Value> {
- ctor public TestPager(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingConfig config);
+ ctor public TestPager(androidx.paging.PagingConfig config, androidx.paging.PagingSource<Key,Value> pagingSource);
method public suspend Object? append(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult<Key,Value>>);
method public suspend Object? getLastLoadedPage(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>);
method public suspend Object? getPages(kotlin.coroutines.Continuation<java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>>);
diff --git a/paging/paging-testing/api/restricted_current.txt b/paging/paging-testing/api/restricted_current.txt
index 066939a..62159d25 100644
--- a/paging/paging-testing/api/restricted_current.txt
+++ b/paging/paging-testing/api/restricted_current.txt
@@ -26,11 +26,12 @@
}
public final class StaticListPagingSourceFactoryKt {
- method public static <Value> kotlin.jvm.functions.Function0<androidx.paging.PagingSource<java.lang.Integer,Value>> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(kotlinx.coroutines.flow.Flow<java.util.List<Value>>, kotlinx.coroutines.CoroutineScope coroutineScope);
+ method public static <Value> androidx.paging.PagingSourceFactory<java.lang.Integer,Value> asPagingSourceFactory(java.util.List<? extends Value>);
}
public final class TestPager<Key, Value> {
- ctor public TestPager(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingConfig config);
+ ctor public TestPager(androidx.paging.PagingConfig config, androidx.paging.PagingSource<Key,Value> pagingSource);
method public suspend Object? append(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult<Key,Value>>);
method public suspend Object? getLastLoadedPage(kotlin.coroutines.Continuation<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>);
method public suspend Object? getPages(kotlin.coroutines.Continuation<java.util.List<androidx.paging.PagingSource.LoadResult.Page<Key,Value>>>);
diff --git a/paging/paging-testing/build.gradle b/paging/paging-testing/build.gradle
index 18e00f6..9557e62 100644
--- a/paging/paging-testing/build.gradle
+++ b/paging/paging-testing/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "androidx.paging:paging-testing"
+ name = "Paging Testing Extensions"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Test artifact for Paging implementation"
diff --git a/paging/paging-testing/src/main/java/androidx/paging/testing/LoadErrorHandler.kt b/paging/paging-testing/src/main/java/androidx/paging/testing/LoadErrorHandler.kt
index 4651e95..2e8df82 100644
--- a/paging/paging-testing/src/main/java/androidx/paging/testing/LoadErrorHandler.kt
+++ b/paging/paging-testing/src/main/java/androidx/paging/testing/LoadErrorHandler.kt
@@ -17,10 +17,10 @@
package androidx.paging.testing
import androidx.paging.CombinedLoadStates
+import androidx.paging.LoadState
import androidx.paging.PagingDataDiffer
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadResult
-import androidx.paging.LoadState
/**
* An interface to implement the error recovery strategy when [PagingSource]
diff --git a/paging/paging-testing/src/main/java/androidx/paging/testing/PagerFlowSnapshot.kt b/paging/paging-testing/src/main/java/androidx/paging/testing/PagerFlowSnapshot.kt
index 64c8ece..b063b7d 100644
--- a/paging/paging-testing/src/main/java/androidx/paging/testing/PagerFlowSnapshot.kt
+++ b/paging/paging-testing/src/main/java/androidx/paging/testing/PagerFlowSnapshot.kt
@@ -25,9 +25,9 @@
import androidx.paging.Pager
import androidx.paging.PagingData
import androidx.paging.PagingDataDiffer
-import androidx.paging.testing.ErrorRecovery.THROW
import androidx.paging.testing.ErrorRecovery.RETRY
import androidx.paging.testing.ErrorRecovery.RETURN_CURRENT_SNAPSHOT
+import androidx.paging.testing.ErrorRecovery.THROW
import androidx.paging.testing.LoaderCallback.CallbackType.ON_CHANGED
import androidx.paging.testing.LoaderCallback.CallbackType.ON_INSERTED
import androidx.paging.testing.LoaderCallback.CallbackType.ON_REMOVED
diff --git a/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSource.kt b/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSource.kt
index 5e28a95..89bca0e 100644
--- a/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSource.kt
+++ b/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSource.kt
@@ -17,11 +17,11 @@
package androidx.paging.testing
import androidx.paging.Pager
+import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
import androidx.paging.PagingSource.LoadParams.Append
import androidx.paging.PagingSource.LoadParams.Prepend
import androidx.paging.PagingSource.LoadParams.Refresh
-import androidx.paging.PagingSource
import androidx.paging.PagingState
/**
diff --git a/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSourceFactory.kt b/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSourceFactory.kt
index e44216e..6744b5e 100644
--- a/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSourceFactory.kt
+++ b/paging/paging-testing/src/main/java/androidx/paging/testing/StaticListPagingSourceFactory.kt
@@ -17,23 +17,24 @@
package androidx.paging.testing
import androidx.paging.InvalidatingPagingSourceFactory
-import androidx.paging.PagingSource
+import androidx.paging.LoadType.REFRESH
import androidx.paging.Pager
+import androidx.paging.PagingSource
+import androidx.paging.PagingSourceFactory
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
/**
- * Returns a factory that creates [PagingSource] instances.
+ * Returns a [PagingSourceFactory] that creates [PagingSource] instances.
*
- * Since this method returns a lambda, call [this.invoke] to create a new PagingSource. Can be
- * used as the pagingSourceFactory when constructing a [Pager]. The same factory should be reused
- * within the lifetime of a ViewModel.
+ * Can be used as the pagingSourceFactory when constructing a [Pager] in tests. The same factory
+ * should be reused within the lifetime of a ViewModel.
*
* Extension method on a [Flow] of list that represents the data source, with each static list
* representing a generation of data from which a [PagingSource] will load from. With every
- * emission, the current [PagingSource] will be invalidated, thereby triggering a new generation
- * of Paged data.
+ * emission to the flow, the current [PagingSource] will be invalidated, thereby triggering
+ * a new generation of Paged data.
*
* Supports multiple factories and thus multiple collection on the same flow.
*
@@ -41,7 +42,7 @@
*/
public fun <Value : Any> Flow<@JvmSuppressWildcards List<Value>>.asPagingSourceFactory(
coroutineScope: CoroutineScope
-): () -> PagingSource<Int, Value> {
+): PagingSourceFactory<Int, Value> {
var data: List<Value>? = null
@@ -60,4 +61,18 @@
}
return factory
-}
\ No newline at end of file
+}
+
+/**
+ * Returns a [PagingSourceFactory] that creates [PagingSource] instances.
+ *
+ * Can be used as the pagingSourceFactory when constructing a [Pager] in tests. The same factory
+ * should be reused within the lifetime of a ViewModel.
+ *
+ * Extension method on a [List] of data from which a [PagingSource] will load from. While this
+ * factory supports multi-generational operations such as [REFRESH], it does not support updating
+ * the data source. This means any PagingSources generated by the same factory will load from
+ * the exact same list of data.
+ */
+public fun <Value : Any> List<Value>.asPagingSourceFactory(): PagingSourceFactory<Int, Value> =
+ PagingSourceFactory { StaticListPagingSource(this) }
diff --git a/paging/paging-testing/src/main/java/androidx/paging/testing/TestPager.kt b/paging/paging-testing/src/main/java/androidx/paging/testing/TestPager.kt
index 85e3efb..bcd13ec 100644
--- a/paging/paging-testing/src/main/java/androidx/paging/testing/TestPager.kt
+++ b/paging/paging-testing/src/main/java/androidx/paging/testing/TestPager.kt
@@ -20,11 +20,11 @@
import androidx.paging.LoadType.APPEND
import androidx.paging.LoadType.PREPEND
import androidx.paging.LoadType.REFRESH
+import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
import androidx.paging.PagingSource.LoadResult
-import androidx.paging.Pager
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
import androidx.paging.PagingState
import java.util.concurrent.atomic.AtomicBoolean
@@ -41,12 +41,12 @@
* multi-generational Paging behavior, you must create a new [TestPager] by supplying a
* new instance of [PagingSource].
*
- * @param pagingSource the [PagingSource] to load data from.
* @param config the [PagingConfig] to configure this TestPager's loading behavior.
+ * @param pagingSource the [PagingSource] to load data from.
*/
public class TestPager<Key : Any, Value : Any>(
- private val pagingSource: PagingSource<Key, Value>,
private val config: PagingConfig,
+ private val pagingSource: PagingSource<Key, Value>,
) {
private val hasRefreshed = AtomicBoolean(false)
diff --git a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/PagerFlowSnapshotTest.kt b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/PagerFlowSnapshotTest.kt
index 42aaa0b5..ca7351a 100644
--- a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/PagerFlowSnapshotTest.kt
+++ b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/PagerFlowSnapshotTest.kt
@@ -20,6 +20,7 @@
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
+import androidx.paging.PagingSourceFactory
import androidx.paging.PagingState
import androidx.paging.cachedIn
import androidx.paging.insertSeparators
@@ -62,6 +63,11 @@
loadDelay
)
+ private fun createSingleGenFactory(data: List<Int>) = WrappedPagingSourceFactory(
+ data.asPagingSourceFactory(),
+ loadDelay
+ )
+
@Before
fun init() {
Dispatchers.setMain(UnconfinedTestDispatcher())
@@ -72,7 +78,20 @@
val dataFlow = flowOf(List(30) { it })
val pager = createPager(dataFlow)
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
+ // first page + prefetched page
+ assertThat(snapshot).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4, 5, 6, 7)
+ )
+ }
+ }
+
+ @Test
+ fun initialRefreshSingleGen() {
+ val data = List(30) { it }
+ val pager = createPager(data)
+ testScope.runTest {
+ val snapshot = pager.asSnapshot(this)
// first page + prefetched page
assertThat(snapshot).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4, 5, 6, 7)
@@ -85,7 +104,7 @@
val dataFlow = flowOf(List(30) { it })
val pager = createPager(dataFlow)
testScope.runTest {
- val snapshot = pager.asSnapshot(this)
+ val snapshot = pager.asSnapshot(this) {}
// first page + prefetched page
assertThat(snapshot).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4, 5, 6, 7)
@@ -102,7 +121,7 @@
}
}
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
// loads 8[initial 5 + prefetch 3] items total, including separators
assertThat(snapshot).containsExactlyElementsIn(
listOf(0, "sep", 1, "sep", 2, "sep", 3, "sep", 4)
@@ -115,7 +134,7 @@
val dataFlow = flowOf(List(30) { it })
val pager = createPagerNoPrefetch(dataFlow)
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
assertThat(snapshot).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
@@ -128,7 +147,7 @@
val dataFlow = flowOf(List(30) { it })
val pager = createPager(dataFlow, 10)
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
assertThat(snapshot).containsExactlyElementsIn(
listOf(7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
@@ -141,7 +160,7 @@
val dataFlow = flowOf(List(30) { it })
val pager = createPagerNoPrefetch(dataFlow, 10)
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
assertThat(snapshot).containsExactlyElementsIn(
listOf(10, 11, 12, 13, 14)
@@ -154,7 +173,20 @@
val dataFlow = emptyFlow<List<Int>>()
val pager = createPager(dataFlow)
testScope.runTest {
- val snapshot = pager.asSnapshot(this) {}
+ val snapshot = pager.asSnapshot(this)
+
+ assertThat(snapshot).containsExactlyElementsIn(
+ emptyList<Int>()
+ )
+ }
+ }
+
+ @Test
+ fun emptyInitialRefreshSingleGen() {
+ val data = emptyList<Int>()
+ val pager = createPager(data)
+ testScope.runTest {
+ val snapshot = pager.asSnapshot(this)
assertThat(snapshot).containsExactlyElementsIn(
emptyList<Int>()
@@ -190,6 +222,37 @@
}
@Test
+ fun manualRefreshSingleGen() {
+ val data = List(30) { it }
+ val pager = createPager(data)
+ testScope.runTest {
+ val snapshot = pager.asSnapshot(this) {
+ refresh()
+ }
+ assertThat(snapshot).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4, 5, 6, 7),
+ )
+ }
+ }
+
+ @Test
+ fun manualRefreshSingleGen_pagingSourceInvalidated() {
+ val data = List(30) { it }
+ val sources = mutableListOf<PagingSource<Int, Int>>()
+ val factory = data.asPagingSourceFactory()
+ val pager = Pager(
+ config = PagingConfig(pageSize = 3, initialLoadSize = 5),
+ pagingSourceFactory = { factory().also { sources.add(it) } },
+ ).flow
+ testScope.runTest {
+ pager.asSnapshot(this) {
+ refresh()
+ }
+ assertThat(sources.first().invalid).isTrue()
+ }
+ }
+
+ @Test
fun manualEmptyRefresh() {
val dataFlow = emptyFlow<List<Int>>()
val pager = createPagerNoPrefetch(dataFlow)
@@ -2311,6 +2374,13 @@
initialKey
)
+ private fun createPager(data: List<Int>, initialKey: Int = 0) =
+ Pager(
+ PagingConfig(pageSize = 3, initialLoadSize = 5),
+ initialKey,
+ createSingleGenFactory(data),
+ ).flow
+
private fun createPagerNoPlaceholders(dataFlow: Flow<List<Int>>, initialKey: Int = 0) =
createPager(
dataFlow,
@@ -2355,9 +2425,9 @@
}
private class WrappedPagingSourceFactory(
- private val factory: () -> PagingSource<Int, Int>,
+ private val factory: PagingSourceFactory<Int, Int>,
private val loadDelay: Long,
-) : () -> PagingSource<Int, Int> {
+) : PagingSourceFactory<Int, Int> {
override fun invoke(): PagingSource<Int, Int> = TestPagingSource(factory(), loadDelay)
}
diff --git a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceFactoryTest.kt b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceFactoryTest.kt
index 6a2f2c1..c327ff5 100644
--- a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceFactoryTest.kt
+++ b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceFactoryTest.kt
@@ -17,8 +17,8 @@
package androidx.paging.testing
import androidx.paging.PagingConfig
-import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadResult.Page
+import androidx.paging.PagingSourceFactory
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
@@ -47,10 +47,10 @@
@Test
fun emptyFlow() {
- val factory: () -> PagingSource<Int, Int> =
+ val factory: PagingSourceFactory<Int, Int> =
flowOf<List<Int>>().asPagingSourceFactory(testScope)
val pagingSource = factory()
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
runTest {
val result = pager.refresh() as Page
@@ -64,10 +64,10 @@
List(20) { it }
)
- val factory: () -> PagingSource<Int, Int> =
+ val factory: PagingSourceFactory<Int, Int> =
flow.asPagingSourceFactory(testScope)
val pagingSource = factory()
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
runTest {
val result = pager.refresh() as Page
@@ -85,14 +85,14 @@
emit(List(15) { it + 30 }) // second gen
}
- val factory: () -> PagingSource<Int, Int> =
+ val factory: PagingSourceFactory<Int, Int> =
flow.asPagingSourceFactory(testScope)
advanceTimeBy(1000)
// first gen
val pagingSource1 = factory()
- val pager1 = TestPager(pagingSource1, CONFIG)
+ val pager1 = TestPager(CONFIG, pagingSource1)
val result1 = pager1.refresh() as Page
assertThat(result1.data).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
@@ -105,7 +105,7 @@
// second gen
val pagingSource2 = factory()
- val pager2 = TestPager(pagingSource2, CONFIG)
+ val pager2 = TestPager(CONFIG, pagingSource2)
val result2 = pager2.refresh() as Page
assertThat(result2.data).containsExactlyElementsIn(
listOf(30, 31, 32, 33, 34)
@@ -117,7 +117,7 @@
val mutableFlow = MutableSharedFlow<List<Int>>()
val collectionScope = this.backgroundScope
- val factory: () -> PagingSource<Int, Int> =
+ val factory: PagingSourceFactory<Int, Int> =
mutableFlow.asPagingSourceFactory(collectionScope)
mutableFlow.emit(List(10) { it })
@@ -125,7 +125,7 @@
advanceUntilIdle()
val pagingSource = factory()
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
val result = pager.refresh() as Page
assertThat(result.data).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
@@ -146,10 +146,10 @@
fun multipleFactories_fromSameFlow() = testScope.runTest {
val mutableFlow = MutableSharedFlow<List<Int>>()
- val factory1: () -> PagingSource<Int, Int> =
+ val factory1: PagingSourceFactory<Int, Int> =
mutableFlow.asPagingSourceFactory(testScope.backgroundScope)
- val factory2: () -> PagingSource<Int, Int> =
+ val factory2: PagingSourceFactory<Int, Int> =
mutableFlow.asPagingSourceFactory(testScope.backgroundScope)
mutableFlow.emit(List(10) { it })
@@ -158,7 +158,7 @@
// factory 1 first gen
val pagingSource = factory1()
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
val result = pager.refresh() as Page
assertThat(result.data).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
@@ -166,7 +166,7 @@
// factory 2 first gen
val pagingSource2 = factory2()
- val pager2 = TestPager(pagingSource2, CONFIG)
+ val pager2 = TestPager(CONFIG, pagingSource2)
val result2 = pager2.refresh() as Page
assertThat(result2.data).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
@@ -182,7 +182,7 @@
// factory 1 second gen
val pagingSource3 = factory1()
- val pager3 = TestPager(pagingSource3, CONFIG)
+ val pager3 = TestPager(CONFIG, pagingSource3)
val result3 = pager3.refresh() as Page
assertThat(result3.data).containsExactlyElementsIn(
listOf(30, 31, 32, 33, 34)
@@ -190,10 +190,84 @@
// factory 2 second gen
val pagingSource4 = factory2()
- val pager4 = TestPager(pagingSource4, CONFIG)
+ val pager4 = TestPager(CONFIG, pagingSource4)
val result4 = pager4.refresh() as Page
assertThat(result4.data).containsExactlyElementsIn(
listOf(30, 31, 32, 33, 34)
)
}
+
+ @Test
+ fun singleListFactory_refresh() = testScope.runTest {
+ val data = List(20) { it }
+ val factory = data.asPagingSourceFactory()
+
+ val pagingSource1 = factory()
+ val pager1 = TestPager(CONFIG, pagingSource1)
+ val refresh1 = pager1.refresh() as Page
+ assertThat(refresh1.data).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4)
+ )
+
+ val pagingSource2 = factory()
+ val pager2 = TestPager(CONFIG, pagingSource2)
+ val refresh2 = pager2.refresh() as Page
+ assertThat(refresh2.data).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4)
+ )
+ }
+
+ @Test
+ fun singleListFactory_empty() = testScope.runTest {
+ val data = emptyList<Int>()
+ val factory = data.asPagingSourceFactory()
+
+ val pagingSource1 = factory()
+ val pager1 = TestPager(CONFIG, pagingSource1)
+ val refresh1 = pager1.refresh() as Page
+ assertThat(refresh1.data).isEmpty()
+
+ val pagingSource2 = factory()
+ val pager2 = TestPager(CONFIG, pagingSource2)
+ val refresh2 = pager2.refresh() as Page
+ assertThat(refresh2.data).isEmpty()
+ }
+
+ @Test
+ fun singleListFactory_append() = testScope.runTest {
+ val data = List(20) { it }
+ val factory = data.asPagingSourceFactory()
+ val pagingSource1 = factory()
+ val pager1 = TestPager(CONFIG, pagingSource1)
+
+ pager1.refresh() as Page
+ pager1.append()
+ assertThat(pager1.getPages().flatMap { it.data }).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4, 5, 6, 7)
+ )
+
+ pager1.append()
+ assertThat(pager1.getPages().flatMap { it.data }).containsExactlyElementsIn(
+ listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ )
+ }
+
+ @Test
+ fun singleListFactory_prepend() = testScope.runTest {
+ val data = List(20) { it }
+ val factory = data.asPagingSourceFactory()
+ val pagingSource1 = factory()
+ val pager1 = TestPager(CONFIG, pagingSource1)
+
+ pager1.refresh(initialKey = 10) as Page
+ pager1.prepend()
+ assertThat(pager1.getPages().flatMap { it.data }).containsExactlyElementsIn(
+ listOf(7, 8, 9, 10, 11, 12, 13, 14)
+ )
+
+ pager1.prepend()
+ assertThat(pager1.getPages().flatMap { it.data }).containsExactlyElementsIn(
+ listOf(4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
+ )
+ }
}
\ No newline at end of file
diff --git a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceTest.kt b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceTest.kt
index 0ab9d08..e93e9d9 100644
--- a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceTest.kt
+++ b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/StaticListPagingSourceTest.kt
@@ -271,7 +271,7 @@
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
private fun runPagingSourceTest(
source: PagingSource<Int, Int> = StaticListPagingSource(DATA),
- pager: TestPager<Int, Int> = TestPager(source, CONFIG),
+ pager: TestPager<Int, Int> = TestPager(CONFIG, source),
block: suspend (pagingSource: PagingSource<Int, Int>, pager: TestPager<Int, Int>) -> Unit
) {
runTest {
diff --git a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/TestPagerTest.kt b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/TestPagerTest.kt
index 72b5b48..6caaea9 100644
--- a/paging/paging-testing/src/test/kotlin/androidx/paging/testing/TestPagerTest.kt
+++ b/paging/paging-testing/src/test/kotlin/androidx/paging/testing/TestPagerTest.kt
@@ -39,7 +39,7 @@
@Test
fun refresh_nullKey() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val result = pager.refresh(null) as LoadResult.Page
@@ -51,7 +51,7 @@
@Test
fun refresh_withInitialKey() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val result = pager.refresh(50) as LoadResult.Page
@@ -63,7 +63,7 @@
@Test
fun refresh_returnError() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
source.errorNextLoad = true
@@ -78,7 +78,7 @@
@Test
fun refresh_returnInvalid() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
source.nextLoadResult = LoadResult.Invalid()
@@ -93,7 +93,7 @@
@Test
fun refresh_invalidPagingSource() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
source.invalidate()
@@ -108,7 +108,7 @@
@Test
fun refresh_getLastLoadedPage() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val page: LoadResult.Page<Int, Int>? = pager.run {
@@ -123,7 +123,7 @@
@Test
fun getLastLoadedPage_afterInvalidPagingSource() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val page = pager.run {
@@ -141,7 +141,7 @@
@Test
fun refresh_getPages() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val pages = pager.run {
@@ -160,7 +160,7 @@
@Test
fun getPages_multiplePages() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
pager.run {
refresh(20)
@@ -179,7 +179,7 @@
@Test
fun getPages_fromEmptyList() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val pages = pager.getPages()
assertThat(pages).isEmpty()
}
@@ -187,7 +187,7 @@
@Test
fun getPages_afterInvalidPagingSource() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
val pages = pager.run {
@@ -209,7 +209,7 @@
@Test
fun getPages_multiThread() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
var pages: List<LoadResult.Page<Int, Int>>? = null
val job = launch {
@@ -250,7 +250,7 @@
@Test
fun multipleRefresh_onSinglePager_throws() {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
runTest {
pager.run {
@@ -269,7 +269,7 @@
@Test
fun multipleRefresh_onMultiplePagers() = runTest {
val source1 = TestPagingSource()
- val pager1 = TestPager(source1, CONFIG)
+ val pager1 = TestPager(CONFIG, source1)
// first gen
val result1 = pager1.run {
@@ -280,7 +280,7 @@
// second gen
val source2 = TestPagingSource()
- val pager2 = TestPager(source2, CONFIG)
+ val pager2 = TestPager(CONFIG, source2)
val result2 = pager2.run {
refresh()
@@ -292,7 +292,7 @@
@Test
fun simpleAppend() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val result = pager.run {
refresh(null)
@@ -311,7 +311,7 @@
@Test
fun simplePrepend() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val result = pager.run {
refresh(30)
@@ -333,7 +333,7 @@
@Test
fun append_beforeRefresh_throws() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
assertFailsWith<IllegalStateException> {
pager.append()
}
@@ -342,7 +342,7 @@
@Test
fun prepend_beforeRefresh_throws() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
assertFailsWith<IllegalStateException> {
pager.prepend()
}
@@ -351,7 +351,7 @@
@Test
fun append_invalidPagingSource() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val result = pager.run {
refresh()
@@ -367,7 +367,7 @@
@Test
fun prepend_invalidPagingSource() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val result = pager.run {
refresh(initialKey = 20)
@@ -383,7 +383,7 @@
@Test
fun consecutive_append() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
pager.run {
refresh(20)
@@ -403,7 +403,7 @@
@Test
fun consecutive_prepend() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
pager.run {
refresh(20)
@@ -427,7 +427,7 @@
@Test
fun append_then_prepend() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
pager.run {
refresh(20)
@@ -450,7 +450,7 @@
@Test
fun prepend_then_append() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
pager.run {
refresh(20)
@@ -473,7 +473,7 @@
@Test
fun multiThread_loads() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
// load operations upon completion add an int to the list.
// after all loads complete, we assert the order that the ints were added.
val loadOrder = mutableListOf<Int>()
@@ -511,7 +511,7 @@
@Test
fun multiThread_operations() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
// operations upon completion add an int to the list.
// after all operations complete, we assert the order that the ints were added.
val loadOrder = mutableListOf<Int>()
@@ -559,7 +559,7 @@
@Test
fun getPagingStateWithAnchorPosition_placeHoldersEnabled() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val state = pager.run {
refresh(20)
@@ -583,7 +583,7 @@
)
)
val source2 = TestPagingSource()
- val pager2 = TestPager(source, CONFIG)
+ val pager2 = TestPager(CONFIG, source)
val page = pager2.run {
refresh(source2.getRefreshKey(state))
}
@@ -598,7 +598,7 @@
initialLoadSize = 5,
enablePlaceholders = false
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
val state = pager.run {
refresh(20)
@@ -621,7 +621,7 @@
)
)
val source2 = TestPagingSource()
- val pager2 = TestPager(source, CONFIG)
+ val pager2 = TestPager(CONFIG, source)
val page = pager2.run {
refresh(source2.getRefreshKey(state))
}
@@ -634,7 +634,7 @@
@Test
fun getPagingStateWithAnchorPosition_indexOutOfBoundsWithPlaceholders() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val msg = assertFailsWith<IllegalStateException> {
pager.run {
@@ -661,12 +661,12 @@
fun getPagingStateWithAnchorPosition_indexOutOfBoundsWithoutPlaceholders() = runTest {
val source = TestPagingSource()
val pager = TestPager(
- source,
PagingConfig(
pageSize = 3,
initialLoadSize = 5,
enablePlaceholders = false
- )
+ ),
+ source
)
val msg = assertFailsWith<IllegalStateException> {
@@ -694,7 +694,7 @@
@Test
fun getPagingStateWithAnchorLookup_placeHoldersEnabled() = runTest {
val source = TestPagingSource()
- val pager = TestPager(source, CONFIG)
+ val pager = TestPager(CONFIG, source)
val state = pager.run {
refresh(20)
@@ -718,7 +718,7 @@
)
// use state to getRefreshKey
val source2 = TestPagingSource()
- val pager2 = TestPager(source, CONFIG)
+ val pager2 = TestPager(CONFIG, source)
val page = pager2.run {
refresh(source2.getRefreshKey(state))
}
@@ -733,7 +733,7 @@
initialLoadSize = 5,
enablePlaceholders = false
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
val state = pager.run {
refresh(20)
@@ -757,7 +757,7 @@
)
// use state to getRefreshKey
val source2 = TestPagingSource()
- val pager2 = TestPager(source, CONFIG)
+ val pager2 = TestPager(CONFIG, source)
val page = pager2.run {
refresh(source2.getRefreshKey(state))
}
@@ -775,7 +775,7 @@
initialLoadSize = 5,
enablePlaceholders = false
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
val msg = assertFailsWith<IllegalArgumentException> {
pager.run {
@@ -801,7 +801,7 @@
enablePlaceholders = false,
maxSize = 10
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
pager.run {
refresh(20)
prepend()
@@ -833,7 +833,7 @@
enablePlaceholders = false,
maxSize = 10
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
pager.run {
refresh(20)
append()
@@ -864,7 +864,7 @@
enablePlaceholders = false,
maxSize = 10
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
pager.run {
refresh(20)
append()
@@ -896,7 +896,7 @@
maxSize = 5,
prefetchDistance = 2
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
pager.refresh(20)
assertThat(pager.getPages()).containsExactlyElementsIn(
listOf(
@@ -931,7 +931,7 @@
maxSize = 3,
prefetchDistance = 1
)
- val pager = TestPager(source, config)
+ val pager = TestPager(config, source)
val result = pager.refresh() as LoadResult.Page
assertThat(result.data).containsExactlyElementsIn(
listOf(0, 1, 2, 3, 4)
diff --git a/paging/samples/build.gradle b/paging/samples/build.gradle
index 4a7e36a..9e5516a 100644
--- a/paging/samples/build.gradle
+++ b/paging/samples/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "AndroidX Paging Samples"
+ name = "Paging Samples"
type = LibraryType.SAMPLES
inceptionYear = "2019"
description = "Contains the sample code for the Androidx Paging library"
diff --git a/paging/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt b/paging/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt
index fa93e32..9de9423 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt
@@ -22,9 +22,9 @@
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.cachedIn
+import androidx.paging.liveData
import androidx.paging.rxjava2.cachedIn
import androidx.paging.rxjava2.flowable
-import androidx.paging.liveData
import kotlinx.coroutines.ExperimentalCoroutinesApi
/**
diff --git a/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsSample.kt b/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsSample.kt
index 71a5a41..da92c7b 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsSample.kt
@@ -28,10 +28,10 @@
import com.google.common.util.concurrent.Futures
import io.reactivex.Maybe
import io.reactivex.schedulers.Schedulers
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
import java.util.concurrent.Callable
import java.util.concurrent.Executors
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
private lateinit var pagingDataStream: Flow<PagingData<String>>
diff --git a/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsUiModelSample.kt b/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsUiModelSample.kt
index 040f6f3..9a2bd7f 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsUiModelSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/InsertSeparatorsUiModelSample.kt
@@ -29,10 +29,10 @@
import com.google.common.util.concurrent.Futures
import io.reactivex.Maybe
import io.reactivex.schedulers.Schedulers
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
import java.util.concurrent.Callable
import java.util.concurrent.Executors
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
class Item(
@JvmField
diff --git a/paging/samples/src/main/java/androidx/paging/samples/ListenableFuturePagingSourceSample.kt b/paging/samples/src/main/java/androidx/paging/samples/ListenableFuturePagingSourceSample.kt
index 21718c3..ca2df59f 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/ListenableFuturePagingSourceSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/ListenableFuturePagingSourceSample.kt
@@ -23,9 +23,9 @@
import androidx.paging.PagingState
import com.google.common.util.concurrent.FluentFuture
import com.google.common.util.concurrent.ListenableFuture
-import retrofit2.HttpException
import java.io.IOException
import java.util.concurrent.Executor
+import retrofit2.HttpException
data class RemoteResult(
val items: List<Item>,
diff --git a/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt b/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
index bd894fc..efaee82 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/PagingSourceSample.kt
@@ -22,8 +22,8 @@
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState
-import retrofit2.HttpException
import java.io.IOException
+import retrofit2.HttpException
internal class MyBackendService {
data class RemoteResult(
diff --git a/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt b/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
index 0b40372..6cbefcb 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/RemoteMediatorSample.kt
@@ -28,9 +28,9 @@
import androidx.paging.samples.shared.RoomDb
import androidx.paging.samples.shared.User
import androidx.room.withTransaction
-import retrofit2.HttpException
import java.io.IOException
import java.util.concurrent.TimeUnit
+import retrofit2.HttpException
private interface ItemDao {
fun withTransaction(block: () -> Any)
diff --git a/paging/samples/src/main/java/androidx/paging/samples/RxPagingSourceSample.kt b/paging/samples/src/main/java/androidx/paging/samples/RxPagingSourceSample.kt
index 0ec0ec4..2e6ce22 100644
--- a/paging/samples/src/main/java/androidx/paging/samples/RxPagingSourceSample.kt
+++ b/paging/samples/src/main/java/androidx/paging/samples/RxPagingSourceSample.kt
@@ -23,8 +23,8 @@
import androidx.paging.rxjava2.RxPagingSource
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
-import retrofit2.HttpException
import java.io.IOException
+import retrofit2.HttpException
private class RxBackendService {
data class RemoteResult(
diff --git a/palette/palette-ktx/src/main/AndroidManifest.xml b/palette/palette-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/palette/palette-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/palette/palette/build.gradle b/palette/palette/build.gradle
index 90bdee7..df6b451 100644
--- a/palette/palette/build.gradle
+++ b/palette/palette/build.gradle
@@ -17,7 +17,7 @@
}
androidx {
- name = "Android Support Palette"
+ name = "Palette"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2014"
description = "Android Support Palette"
diff --git a/palette/palette/src/main/AndroidManifest.xml b/palette/palette/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/palette/palette/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/percentlayout/percentlayout/build.gradle b/percentlayout/percentlayout/build.gradle
index a28d3b0..737f4d4 100644
--- a/percentlayout/percentlayout/build.gradle
+++ b/percentlayout/percentlayout/build.gradle
@@ -24,7 +24,7 @@
}
androidx {
- name = "Android Percent Support Library"
+ name = "Percent"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2015"
description = "Android Percent Support Library"
diff --git a/percentlayout/percentlayout/src/main/AndroidManifest.xml b/percentlayout/percentlayout/src/main/AndroidManifest.xml
deleted file mode 100644
index 5197378..0000000
--- a/percentlayout/percentlayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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 />
diff --git a/playground-common/playground.properties b/playground-common/playground.properties
index fec6fdf..68b1459 100644
--- a/playground-common/playground.properties
+++ b/playground-common/playground.properties
@@ -26,5 +26,5 @@
# Disable docs
androidx.enableDocumentation=false
androidx.playground.snapshotBuildId=10041883
-androidx.playground.metalavaBuildId=10009114
+androidx.playground.metalavaBuildId=10074764
androidx.studio.type=playground
diff --git a/preference/preference-ktx/build.gradle b/preference/preference-ktx/build.gradle
index ebef733..e6e8c4f 100644
--- a/preference/preference-ktx/build.gradle
+++ b/preference/preference-ktx/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "Android Preferences KTX"
+ name = "Preferences KTX"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for preferences"
diff --git a/preference/preference-ktx/src/main/AndroidManifest.xml b/preference/preference-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/preference/preference-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/preference/preference/build.gradle b/preference/preference/build.gradle
index 366ccdc..0e7815d 100644
--- a/preference/preference/build.gradle
+++ b/preference/preference/build.gradle
@@ -64,7 +64,7 @@
}
androidx {
- name = "AndroidX Preference"
+ name = "Preference"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2015"
description = "AndroidX Preference"
diff --git a/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.kt b/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.kt
index 037659f..7f87518 100644
--- a/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.kt
+++ b/preference/preference/src/androidTest/java/androidx/preference/tests/helpers/PreferenceTestHelperActivity.kt
@@ -17,7 +17,6 @@
package androidx.preference.tests.helpers
import android.os.Bundle
-
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceFragmentCompat
diff --git a/preference/preference/src/main/AndroidManifest.xml b/preference/preference/src/main/AndroidManifest.xml
deleted file mode 100644
index 5197378..0000000
--- a/preference/preference/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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 />
diff --git a/print/print/build.gradle b/print/print/build.gradle
index 3b8be7c..6e9dc83 100644
--- a/print/print/build.gradle
+++ b/print/print/build.gradle
@@ -10,7 +10,7 @@
}
androidx {
- name = "Android Support Library Print"
+ name = "Print"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/print/print/src/main/AndroidManifest.xml b/print/print/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/print/print/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFuturesTest.kt b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFuturesTest.kt
index ff87882..e0c2574 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFuturesTest.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFuturesTest.kt
@@ -24,10 +24,10 @@
import androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig
import androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome
import androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest
-import androidx.test.core.app.ApplicationProvider
import androidx.privacysandbox.ads.adservices.common.AdSelectionSignals
import androidx.privacysandbox.ads.adservices.common.AdTechIdentifier
import androidx.privacysandbox.ads.adservices.java.adselection.AdSelectionManagerFutures.Companion.from
+import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
diff --git a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFuturesTest.kt b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFuturesTest.kt
index 1ebf7e7..d2f5802 100644
--- a/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFuturesTest.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/androidTest/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFuturesTest.kt
@@ -26,10 +26,10 @@
import androidx.privacysandbox.ads.adservices.common.AdSelectionSignals
import androidx.privacysandbox.ads.adservices.common.AdTechIdentifier
import androidx.privacysandbox.ads.adservices.customaudience.CustomAudience
-import androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion.from
import androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest
import androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest
import androidx.privacysandbox.ads.adservices.customaudience.TrustedBiddingData
+import androidx.privacysandbox.ads.adservices.java.customaudience.CustomAudienceManagerFutures.Companion.from
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adid/AdIdManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adid/AdIdManagerFutures.kt
index 8ffa244..860cccf 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adid/AdIdManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adid/AdIdManagerFutures.kt
@@ -16,7 +16,6 @@
package androidx.privacysandbox.ads.adservices.java.adid
-import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import android.adservices.common.AdServicesPermissions
import android.content.Context
import android.os.LimitExceededException
@@ -24,6 +23,7 @@
import androidx.annotation.RequiresPermission
import androidx.privacysandbox.ads.adservices.adid.AdId
import androidx.privacysandbox.ads.adservices.adid.AdIdManager
+import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFutures.kt
index 4726167..0dc0c4c 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/adselection/AdSelectionManagerFutures.kt
@@ -16,9 +16,6 @@
package androidx.privacysandbox.ads.adservices.java.adselection
-import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
-import androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager
-import androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion.obtain
import android.adservices.common.AdServicesPermissions
import android.content.Context
import android.os.LimitExceededException
@@ -26,8 +23,11 @@
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresPermission
import androidx.privacysandbox.ads.adservices.adselection.AdSelectionConfig
+import androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager
+import androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion.obtain
import androidx.privacysandbox.ads.adservices.adselection.AdSelectionOutcome
import androidx.privacysandbox.ads.adservices.adselection.ReportImpressionRequest
+import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import com.google.common.util.concurrent.ListenableFuture
import java.util.concurrent.TimeoutException
import kotlinx.coroutines.CoroutineScope
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/appsetid/AppSetIdManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/appsetid/AppSetIdManagerFutures.kt
index fcae8d8..5c003dd 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/appsetid/AppSetIdManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/appsetid/AppSetIdManagerFutures.kt
@@ -16,12 +16,12 @@
package androidx.privacysandbox.ads.adservices.java.appsetid
-import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import android.content.Context
import android.os.LimitExceededException
import androidx.annotation.DoNotInline
import androidx.privacysandbox.ads.adservices.appsetid.AppSetId
import androidx.privacysandbox.ads.adservices.appsetid.AppSetIdManager
+import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures.kt
index cb43cf4..f74372d 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/customaudience/CustomAudienceManagerFutures.kt
@@ -16,17 +16,17 @@
package androidx.privacysandbox.ads.adservices.java.customaudience
-import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
-import androidx.privacysandbox.ads.adservices.customaudience.CustomAudience
-import androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager
-import androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion.obtain
import android.adservices.common.AdServicesPermissions
import android.content.Context
import android.os.LimitExceededException
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresPermission
+import androidx.privacysandbox.ads.adservices.customaudience.CustomAudience
+import androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager
+import androidx.privacysandbox.ads.adservices.customaudience.CustomAudienceManager.Companion.obtain
import androidx.privacysandbox.ads.adservices.customaudience.JoinCustomAudienceRequest
import androidx.privacysandbox.ads.adservices.customaudience.LeaveCustomAudienceRequest
+import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
diff --git a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/topics/TopicsManagerFutures.kt b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/topics/TopicsManagerFutures.kt
index 5f80cd7..00fa709 100644
--- a/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/topics/TopicsManagerFutures.kt
+++ b/privacysandbox/ads/ads-adservices-java/src/main/java/androidx/privacysandbox/ads/adservices/java/topics/TopicsManagerFutures.kt
@@ -16,15 +16,15 @@
package androidx.privacysandbox.ads.adservices.java.topics
-import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
-import androidx.privacysandbox.ads.adservices.topics.TopicsManager
-import androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion.obtain
-import androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest
-import androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse
import android.adservices.common.AdServicesPermissions
import android.content.Context
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresPermission
+import androidx.privacysandbox.ads.adservices.java.internal.asListenableFuture
+import androidx.privacysandbox.ads.adservices.topics.GetTopicsRequest
+import androidx.privacysandbox.ads.adservices.topics.GetTopicsResponse
+import androidx.privacysandbox.ads.adservices.topics.TopicsManager
+import androidx.privacysandbox.ads.adservices.topics.TopicsManager.Companion.obtain
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
diff --git a/privacysandbox/ads/ads-adservices/build.gradle b/privacysandbox/ads/ads-adservices/build.gradle
index 70c6da1..13284aa 100644
--- a/privacysandbox/ads/ads-adservices/build.gradle
+++ b/privacysandbox/ads/ads-adservices/build.gradle
@@ -50,7 +50,7 @@
}
androidx {
- name = "Androidx library for Privacy Preserving APIs."
+ name = "Privacy Sandbox for Ad Services"
type = LibraryType.PUBLISHED_LIBRARY
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2022"
diff --git a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManagerTest.kt b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManagerTest.kt
index 7ce3d77..5c658d3 100644
--- a/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManagerTest.kt
+++ b/privacysandbox/ads/ads-adservices/src/androidTest/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManagerTest.kt
@@ -22,10 +22,10 @@
import android.os.OutcomeReceiver
import android.os.ext.SdkExtensions
import androidx.annotation.RequiresExtension
-import androidx.test.core.app.ApplicationProvider
import androidx.privacysandbox.ads.adservices.adselection.AdSelectionManager.Companion.obtain
import androidx.privacysandbox.ads.adservices.common.AdSelectionSignals
import androidx.privacysandbox.ads.adservices.common.AdTechIdentifier
+import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adid/AdIdManager.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adid/AdIdManager.kt
index eaaae29..129d17b 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adid/AdIdManager.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adid/AdIdManager.kt
@@ -19,8 +19,8 @@
import android.adservices.common.AdServicesPermissions
import android.annotation.SuppressLint
import android.content.Context
-import android.os.ext.SdkExtensions
import android.os.LimitExceededException
+import android.os.ext.SdkExtensions
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresExtension
import androidx.annotation.RequiresPermission
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManager.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManager.kt
index 454a7cb..7e280c4 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManager.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/adselection/AdSelectionManager.kt
@@ -27,8 +27,8 @@
import androidx.annotation.RequiresPermission
import androidx.core.os.asOutcomeReceiver
import androidx.privacysandbox.ads.adservices.common.AdSelectionSignals
-import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
import androidx.privacysandbox.ads.adservices.common.AdTechIdentifier
+import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
import java.util.concurrent.TimeoutException
import kotlinx.coroutines.suspendCancellableCoroutine
diff --git a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/CustomAudienceManager.kt b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/CustomAudienceManager.kt
index f41199b..981aeaa 100644
--- a/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/CustomAudienceManager.kt
+++ b/privacysandbox/ads/ads-adservices/src/main/java/androidx/privacysandbox/ads/adservices/customaudience/CustomAudienceManager.kt
@@ -27,8 +27,8 @@
import androidx.core.os.asOutcomeReceiver
import androidx.privacysandbox.ads.adservices.common.AdData
import androidx.privacysandbox.ads.adservices.common.AdSelectionSignals
-import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
import androidx.privacysandbox.ads.adservices.common.AdTechIdentifier
+import androidx.privacysandbox.ads.adservices.internal.AdServicesInfo
import kotlinx.coroutines.suspendCancellableCoroutine
/**
diff --git a/privacysandbox/plugins/plugins-privacysandbox-library/src/test/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPluginTest.kt b/privacysandbox/plugins/plugins-privacysandbox-library/src/test/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPluginTest.kt
index e623e74..ac1f28b 100644
--- a/privacysandbox/plugins/plugins-privacysandbox-library/src/test/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPluginTest.kt
+++ b/privacysandbox/plugins/plugins-privacysandbox-library/src/test/java/androidx/privacysandboxlibraryplugin/PrivacySandboxLibraryPluginTest.kt
@@ -23,10 +23,9 @@
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
-import org.junit.Test
-
import org.junit.Before
import org.junit.Rule
+import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/FileClassLoaderFactoryTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/FileClassLoaderFactoryTest.kt
index 31fee55..22d795b 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/FileClassLoaderFactoryTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/FileClassLoaderFactoryTest.kt
@@ -18,8 +18,8 @@
import android.content.Context
import androidx.privacysandbox.sdkruntime.client.config.LocalSdkConfig
-import androidx.privacysandbox.sdkruntime.client.loader.storage.LocalSdkStorage
import androidx.privacysandbox.sdkruntime.client.loader.storage.LocalSdkDexFiles
+import androidx.privacysandbox.sdkruntime.client.loader.storage.LocalSdkStorage
import androidx.privacysandbox.sdkruntime.client.loader.storage.TestLocalSdkStorage
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
index def9887..40aee3a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkTestUtils.kt
@@ -20,8 +20,8 @@
import android.os.Bundle
import android.os.IBinder
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
-import androidx.privacysandbox.sdkruntime.core.Versions
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
+import androidx.privacysandbox.sdkruntime.core.Versions
import kotlin.reflect.cast
/**
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
index 049e853..5104e2a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
@@ -36,6 +36,7 @@
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_NOT_FOUND
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.toLoadCompatSdkException
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import java.lang.ref.WeakReference
import java.util.WeakHashMap
import java.util.concurrent.Executor
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -346,7 +347,7 @@
companion object {
- private val sInstances = WeakHashMap<Context, SdkSandboxManagerCompat>()
+ private val sInstances = WeakHashMap<Context, WeakReference<SdkSandboxManagerCompat>>()
/**
* Creates [SdkSandboxManagerCompat].
@@ -358,7 +359,8 @@
@JvmStatic
fun from(context: Context): SdkSandboxManagerCompat {
synchronized(sInstances) {
- var instance = sInstances[context]
+ val reference = sInstances[context]
+ var instance = reference?.get()
if (instance == null) {
val configHolder = LocalSdkConfigsHolder.load(context)
val localSdks = LocallyLoadedSdks()
@@ -371,7 +373,7 @@
localSdks,
sdkLoader
)
- sInstances[context] = instance
+ sInstances[context] = WeakReference(instance)
}
return instance
}
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
index d43d7fc..598b368 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/parser/InterfaceParserTest.kt
@@ -22,8 +22,8 @@
import androidx.privacysandbox.tools.core.model.Method
import androidx.privacysandbox.tools.core.model.Parameter
import androidx.privacysandbox.tools.core.model.ParsedApi
-import androidx.privacysandbox.tools.core.model.Types
import androidx.privacysandbox.tools.core.model.Type
+import androidx.privacysandbox.tools.core.model.Types
import androidx.privacysandbox.tools.core.model.Types.asNullable
import androidx.room.compiler.processing.util.Source
import com.google.common.truth.Truth.assertThat
diff --git a/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/InterfaceFileGenerator.kt b/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/InterfaceFileGenerator.kt
index e7e87a0..19d9baf 100644
--- a/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/InterfaceFileGenerator.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/InterfaceFileGenerator.kt
@@ -17,12 +17,12 @@
package androidx.privacysandbox.tools.apigenerator
import androidx.privacysandbox.tools.core.generator.addCommonSettings
-import androidx.privacysandbox.tools.core.model.AnnotatedInterface
-import androidx.privacysandbox.tools.core.model.Method
import androidx.privacysandbox.tools.core.generator.build
import androidx.privacysandbox.tools.core.generator.poetClassName
import androidx.privacysandbox.tools.core.generator.poetSpec
import androidx.privacysandbox.tools.core.generator.poetTypeName
+import androidx.privacysandbox.tools.core.model.AnnotatedInterface
+import androidx.privacysandbox.tools.core.model.Method
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
diff --git a/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/PrivacySandboxApiGenerator.kt b/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/PrivacySandboxApiGenerator.kt
index e43ec79..1e13499 100644
--- a/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/PrivacySandboxApiGenerator.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/main/java/androidx/privacysandbox/tools/apigenerator/PrivacySandboxApiGenerator.kt
@@ -25,8 +25,8 @@
import androidx.privacysandbox.tools.core.generator.ClientProxyTypeGenerator
import androidx.privacysandbox.tools.core.generator.CoreLibInfoAndBinderWrapperConverterGenerator
import androidx.privacysandbox.tools.core.generator.GenerationTarget
-import androidx.privacysandbox.tools.core.generator.PrivacySandboxExceptionFileGenerator
import androidx.privacysandbox.tools.core.generator.PrivacySandboxCancellationExceptionFileGenerator
+import androidx.privacysandbox.tools.core.generator.PrivacySandboxExceptionFileGenerator
import androidx.privacysandbox.tools.core.generator.ServiceFactoryFileGenerator
import androidx.privacysandbox.tools.core.generator.StubDelegatesGenerator
import androidx.privacysandbox.tools.core.generator.ThrowableParcelConverterFileGenerator
diff --git a/privacysandbox/tools/tools-apipackager/src/main/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackager.kt b/privacysandbox/tools/tools-apipackager/src/main/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackager.kt
index 382927c..8471190 100644
--- a/privacysandbox/tools/tools-apipackager/src/main/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackager.kt
+++ b/privacysandbox/tools/tools-apipackager/src/main/java/androidx/privacysandbox/tools/apipackager/PrivacySandboxApiPackager.kt
@@ -17,15 +17,15 @@
package androidx.privacysandbox.tools.apipackager
import androidx.privacysandbox.tools.apipackager.AnnotationInspector.hasPrivacySandboxAnnotation
+import androidx.privacysandbox.tools.core.Metadata
import java.nio.file.Path
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import kotlin.io.path.exists
-import kotlin.io.path.isDirectory
-import kotlin.io.path.notExists
-import androidx.privacysandbox.tools.core.Metadata
import kotlin.io.path.extension
import kotlin.io.path.inputStream
+import kotlin.io.path.isDirectory
+import kotlin.io.path.notExists
class PrivacySandboxApiPackager {
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ServiceFactoryFileGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ServiceFactoryFileGenerator.kt
index ffc5941..99979ab 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ServiceFactoryFileGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ServiceFactoryFileGenerator.kt
@@ -16,8 +16,8 @@
package androidx.privacysandbox.tools.core.generator
-import androidx.privacysandbox.tools.internal.GeneratedPublicApi
import androidx.privacysandbox.tools.core.model.AnnotatedInterface
+import androidx.privacysandbox.tools.internal.GeneratedPublicApi
import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ValueConverterFileGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ValueConverterFileGenerator.kt
index e5e0ba2..e2d5768 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ValueConverterFileGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ValueConverterFileGenerator.kt
@@ -16,9 +16,9 @@
package androidx.privacysandbox.tools.core.generator
+import androidx.privacysandbox.tools.core.generator.GenerationTarget.SERVER
import androidx.privacysandbox.tools.core.generator.SpecNames.contextClass
import androidx.privacysandbox.tools.core.generator.SpecNames.contextPropertyName
-import androidx.privacysandbox.tools.core.generator.GenerationTarget.SERVER
import androidx.privacysandbox.tools.core.model.AnnotatedValue
import androidx.privacysandbox.tools.core.model.ValueProperty
import com.squareup.kotlinpoet.CodeBlock
diff --git a/privacysandbox/ui/integration-tests/testapp/src/main/java/androidx/privacysandbox/ui/integration/testapp/MainActivity.kt b/privacysandbox/ui/integration-tests/testapp/src/main/java/androidx/privacysandbox/ui/integration/testapp/MainActivity.kt
index 4e15e86..9373477 100644
--- a/privacysandbox/ui/integration-tests/testapp/src/main/java/androidx/privacysandbox/ui/integration/testapp/MainActivity.kt
+++ b/privacysandbox/ui/integration-tests/testapp/src/main/java/androidx/privacysandbox/ui/integration/testapp/MainActivity.kt
@@ -20,7 +20,6 @@
import android.app.sdksandbox.SandboxedSdk
import android.app.sdksandbox.SdkSandboxManager
import android.content.res.Configuration
-import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.OutcomeReceiver
import android.os.ext.SdkExtensions
@@ -29,6 +28,7 @@
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.RequiresExtension
+import androidx.appcompat.app.AppCompatActivity
import androidx.privacysandbox.ui.client.SandboxedUiAdapterFactory
import androidx.privacysandbox.ui.client.view.SandboxedSdkUiSessionState
import androidx.privacysandbox.ui.client.view.SandboxedSdkUiSessionStateChangedListener
diff --git a/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
index 84d3466..68778460 100644
--- a/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
+++ b/privacysandbox/ui/ui-client/src/androidTest/java/androidx/privacysandbox/ui/client/test/SandboxedSdkViewTest.kt
@@ -43,6 +43,7 @@
import org.junit.Assert.assertTrue
import org.junit.Assume
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -277,6 +278,7 @@
}
@Test
+ @Ignore("b/272324246")
fun onConfigurationChangedTest() {
val layout = activity.findViewById<LinearLayout>(R.id.mainlayout)
diff --git a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
index 5084dc1..a2ea2da 100644
--- a/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
+++ b/privacysandbox/ui/ui-tests/src/androidTest/java/androidx/privacysandbox/ui/tests/endtoend/IntegrationTests.kt
@@ -182,6 +182,7 @@
}
@Test
+ @Ignore("b/272324246")
fun testConfigurationChanged() {
val configChangedLatch = CountDownLatch(1)
val adapter = TestSandboxedUiAdapter(
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/build.gradle b/profileinstaller/integration-tests/init-macrobenchmark/build.gradle
index 0d054c7..7088271 100644
--- a/profileinstaller/integration-tests/init-macrobenchmark/build.gradle
+++ b/profileinstaller/integration-tests/init-macrobenchmark/build.gradle
@@ -16,7 +16,7 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -25,24 +25,21 @@
minSdkVersion 23
}
namespace "androidx.profileinstaller.integration.macrobenchmark"
+ targetProjectPath = ":profileinstaller:integration-tests:init-macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":profileinstaller:profileinstaller"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":profileinstaller:integration-tests:init-macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":profileinstaller:integration-tests:init-macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":profileinstaller:profileinstaller"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
}
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml b/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 5b41847..0000000
--- a/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml
index ed173d5..5b41847 100644
--- a/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml
+++ b/profileinstaller/integration-tests/init-macrobenchmark/src/main/AndroidManifest.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
~ Copyright (C) 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt b/profileinstaller/integration-tests/init-macrobenchmark/src/main/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt
similarity index 100%
rename from profileinstaller/integration-tests/init-macrobenchmark/src/androidTest/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt
rename to profileinstaller/integration-tests/init-macrobenchmark/src/main/java/androidx/profileinstaller/integration/macrobenchmark/ProfileinstallerStartupBenchmark.kt
diff --git a/profileinstaller/integration-tests/profile-verification/src/androidTest/AndroidManifest.xml b/profileinstaller/integration-tests/profile-verification/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index bae036b..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?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 />
diff --git a/profileinstaller/integration-tests/profile-verification/src/main/AndroidManifest.xml b/profileinstaller/integration-tests/profile-verification/src/main/AndroidManifest.xml
deleted file mode 100644
index d4c1970..0000000
--- a/profileinstaller/integration-tests/profile-verification/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?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 />
diff --git a/profileinstaller/profileinstaller-benchmark/src/androidTest/java/androidx/profileinstaller/benchmark/ProfileInstallerTranscodeBenchmark.kt b/profileinstaller/profileinstaller-benchmark/src/androidTest/java/androidx/profileinstaller/benchmark/ProfileInstallerTranscodeBenchmark.kt
index 597baf4..b85813e 100644
--- a/profileinstaller/profileinstaller-benchmark/src/androidTest/java/androidx/profileinstaller/benchmark/ProfileInstallerTranscodeBenchmark.kt
+++ b/profileinstaller/profileinstaller-benchmark/src/androidTest/java/androidx/profileinstaller/benchmark/ProfileInstallerTranscodeBenchmark.kt
@@ -25,13 +25,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry
+import java.io.File
import org.junit.After
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/profileinstaller/profileinstaller-benchmark/src/main/AndroidManifest.xml b/profileinstaller/profileinstaller-benchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 29b496b..0000000
--- a/profileinstaller/profileinstaller-benchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/profileinstaller/profileinstaller/build.gradle b/profileinstaller/profileinstaller/build.gradle
index ba3d60d..793c5e5 100644
--- a/profileinstaller/profileinstaller/build.gradle
+++ b/profileinstaller/profileinstaller/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "androidx.profileinstaller:profileinstaller"
+ name = "Profile Installer"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Allows libraries to prepopulate ahead of time compilation traces to be read by" +
diff --git a/recommendation/recommendation/build.gradle b/recommendation/recommendation/build.gradle
index 25a96bf..50c69b0 100644
--- a/recommendation/recommendation/build.gradle
+++ b/recommendation/recommendation/build.gradle
@@ -17,7 +17,7 @@
}
androidx {
- name = "Android Support Recommendation"
+ name = "Recommendation"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2015"
description = "Android Support Recommendation"
diff --git a/recommendation/recommendation/src/main/AndroidManifest.xml b/recommendation/recommendation/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/recommendation/recommendation/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeDetector.kt b/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeDetector.kt
index addc95f..6b24503 100644
--- a/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeDetector.kt
+++ b/recyclerview/recyclerview-lint/src/main/java/androidx/recyclerview/lint/InvalidSetHasFixedSizeDetector.kt
@@ -36,12 +36,12 @@
import com.android.tools.lint.detector.api.XmlContext
import com.android.tools.lint.detector.api.XmlScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.toUElement
import org.jetbrains.uast.visitor.AbstractUastVisitor
import org.w3c.dom.Element
-import java.util.EnumSet
class InvalidSetHasFixedSizeDetector : Detector(), XmlScanner, SourceCodeScanner {
diff --git a/recyclerview/recyclerview-selection/build.gradle b/recyclerview/recyclerview-selection/build.gradle
index 49f9cfd..12c9e66 100644
--- a/recyclerview/recyclerview-selection/build.gradle
+++ b/recyclerview/recyclerview-selection/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android RecyclerView Selection"
+ name = "RecyclerView Selection"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.RECYCLERVIEW_SELECTION
inceptionYear = "2017"
diff --git a/recyclerview/recyclerview-selection/src/main/AndroidManifest.xml b/recyclerview/recyclerview-selection/src/main/AndroidManifest.xml
deleted file mode 100644
index 8162281..0000000
--- a/recyclerview/recyclerview-selection/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2017 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 />
diff --git a/recyclerview/recyclerview/build.gradle b/recyclerview/recyclerview/build.gradle
index aecfc856..8c7e013 100644
--- a/recyclerview/recyclerview/build.gradle
+++ b/recyclerview/recyclerview/build.gradle
@@ -58,7 +58,7 @@
}
androidx {
- name = "Android Support RecyclerView"
+ name = "RecyclerView"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.RECYCLERVIEW
inceptionYear = "2014"
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/AsyncListDifferTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/AsyncListDifferTest.kt
index 2b4ec9a..c3da7a7 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/AsyncListDifferTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/AsyncListDifferTest.kt
@@ -19,6 +19,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.testutils.TestExecutor
+import java.util.Collections.emptyList
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotSame
import org.junit.Assert.assertSame
@@ -30,7 +31,6 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.verifyZeroInteractions
-import java.util.Collections.emptyList
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/BaseSnapHelperCenterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/BaseSnapHelperCenterTest.kt
index 2d8f2e1..eac39fc 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/BaseSnapHelperCenterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/BaseSnapHelperCenterTest.kt
@@ -16,22 +16,19 @@
package androidx.recyclerview.widget
-import org.hamcrest.CoreMatchers.`is`
-import org.hamcrest.MatcherAssert.assertThat
-
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.test.core.app.ApplicationProvider
import androidx.test.filters.LargeTest
-
+import java.util.ArrayList
+import org.hamcrest.CoreMatchers.`is`
+import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.ArrayList
-
/**
* Small integration test base that helps verify that [SnapHelper]s that implement "center"
* snapping define "center" correctly.
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ConcatAdapterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ConcatAdapterTest.kt
index be28ecd..89330ac 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ConcatAdapterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ConcatAdapterTest.kt
@@ -44,12 +44,12 @@
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.reflect.Method
-import java.lang.reflect.Modifier
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LazyStateRestorationTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LazyStateRestorationTest.kt
index b9265e5..841555c 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LazyStateRestorationTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LazyStateRestorationTest.kt
@@ -33,12 +33,12 @@
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import java.util.LinkedHashMap
+import java.util.UUID
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.LinkedHashMap
-import java.util.UUID
@RunWith(Parameterized::class)
@SmallTest
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindReferenceChildTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindReferenceChildTest.kt
index 12a8a44..987a3f9 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindReferenceChildTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindReferenceChildTest.kt
@@ -21,11 +21,11 @@
import androidx.recyclerview.widget.RecyclerView.HORIZONTAL
import androidx.recyclerview.widget.RecyclerView.VERTICAL
import androidx.test.filters.MediumTest
+import java.util.ArrayList
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.ArrayList
// Size of both the width and height of both RecyclerView and it's children
private const val size = 500
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindZeroPxReferenceChildTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindZeroPxReferenceChildTest.kt
index 5476284..da4e121 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindZeroPxReferenceChildTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearLayoutManagerFindZeroPxReferenceChildTest.kt
@@ -21,11 +21,11 @@
import androidx.recyclerview.widget.RecyclerView.HORIZONTAL
import androidx.recyclerview.widget.RecyclerView.VERTICAL
import androidx.test.filters.MediumTest
+import java.util.ArrayList
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.ArrayList
// Number of items that fit in RecyclerView's viewport
private const val n = 4
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearSnapHelperCenterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearSnapHelperCenterTest.kt
index ac974a6..e05e6c00 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearSnapHelperCenterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/LinearSnapHelperCenterTest.kt
@@ -17,7 +17,6 @@
package androidx.recyclerview.widget
import androidx.test.filters.LargeTest
-
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ListAdapterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ListAdapterTest.kt
index 5e811b7..5411f39 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ListAdapterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/ListAdapterTest.kt
@@ -20,6 +20,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.testutils.TestExecutor
+import java.util.Collections.emptyList
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
@@ -28,7 +29,6 @@
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.Mockito.verifyZeroInteractions
-import java.util.Collections.emptyList
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PagerSnapHelperCenterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PagerSnapHelperCenterTest.kt
index 017572a..1d62973 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PagerSnapHelperCenterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/PagerSnapHelperCenterTest.kt
@@ -17,7 +17,6 @@
package androidx.recyclerview.widget
import androidx.test.filters.LargeTest
-
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewNestedScrollingFlingTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewNestedScrollingFlingTest.kt
index 6954bc2..201394a 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewNestedScrollingFlingTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewNestedScrollingFlingTest.kt
@@ -28,6 +28,8 @@
import androidx.test.filters.LargeTest
import androidx.testutils.ActivityScenarioResetRule
import androidx.testutils.ResettableActivityScenarioRule
+import java.util.ArrayList
+import java.util.Arrays
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.closeTo
import org.junit.Before
@@ -36,8 +38,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.ArrayList
-import java.util.Arrays
/**
* This test verifies that the velocity that RecyclerView flings with in response to finger input
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewSmoothScrollToPositionTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewSmoothScrollToPositionTest.kt
index 6fdbaf7..fcfce45 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewSmoothScrollToPositionTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewSmoothScrollToPositionTest.kt
@@ -22,14 +22,14 @@
import android.widget.TextView
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers.`is`
-import org.junit.Assert
import org.hamcrest.MatcherAssert.assertThat
+import org.junit.Assert
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
index dd7781b..e5076f6 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/StaggeredGridLayoutManagerCacheTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertTrue;
import android.os.Build;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SdkSuppress;
@@ -92,6 +93,7 @@
@MediumTest
@Test
+ @FlakyTest(bugId = 281085288)
public void cacheAndPrefetch() throws Throwable {
final Config config = (Config) mConfig.clone();
setupByConfig(config);
diff --git a/recyclerview/recyclerview/src/main/AndroidManifest.xml b/recyclerview/recyclerview/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c8a63b..0000000
--- a/recyclerview/recyclerview/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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 />
\ No newline at end of file
diff --git a/recyclerview/recyclerview/src/test/java/androidx/recyclerview/widget/DiffUtilTest.kt b/recyclerview/recyclerview/src/test/java/androidx/recyclerview/widget/DiffUtilTest.kt
index 8aa135a..7146b50 100644
--- a/recyclerview/recyclerview/src/test/java/androidx/recyclerview/widget/DiffUtilTest.kt
+++ b/recyclerview/recyclerview/src/test/java/androidx/recyclerview/widget/DiffUtilTest.kt
@@ -15,8 +15,10 @@
*/
package androidx.recyclerview.widget
-import org.hamcrest.CoreMatchers.`is`
+import java.util.Random
+import java.util.UUID
import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.not
import org.hamcrest.CoreMatchers.nullValue
import org.hamcrest.MatcherAssert.assertThat
@@ -29,8 +31,6 @@
import org.junit.runner.Description
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.Random
-import java.util.UUID
@RunWith(JUnit4::class)
class DiffUtilTest {
diff --git a/resourceinspection/resourceinspection-annotation/build.gradle b/resourceinspection/resourceinspection-annotation/build.gradle
index 86bb07a..a5b9ce9 100644
--- a/resourceinspection/resourceinspection-annotation/build.gradle
+++ b/resourceinspection/resourceinspection-annotation/build.gradle
@@ -26,7 +26,7 @@
}
androidx {
- name = "Android Resource Inspection - Annotations"
+ name = "Resource Inspection - Annotations"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Annotation processors for Android resource and layout inspection"
diff --git a/resourceinspection/resourceinspection-processor/build.gradle b/resourceinspection/resourceinspection-processor/build.gradle
index a633319..959ea3d 100644
--- a/resourceinspection/resourceinspection-processor/build.gradle
+++ b/resourceinspection/resourceinspection-processor/build.gradle
@@ -50,7 +50,7 @@
}
androidx {
- name = "Android Resource Inspection - Annotation Processor"
+ name = "Resource Inspection - Annotation Processor"
type = LibraryType.ANNOTATION_PROCESSOR
inceptionYear = "2021"
description = "Annotation processors for Android resource and layout inspection"
diff --git a/resourceinspection/resourceinspection-processor/src/main/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessor.kt b/resourceinspection/resourceinspection-processor/src/main/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessor.kt
index 4611436..41a9564 100644
--- a/resourceinspection/resourceinspection-processor/src/main/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessor.kt
+++ b/resourceinspection/resourceinspection-processor/src/main/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessor.kt
@@ -18,10 +18,10 @@
import com.google.auto.common.BasicAnnotationProcessor
import com.google.auto.service.AutoService
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessor
-import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING
import javax.annotation.processing.Processor
import javax.lang.model.SourceVersion
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING
/** Annotation processor for resource inspection tools. */
@AutoService(Processor::class)
diff --git a/resourceinspection/resourceinspection-processor/src/test/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessorTest.kt b/resourceinspection/resourceinspection-processor/src/test/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessorTest.kt
index 0395f1c..87c1746 100644
--- a/resourceinspection/resourceinspection-processor/src/test/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessorTest.kt
+++ b/resourceinspection/resourceinspection-processor/src/test/kotlin/androidx/resourceinspection/processor/ResourceInspectionProcessorTest.kt
@@ -21,11 +21,11 @@
import com.google.testing.compile.CompilationSubject.assertThat
import com.google.testing.compile.Compiler.javac
import com.google.testing.compile.JavaFileObjects
-import org.intellij.lang.annotations.Language
-import org.junit.Test
import java.io.File
import javax.lang.model.SourceVersion
import javax.tools.JavaFileObject
+import org.intellij.lang.annotations.Language
+import org.junit.Test
/** Integration and unit tests for [ResourceInspectionProcessor]. */
class ResourceInspectionProcessorTest {
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/NewThreadDispatcher.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/NewThreadDispatcher.kt
index 376823b..e61991e 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/NewThreadDispatcher.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/NewThreadDispatcher.kt
@@ -16,12 +16,12 @@
package androidx.room.integration.kotlintestapp
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.InternalCoroutinesApi
-import kotlinx.coroutines.Runnable
import java.util.concurrent.atomic.AtomicInteger
import kotlin.concurrent.thread
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.Runnable
/**
* A CoroutineDispatcher that dispatches every block into a new thread
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/TestDatabase.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/TestDatabase.kt
index 5ecead7..2d4cb03 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/TestDatabase.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/TestDatabase.kt
@@ -47,11 +47,11 @@
import androidx.room.integration.kotlintestapp.vo.PlaylistSongXRef
import androidx.room.integration.kotlintestapp.vo.Publisher
import androidx.room.integration.kotlintestapp.vo.Song
+import androidx.room.integration.kotlintestapp.vo.Toy
+import androidx.room.integration.kotlintestapp.vo.User
import java.nio.ByteBuffer
import java.util.Date
import java.util.UUID
-import androidx.room.integration.kotlintestapp.vo.Toy
-import androidx.room.integration.kotlintestapp.vo.User
@Database(
entities = [
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
index d5bc9e5..625d44f 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
@@ -24,15 +24,15 @@
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry
-import org.hamcrest.CoreMatchers.`is`
+import java.io.FileNotFoundException
+import java.io.IOException
import org.hamcrest.CoreMatchers.containsString
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.nullValue
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Rule
import org.junit.Test
-import java.io.FileNotFoundException
-import java.io.IOException
@MediumTest
class MigrationKotlinTest {
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/BoxedNonNullTypesTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/BoxedNonNullTypesTest.kt
index 005da89..9679239 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/BoxedNonNullTypesTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/BoxedNonNullTypesTest.kt
@@ -37,13 +37,13 @@
import com.google.common.util.concurrent.ListenableFuture
import io.reactivex.Flowable
import io.reactivex.Observable
+import java.util.Optional
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Optional
/**
* This test matters in KSP specifically where we might use primitive adapter for non-null java
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ConstructorInheritanceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ConstructorInheritanceTest.kt
index f5af52b..64f21a7 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ConstructorInheritanceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/ConstructorInheritanceTest.kt
@@ -30,9 +30,9 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.hasItems
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.hasSize
import org.junit.Test
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
index 31b33dc..6653b7f 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/FlowQueryTest.kt
@@ -21,6 +21,8 @@
import androidx.room.withTransaction
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
@@ -38,8 +40,6 @@
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
@MediumTest
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
index 909eabb..4f6a445 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/QueryInterceptorTest.kt
@@ -32,6 +32,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.util.concurrent.MoreExecutors
+import java.util.concurrent.CopyOnWriteArrayList
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
@@ -39,7 +40,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CopyOnWriteArrayList
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
index 1423d98..cef0319 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/Rx3PagingSourceTest.kt
@@ -16,10 +16,10 @@
package androidx.room.integration.kotlintestapp.test
+import androidx.kruth.assertThat
import androidx.paging.Pager
import androidx.paging.PagingState
import androidx.paging.rxjava3.RxPagingSource
-import androidx.kruth.assertThat
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.integration.kotlintestapp.testutil.ItemStore
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SneakyThrowTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SneakyThrowTest.kt
index 2fee4f7..977ba54 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SneakyThrowTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SneakyThrowTest.kt
@@ -18,12 +18,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import java.util.concurrent.Callable
import org.json.JSONException
import org.json.JSONObject
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.Callable
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendRoomDispatcherTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendRoomDispatcherTest.kt
index 744283c..10770bc 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendRoomDispatcherTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendRoomDispatcherTest.kt
@@ -19,13 +19,13 @@
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.arch.core.executor.DefaultTaskExecutor
import androidx.test.filters.SmallTest
+import java.util.concurrent.atomic.AtomicInteger
import kotlinx.coroutines.runBlocking
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
-import java.util.concurrent.atomic.AtomicInteger
/**
* A small test to verify Room's executor is used as dispatcher for DAO suspend functions.
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingTransactionCancellationTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingTransactionCancellationTest.kt
index 3bf3982..f92825f 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingTransactionCancellationTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingTransactionCancellationTest.kt
@@ -16,14 +16,15 @@
package androidx.room.integration.kotlintestapp.test
+import androidx.kruth.assertThat
import androidx.room.integration.kotlintestapp.vo.Book
import androidx.room.withTransaction
-import androidx.kruth.assertThat
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.filters.MediumTest
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
@@ -40,7 +41,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
// see b/148181325
@RunWith(AndroidJUnit4::class)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/UuidColumnTypeAdapterTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/UuidColumnTypeAdapterTest.kt
index f7d3dc9..4bd0c4f 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/UuidColumnTypeAdapterTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/UuidColumnTypeAdapterTest.kt
@@ -30,11 +30,11 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import org.junit.Test
-import org.junit.runner.RunWith
import java.nio.ByteBuffer
import java.util.UUID
import kotlin.reflect.KClass
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/room/room-common/build.gradle b/room/room-common/build.gradle
index 151639e..bd514ec 100644
--- a/room/room-common/build.gradle
+++ b/room/room-common/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Room-Common"
+ name = "Room-Common"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Room-Common"
diff --git a/room/room-common/src/main/java/androidx/room/Delete.kt b/room/room-common/src/main/java/androidx/room/Delete.kt
index 176fd26..fbae415 100644
--- a/room/room-common/src/main/java/androidx/room/Delete.kt
+++ b/room/room-common/src/main/java/androidx/room/Delete.kt
@@ -34,7 +34,7 @@
* public fun deleteSongs(vararg songs: Song)
*
* @Delete
- * public fun deleteAlbumAndSongs(val album: Album, val songs: List<Song>)
+ * public fun deleteAlbumAndSongs(album: Album, songs: List<Song>)
* }
* ```
*
diff --git a/room/room-common/src/main/java/androidx/room/Fts4.kt b/room/room-common/src/main/java/androidx/room/Fts4.kt
index 7255265..f9ed6e1 100644
--- a/room/room-common/src/main/java/androidx/room/Fts4.kt
+++ b/room/room-common/src/main/java/androidx/room/Fts4.kt
@@ -16,12 +16,11 @@
package androidx.room
-import kotlin.reflect.KClass
-
import androidx.annotation.RequiresApi
-import androidx.room.FtsOptions.TOKENIZER_SIMPLE
import androidx.room.FtsOptions.MatchInfo
import androidx.room.FtsOptions.Order
+import androidx.room.FtsOptions.TOKENIZER_SIMPLE
+import kotlin.reflect.KClass
/**
* Marks an [Entity] annotated class as a FTS4 entity. This class will have a mapping SQLite
diff --git a/room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt b/room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt
index 80885a53..65dc715 100644
--- a/room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt
+++ b/room/room-common/src/test/java/androidx/room/AmbiguousColumnResolverTest.kt
@@ -18,8 +18,8 @@
import androidx.kruth.assertThat
import java.util.Locale
-import org.junit.Test
import org.junit.Ignore
+import org.junit.Test
class AmbiguousColumnResolverTest {
diff --git a/room/room-common/src/test/java/androidx/room/AnnotationRetentionPolicyTest.kt b/room/room-common/src/test/java/androidx/room/AnnotationRetentionPolicyTest.kt
index 43a60e5..025fe3b 100644
--- a/room/room-common/src/test/java/androidx/room/AnnotationRetentionPolicyTest.kt
+++ b/room/room-common/src/test/java/androidx/room/AnnotationRetentionPolicyTest.kt
@@ -18,9 +18,9 @@
import androidx.kruth.assertThat
import com.google.common.reflect.ClassPath
-import org.junit.Test
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
+import org.junit.Test
/** Test to make sure annotations have the correct retention policy. */
class AnnotationRetentionPolicyTest {
diff --git a/room/room-compiler-processing-testing/build.gradle b/room/room-compiler-processing-testing/build.gradle
index 2d1f1e7c..abc8872 100644
--- a/room/room-compiler-processing-testing/build.gradle
+++ b/room/room-compiler-processing-testing/build.gradle
@@ -72,7 +72,7 @@
}
androidx {
- name = "AndroidX Room XProcessor Testing"
+ name = "Room XProcessor Testing"
type = LibraryType.ANNOTATION_PROCESSOR_UTILS
inceptionYear = "2020"
description = "Testing helpers for Room XProcessing APIs"
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationTestCapabilities.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationTestCapabilities.kt
index d611ef2..ba27129 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationTestCapabilities.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/CompilationTestCapabilities.kt
@@ -16,8 +16,8 @@
package androidx.room.compiler.processing.util
-import org.junit.AssumptionViolatedException
import java.util.Properties
+import org.junit.AssumptionViolatedException
/**
* Provides the information about compilation test capabilities.
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/Source.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/Source.kt
index 4860763..4e97a26 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/Source.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/Source.kt
@@ -17,9 +17,9 @@
package androidx.room.compiler.processing.util
import com.google.testing.compile.JavaFileObjects
-import org.intellij.lang.annotations.Language
import java.io.File
import javax.tools.JavaFileObject
+import org.intellij.lang.annotations.Language
/**
* Common abstraction for test sources in kotlin and java
diff --git a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/compiler/steps/KotlinSourceCompilationStep.kt b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/compiler/steps/KotlinSourceCompilationStep.kt
index aa80eaf..940b4e6 100644
--- a/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/compiler/steps/KotlinSourceCompilationStep.kt
+++ b/room/room-compiler-processing-testing/src/main/java/androidx/room/compiler/processing/util/compiler/steps/KotlinSourceCompilationStep.kt
@@ -17,9 +17,9 @@
package androidx.room.compiler.processing.util.compiler.steps
import androidx.room.compiler.processing.util.compiler.KotlinCliRunner
-import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
-import org.jetbrains.kotlin.cli.common.ExitCode
import java.io.File
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
/**
* Compiles kotlin sources.
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
index cf0ef44..dda1356 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/DiagnosticsTest.kt
@@ -18,10 +18,10 @@
import androidx.room.compiler.processing.ExperimentalProcessingApi
import com.google.common.truth.Truth.assertThat
+import javax.tools.Diagnostic
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import javax.tools.Diagnostic
@RunWith(Parameterized::class)
@OptIn(ExperimentalProcessingApi::class)
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
index 11372ae..ba43888 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/GeneratedCodeMatchTest.kt
@@ -16,7 +16,6 @@
package androidx.room.compiler.processing.util
-import com.squareup.kotlinpoet.TypeSpec as KTypeSpec
import androidx.room.compiler.processing.ExperimentalProcessingApi
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.compat.XConverters.toXProcessing
@@ -26,6 +25,7 @@
import com.squareup.javapoet.TypeSpec
import com.squareup.kotlinpoet.BOOLEAN
import com.squareup.kotlinpoet.FileSpec
+import com.squareup.kotlinpoet.TypeSpec as KTypeSpec
import java.io.File
import org.junit.AssumptionViolatedException
import org.junit.Test
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
index 0313f36..b6e62b6 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/MultiRoundProcessingTest.kt
@@ -20,10 +20,10 @@
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.TypeSpec
+import javax.tools.Diagnostic
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import javax.tools.Diagnostic
@RunWith(Parameterized::class)
class MultiRoundProcessingTest(
diff --git a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
index 3ad0d31..f13460d 100644
--- a/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
+++ b/room/room-compiler-processing-testing/src/test/java/androidx/room/compiler/processing/util/TestRunnerTest.kt
@@ -38,11 +38,11 @@
import com.squareup.javapoet.TypeSpec
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
-import org.junit.Test
import java.net.URLClassLoader
import java.nio.file.Files
import javax.lang.model.element.Modifier
import javax.tools.Diagnostic
+import org.junit.Test
@OptIn(ExperimentalProcessingApi::class)
class TestRunnerTest {
diff --git a/room/room-compiler-processing/build.gradle b/room/room-compiler-processing/build.gradle
index 345e56b..f8d3190 100644
--- a/room/room-compiler-processing/build.gradle
+++ b/room/room-compiler-processing/build.gradle
@@ -20,6 +20,42 @@
plugins {
id("AndroidXPlugin")
id("kotlin")
+ id("com.github.johnrengelman.shadow")
+}
+
+configurations {
+ // For shadowed / jarjared deps
+ shadowed
+ // shadowed deps are compile only deps
+ compileOnly.extendsFrom(shadowed)
+ // compiler tests don't use shadowed, so include them
+ testCompile.extendsFrom(shadowed)
+ // for downstream tests
+ shadowAndImplementation.extendsFrom(shadow)
+ shadowAndImplementation.extendsFrom(implementation)
+}
+
+shadowJar {
+ archiveClassifier = ""
+ configurations = [project.configurations.shadowed]
+ relocate("kotlinx.metadata", "androidx.room.jarjarred.kotlinx.metadata")
+ mergeServiceFiles() // kotlinx-metadata-jvm has a service descriptor that needs transformation
+}
+
+jar {
+ archiveClassifier = "before-jarjar"
+}
+
+configurations {
+ // replace the standard jar with the one built by 'shadowJar' in both api and runtime variants
+ apiElements.outgoing.artifacts.clear()
+ apiElements.outgoing.artifact(shadowJar) {
+ builtBy shadowJar
+ }
+ runtimeElements.outgoing.artifacts.clear()
+ runtimeElements.outgoing.artifact(shadowJar) {
+ builtBy shadowJar
+ }
}
dependencies {
@@ -30,8 +66,9 @@
implementation(libs.guava)
implementation(libs.autoCommon)
implementation(libs.autoValueAnnotations)
-
- implementation(libs.kotlinMetadataJvm)
+ shadowed(libs.kotlinMetadataJvm) {
+ exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib"
+ }
implementation(libs.intellijAnnotations)
implementation(libs.kspApi)
implementation(libs.kotlinStdlibJdk8) // KSP defines older version as dependency, force update.
@@ -41,6 +78,7 @@
testImplementation(libs.junit)
testImplementation(libs.jsr250)
testImplementation(libs.ksp)
+ testImplementation(libs.kotlinMetadataJvm)
testImplementation(project(":room:room-compiler-processing-testing"))
testImplementation(project(":internal-testutils-common"))
}
@@ -60,7 +98,7 @@
}
androidx {
- name = "AndroidX Room XProcessor"
+ name = "Room XProcessor"
type = LibraryType.ANNOTATION_PROCESSOR_UTILS
inceptionYear = "2020"
description = "Processing Environment Abstraction for AndroidX Room"
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
index df2a0b3..522d97d 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
@@ -16,8 +16,6 @@
package androidx.room.compiler.codegen
-import com.squareup.kotlinpoet.asClassName as asKClassName
-import com.squareup.kotlinpoet.asTypeName as asKTypeName
import androidx.room.compiler.processing.XNullability
import com.squareup.kotlinpoet.ARRAY
import com.squareup.kotlinpoet.BOOLEAN_ARRAY
@@ -35,6 +33,8 @@
import com.squareup.kotlinpoet.MUTABLE_SET
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.SHORT_ARRAY
+import com.squareup.kotlinpoet.asClassName as asKClassName
+import com.squareup.kotlinpoet.asTypeName as asKTypeName
import com.squareup.kotlinpoet.javapoet.JClassName
import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
import com.squareup.kotlinpoet.javapoet.JTypeName
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
index 7dec0bc..9dee083 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
@@ -20,8 +20,8 @@
import androidx.room.compiler.processing.ksp.KSFileAsOriginatingElement
import androidx.room.compiler.processing.ksp.KspElement
import androidx.room.compiler.processing.ksp.KspMemberContainer
-import androidx.room.compiler.processing.ksp.wrapAsOriginatingElement
import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
+import androidx.room.compiler.processing.ksp.wrapAsOriginatingElement
import javax.lang.model.element.Element
import kotlin.contracts.contract
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacAnnotation.kt
index 7f45596..2e532d3 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacAnnotation.kt
@@ -18,9 +18,9 @@
import androidx.room.compiler.processing.InternalXAnnotation
import androidx.room.compiler.processing.XAnnotationBox
+import androidx.room.compiler.processing.XAnnotationValue
import androidx.room.compiler.processing.XNullability
import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.XAnnotationValue
import androidx.room.compiler.processing.compat.XConverters.toXProcessing
import com.google.auto.common.AnnotationMirrors
import com.google.auto.common.MoreTypes
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index 470c9af..1b31225 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -22,10 +22,10 @@
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSNode
import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.KSTypeAlias
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.KSTypeParameter
import com.google.devtools.ksp.symbol.KSTypeReference
-import com.google.devtools.ksp.symbol.Modifier
/**
* Root package comes as <root> instead of "" so we work around it here.
@@ -47,10 +47,12 @@
}
internal fun KSTypeReference.isTypeParameterReference(): Boolean {
- return this.resolve().declaration is KSTypeParameter
+ return this.resolve().isTypeParameter()
}
-fun KSType.isInline() = declaration.modifiers.contains(Modifier.INLINE)
+internal fun KSType.isTypeParameter(): Boolean {
+ return declaration is KSTypeParameter
+}
internal fun KSType.withNullability(nullability: XNullability) = when (nullability) {
XNullability.NULLABLE -> makeNullable()
@@ -59,14 +61,15 @@
}
private fun KSAnnotated.hasAnnotation(qName: String) =
- annotations.any { it.hasQualifiedName(qName) }
+ annotations.any { it.hasQualifiedNameOrAlias(qName) }
-private fun KSAnnotation.hasQualifiedName(qName: String): Boolean {
- return annotationType.resolve().hasQualifiedName(qName)
+private fun KSAnnotation.hasQualifiedNameOrAlias(qName: String): Boolean {
+ return annotationType.resolve().hasQualifiedNameOrAlias(qName)
}
-private fun KSType.hasQualifiedName(qName: String): Boolean {
- return declaration.qualifiedName?.asString() == qName
+private fun KSType.hasQualifiedNameOrAlias(qName: String): Boolean {
+ return declaration.qualifiedName?.asString() == qName ||
+ (declaration as? KSTypeAlias)?.type?.resolve()?.hasQualifiedNameOrAlias(qName) ?: false
}
internal fun KSAnnotated.hasJvmWildcardAnnotation() =
@@ -75,20 +78,46 @@
internal fun KSAnnotated.hasSuppressJvmWildcardAnnotation() =
hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
-private fun KSType.hasAnnotation(qName: String) = annotations.any { it.hasQualifiedName(qName) }
-
-internal fun KSType.hasJvmWildcardAnnotation() =
- hasAnnotation(JvmWildcard::class.java.canonicalName!!)
+// TODO(bcorso): There's a bug in KSP where, after using KSType#asMemberOf() or KSType#replace(),
+// the annotations are removed from the resulting type. However, it turns out that the annotation
+// information is still available in the underlying KotlinType, so we use reflection to get them.
+// See https://github.com/google/ksp/issues/1376.
+private fun KSType.hasAnnotation(qName: String): Boolean {
+ fun String.toFqName(): Any {
+ return Class.forName("org.jetbrains.kotlin.name.FqName")
+ .getConstructor(String::class.java)
+ .newInstance(this)
+ }
+ fun hasAnnotationViaReflection(qName: String): Boolean {
+ val kotlinType = javaClass.methods.find { it.name == "getKotlinType" }?.invoke(this)
+ val kotlinAnnotations =
+ kotlinType?.javaClass
+ ?.methods
+ ?.find { it.name == "getAnnotations" }
+ ?.invoke(kotlinType)
+ return kotlinAnnotations?.javaClass
+ ?.methods
+ ?.find { it.name == "hasAnnotation" }
+ ?.invoke(kotlinAnnotations, qName.toFqName()) == true
+ }
+ return if (annotations.toList().isEmpty()) {
+ // If there are no annotations but KSType#toString() shows annotations, check the underlying
+ // KotlinType for annotations using reflection.
+ toString().startsWith("[") && hasAnnotationViaReflection(qName)
+ } else {
+ annotations.any { it.annotationType.resolve().hasQualifiedNameOrAlias(qName) }
+ }
+}
internal fun KSType.hasSuppressJvmWildcardAnnotation() =
hasAnnotation(JvmSuppressWildcards::class.java.canonicalName!!)
internal fun KSNode.hasSuppressWildcardsAnnotationInHierarchy(): Boolean {
- (this as? KSAnnotated)?.let {
- if (hasSuppressJvmWildcardAnnotation()) {
- return true
- }
- }
- val parent = parent ?: return false
- return parent.hasSuppressWildcardsAnnotationInHierarchy()
- }
\ No newline at end of file
+ (this as? KSAnnotated)?.let {
+ if (hasSuppressJvmWildcardAnnotation()) {
+ return true
+ }
+ }
+ val parent = parent ?: return false
+ return parent.hasSuppressWildcardsAnnotationInHierarchy()
+}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
index 6150713..a40fe41 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeJavaPoetExt.kt
@@ -35,7 +35,6 @@
import com.squareup.kotlinpoet.javapoet.JTypeName
import com.squareup.kotlinpoet.javapoet.JTypeVariableName
import com.squareup.kotlinpoet.javapoet.JWildcardTypeName
-import kotlin.coroutines.Continuation
// Catch-all type name when we cannot resolve to anything. This is what KAPT uses as error type
// and we use the same type in KSP for consistency.
@@ -150,16 +149,8 @@
return when (variance) {
Variance.CONTRAVARIANT -> JWildcardTypeName.supertypeOf(resolveTypeName())
Variance.COVARIANT -> JWildcardTypeName.subtypeOf(resolveTypeName())
- Variance.STAR -> {
- JWildcardTypeName.subtypeOf(JTypeName.OBJECT)
- }
- else -> {
- if (hasJvmWildcardAnnotation()) {
- JWildcardTypeName.subtypeOf(resolveTypeName())
- } else {
- resolveTypeName()
- }
- }
+ Variance.STAR -> JWildcardTypeName.subtypeOf(JTypeName.OBJECT)
+ else -> resolveTypeName()
}
}
@@ -179,28 +170,13 @@
): JTypeName {
return if (this.arguments.isNotEmpty() && !resolver.isJavaRawType(this)) {
val args: Array<JTypeName> = this.arguments
- .map { typeArg ->
- typeArg.asJTypeName(
- resolver = resolver,
- typeArgumentTypeLookup = typeArgumentTypeLookup
- )
- }
+ .map { typeArg -> typeArg.asJTypeName(resolver, typeArgumentTypeLookup) }
.map { it.tryBox() }
- .let { args ->
- if (this.isSuspendFunctionType) args.convertToSuspendSignature()
- else args
- }
.toTypedArray()
- when (
- val typeName = declaration
- .asJTypeName(resolver, typeArgumentTypeLookup).tryBox()
- ) {
+ when (val typeName = declaration.asJTypeName(resolver, typeArgumentTypeLookup).tryBox()) {
is JArrayTypeName -> JArrayTypeName.of(args.single())
- is JClassName -> JParameterizedTypeName.get(
- typeName,
- *args
- )
+ is JClassName -> JParameterizedTypeName.get(typeName, *args)
else -> error("Unexpected type name for KSType: $typeName")
}
} else {
@@ -209,29 +185,6 @@
}
/**
- * Transforms [this] list of arguments to a suspend signature. For a [suspend] functional type, we
- * need to transform it to be a FunctionX with a [Continuation] with the correct return type. A
- * transformed SuspendFunction looks like this:
- *
- * FunctionX<[? super $params], ? super Continuation<? super $ReturnType>, ?>
- */
-private fun List<JTypeName>.convertToSuspendSignature(): List<JTypeName> {
- val args = this
-
- // The last arg is the return type, so take everything except the last arg
- val actualArgs = args.subList(0, args.size - 1)
- val continuationReturnType = JWildcardTypeName.supertypeOf(args.last())
- val continuationType = JParameterizedTypeName.get(
- JClassName.get(Continuation::class.java),
- continuationReturnType
- )
- return actualArgs + listOf(
- JWildcardTypeName.supertypeOf(continuationType),
- JWildcardTypeName.subtypeOf(JTypeName.OBJECT)
- )
-}
-
-/**
* The private constructor of [JTypeVariableName] which receives a list.
* We use this in [createModifiableTypeVariableName] to create a [JTypeVariableName] whose bounds
* can be modified afterwards.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
index bdade61..56c3455 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolver.kt
@@ -16,6 +16,7 @@
package androidx.room.compiler.processing.ksp
+import androidx.room.compiler.processing.rawTypeName
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.isOpen
import com.google.devtools.ksp.processing.Resolver
@@ -27,6 +28,7 @@
import com.google.devtools.ksp.symbol.KSTypeParameter
import com.google.devtools.ksp.symbol.Modifier
import com.google.devtools.ksp.symbol.Variance
+import com.squareup.kotlinpoet.javapoet.JClassName
/**
* When kotlin generates java code, it has some interesting rules on how variance is handled.
@@ -50,104 +52,62 @@
* @param scope The [KSTypeVarianceResolverScope] associated with the given type.
*/
@OptIn(KspExperimental::class)
- fun applyTypeVariance(type: KSType, scope: KSTypeVarianceResolverScope): KSType {
+ fun applyTypeVariance(type: KSType, scope: KSTypeVarianceResolverScope?): KSType {
if (type.isError ||
type.arguments.isEmpty() ||
resolver.isJavaRawType(type) ||
- !scope.needsWildcardResolution) {
+ scope?.needsWildcardResolution == false) {
// There's nothing to resolve in this case, so just return the original type.
return type
}
- val resolvedType = if (hasTypeVariables(scope.declarationType())) {
- // If the associated declared type contains type variables that were resolved, e.g.
- // using "asMemberOf", then it has special rules about how to resolve the types.
- getJavaWildcardWithTypeVariables(
- type = type,
- declarationType = getJavaWildcard(scope.declarationType(), scope),
- scope = scope,
- )
- } else {
- getJavaWildcard(type, scope)
- }
-
- // As a final pass, we apply variance from any @JvmSuppressWildcards or @JvmWildcard
- // annotations on the resolved type.
- return applyJvmWildcardAnnotations(resolvedType)
+ // First wrap types/arguments in our own wrappers so that we can keep track of the original
+ // type, which is needed to get annotations.
+ return KSTypeWrapper(resolver, type)
+ // Next, resolve wildcards based on the scope of the type
+ .resolveWildcards(scope)
+ // Next, apply any additional variance changes based on the @JvmSuppressWildcards or
+ // @JvmWildcard annotations on the resolved type.
+ .applyJvmWildcardAnnotations(scope)
+ // Finally, unwrap any delegate types. (Note: as part of resolving wildcards, we wrap
+ // types/type arguments in delegates to avoid loosing annotation information. However,
+ // those delegates may cause issues later if KSP tries to cast the type/argument to a
+ // particular implementation, so we unwrap them here.
+ .unwrap()
}
- private fun hasTypeVariables(
- type: KSType?,
- stack: ReferenceStack = ReferenceStack()
- ): Boolean {
- if (type == null || type.isError || stack.queue.contains(type)) {
+ private fun KSTypeWrapper.resolveWildcards(
+ scope: KSTypeVarianceResolverScope?
+ ) = if (scope == null) {
+ this
+ } else if (hasTypeVariables(scope.declarationType())) {
+ // If the associated declared type contains type variables that were resolved, e.g.
+ // using "asMemberOf", then it has special rules about how to resolve the types.
+ getJavaWildcardWithTypeVariables(
+ declarationType = KSTypeWrapper(resolver, scope.declarationType())
+ .getJavaWildcard(scope),
+ scope = scope,
+ )
+ } else {
+ getJavaWildcard(scope)
+ }
+
+ private fun hasTypeVariables(type: KSType?, stack: List<KSType> = emptyList()): Boolean {
+ if (type == null || type.isError || stack.contains(type)) {
return false
}
- return stack.withReference(type) {
- type.isTypeParameter() ||
- type.arguments.any { hasTypeVariables(it.type?.resolve(), stack) }
- }
+ return type.isTypeParameter() ||
+ type.arguments.any { hasTypeVariables(it.type?.resolve(), stack + type) }
}
- private fun getJavaWildcard(
- type: KSType,
- scope: KSTypeVarianceResolverScope,
- typeStack: ReferenceStack = ReferenceStack(),
- typeArgStack: List<KSTypeArgument> = emptyList(),
- typeParamStack: List<KSTypeParameter> = emptyList(),
- ): KSType {
- if (type.isError || typeStack.queue.contains(type)) {
- return type
- }
- if (type.declaration is KSTypeAlias) {
- return getJavaWildcard(
- type = (type.declaration as KSTypeAlias).type.resolve(),
- scope = scope,
- typeStack = typeStack,
- typeArgStack = typeArgStack,
- typeParamStack = typeParamStack,
- )
- }
- return typeStack.withReference(type) {
- val resolvedTypeArgs =
- type.arguments.indices.map { i ->
- getJavaWildcard(
- typeArg = type.arguments[i],
- typeParam = type.declaration.typeParameters[i],
- scope = scope,
- typeStack = typeStack,
- typeArgStack = typeArgStack,
- typeParamStack = typeParamStack,
- )
- }
- type.replace(resolvedTypeArgs)
- }
- }
+ private fun KSTypeWrapper.getJavaWildcard(scope: KSTypeVarianceResolverScope) =
+ replace(arguments.map { it.getJavaWildcard(scope) })
- private fun getJavaWildcard(
- typeArg: KSTypeArgument,
- typeParam: KSTypeParameter,
- scope: KSTypeVarianceResolverScope,
- typeStack: ReferenceStack,
- typeArgStack: List<KSTypeArgument>,
- typeParamStack: List<KSTypeParameter>,
- ): KSTypeArgument {
- val type = typeArg.type?.resolve()
- if (
- type == null ||
- type.isError ||
- typeArg.variance == Variance.STAR ||
- typeStack.queue.contains(type)
- ) {
- return typeArg
- }
- val resolvedType = getJavaWildcard(
- type = type,
- scope = scope,
- typeStack = typeStack,
- typeArgStack = typeArgStack + typeArg,
- typeParamStack = typeParamStack + typeParam
- )
+ private fun KSTypeArgumentWrapper.getJavaWildcard(
+ scope: KSTypeVarianceResolverScope
+ ): KSTypeArgumentWrapper {
+ val type = type ?: return this
+ val resolvedType = type.getJavaWildcard(scope)
fun inheritDeclarationSiteVariance(): Boolean {
// Before we check the current variance, we need to check the previous variance in the
// stack to see if they allow us to inherit the current variance, and that logic differs
@@ -158,10 +118,10 @@
if (typeParamStack.indices.none { i ->
(typeParamStack[i].variance == Variance.CONTRAVARIANT ||
typeArgStack[i].variance == Variance.CONTRAVARIANT) &&
- // The declaration and use site variance is ignored when using @JvmWildcard
- // explicitly on a type.
- !typeArgStack[i].hasJvmWildcardAnnotation()
- }) {
+ // The declaration and use site variance is ignored when using
+ // @JvmWildcard explicitly on a type.
+ !typeArgStack[i].hasJvmWildcardAnnotation()
+ }) {
return false
}
} else {
@@ -209,74 +169,48 @@
}
val resolvedVariance = if (inheritDeclarationSiteVariance()) {
typeParam.variance
- } else if (typeParam.variance == typeArg.variance) {
+ } else if (typeParam.variance == variance) {
// If we're not applying the declaration-site variance, and the use-site variance is the
// same as the declaration-site variance then we don't include the use-site variance in
// the jvm type either.
Variance.INVARIANT
} else {
- typeArg.variance
+ variance
}
- return createTypeArgument(resolvedType, resolvedVariance)
+ return replace(resolvedType, resolvedVariance)
}
- private fun getJavaWildcardWithTypeVariables(
- type: KSType,
- declarationType: KSType? = null,
+ private fun KSTypeWrapper.getJavaWildcardWithTypeVariables(
scope: KSTypeVarianceResolverScope,
- typeStack: ReferenceStack = ReferenceStack(),
+ declarationType: KSTypeWrapper?,
+ ) = if (declarationType?.isTypeParameter() == false) {
+ replace(
+ declarationType.arguments.indices.map { i ->
+ arguments[i].getJavaWildcardWithTypeVariablesForOuterType(
+ declarationTypeArg = declarationType.arguments[i],
+ scope = scope,
+ )
+ }
+ )
+ } else {
+ getJavaWildcardWithTypeVariablesForInnerType(scope)
+ }
+
+ private fun KSTypeWrapper.getJavaWildcardWithTypeVariablesForInnerType(
+ scope: KSTypeVarianceResolverScope,
typeParamStack: List<KSTypeParameter> = emptyList(),
- ): KSType {
- if (type.isError || typeStack.queue.contains(type)) {
- return type
- }
- return typeStack.withReference(type) {
- val resolvedTypeArgs =
- if (declarationType != null && !declarationType.isTypeParameter()) {
- declarationType.arguments.indices.map { i ->
- getJavaWildcardWithTypeVariablesForOuterType(
- typeArg = type.arguments[i],
- declarationTypeArg = declarationType.arguments[i],
- scope = scope,
- typeStack = typeStack,
- )
- }
- } else {
- type.arguments.indices.map { i ->
- getJavaWildcardWithTypeVariablesForInnerType(
- typeArg = type.arguments[i],
- typeParam = type.declaration.typeParameters[i],
- scope = scope,
- typeStack = typeStack,
- typeParamStack = typeParamStack
- )
- }
- }
- type.replace(resolvedTypeArgs)
- }
- }
+ ) = replace(
+ arguments.map { it.getJavaWildcardWithTypeVariablesForInnerType(scope, typeParamStack) }
+ )
- private fun getJavaWildcardWithTypeVariablesForInnerType(
- typeArg: KSTypeArgument,
- typeParam: KSTypeParameter,
+ private fun KSTypeArgumentWrapper.getJavaWildcardWithTypeVariablesForInnerType(
scope: KSTypeVarianceResolverScope,
- typeStack: ReferenceStack,
typeParamStack: List<KSTypeParameter>,
- ): KSTypeArgument {
- val type = typeArg.type?.resolve()
- if (
- type == null ||
- type.isError ||
- typeArg.variance == Variance.STAR ||
- typeStack.queue.contains(type)
- ) {
- return typeArg
- }
- val resolvedType = getJavaWildcardWithTypeVariables(
- type = type,
+ ): KSTypeArgumentWrapper {
+ val type = type ?: return this
+ val resolvedType = type.getJavaWildcardWithTypeVariablesForInnerType(
scope = scope,
- typeStack = typeStack,
- typeParamStack = typeParamStack + typeParam,
+ typeParamStack = typeParamStack + typeParam
)
val resolvedVariance = if (
typeParam.variance != Variance.INVARIANT &&
@@ -291,116 +225,211 @@
) {
typeParam.variance
} else {
- typeArg.variance
+ variance
}
- return createTypeArgument(resolvedType, resolvedVariance)
+ return replace(resolvedType, resolvedVariance)
}
- private fun getJavaWildcardWithTypeVariablesForOuterType(
- typeArg: KSTypeArgument,
- declarationTypeArg: KSTypeArgument,
+ private fun KSTypeArgumentWrapper.getJavaWildcardWithTypeVariablesForOuterType(
+ declarationTypeArg: KSTypeArgumentWrapper,
scope: KSTypeVarianceResolverScope,
- typeStack: ReferenceStack,
- ): KSTypeArgument {
- val type = typeArg.type?.resolve()
- if (
- type == null ||
- type.isError ||
- typeArg.variance == Variance.STAR ||
- typeStack.queue.contains(type)
- ) {
- return typeArg
- }
- val resolvedType = getJavaWildcardWithTypeVariables(
- type = type,
- declarationType = declarationTypeArg.type?.resolve(),
+ ): KSTypeArgumentWrapper {
+ val type = type ?: return this
+ val resolvedType = type.getJavaWildcardWithTypeVariables(
+ declarationType = declarationTypeArg.type,
scope = scope,
- typeStack = typeStack
)
val resolvedVariance = if (declarationTypeArg.variance != Variance.INVARIANT) {
declarationTypeArg.variance
} else {
- typeArg.variance
+ variance
}
- return createTypeArgument(resolvedType, resolvedVariance)
+ return replace(resolvedType, resolvedVariance)
}
- private fun applyJvmWildcardAnnotations(
- type: KSType,
- typeStack: ReferenceStack = ReferenceStack(),
- ): KSType {
- if (type.isError || typeStack.queue.contains(type)) {
- return type
- }
- return typeStack.withReference(type) {
- val resolvedTypeArgs =
- type.arguments.indices.map { i ->
- applyJvmWildcardAnnotations(
- typeArg = type.arguments[i],
- typeParameter = type.declaration.typeParameters[i],
- typeStack = typeStack,
- )
- }
- type.replace(resolvedTypeArgs)
- }
- }
+ private fun KSTypeWrapper.applyJvmWildcardAnnotations(
+ scope: KSTypeVarianceResolverScope?
+ ) =
+ replace(arguments.map { it.applyJvmWildcardAnnotations(scope) })
- private fun applyJvmWildcardAnnotations(
- typeArg: KSTypeArgument,
- typeParameter: KSTypeParameter,
- typeStack: ReferenceStack,
- ): KSTypeArgument {
- val type = typeArg.type?.resolve()
- if (
- type == null ||
- type.isError ||
- typeArg.variance == Variance.STAR ||
- typeStack.queue.contains(type)
- ) {
- return typeArg
- }
- val resolvedType = applyJvmWildcardAnnotations(
- type = type,
- typeStack = typeStack,
- )
+ private fun KSTypeArgumentWrapper.applyJvmWildcardAnnotations(
+ scope: KSTypeVarianceResolverScope?
+ ): KSTypeArgumentWrapper {
+ val type = type ?: return this
+ val resolvedType = type.applyJvmWildcardAnnotations(scope)
val resolvedVariance = when {
- typeParameter.variance == Variance.INVARIANT &&
- typeArg.variance != Variance.INVARIANT -> typeArg.variance
- typeArg.hasJvmWildcardAnnotation() -> typeParameter.variance
- typeStack.queue.any { it.hasSuppressJvmWildcardAnnotation() } ||
- typeArg.hasSuppressWildcardsAnnotationInHierarchy() ||
- typeParameter.hasSuppressWildcardsAnnotationInHierarchy() -> Variance.INVARIANT
- else -> typeArg.variance
+ typeParam.variance == Variance.INVARIANT && variance != Variance.INVARIANT -> variance
+ hasJvmWildcardAnnotation() -> typeParam.variance
+ scope?.hasSuppressWildcards == true ||
+ // We only need to check the first type in the stack for @JvmSuppressWildcards.
+ // Any other @JvmSuppressWildcards usages will be placed on the type arguments
+ // rather than the types, so no need to check the rest of the types.
+ typeStack.first().hasSuppressJvmWildcardAnnotation() ||
+ this.hasSuppressWildcardsAnnotationInHierarchy() ||
+ typeArgStack.any { it.hasSuppressJvmWildcardAnnotation() } ||
+ typeParam.hasSuppressWildcardsAnnotationInHierarchy() -> Variance.INVARIANT
+ else -> variance
}
- return createTypeArgument(resolvedType, resolvedVariance)
- }
-
- private fun KSType.isTypeParameter(): Boolean {
- return createTypeReference().isTypeParameterReference()
- }
-
- private fun createTypeArgument(type: KSType, variance: Variance): KSTypeArgument {
- return resolver.getTypeArgument(type.createTypeReference(), variance)
+ return replace(resolvedType, resolvedVariance)
}
}
/**
- * Inheriting variance for self referencing types (e.g. Foo<T : Foo>) could go into an infinite
- * loop. To avoid that issue, every time we visit a type, we keep it in the reference stack and
- * if a type argument resolves to it, it will stop recursion.
+ * A wrapper for creating a new [KSType] that allows arguments of type [KSTypeArgumentWrapper].
+ *
+ * Note: This wrapper acts similar to [KSType#replace(KSTypeArgument)]. However, we can't call
+ * [KSType#replace(KSTypeArgument)] directly when using [KSTypeArgumentWrapper] or we'll get an
+ * [IllegalStateException] since KSP tries to cast to its own implementation of [KSTypeArgument].
*/
-private class ReferenceStack {
- val queue = ArrayDeque<KSType>()
+private class KSTypeWrapper constructor(
+ private val resolver: Resolver,
+ private val originalType: KSType,
+ private val newType: KSType =
+ originalType.replaceTypeAliases().replaceSuspendFunctionTypes(resolver),
+ newTypeArguments: List<KSTypeArgumentWrapper>? = null,
+ private val typeStack: List<KSTypeWrapper> = emptyList(),
+ private val typeArgStack: List<KSTypeArgumentWrapper> = emptyList(),
+ private val typeParamStack: List<KSTypeParameter> = emptyList(),
+) {
+ val declaration = originalType.declaration
- inline fun <T> withReference(
- ksType: KSType,
- crossinline block: () -> T
- ): T {
- return try {
- queue.addLast(ksType)
- block()
- } finally {
- queue.removeLast()
+ val arguments: List<KSTypeArgumentWrapper> by lazy {
+ newTypeArguments ?: newType.arguments.indices.map { i ->
+ KSTypeArgumentWrapper(
+ originalTypeArg = newType.arguments[i],
+ typeParam = newType.declaration.typeParameters[i],
+ resolver = resolver,
+ typeStack = typeStack + this,
+ typeArgStack = typeArgStack,
+ typeParamStack = typeParamStack,
+ )
}
}
+
+ fun replace(newTypeArguments: List<KSTypeArgumentWrapper>) = KSTypeWrapper(
+ originalType = originalType,
+ newType = newType,
+ newTypeArguments = newTypeArguments,
+ resolver = resolver,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack,
+ typeParamStack = typeParamStack,
+ )
+
+ fun hasSuppressJvmWildcardAnnotation() = originalType.hasSuppressJvmWildcardAnnotation()
+
+ fun isTypeParameter() = originalType.isTypeParameter()
+
+ fun unwrap() = newType.replace(arguments.map { it.unwrap() })
+
+ override fun toString() = buildString {
+ if (originalType.annotations.toList().isNotEmpty()) {
+ append("${originalType.annotations.toList()} ")
+ }
+ append(newType.declaration.simpleName.asString())
+ if (arguments.isNotEmpty()) {
+ append("$arguments")
+ }
+ }
+
+ private companion object {
+ fun KSType.replaceTypeAliases() = (declaration as? KSTypeAlias)?.type?.resolve() ?: this
+
+ fun KSType.replaceSuspendFunctionTypes(resolver: Resolver) = if (!isSuspendFunctionType) {
+ this
+ } else {
+ // Find the JVM FunctionN type that will replace the suspend function and use that.
+ val functionN = resolver.requireType(
+ (declaration.asJTypeName(resolver).rawTypeName() as JClassName).canonicalName()
+ )
+ functionN.replace(
+ buildList {
+ addAll(arguments.dropLast(1))
+ val continuationArgs = arguments.takeLast(1)
+ val continuationTypeRef = resolver.requireType("kotlin.coroutines.Continuation")
+ .replace(continuationArgs)
+ .createTypeReference()
+ val objTypeRef = resolver.requireType("java.lang.Object").createTypeReference()
+ add(resolver.getTypeArgument(continuationTypeRef, Variance.INVARIANT))
+ add(resolver.getTypeArgument(objTypeRef, Variance.INVARIANT))
+ }
+ )
+ }
+ }
+}
+
+/**
+ * A wrapper for creating a new [KSTypeArgument] that delegates to the original argument for
+ * annotations.
+ *
+ * Note: This wrapper acts similar to [Resolver#getTypeArgument(KSTypeReference, Variance)].
+ * However, we can't call [Resolver#getTypeArgument(KSTypeReference, Variance)] directly because
+ * we'll lose information about annotations (e.g. `@JvmSuppressWildcards`) that were on the original
+ * type argument.
+ */
+private class KSTypeArgumentWrapper constructor(
+ private val originalTypeArg: KSTypeArgument,
+ private val newType: KSTypeWrapper? = null,
+ private val resolver: Resolver,
+ val typeParam: KSTypeParameter,
+ val variance: Variance = originalTypeArg.variance,
+ val typeStack: List<KSTypeWrapper>,
+ val typeArgStack: List<KSTypeArgumentWrapper>,
+ val typeParamStack: List<KSTypeParameter>,
+) {
+ val type: KSTypeWrapper? by lazy {
+ if (variance == Variance.STAR || originalTypeArg.type == null) {
+ // Return null for star projections, otherwise we'll end up in an infinite loop.
+ null
+ } else {
+ newType ?: KSTypeWrapper(
+ originalType = originalTypeArg.type!!.resolve(),
+ resolver = resolver,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack + this,
+ typeParamStack = typeParamStack + typeParam,
+ )
+ }
+ }
+
+ fun replace(newType: KSTypeWrapper, newVariance: Variance) = KSTypeArgumentWrapper(
+ originalTypeArg = originalTypeArg,
+ typeParam = typeParam,
+ newType = newType,
+ variance = newVariance,
+ resolver = resolver,
+ typeStack = typeStack,
+ typeArgStack = typeArgStack,
+ typeParamStack = typeParamStack,
+ )
+
+ fun hasJvmWildcardAnnotation() = originalTypeArg.hasJvmWildcardAnnotation()
+
+ fun hasSuppressJvmWildcardAnnotation() = originalTypeArg.hasSuppressJvmWildcardAnnotation()
+
+ fun hasSuppressWildcardsAnnotationInHierarchy() =
+ originalTypeArg.hasSuppressWildcardsAnnotationInHierarchy()
+
+ fun unwrap(): KSTypeArgument {
+ val unwrappedType = type?.unwrap()
+ return if (unwrappedType == null || unwrappedType.isError) {
+ originalTypeArg
+ } else {
+ resolver.getTypeArgument(unwrappedType.createTypeReference(), variance)
+ }
+ }
+
+ override fun toString() = buildString {
+ if (originalTypeArg.annotations.toList().isNotEmpty()) {
+ append("${originalTypeArg.annotations.toList()} ")
+ }
+ append(
+ when (variance) {
+ Variance.INVARIANT -> "$type"
+ Variance.CONTRAVARIANT -> "in $type"
+ Variance.COVARIANT -> "out $type"
+ Variance.STAR -> "*"
+ }
+ )
+ }
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
index f39ab11..a124660 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverScope.kt
@@ -27,7 +27,7 @@
* Provides KSType resolution scope for a type.
*/
internal sealed class KSTypeVarianceResolverScope(
- private val annotated: KSAnnotated,
+ val annotated: KSAnnotated,
private val container: KSDeclaration?,
private val asMemberOf: KspType?
) {
@@ -36,8 +36,18 @@
* parameter is in kotlin or the containing class, which inherited the method, is in kotlin.
*/
val needsWildcardResolution: Boolean by lazy {
- (annotated.isInKotlinCode() || container?.isInKotlinCode() == true) &&
- !annotated.hasSuppressWildcardsAnnotationInHierarchy()
+ annotated.isInKotlinCode() || container?.isInKotlinCode() == true
+ }
+
+ val hasSuppressWildcards: Boolean by lazy {
+ val nodeForSuppressionCheck = when (this) {
+ // For property setter and getter methods skip to the enclosing class to check for
+ // suppression annotations to match KAPT.
+ is PropertySetterParameterType,
+ is PropertyGetterMethodReturnType -> annotated.parent?.parent as? KSAnnotated
+ else -> annotated
+ }
+ nodeForSuppressionCheck?.hasSuppressWildcardsAnnotationInHierarchy() == true
}
private fun KSAnnotated.isInKotlinCode(): Boolean {
@@ -60,7 +70,7 @@
abstract fun isValOrReturnType(): Boolean
/** Returns the scope of the `asMemberOf` container type. */
- fun asMemberOfScopeOrSelf(): KSTypeVarianceResolverScope? {
+ fun asMemberOfScopeOrSelf(): KSTypeVarianceResolverScope {
return asMemberOf?.scope ?: this
}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
index 4e48afc..dbfb091 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotation.kt
@@ -18,8 +18,8 @@
import androidx.room.compiler.processing.InternalXAnnotation
import androidx.room.compiler.processing.XAnnotationBox
-import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XAnnotationValue
+import androidx.room.compiler.processing.XType
import com.google.devtools.ksp.symbol.KSAnnotation
import com.google.devtools.ksp.symbol.KSType
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
index acf2615..ae5a43cb 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
@@ -295,7 +295,7 @@
/**
* Resolves the wildcards for the given ksType. See [KSTypeVarianceResolver] for details.
*/
- internal fun resolveWildcards(ksType: KSType, scope: KSTypeVarianceResolverScope) =
+ internal fun resolveWildcards(ksType: KSType, scope: KSTypeVarianceResolverScope?) =
ksTypeVarianceResolver.applyTypeVariance(ksType, scope)
internal fun clearCache() {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index 74709b2..dc5cf7c 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -69,23 +69,19 @@
* The [XTypeName] represents those differences as [JTypeName] and [KTypeName], respectively.
*/
private val xTypeName: XTypeName by lazy {
- val jvmWildcardType = if (scope == null) {
- this
- } else {
- env.resolveWildcards(ksType, scope).let {
- if (it == ksType) {
- this
- } else {
- env.wrap(
- ksType = it,
- allowPrimitives = this is KspPrimitiveType
- ).copyWithScope(scope)
- }
+ val jvmWildcardType = env.resolveWildcards(ksType, scope).let {
+ if (it == ksType) {
+ this
+ } else {
+ env.wrap(
+ ksType = it,
+ allowPrimitives = this is KspPrimitiveType
+ )
}
}
XTypeName(
jvmWildcardType.resolveJTypeName(),
- jvmWildcardType.resolveKTypeName(),
+ resolveKTypeName(),
nullability
)
}
@@ -141,15 +137,12 @@
if (argDeclaration is KSTypeParameter) {
// If this is a type parameter, replace it with the resolved type argument.
resolvedTypeArguments[argDeclaration.name.asString()] ?: argument
- } else if (
- argument.type != null && argument.type?.resolve()?.arguments?.isEmpty() == false
- ) {
+ } else if (argument.type?.resolve()?.arguments?.isEmpty() == false) {
// If this is a type with arguments, the arguments may contain a type parameter,
// e.g. Foo<T>, so try to resolve the type and then convert to a type argument.
env.resolver.getTypeArgument(
- env.resolver.createKSTypeReferenceFromKSType(
- resolveTypeArguments(argument.type!!.resolve(), resolvedTypeArguments)
- ),
+ resolveTypeArguments(argument.type!!.resolve(), resolvedTypeArguments)
+ .createTypeReference(),
variance = Variance.INVARIANT
)
} else {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
index 7593b7f..589244d 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeArgumentType.kt
@@ -21,6 +21,7 @@
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.KSTypeParameter
import com.google.devtools.ksp.symbol.KSTypeReference
+import com.google.devtools.ksp.symbol.Variance
import com.squareup.kotlinpoet.javapoet.JTypeName
import com.squareup.kotlinpoet.javapoet.KTypeName
@@ -47,7 +48,8 @@
ksType = ksType,
allowPrimitives = false
)
- if (this.ksType.declaration is KSTypeParameter && this == extendBound) {
+ if (typeArg.variance == Variance.STAR ||
+ (this.ksType.declaration is KSTypeParameter && this == extendBound)) {
null
} else {
extendBound
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
index f9e64b5..d408755 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
@@ -21,22 +21,22 @@
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.XTestInvocation
import androidx.room.compiler.processing.util.compileFiles
-import androidx.testutils.generateAllEnumerations
import androidx.room.compiler.processing.util.javaTypeUtils
import androidx.room.compiler.processing.util.runKaptTest
import androidx.room.compiler.processing.util.runProcessorTest
+import androidx.testutils.generateAllEnumerations
import com.google.auto.common.MoreTypes
import com.google.common.truth.Truth.assertThat
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.ParameterSpec
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.io.File
import javax.lang.model.element.ExecutableElement
import javax.lang.model.element.Modifier
import javax.lang.model.type.DeclaredType
import javax.lang.model.util.Types
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class MethodSpecHelperTest(
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
index 1c18366..800f064 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/OriginatingElementsTest.kt
@@ -24,11 +24,11 @@
import androidx.room.compiler.processing.util.runProcessorTest
import com.google.common.truth.Truth.assertThat
import com.squareup.javapoet.TypeSpec
+import javax.lang.model.element.ExecutableElement
+import javax.lang.model.element.TypeElement
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import javax.lang.model.element.ExecutableElement
-import javax.lang.model.element.TypeElement
@RunWith(JUnit4::class)
class OriginatingElementsTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
index ba7cb80..f09dcbd 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeAliasTest.kt
@@ -32,7 +32,6 @@
import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
import com.squareup.kotlinpoet.javapoet.JTypeName
import com.squareup.kotlinpoet.javapoet.JWildcardTypeName
-import com.squareup.kotlinpoet.javapoet.KWildcardTypeName
import kotlin.coroutines.Continuation
import org.junit.Test
import org.junit.runner.RunWith
@@ -94,8 +93,7 @@
)
if (invocation.isKsp) {
assertThat(it.asTypeName().kotlin).isEqualTo(
- Continuation::class.asKClassName()
- .parameterizedBy(KWildcardTypeName.consumerOf(LONG))
+ Continuation::class.asKClassName().parameterizedBy(LONG)
)
}
}
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
index f337713..e9b693c 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/TypeInheritanceTest.kt
@@ -64,20 +64,13 @@
fieldName: String,
expectedJTypeName: String,
) {
- val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
val sub = processingEnv.requireTypeElement("SubClass")
val subField = sub.getField(fieldName).asMemberOf(sub.type)
assertThat(subField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
- if (isKsp) {
- assertThat(subField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
- }
val base = processingEnv.requireTypeElement("BaseClass")
val baseField = base.getField(fieldName).asMemberOf(sub.type)
assertThat(baseField.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
- if (isKsp) {
- assertThat(baseField.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
- }
}
private fun XTestInvocation.assertParamType(
@@ -85,23 +78,16 @@
paramName: String,
expectedJTypeName: String,
) {
- val expectedKTypeName = expectedJTypeName.replace("? extends", "out")
val sub = processingEnv.requireTypeElement("SubClass")
val subMethod = sub.getMethodByJvmName(methodName)
val paramIndex = subMethod.parameters.indexOf(subMethod.getParameter(paramName))
val subMethodParam = subMethod.asMemberOf(sub.type).parameterTypes[paramIndex]
assertThat(subMethodParam.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
- if (isKsp) {
- assertThat(subMethodParam.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
- }
val base = processingEnv.requireTypeElement("BaseClass")
val baseMethod = base.getMethodByJvmName(methodName)
val baseMethodParam = baseMethod.asMemberOf(sub.type).parameterTypes[paramIndex]
assertThat(baseMethodParam.asTypeName().java.toString()).isEqualTo(expectedJTypeName)
- if (isKsp) {
- assertThat(baseMethodParam.asTypeName().kotlin.toString()).isEqualTo(expectedKTypeName)
- }
}
private fun XTestInvocation.assertReturnType(methodName: String, expectedTypeName: String) {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
index c540af4..7574266 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XMessagerTest.kt
@@ -19,10 +19,10 @@
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.runProcessorTest
import com.google.common.truth.Truth.assertThat
+import javax.tools.Diagnostic
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import javax.tools.Diagnostic
@RunWith(JUnit4::class)
class XMessagerTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index 0e44884..6dde1fd 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -2075,272 +2075,6 @@
}
}
- @Test
- fun javaFieldDescriptors() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassA",
- """
- import java.util.List;
- class TestClassA<T> {
- int field1;
- String field2;
- T field3;
- List<String> field4;
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassA")
- assertThat(foo.getDeclaredFields().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "field1:I",
- "field2:Ljava/lang/String;",
- "field3:Ljava/lang/Object;",
- "field4:Ljava/util/List;"
- )
- }
- }
-
- @Test
- fun javaMethodDescriptorsPrimitives() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassB",
- """
- class TestClassB<T> {
- void method1(boolean yesOrNo, int number) {}
-
- byte method2(char letter) {
- return 0;
- }
-
- void method3(double realNumber1, float realNummber2) {}
-
- void method4(long bigNumber, short littlerNumber) {}
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassB")
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1(ZI)V", "method2(C)B", "method3(DF)V", "method4(JS)V"
- )
- }
- }
-
- @Test
- fun javaMethodDescriptorsJavaTypes() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassC",
- """
- import java.util.*;
- class TestClassC<T> {
- void method1(Object something) {}
-
- Object method2() {
- return null;
- }
-
- List<String> method3(ArrayList<Integer> list) {
- return null;
- }
-
- Map<String, Object> method4() {
- return null;
- }
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassC")
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1(Ljava/lang/Object;)V",
- "method2()Ljava/lang/Object;",
- "method3(Ljava/util/ArrayList;)Ljava/util/List;",
- "method4()Ljava/util/Map;"
- )
- }
- }
-
- @Test
- fun javaMethodDescriptorsTestTypes() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassD",
- """
- class TestDataClass {}
- class TestClassD<T> {
- void method1(TestDataClass data) {}
-
- TestDataClass method2() {
- return null;
- }
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassD")
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1(LTestDataClass;)V",
- "method2()LTestDataClass;"
- )
- }
- }
-
- @Test
- fun javaMethodDescriptorsArrays() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassE",
- """
- class TestDataClass {}
- class TestClassE<T> {
- void method1(TestDataClass[] data) {}
-
- TestDataClass[] method2() {
- return null;
- }
-
- void method3(int[] array) {}
-
- void method4(int... array) {}
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassE")
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1([LTestDataClass;)V",
- "method2()[LTestDataClass;",
- "method3([I)V",
- "method4([I)V"
- )
- }
- }
-
- @Test
- fun javaMethodDescriptorsInnerTestType() {
- runTest(
- // KSP can't see nested types if the filename does not match the name of the
- // enclosing class.
- sources = listOf(
- Source.java(
- "TestDataClass",
- """
- public class TestDataClass {
- class MemberInnerData {}
-
- static class StaticInnerData {}
-
- enum EnumData {
- VALUE1,
- VALUE2
- }
- }
- """.trimIndent()
- ),
- Source.java(
- "TestClassF",
- """
- class TestClassF<T> {
- void method1(TestDataClass.MemberInnerData data) {}
-
- void method2(TestDataClass.StaticInnerData data) {}
-
- void method3(TestDataClass.EnumData enumData) {}
-
- TestDataClass.StaticInnerData method4() {
- return null;
- }
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassF")
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1(LTestDataClass\$MemberInnerData;)V",
- "method2(LTestDataClass\$StaticInnerData;)V",
- "method3(LTestDataClass\$EnumData;)V",
- "method4()LTestDataClass\$StaticInnerData;"
- )
- }
- }
-
- @Test
- fun methodDescriptorsErasure() {
- runTest(
- sources = listOf(
- Source.java(
- "TestClassG",
- """
- import java.util.*;
- class TestClassG<T> {
- void method1(T something) {}
- T method2() {
- return null;
- }
- List<? extends String> method3() {
- return null;
- }
- Map<T, String> method4() {
- return null;
- }
- ArrayList<Map<T, String>> method5() {
- return null;
- }
- static <I, O extends I> O method6(I input) {
- return null;
- }
- static <I, O extends String> O method7(I input) {
- return null;
- }
- static <P extends Collection<String> & Comparable<String>> P method8() {
- return null;
- }
- static <P extends String & List<Character>> P method9() {
- return null;
- }
- }
- """.trimIndent()
- )
- )
- ) { invocation ->
- val foo = invocation.processingEnv.requireTypeElement("TestClassG")
- if (!invocation.isKsp) {
- assertThat(foo.getDeclaredMethods().map { it.jvmDescriptor }.toList())
- .containsExactly(
- "method1(Ljava/lang/Object;)V",
- "method2()Ljava/lang/Object;",
- "method3()Ljava/util/List;",
- "method4()Ljava/util/Map;",
- "method5()Ljava/util/ArrayList;",
- "method6(Ljava/lang/Object;)Ljava/lang/Object;",
- "method7(Ljava/lang/Object;)Ljava/lang/String;",
- "method8()Ljava/util/Collection;",
- "method9()Ljava/lang/String;"
- )
- }
- }
- }
-
/**
* it is good to exclude methods coming from Object when testing as they differ between KSP
* and KAPT but irrelevant for Room.
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index 724c037..12b61d7 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -933,7 +933,7 @@
assertThat(actual["starList"]?.kotlin.toString())
.isEqualTo("kotlin.collections.List<*>")
assertThat(actual["rList"]?.kotlin.toString())
- .isEqualTo("kotlin.collections.List<out R>")
+ .isEqualTo("kotlin.collections.List<R>")
}
}
}
@@ -1637,4 +1637,56 @@
}
)
}
+
+ @Test
+ fun selfReferenceTypesDoesNotInfinitelyRecurse() {
+ fun runTest(src: Source) {
+ runProcessorTest(
+ sources = listOf(src),
+ ) { invocation ->
+ val fooTypeElement = invocation.processingEnv.requireTypeElement("test.Usage")
+ val fooType = fooTypeElement.getDeclaredField("foo").type
+
+ assertThat(fooType.asTypeName().java)
+ .isEqualTo(
+ JParameterizedTypeName.get(
+ JClassName.get("test", "Foo"),
+ JWildcardTypeName.subtypeOf(JClassName.OBJECT)
+ )
+ )
+
+ val typeParam = fooType.typeArguments.single()
+ assertThat(typeParam.asTypeName().java)
+ .isEqualTo(JWildcardTypeName.subtypeOf(JClassName.OBJECT))
+
+ assertThat(typeParam.extendsBound()).isNull()
+ }
+ }
+ runTest(
+ Source.java(
+ "test.Usage",
+ """
+ package test;
+ public final class Usage {
+ private final Foo<?> foo = null;
+ private final Foo<? extends Foo<?>> fooExtendsFoo = null;
+ }
+ abstract class Foo<T extends Foo<T>> {}
+ """.trimIndent()
+ ),
+ )
+ runTest(
+ Source.kotlin(
+ "test.Foo.kt",
+ """
+ package test
+ class Usage {
+ val foo: Foo<*> = TODO()
+ val fooExtendsFoo: Foo<out Foo<*>> = TODO()
+ }
+ abstract class Foo<T: Foo<T>>
+ """.trimIndent()
+ )
+ )
+ }
}
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
index 2c297e0..f83d2f4 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/javac/kotlin/JvmDescriptorUtilsTest.kt
@@ -24,9 +24,6 @@
import com.squareup.javapoet.ArrayTypeName
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import javax.annotation.processing.AbstractProcessor
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.ElementKind.CONSTRUCTOR
@@ -34,6 +31,9 @@
import javax.lang.model.element.ElementKind.METHOD
import javax.lang.model.element.TypeElement
import javax.tools.JavaFileObject
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class JvmDescriptorUtilsTest {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
index 16b8f8c..0fb042c 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KSTypeVarianceResolverWithTypeParametersTest.kt
@@ -91,17 +91,13 @@
""".trimIndent()
)
val kaptSignaturesMap = buildMap(sourcesMap.size) {
- runKaptTest(sources) {
- sourcesMap.keys.forEach { key ->
- put(key, IntRange(0, 5).flatMap { i -> collectSignatures(it, key, i) })
- }
+ runKaptTest(sources) { invocation ->
+ sourcesMap.keys.forEach { key -> put(key, invocation.collectSignatures(key)) }
}
}
val kspSignaturesMap = buildMap(sourcesMap.size) {
- runKspTest(sources) {
- sourcesMap.keys.forEach { key ->
- put(key, IntRange(0, 5).flatMap { i -> collectSignatures(it, key, i) })
- }
+ runKspTest(sources) { invocation ->
+ sourcesMap.keys.forEach { key -> put(key, invocation.collectSignatures(key)) }
}
}
CompilationResults(kaptSignaturesMap, kspSignaturesMap)
@@ -123,48 +119,47 @@
)
}
- private fun collectSignatures(
- invocation: XTestInvocation,
- key: String,
- configuration: Int,
- ): List<String> {
- val subName = "Sub$key$configuration"
- val baseName = "Base$key$configuration"
- val sub = invocation.processingEnv.requireTypeElement(subName)
- val subMethod = sub.getDeclaredMethodByJvmName("subMethod")
- val subSuperclassType = sub.superClass!!
- val subMethodParamType = subMethod.parameters.single().type
- val subMethodReturnType = subMethod.returnType
- val base = invocation.processingEnv.requireTypeElement(baseName)
- // Note: For each method/field we test its signature when resolved asMemberOf from a
- // subtype, super class, param type, and return type, as we may get different signatures
- // depending on the scope of the type used with asMemberOf.
+ private fun XTestInvocation.collectSignatures(key: String): List<String> {
return buildList {
- base.getDeclaredMethods().forEach { method ->
- fun XMethodType.signature(): String {
- val returnType = returnType.typeName
- val parameters = parameterTypes.map { it.typeName }
- return "${method.name} : $returnType : $parameters"
+ IntRange(0, 5).forEach { configuration ->
+ val subName = "Sub$key$configuration"
+ val baseName = "Base$key$configuration"
+ val sub = processingEnv.requireTypeElement(subName)
+ val subMethod = sub.getDeclaredMethodByJvmName("subMethod")
+ val subSuperclassType = sub.superClass!!
+ val subMethodParamType = subMethod.parameters.single().type
+ val subMethodReturnType = subMethod.returnType
+ val base = processingEnv.requireTypeElement(baseName)
+ // Note: For each method/field we test its signature when resolved asMemberOf from a
+ // subtype, super class, param type, and return type, as we may get different signatures
+ // depending on the scope of the type used with asMemberOf.
+ base.getDeclaredMethods().forEach { method ->
+ fun XMethodType.signature(): String {
+ val returnType = returnType.typeName
+ val parameters = parameterTypes.map { it.typeName }
+ return "${method.name} : $returnType : $parameters"
+ }
+
+ val fromSubType = method.asMemberOf(sub.type)
+ val fromSuperClassType = method.asMemberOf(subSuperclassType)
+ val fromParamType = method.asMemberOf(subMethodParamType)
+ val fromReturnType = method.asMemberOf(subMethodReturnType)
+ add("$configuration-fromSub-${fromSubType.signature()}")
+ add("$configuration-fromSuperClass-${fromSuperClassType.signature()}")
+ add("$configuration-fromParam-${fromParamType.signature()}")
+ add("$configuration-fromReturnType-${fromReturnType.signature()}")
}
- val fromSubType = method.asMemberOf(sub.type)
- val fromSuperClassType = method.asMemberOf(subSuperclassType)
- val fromParamType = method.asMemberOf(subMethodParamType)
- val fromReturnType = method.asMemberOf(subMethodReturnType)
- add("$configuration-fromSub-${fromSubType.signature()}")
- add("$configuration-fromSuperClass-${fromSuperClassType.signature()}")
- add("$configuration-fromParam-${fromParamType.signature()}")
- add("$configuration-fromReturnType-${fromReturnType.signature()}")
- }
- base.getDeclaredFields().forEach { field ->
- fun XType.signature() = "${field.name} : $typeName"
- val fromSubType = field.asMemberOf(sub.type)
- val fromSuperClassType = field.asMemberOf(subSuperclassType)
- val fromParamType = field.asMemberOf(subMethodParamType)
- val fromReturnType = field.asMemberOf(subMethodReturnType)
- add("$configuration-fromSub-${fromSubType.signature()}")
- add("$configuration-fromSuperClass-${fromSuperClassType.signature()}")
- add("$configuration-fromParam-${fromParamType.signature()}")
- add("$configuration-fromReturnType-${fromReturnType.signature()}")
+ base.getDeclaredFields().forEach { field ->
+ fun XType.signature() = "${field.name} : $typeName"
+ val fromSubType = field.asMemberOf(sub.type)
+ val fromSuperClassType = field.asMemberOf(subSuperclassType)
+ val fromParamType = field.asMemberOf(subMethodParamType)
+ val fromReturnType = field.asMemberOf(subMethodReturnType)
+ add("$configuration-fromSub-${fromSubType.signature()}")
+ add("$configuration-fromSuperClass-${fromSuperClassType.signature()}")
+ add("$configuration-fromParam-${fromParamType.signature()}")
+ add("$configuration-fromReturnType-${fromReturnType.signature()}")
+ }
}
}
}
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
index b753598..688c746 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspFieldElementTest.kt
@@ -17,10 +17,10 @@
package androidx.room.compiler.processing.ksp
import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.FINAL
import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.PRIVATE
import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.PROTECTED
import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.PUBLIC
-import androidx.room.compiler.processing.ksp.KspFieldElementTest.TestModifier.FINAL
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.XTestInvocation
import androidx.room.compiler.processing.util.className
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
index 2e3bd5f..de768e6 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspJvmDescriptorUtilsTest.kt
@@ -17,19 +17,25 @@
package androidx.room.compiler.processing.ksp
import androidx.room.compiler.processing.XElement
+import androidx.room.compiler.processing.XTypeElement
import androidx.room.compiler.processing.isConstructor
import androidx.room.compiler.processing.isField
import androidx.room.compiler.processing.isMethod
+import androidx.room.compiler.processing.isTypeElement
import androidx.room.compiler.processing.util.Source
import androidx.room.compiler.processing.util.XTestInvocation
+import androidx.room.compiler.processing.util.compileFiles
import androidx.room.compiler.processing.util.runProcessorTest
import com.google.common.truth.Truth.assertThat
+import com.squareup.javapoet.ClassName
import org.junit.Test
import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
+import org.junit.runners.Parameterized
-@RunWith(JUnit4::class)
-class KspJvmDescriptorUtilsTest {
+@RunWith(Parameterized::class)
+class KspJvmDescriptorUtilsTest(
+ private val isPreCompiled: Boolean
+) {
private val describeAnnotation =
Source.java(
"androidx.room.test.Describe",
@@ -487,15 +493,55 @@
)
}
- private fun runTest(vararg sources: Source, handler: (XTestInvocation) -> Unit) {
- runProcessorTest(
- sources = sources.toList() + describeAnnotation,
- handler = handler
- )
+ private fun runTest(
+ vararg sources: Source,
+ handler: (XTestInvocation) -> Unit
+ ) {
+ if (isPreCompiled) {
+ val compiled = compileFiles(listOf(*sources) + describeAnnotation)
+ val hasKotlinSources = sources.any {
+ it is Source.KotlinSource
+ }
+ val kotlinSources = if (hasKotlinSources) {
+ listOf(
+ Source.kotlin("placeholder.kt", "class PlaceholderKotlin")
+ )
+ } else {
+ emptyList()
+ }
+ val newSources = kotlinSources + Source.java(
+ "PlaceholderJava",
+ "public class " +
+ "PlaceholderJava {}"
+ )
+ runProcessorTest(
+ sources = newSources,
+ handler = handler,
+ classpath = compiled
+ )
+ } else {
+ runProcessorTest(
+ sources = listOf(*sources) + describeAnnotation,
+ handler = handler
+ )
+ }
}
private fun XTestInvocation.annotatedElements(): Set<XElement> {
- return roundEnv.getElementsAnnotatedWith("androidx.room.test.Describe")
+ // RoundEnv.getElementsAnnotatedWith() only processes current round and could not see
+ // precompiled classes.
+ val typeElements = processingEnv.getTypeElementsFromPackage("androidx.room.test")
+ return typeElements
+ .flatMap {
+ it.getElementsAnnotatedWith(ClassName.get(
+ "androidx.room.test", "Describe"))
+ }.toSet()
+ }
+
+ private fun XTypeElement.getElementsAnnotatedWith(annotation: ClassName): Set<XElement> {
+ return (getEnclosedElements().filter { !it.isTypeElement() } + this)
+ .filter { it.hasAnnotation(annotation) }
+ .toSet() + getEnclosedTypeElements().flatMap { it.getElementsAnnotatedWith(annotation) }
}
private fun descriptor(element: XElement): String {
@@ -506,4 +552,12 @@
else -> error("Unsupported element to describe.")
}
}
+
+ companion object {
+ @JvmStatic
+ @Parameterized.Parameters(name = "isPreCompiled_{0}")
+ fun params(): List<Array<Any>> {
+ return listOf(arrayOf(false), arrayOf(true))
+ }
+ }
}
\ No newline at end of file
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
index 8c694265..cc3a950 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspReflectiveAnnotationBoxTest.kt
@@ -20,8 +20,8 @@
import com.google.common.truth.Truth.assertThat
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.TypeName
-import org.junit.Test
import kotlin.reflect.KClass
+import org.junit.Test
class KspReflectiveAnnotationBoxTest {
enum class TestEnum {
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
index 2bd5ed4..35f0b23 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeNamesGoldenTest.kt
@@ -159,6 +159,25 @@
class MyGenericIn<in T>
class MyGenericOut<out T>
class MyGenericMultipleParameters<T1: MyGeneric<*>, T2: MyGeneric<T1>>
+ interface MyInterface
+ typealias MyInterfaceAlias = MyInterface
+ typealias MyGenericAlias = MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>
+ typealias MyLambdaAlias1 = (List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias2 = @JSW (List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias3 = (@JSW List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> @JSW List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias4 = (List<@JSW MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<@JSW MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias5 = (List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias6 = (List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>
+ typealias MyLambdaAlias7 = (List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>
+ typealias MySuspendLambdaAlias1 = suspend (List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias2 = @JSW suspend (List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias3 = suspend (@JSW List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> @JSW List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias4 = suspend (List<@JSW MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>) -> List<@JSW MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias5 = suspend (List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>) -> List<MyGenericIn<@JSW MyGenericOut<MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias6 = suspend (List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>) -> List<MyGenericIn<MyGenericOut<@JSW MyGenericOut<MyType>>>>
+ typealias MySuspendLambdaAlias7 = suspend (List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>) -> List<MyGenericIn<MyGenericOut<MyGenericOut<@JSW MyType>>>>
+ typealias JSW = JvmSuppressWildcards
+ typealias JW = JvmWildcard
typealias MyLambdaTypeAlias = (@JvmWildcard MyType) -> @JvmWildcard MyType
enum class MyEnum {
VAL1,
@@ -341,6 +360,14 @@
sealedListChild: List<GrandParentSealed.Parent2.Child1>,
jvmWildcard: List<@JvmWildcard String>,
suppressJvmWildcard: List<@JvmSuppressWildcards Number>,
+ suppressJvmWildcardsGeneric1: @JvmSuppressWildcards List<MyGenericOut<MyGenericIn<MyGeneric<MyType>>>>,
+ suppressJvmWildcardsGeneric2: List<@JvmSuppressWildcards MyGenericOut<MyGenericIn<MyGeneric<MyType>>>>,
+ suppressJvmWildcardsGeneric3: List<MyGenericOut<@JvmSuppressWildcards MyGenericIn<MyGeneric<MyType>>>>,
+ suppressJvmWildcardsGeneric4: List<MyGenericOut<MyGenericIn<@JvmSuppressWildcards MyGeneric<MyType>>>>,
+ interfaceAlias: List<MyInterfaceAlias>,
+ genericAlias: List<MyGenericAlias>,
+ jvmWildcardTypeAlias: List<@JW String>,
+ suppressJvmWildcardTypeAlias: List<@JSW Number>,
) {
var propWithFinalType: String = ""
var propWithOpenType: Number = 3
@@ -353,6 +380,16 @@
var propSealedListChild: List<GrandParentSealed.Parent2.Child1> = TODO()
@JvmSuppressWildcards
var propWithOpenTypeButSuppressAnnotation: Number = 3
+ var genericVar: List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>> = TODO()
+ @JvmSuppressWildcards var suppressJvmWildcardsGenericVar1: List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>> = TODO()
+ var suppressJvmWildcardsGenericVar2: @JvmSuppressWildcards List<MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>> = TODO()
+ var suppressJvmWildcardsGenericVar3: List<@JvmSuppressWildcards MyGenericIn<MyGenericOut<MyGenericOut<MyType>>>> = TODO()
+ var suppressJvmWildcardsGenericVar4: List<MyGenericIn<@JvmSuppressWildcards MyGenericOut<MyGenericOut<MyType>>>> = TODO()
+ var suppressJvmWildcardsGenericVar5: List<MyGenericIn<MyGenericOut<@JvmSuppressWildcards MyGenericOut<MyType>>>> = TODO()
+ var interfaceAlias: List<MyInterfaceAlias> = TODO()
+ var genericAlias: List<MyGenericAlias> = TODO()
+ var jvmWildcardTypeAlias: List<@JW String> = TODO()
+ var suppressJvmWildcardTypeAlias: List<@JSW Number> = TODO()
fun list(list: List<*>): List<*> { TODO() }
fun listTypeArg(list: List<R>): List<R> { TODO() }
fun listTypeArgNumber(list: List<Number>): List<Number> { TODO() }
@@ -393,6 +430,71 @@
fun suspendExplicitJvmSuppressWildcard_OnType2(
list: @JvmSuppressWildcards List<Number>
): @JvmSuppressWildcards List<Number> { TODO() }
+ fun interfaceAlias(
+ param: List<MyInterfaceAlias>
+ ): List<MyInterfaceAlias> = TODO()
+ fun explicitJvmSuppressWildcardsOnAlias(
+ param: List<@JvmSuppressWildcards MyInterfaceAlias>,
+ ): List<@JvmSuppressWildcards MyInterfaceAlias> = TODO()
+ fun genericAlias(param: List<MyGenericAlias>): List<MyGenericAlias> = TODO()
+ fun explicitJvmSuppressWildcardsOnGenericAlias(
+ param: List<@JvmSuppressWildcards MyGenericAlias>,
+ ): List<@JvmSuppressWildcards MyGenericAlias> = TODO()
+ fun explicitOutOnInvariant_onType1_WithExplicitJvmSuppressWildcardAlias(
+ list: @JSW MyGeneric<out MyGeneric<MyType>>
+ ): @JSW MyGeneric<out MyGeneric<MyType>> { TODO() }
+ fun explicitOutOnInvariant_onType2_WithExplicitJvmSuppressWildcardAlias(
+ list: @JSW MyGeneric<MyGeneric<out MyType>>
+ ): @JSW MyGeneric<MyGeneric<out MyType>> { TODO() }
+ fun explicitOutOnVariant_onType1(
+ list: List<out List<Number>>
+ ): List<out List<Number>> { TODO() }
+ fun explicitOutOnVariant_onType2(
+ list: List<List<out Number>>
+ ): List<List<out Number>> { TODO() }
+ fun explicitOutOnVariant_onType1_WithExplicitJvmSuppressWildcardAlias(
+ list: @JSW List<out List<Number>>
+ ): @JSW List<out List<Number>> { TODO() }
+ fun explicitOutOnVariant_onType2_WithExplicitJvmSuppressWildcardAlias(
+ list: @JSW List<List<out Number>>
+ ): @JSW List<List<out Number>> { TODO() }
+ fun explicitJvmWildcardTypeAlias(
+ list: List<@JW String>
+ ): List<@JW String> { TODO() }
+ fun explicitJvmSuppressWildcardTypeAlias_OnType(
+ list: List<@JSW Number>
+ ): List<@JSW Number> { TODO() }
+ fun explicitJvmSuppressWildcardTypeAlias_OnType2(
+ list: @JSW List<Number>
+ ): @JSW List<Number> { TODO() }
+ fun lambda1(param: MyLambdaAlias1): MyLambdaAlias1 = TODO()
+ fun lambda2(param: MyLambdaAlias2): MyLambdaAlias2 = TODO()
+ fun lambda3(param: MyLambdaAlias3): MyLambdaAlias3 = TODO()
+ fun lambda4(param: MyLambdaAlias4): MyLambdaAlias4 = TODO()
+ fun lambda5(param: MyLambdaAlias5): MyLambdaAlias5 = TODO()
+ fun lambda6(param: MyLambdaAlias6): MyLambdaAlias6 = TODO()
+ fun lambda7(param: MyLambdaAlias7): MyLambdaAlias7 = TODO()
+ @JSW fun lambda1WithJSW(param: MyLambdaAlias1): MyLambdaAlias1 = TODO()
+ @JSW fun lambda2WithJSW(param: MyLambdaAlias2): MyLambdaAlias2 = TODO()
+ @JSW fun lambda3WithJSW(param: MyLambdaAlias3): MyLambdaAlias3 = TODO()
+ @JSW fun lambda4WithJSW(param: MyLambdaAlias4): MyLambdaAlias4 = TODO()
+ @JSW fun lambda5WithJSW(param: MyLambdaAlias5): MyLambdaAlias5 = TODO()
+ @JSW fun lambda6WithJSW(param: MyLambdaAlias6): MyLambdaAlias6 = TODO()
+ @JSW fun lambda7WithJSW(param: MyLambdaAlias7): MyLambdaAlias7 = TODO()
+ fun suspendLambda1(param: MySuspendLambdaAlias1): MySuspendLambdaAlias1 = TODO()
+ fun suspendLambda2(param: MySuspendLambdaAlias2): MySuspendLambdaAlias2 = TODO()
+ fun suspendLambda3(param: MySuspendLambdaAlias3): MySuspendLambdaAlias3 = TODO()
+ fun suspendLambda4(param: MySuspendLambdaAlias4): MySuspendLambdaAlias4 = TODO()
+ fun suspendLambda5(param: MySuspendLambdaAlias5): MySuspendLambdaAlias5 = TODO()
+ fun suspendLambda6(param: MySuspendLambdaAlias6): MySuspendLambdaAlias6 = TODO()
+ fun suspendLambda7(param: MySuspendLambdaAlias7): MySuspendLambdaAlias7 = TODO()
+ @JSW fun suspendLambda1WithJSW(param: MySuspendLambdaAlias1): MySuspendLambdaAlias1 = TODO()
+ @JSW fun suspendLambda2WithJSW(param: MySuspendLambdaAlias2): MySuspendLambdaAlias2 = TODO()
+ @JSW fun suspendLambda3WithJSW(param: MySuspendLambdaAlias3): MySuspendLambdaAlias3 = TODO()
+ @JSW fun suspendLambda4WithJSW(param: MySuspendLambdaAlias4): MySuspendLambdaAlias4 = TODO()
+ @JSW fun suspendLambda5WithJSW(param: MySuspendLambdaAlias5): MySuspendLambdaAlias5 = TODO()
+ @JSW fun suspendLambda6WithJSW(param: MySuspendLambdaAlias6): MySuspendLambdaAlias6 = TODO()
+ @JSW fun suspendLambda7WithJSW(param: MySuspendLambdaAlias7): MySuspendLambdaAlias7 = TODO()
}
""".trimIndent()
), listOf(className)
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/profiling/ProfileRule.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/profiling/ProfileRule.kt
index 03bc13c..b14ba17 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/profiling/ProfileRule.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/profiling/ProfileRule.kt
@@ -16,14 +16,14 @@
package androidx.room.compiler.processing.profiling
-import org.junit.AssumptionViolatedException
-import org.junit.rules.TestRule
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
import kotlin.time.Duration
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.DurationUnit
import kotlin.time.ExperimentalTime
+import org.junit.AssumptionViolatedException
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
/**
* Helper rule to run profiling tests.
diff --git a/room/room-compiler/build.gradle b/room/room-compiler/build.gradle
index 6b7096e..98470ed 100644
--- a/room/room-compiler/build.gradle
+++ b/room/room-compiler/build.gradle
@@ -299,7 +299,7 @@
}
androidx {
- name = "Android Room Compiler"
+ name = "Room Compiler"
type = LibraryType.ANNOTATION_PROCESSOR
inceptionYear = "2017"
description = "Android Room annotation processor"
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
index 5c36768..42a63d5 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/xelement_ext.kt
@@ -16,10 +16,10 @@
package androidx.room.ext
-import kotlin.contracts.contract
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XFieldElement
import androidx.room.compiler.processing.XTypeElement
+import kotlin.contracts.contract
fun XElement.isEntityElement(): Boolean {
contract {
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/DatabaseViewProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/DatabaseViewProcessor.kt
index 67aecd0..44f349e 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/DatabaseViewProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/DatabaseViewProcessor.kt
@@ -16,10 +16,10 @@
package androidx.room.processor
+import androidx.room.compiler.processing.XTypeElement
import androidx.room.parser.ParsedQuery
import androidx.room.parser.QueryType
import androidx.room.parser.SqlParser
-import androidx.room.compiler.processing.XTypeElement
import androidx.room.vo.DatabaseView
class DatabaseViewProcessor(
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/LiveDataQueryResultBinderProvider.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/LiveDataQueryResultBinderProvider.kt
index 042b24a..3bd2cda 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/LiveDataQueryResultBinderProvider.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/LiveDataQueryResultBinderProvider.kt
@@ -16,9 +16,9 @@
package androidx.room.solver.binderprovider
-import androidx.room.ext.LifecyclesTypeNames
import androidx.room.compiler.processing.XRawType
import androidx.room.compiler.processing.XType
+import androidx.room.ext.LifecyclesTypeNames
import androidx.room.processor.Context
import androidx.room.solver.ObservableQueryResultBinderProvider
import androidx.room.solver.query.result.LiveDataQueryResultBinder
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/types/CursorValueReader.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/types/CursorValueReader.kt
index 2e560af..6771c01 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/types/CursorValueReader.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/types/CursorValueReader.kt
@@ -16,8 +16,8 @@
package androidx.room.solver.types
-import androidx.room.parser.SQLTypeAffinity
import androidx.room.compiler.processing.XType
+import androidx.room.parser.SQLTypeAffinity
import androidx.room.solver.CodeGenScope
/**
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt b/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
index ceb7f64..9d59d4d 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/util/SchemaDiffer.kt
@@ -23,12 +23,12 @@
import androidx.room.migration.bundle.ForeignKeyBundle
import androidx.room.migration.bundle.FtsEntityBundle
import androidx.room.migration.bundle.IndexBundle
-import androidx.room.processor.ProcessorErrors.deletedOrRenamedTableFound
-import androidx.room.processor.ProcessorErrors.tableRenameError
import androidx.room.processor.ProcessorErrors.conflictingRenameColumnAnnotationsFound
import androidx.room.processor.ProcessorErrors.conflictingRenameTableAnnotationsFound
-import androidx.room.processor.ProcessorErrors.newNotNullColumnMustHaveDefaultValue
import androidx.room.processor.ProcessorErrors.deletedOrRenamedColumnFound
+import androidx.room.processor.ProcessorErrors.deletedOrRenamedTableFound
+import androidx.room.processor.ProcessorErrors.newNotNullColumnMustHaveDefaultValue
+import androidx.room.processor.ProcessorErrors.tableRenameError
import androidx.room.processor.ProcessorErrors.tableWithConflictingPrefixFound
import androidx.room.vo.AutoMigration
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/DatabaseView.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/DatabaseView.kt
index 142cdf8..acdf443 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/DatabaseView.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/DatabaseView.kt
@@ -17,10 +17,10 @@
package androidx.room.vo
import androidx.room.compiler.processing.XType
-import androidx.room.migration.bundle.DatabaseViewBundle
-import androidx.room.parser.ParsedQuery
import androidx.room.compiler.processing.XTypeElement
+import androidx.room.migration.bundle.DatabaseViewBundle
import androidx.room.migration.bundle.VIEW_NAME_PLACEHOLDER
+import androidx.room.parser.ParsedQuery
class DatabaseView(
element: XTypeElement,
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/Entity.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/Entity.kt
index a565c5f..6f4b932 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/Entity.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/Entity.kt
@@ -17,8 +17,8 @@
package androidx.room.vo
import androidx.room.compiler.processing.XType
-import androidx.room.migration.bundle.EntityBundle
import androidx.room.compiler.processing.XTypeElement
+import androidx.room.migration.bundle.EntityBundle
import androidx.room.migration.bundle.TABLE_NAME_PLACEHOLDER
/**
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/FtsEntity.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/FtsEntity.kt
index 0a33965..7295095 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/FtsEntity.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/FtsEntity.kt
@@ -17,10 +17,10 @@
package androidx.room.vo
import androidx.room.compiler.processing.XType
-import androidx.room.migration.bundle.FtsEntityBundle
-import androidx.room.parser.FtsVersion
import androidx.room.compiler.processing.XTypeElement
+import androidx.room.migration.bundle.FtsEntityBundle
import androidx.room.migration.bundle.TABLE_NAME_PLACEHOLDER
+import androidx.room.parser.FtsVersion
/**
* An Entity with a mapping FTS table.
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/PrimaryKey.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/PrimaryKey.kt
index fde1bf8..69816b4 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/PrimaryKey.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/PrimaryKey.kt
@@ -15,8 +15,8 @@
*/
package androidx.room.vo
-import androidx.room.migration.bundle.PrimaryKeyBundle
import androidx.room.compiler.processing.XElement
+import androidx.room.migration.bundle.PrimaryKeyBundle
/**
* Represents a PrimaryKey for an Entity.
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/QueryMethod.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/QueryMethod.kt
index 2a87a34..81d260c 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/QueryMethod.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/QueryMethod.kt
@@ -16,9 +16,9 @@
package androidx.room.vo
-import androidx.room.parser.ParsedQuery
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XType
+import androidx.room.parser.ParsedQuery
import androidx.room.solver.prepared.binder.PreparedQueryResultBinder
import androidx.room.solver.query.result.QueryResultBinder
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/vo/SchemaIdentityKey.kt b/room/room-compiler/src/main/kotlin/androidx/room/vo/SchemaIdentityKey.kt
index 007ea5d..75e5117 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/vo/SchemaIdentityKey.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/vo/SchemaIdentityKey.kt
@@ -16,8 +16,8 @@
package androidx.room.vo
-import org.apache.commons.codec.digest.DigestUtils
import java.util.Locale
+import org.apache.commons.codec.digest.DigestUtils
interface HasSchemaIdentity {
fun getIdKey(): String
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/log/RLogTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/log/RLogTest.kt
index 0e39b5a..a45785d 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/log/RLogTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/log/RLogTest.kt
@@ -21,10 +21,10 @@
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XMessager
import androidx.room.vo.Warning
+import javax.tools.Diagnostic
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import javax.tools.Diagnostic
@RunWith(JUnit4::class)
class RLogTest {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/parser/ExpandableSqlParserTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/parser/ExpandableSqlParserTest.kt
index 0a030e4..61d54d2 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/parser/ExpandableSqlParserTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/parser/ExpandableSqlParserTest.kt
@@ -18,9 +18,9 @@
import androidx.room.parser.expansion.ExpandableSection
import androidx.room.parser.expansion.ExpandableSqlParser
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
index f8e5603..076ccf0 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/DaoProcessorTest.kt
@@ -24,8 +24,8 @@
import androidx.room.compiler.processing.util.runKspTest
import androidx.room.compiler.processing.util.runProcessorTest
import androidx.room.ext.RoomTypeNames.ROOM_DB
-import androidx.room.processor.ProcessorErrors.nullableComponentInDaoMethodReturnType
import androidx.room.processor.ProcessorErrors.nullableCollectionOrArrayReturnTypeInDaoMethod
+import androidx.room.processor.ProcessorErrors.nullableComponentInDaoMethodReturnType
import androidx.room.testing.context
import androidx.room.vo.Dao
import androidx.room.vo.ReadQueryMethod
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
index 1806453c..55f7026 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/InsertionMethodProcessorTest.kt
@@ -20,8 +20,8 @@
import androidx.room.OnConflictStrategy
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XType
-import androidx.room.processor.ProcessorErrors.INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT
import androidx.room.processor.ProcessorErrors.CANNOT_FIND_INSERT_RESULT_ADAPTER
+import androidx.room.processor.ProcessorErrors.INSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_INSERT
import androidx.room.processor.ProcessorErrors.INSERT_MULTI_PARAM_SINGLE_RETURN_MISMATCH
import androidx.room.processor.ProcessorErrors.INSERT_SINGLE_PARAM_MULTI_RETURN_MISMATCH
import androidx.room.vo.InsertionMethod
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/ProjectionExpanderTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/ProjectionExpanderTest.kt
index 3a136ab..2b5edd13 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/ProjectionExpanderTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/ProjectionExpanderTest.kt
@@ -25,8 +25,8 @@
import androidx.room.parser.expansion.ProjectionExpander
import androidx.room.testing.context
import createVerifierFromEntitiesAndViews
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/UpsertionMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/UpsertionMethodProcessorTest.kt
index 49832fb..0dea532 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/UpsertionMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/UpsertionMethodProcessorTest.kt
@@ -19,8 +19,8 @@
import androidx.room.Upsert
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XType
-import androidx.room.processor.ProcessorErrors.UPSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_UPSERT
import androidx.room.processor.ProcessorErrors.CANNOT_FIND_UPSERT_RESULT_ADAPTER
+import androidx.room.processor.ProcessorErrors.UPSERTION_DOES_NOT_HAVE_ANY_PARAMETERS_TO_UPSERT
import androidx.room.processor.ProcessorErrors.UPSERT_MULTI_PARAM_SINGLE_RETURN_MISMATCH
import androidx.room.processor.ProcessorErrors.UPSERT_SINGLE_PARAM_MULTI_RETURN_MISMATCH
import androidx.room.vo.UpsertionMethod
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/vo/FtsEntityTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/vo/FtsEntityTest.kt
index fcca115..c589003 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/vo/FtsEntityTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/vo/FtsEntityTest.kt
@@ -16,10 +16,10 @@
package androidx.room.vo
-import androidx.room.parser.FtsVersion
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XTypeElement
+import androidx.room.parser.FtsVersion
import mockElementAndType
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
diff --git a/room/room-gradle-plugin/build.gradle b/room/room-gradle-plugin/build.gradle
index 8b12c66..e9dfec6 100644
--- a/room/room-gradle-plugin/build.gradle
+++ b/room/room-gradle-plugin/build.gradle
@@ -81,7 +81,7 @@
}
androidx {
- name = "Android Room Gradle Plugin"
+ name = "Room Gradle Plugin"
type = LibraryType.GRADLE_PLUGIN
inceptionYear = "2023"
description = "Android Room Gradle Plugin"
diff --git a/room/room-guava/build.gradle b/room/room-guava/build.gradle
index 99c5ad7..572953f 100644
--- a/room/room-guava/build.gradle
+++ b/room/room-guava/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "Android Room Guava"
+ name = "Room Guava"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android Room Guava"
diff --git a/room/room-ktx/build.gradle b/room/room-ktx/build.gradle
index 5e4a868..3dfa666 100644
--- a/room/room-ktx/build.gradle
+++ b/room/room-ktx/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "Android Room Kotlin Extensions"
+ name = "Room Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android Room Kotlin Extensions"
diff --git a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
index 97dcc0d..c3e1e03 100644
--- a/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
+++ b/room/room-ktx/src/androidTest/java/androidx/room/CoroutineRoomCancellationTest.kt
@@ -22,6 +22,8 @@
import androidx.sqlite.db.SupportSQLiteOpenHelper
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
+import java.util.concurrent.Callable
+import java.util.concurrent.CountDownLatch
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -34,8 +36,6 @@
import kotlinx.coroutines.test.runCurrent
import org.junit.Assert.fail
import org.junit.Test
-import java.util.concurrent.Callable
-import java.util.concurrent.CountDownLatch
@SmallTest
@SdkSuppress(minSdkVersion = 16)
diff --git a/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt b/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
index 08dc8c5..af8d5a7 100644
--- a/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
+++ b/room/room-ktx/src/test/java/androidx/room/CoroutinesRoomTest.kt
@@ -18,6 +18,7 @@
import androidx.kruth.assertThat
import androidx.sqlite.db.SupportSQLiteOpenHelper
+import kotlin.coroutines.ContinuationInterceptor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.flow.first
@@ -26,7 +27,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import kotlin.coroutines.ContinuationInterceptor
@RunWith(JUnit4::class)
class CoroutinesRoomTest {
diff --git a/room/room-ktx/src/test/java/androidx/room/MigrationTest.kt b/room/room-ktx/src/test/java/androidx/room/MigrationTest.kt
index f49e8ce..bf24923 100644
--- a/room/room-ktx/src/test/java/androidx/room/MigrationTest.kt
+++ b/room/room-ktx/src/test/java/androidx/room/MigrationTest.kt
@@ -26,10 +26,10 @@
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteStatement
+import java.util.Locale
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.Locale
@RunWith(JUnit4::class)
class MigrationTest {
diff --git a/room/room-migration/build.gradle b/room/room-migration/build.gradle
index 20954b0..3eb7477 100644
--- a/room/room-migration/build.gradle
+++ b/room/room-migration/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Room Migration"
+ name = "Room Migration"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Room Migration"
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/DatabaseViewBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/DatabaseViewBundle.kt
index 247ec91a..4d8d0d4 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/DatabaseViewBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/DatabaseViewBundle.kt
@@ -17,7 +17,6 @@
package androidx.room.migration.bundle
import androidx.annotation.RestrictTo
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/EntityBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/EntityBundle.kt
index 515574b..ca445ae 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/EntityBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/EntityBundle.kt
@@ -18,7 +18,6 @@
import androidx.annotation.RestrictTo
import androidx.room.migration.bundle.SchemaEqualityUtil.checkSchemaEquality
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/FieldBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/FieldBundle.kt
index 4b3e07e9..c13f17f 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/FieldBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/FieldBundle.kt
@@ -17,7 +17,6 @@
package androidx.room.migration.bundle
import androidx.annotation.RestrictTo
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/ForeignKeyBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/ForeignKeyBundle.kt
index 5420167..3939331 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/ForeignKeyBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/ForeignKeyBundle.kt
@@ -17,7 +17,6 @@
package androidx.room.migration.bundle
import androidx.annotation.RestrictTo
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsEntityBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsEntityBundle.kt
index a66911b..0653167 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsEntityBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsEntityBundle.kt
@@ -18,7 +18,6 @@
import androidx.annotation.RestrictTo
import androidx.room.migration.bundle.SchemaEqualityUtil.checkSchemaEquality
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsOptionsBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsOptionsBundle.kt
index da62796..1040374 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsOptionsBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/FtsOptionsBundle.kt
@@ -17,7 +17,6 @@
package androidx.room.migration.bundle
import androidx.annotation.RestrictTo
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/IndexBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/IndexBundle.kt
index a54c633..c245c78 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/IndexBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/IndexBundle.kt
@@ -18,7 +18,6 @@
import androidx.annotation.RestrictTo
import androidx.room.Index
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/main/java/androidx/room/migration/bundle/PrimaryKeyBundle.kt b/room/room-migration/src/main/java/androidx/room/migration/bundle/PrimaryKeyBundle.kt
index b8f2406..1fd0e00 100644
--- a/room/room-migration/src/main/java/androidx/room/migration/bundle/PrimaryKeyBundle.kt
+++ b/room/room-migration/src/main/java/androidx/room/migration/bundle/PrimaryKeyBundle.kt
@@ -17,7 +17,6 @@
package androidx.room.migration.bundle
import androidx.annotation.RestrictTo
-
import com.google.gson.annotations.SerializedName
/**
diff --git a/room/room-migration/src/test/java/androidx/room/migration/bundle/DatabaseViewBundleTest.kt b/room/room-migration/src/test/java/androidx/room/migration/bundle/DatabaseViewBundleTest.kt
index 3f37dba..75fb554 100644
--- a/room/room-migration/src/test/java/androidx/room/migration/bundle/DatabaseViewBundleTest.kt
+++ b/room/room-migration/src/test/java/androidx/room/migration/bundle/DatabaseViewBundleTest.kt
@@ -18,7 +18,6 @@
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
-
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/room/room-migration/src/test/java/androidx/room/migration/bundle/PrimaryKeyBundleTest.kt b/room/room-migration/src/test/java/androidx/room/migration/bundle/PrimaryKeyBundleTest.kt
index 9a42f55..8b43988 100644
--- a/room/room-migration/src/test/java/androidx/room/migration/bundle/PrimaryKeyBundleTest.kt
+++ b/room/room-migration/src/test/java/androidx/room/migration/bundle/PrimaryKeyBundleTest.kt
@@ -18,7 +18,6 @@
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
-
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/room/room-paging/src/androidTest/kotlin/androidx/room/InvalidationTrackerExtRoomPaging.kt b/room/room-paging/src/androidTest/kotlin/androidx/room/InvalidationTrackerExtRoomPaging.kt
index 654a96e..fe1df3e6 100644
--- a/room/room-paging/src/androidTest/kotlin/androidx/room/InvalidationTrackerExtRoomPaging.kt
+++ b/room/room-paging/src/androidTest/kotlin/androidx/room/InvalidationTrackerExtRoomPaging.kt
@@ -15,9 +15,9 @@
*/
package androidx.room
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.delay
import kotlinx.coroutines.withTimeout
-import java.util.concurrent.TimeUnit
/**
* True if invalidation tracker is pending a refresh event to get database changes.
diff --git a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
index 09a9564..8231cf1 100644
--- a/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
+++ b/room/room-paging/src/androidTest/kotlin/androidx/room/paging/LimitOffsetPagingSourceTest.kt
@@ -34,23 +34,23 @@
import androidx.testutils.FilteringExecutor
import androidx.testutils.TestExecutor
import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.advanceUntilIdle
-import org.junit.After
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
import kotlin.test.assertTrue
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
private const val tableName: String = "TestItem"
@@ -573,7 +573,7 @@
val refreshKey = 85 - (15 / 2)
val pagingSource2 = LimitOffsetPagingSourceImpl(database)
- val pager2 = TestPager(pagingSource2, CONFIG)
+ val pager2 = TestPager(CONFIG, pagingSource2)
val result = pager2.refresh(initialKey = refreshKey) as LoadResult.Page
// database should only have 40 items left. Refresh key is invalid at this point
@@ -616,7 +616,7 @@
dao.deleteTestItems(0, 29)
val pagingSource2 = LimitOffsetPagingSourceImpl(database)
- val pager2 = TestPager(pagingSource2, CONFIG)
+ val pager2 = TestPager(CONFIG, pagingSource2)
// assume user was viewing first few items with anchorPosition = 0 and refresh key
// clips to 0
val result = pager2.refresh(initialKey = 0) as LoadResult.Page
@@ -648,7 +648,7 @@
dao.deleteTestItems(0, 94)
val pagingSource2 = LimitOffsetPagingSourceImpl(database)
- val pager2 = TestPager(pagingSource2, CONFIG)
+ val pager2 = TestPager(CONFIG, pagingSource2)
// assume user was viewing first few items with anchorPosition = 0 and refresh key
// clips to 0
val result = pager2.refresh(initialKey = 0) as LoadResult.Page
@@ -682,7 +682,7 @@
) -> Unit
) {
runBlocking {
- block(TestPager(pagingSource, config), pagingSource)
+ block(TestPager(config, pagingSource), pagingSource)
}
}
}
@@ -736,7 +736,7 @@
@Test
fun invalid_append() = runTest {
val pagingSource = LimitOffsetPagingSourceImpl(db)
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
dao.addAllItems(ITEMS_LIST)
val result = pager.refresh() as LoadResult.Page
@@ -769,7 +769,7 @@
@Test
fun invalid_prepend() = runTest {
val pagingSource = LimitOffsetPagingSourceImpl(db)
- val pager = TestPager(pagingSource, CONFIG)
+ val pager = TestPager(CONFIG, pagingSource)
dao.addAllItems(ITEMS_LIST)
val result = pager.refresh(initialKey = 20) as LoadResult.Page
diff --git a/room/room-paging/src/main/java/androidx/room/paging/LimitOffsetPagingSource.kt b/room/room-paging/src/main/java/androidx/room/paging/LimitOffsetPagingSource.kt
index 6634131..bca76d1 100644
--- a/room/room-paging/src/main/java/androidx/room/paging/LimitOffsetPagingSource.kt
+++ b/room/room-paging/src/main/java/androidx/room/paging/LimitOffsetPagingSource.kt
@@ -32,8 +32,8 @@
import androidx.room.paging.util.queryItemCount
import androidx.room.withTransaction
import androidx.sqlite.db.SupportSQLiteQuery
-import kotlinx.coroutines.withContext
import java.util.concurrent.atomic.AtomicInteger
+import kotlinx.coroutines.withContext
/**
* An implementation of [PagingSource] to perform a LIMIT OFFSET query
diff --git a/room/room-paging/src/main/java/androidx/room/paging/util/RoomPagingUtil.kt b/room/room-paging/src/main/java/androidx/room/paging/util/RoomPagingUtil.kt
index 1722c11..e51ceb0 100644
--- a/room/room-paging/src/main/java/androidx/room/paging/util/RoomPagingUtil.kt
+++ b/room/room-paging/src/main/java/androidx/room/paging/util/RoomPagingUtil.kt
@@ -22,8 +22,8 @@
import androidx.annotation.RestrictTo
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
-import androidx.paging.PagingSource.LoadParams.Prepend
import androidx.paging.PagingSource.LoadParams.Append
+import androidx.paging.PagingSource.LoadParams.Prepend
import androidx.paging.PagingSource.LoadParams.Refresh
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState
diff --git a/room/room-runtime-lint/build.gradle b/room/room-runtime-lint/build.gradle
index ea43587..52cc23c 100644
--- a/room/room-runtime-lint/build.gradle
+++ b/room/room-runtime-lint/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "Android Room-Runtime Lint Checks"
+ name = "Room-Runtime Lint Checks"
type = LibraryType.LINT
inceptionYear = "2022"
description = "Android Room-Runtime Lint Checks"
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 5859784..f5a047d 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -73,7 +73,7 @@
}
androidx {
- name = "Android Room-Runtime"
+ name = "Room-Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Room-Runtime"
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt b/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt
index ceaacd1..6a3fc94 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt
+++ b/room/room-runtime/src/androidTest/java/androidx/room/AutoCloserTest.kt
@@ -27,14 +27,14 @@
import androidx.test.filters.MediumTest
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
+import java.io.IOException
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.IOException
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt b/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
index 5b2fc1d..2efa582 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
+++ b/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperFactoryTest.kt
@@ -24,13 +24,13 @@
import androidx.sqlite.db.SupportSQLiteOpenHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicInteger
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicInteger
public class AutoClosingRoomOpenHelperFactoryTest {
private val DB_NAME = "name"
diff --git a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt b/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
index d8f36a4a..0a22c62 100644
--- a/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
+++ b/room/room-runtime/src/androidTest/java/androidx/room/AutoClosingRoomOpenHelperTest.kt
@@ -29,12 +29,12 @@
import androidx.test.filters.SdkSuppress
import androidx.testutils.assertThrows
import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
import java.io.IOException
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
class AutoClosingRoomOpenHelperTest {
diff --git a/room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt b/room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt
index 89fb70a..b1c65a8 100644
--- a/room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt
+++ b/room/room-runtime/src/main/java/androidx/room/EntityUpsertionAdapter.kt
@@ -17,8 +17,8 @@
package androidx.room
import android.database.sqlite.SQLiteConstraintException
-import androidx.annotation.RestrictTo
import android.os.Build
+import androidx.annotation.RestrictTo
/**
* The ErrorCode defined by SQLite Library for SQLITE_CONSTRAINT_PRIMARYKEY error
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt
index 0659f92..bbf6f8e 100644
--- a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt
+++ b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationClient.kt
@@ -15,10 +15,10 @@
*/
package androidx.room
-import android.content.Intent
-import android.content.ServiceConnection
import android.content.ComponentName
import android.content.Context
+import android.content.Intent
+import android.content.ServiceConnection
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
diff --git a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt
index 761541d..06ecd35 100644
--- a/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt
+++ b/room/room-runtime/src/main/java/androidx/room/MultiInstanceInvalidationService.kt
@@ -16,9 +16,9 @@
package androidx.room
import android.app.Service
-import android.os.RemoteCallbackList
import android.content.Intent
import android.os.IBinder
+import android.os.RemoteCallbackList
import android.os.RemoteException
import android.util.Log
import androidx.room.Room.LOG_TAG
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt
index 4fb5661..d6a4107 100644
--- a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt
+++ b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorDatabase.kt
@@ -19,7 +19,6 @@
import android.database.Cursor
import android.database.sqlite.SQLiteTransactionListener
import android.os.CancellationSignal
-
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteStatement
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt
index 4f36a1f..c15672f 100644
--- a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt
+++ b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelper.kt
@@ -18,7 +18,6 @@
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteOpenHelper
-
import java.util.concurrent.Executor
internal class QueryInterceptorOpenHelper(
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt
index d0fab60..1d86465 100644
--- a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt
+++ b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorOpenHelperFactory.kt
@@ -17,7 +17,6 @@
package androidx.room
import androidx.sqlite.db.SupportSQLiteOpenHelper
-
import java.util.concurrent.Executor
/**
diff --git a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt
index 2ec9508..50cf02c 100644
--- a/room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt
+++ b/room/room-runtime/src/main/java/androidx/room/QueryInterceptorStatement.kt
@@ -17,7 +17,6 @@
package androidx.room
import androidx.sqlite.db.SupportSQLiteStatement
-
import java.util.concurrent.Executor
/**
diff --git a/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt b/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt
index dceaab0..37d3ebd 100644
--- a/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt
+++ b/room/room-runtime/src/main/java/androidx/room/SQLiteCopyOpenHelper.kt
@@ -20,8 +20,8 @@
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.room.Room.LOG_TAG
-import androidx.room.util.readVersion
import androidx.room.util.copy
+import androidx.room.util.readVersion
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteOpenHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
diff --git a/room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt b/room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt
index 62d6ecd..b63bfa0 100644
--- a/room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt
+++ b/room/room-runtime/src/test/java/androidx/room/InvalidationLiveDataContainerTest.kt
@@ -17,6 +17,7 @@
package androidx.room
import androidx.lifecycle.LiveData
+import java.util.concurrent.Callable
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
@@ -24,7 +25,6 @@
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito
-import java.util.concurrent.Callable
@RunWith(JUnit4::class)
class InvalidationLiveDataContainerTest {
diff --git a/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt b/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
index b1b2124..be50aa4 100644
--- a/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
+++ b/room/room-runtime/src/test/java/androidx/room/SQLiteCopyOpenHelperTest.kt
@@ -22,19 +22,6 @@
import androidx.annotation.RequiresApi
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteOpenHelper
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertSame
-import org.junit.Ignore
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TemporaryFolder
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import org.mockito.Mockito.`when`
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
import java.io.File
import java.io.FileInputStream
import java.io.IOException
@@ -45,6 +32,19 @@
import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicInteger
import kotlin.concurrent.thread
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertSame
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.Mockito.`when`
@RunWith(JUnit4::class)
class SQLiteCopyOpenHelperTest {
diff --git a/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt b/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt
index edda059..9163232 100644
--- a/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt
+++ b/room/room-runtime/src/test/java/androidx/room/TransactionExecutorTest.kt
@@ -17,13 +17,13 @@
package androidx.room
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
@RunWith(JUnit4::class)
class TransactionExecutorTest {
diff --git a/room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt b/room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt
index 19ec25d..aafd7cd 100644
--- a/room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt
+++ b/room/room-runtime/src/test/java/androidx/room/util/UUIDUtilTest.kt
@@ -17,12 +17,12 @@
package androidx.room.util
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
import java.nio.ByteBuffer
import java.util.UUID
import kotlin.random.Random
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
@RunWith(JUnit4::class)
class UUIDUtilTest {
diff --git a/room/room-rxjava2/build.gradle b/room/room-rxjava2/build.gradle
index 6cc2e1e..c802802 100644
--- a/room/room-rxjava2/build.gradle
+++ b/room/room-rxjava2/build.gradle
@@ -39,7 +39,7 @@
}
androidx {
- name = "Android Room RXJava2"
+ name = "Room RXJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Room RXJava2"
diff --git a/room/room-rxjava2/src/test/java/androidx/room/RxRoomTest.kt b/room/room-rxjava2/src/test/java/androidx/room/RxRoomTest.kt
index bea3aa5..a5d9af9 100644
--- a/room/room-rxjava2/src/test/java/androidx/room/RxRoomTest.kt
+++ b/room/room-rxjava2/src/test/java/androidx/room/RxRoomTest.kt
@@ -17,25 +17,24 @@
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.arch.core.executor.testing.CountingTaskExecutorRule
+import com.google.common.truth.Truth.assertThat
import io.reactivex.functions.Consumer
import io.reactivex.observers.TestObserver
import io.reactivex.subscribers.TestSubscriber
-
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference
-import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.whenever
import org.mockito.kotlin.doAnswer
-import org.mockito.kotlin.verify
+import org.mockito.kotlin.mock
import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(JUnit4::class)
class RxRoomTest {
diff --git a/room/room-rxjava3/build.gradle b/room/room-rxjava3/build.gradle
index fee4abe..3533c33 100644
--- a/room/room-rxjava3/build.gradle
+++ b/room/room-rxjava3/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "Android Room RXJava3"
+ name = "Room RXJava3"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Room RXJava3"
diff --git a/room/room-rxjava3/src/test/java/androidx/room/rxjava3/RxRoomTest.kt b/room/room-rxjava3/src/test/java/androidx/room/rxjava3/RxRoomTest.kt
index cb5b547..e63839a 100644
--- a/room/room-rxjava3/src/test/java/androidx/room/rxjava3/RxRoomTest.kt
+++ b/room/room-rxjava3/src/test/java/androidx/room/rxjava3/RxRoomTest.kt
@@ -30,14 +30,14 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
-import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.whenever
-import org.mockito.kotlin.doAnswer
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.never
import org.mockito.invocation.InvocationOnMock
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
@RunWith(JUnit4::class)
class RxRoomTest {
diff --git a/room/room-testing/build.gradle b/room/room-testing/build.gradle
index 1471e49..e8970dc 100644
--- a/room/room-testing/build.gradle
+++ b/room/room-testing/build.gradle
@@ -54,7 +54,7 @@
}
androidx {
- name = "Android Room Testing"
+ name = "Room Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Room Testing"
diff --git a/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/RecyclerViewCoordinatorLayoutAppBarActivity.kt b/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/RecyclerViewCoordinatorLayoutAppBarActivity.kt
index 163843d..ce8e561 100644
--- a/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/RecyclerViewCoordinatorLayoutAppBarActivity.kt
+++ b/samples/AndroidXDemos/src/main/java/com/example/androidx/widget/RecyclerViewCoordinatorLayoutAppBarActivity.kt
@@ -21,11 +21,9 @@
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
-
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-
import com.example.androidx.R
class RecyclerViewCoordinatorLayoutAppBarActivity : AppCompatActivity() {
diff --git a/savedstate/savedstate-ktx/src/main/AndroidManifest.xml b/savedstate/savedstate-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/savedstate/savedstate-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistryOwner.kt b/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistryOwner.kt
index dc63d7f..4d8667a 100644
--- a/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistryOwner.kt
+++ b/savedstate/savedstate/src/main/java/androidx/savedstate/SavedStateRegistryOwner.kt
@@ -16,8 +16,8 @@
package androidx.savedstate
import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleObserver
+import androidx.lifecycle.LifecycleOwner
/**
* A scope that owns [SavedStateRegistry]
*
diff --git a/security/security-app-authenticator-testing/build.gradle b/security/security-app-authenticator-testing/build.gradle
index 7f3ed40..e0e8856 100644
--- a/security/security-app-authenticator-testing/build.gradle
+++ b/security/security-app-authenticator-testing/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android Security App Package Authenticator Testing"
+ name = "Security App Authenticator Testing Extensions"
type = LibraryType.PUBLISHED_TEST_LIBRARY
mavenVersion = LibraryVersions.SECURITY_APP_AUTHENTICATOR_TESTING
inceptionYear = "2021"
diff --git a/security/security-app-authenticator/build.gradle b/security/security-app-authenticator/build.gradle
index cb80735..de6d420 100644
--- a/security/security-app-authenticator/build.gradle
+++ b/security/security-app-authenticator/build.gradle
@@ -48,7 +48,7 @@
}
androidx {
- name = "Android Security App Package Authenitcator Library"
+ name = "Security App Authenitcator"
type = LibraryType.PUBLISHED_LIBRARY
mavenVersion = LibraryVersions.SECURITY_APP_AUTHENTICATOR
inceptionYear = "2020"
diff --git a/security/security-biometric/build.gradle b/security/security-biometric/build.gradle
index c8204ad..c48792f 100644
--- a/security/security-biometric/build.gradle
+++ b/security/security-biometric/build.gradle
@@ -43,7 +43,7 @@
}
androidx {
- name = "AndroidX Security Biometric"
+ name = "Security Biometric"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.SECURITY_BIOMETRIC
inceptionYear = "2020"
diff --git a/security/security-crypto-ktx/build.gradle b/security/security-crypto-ktx/build.gradle
index adf0c8b..6717a1f 100644
--- a/security/security-crypto-ktx/build.gradle
+++ b/security/security-crypto-ktx/build.gradle
@@ -42,7 +42,7 @@
}
androidx {
- name = "AndroidX Security Kotlin Extensions"
+ name = "Security Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.SECURITY
inceptionYear = "2020"
diff --git a/security/security-crypto-ktx/src/androidTest/java/androidx/security/crypto/KtxTests.kt b/security/security-crypto-ktx/src/androidTest/java/androidx/security/crypto/KtxTests.kt
index d91fc08..5e2e079 100644
--- a/security/security-crypto-ktx/src/androidTest/java/androidx/security/crypto/KtxTests.kt
+++ b/security/security-crypto-ktx/src/androidTest/java/androidx/security/crypto/KtxTests.kt
@@ -20,13 +20,13 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import java.io.File
+import java.nio.charset.StandardCharsets
+import java.security.KeyStore
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
-import java.nio.charset.StandardCharsets
-import java.security.KeyStore
private const val PREFS_FILE = "test_shared_prefs"
diff --git a/security/security-crypto/build.gradle b/security/security-crypto/build.gradle
index 4b86de9..f33cc83 100644
--- a/security/security-crypto/build.gradle
+++ b/security/security-crypto/build.gradle
@@ -46,7 +46,7 @@
}
androidx {
- name = "AndroidX Security"
+ name = "Security"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.SECURITY
inceptionYear = "2019"
diff --git a/security/security-identity-credential/build.gradle b/security/security-identity-credential/build.gradle
index d6b322a..b81043e 100644
--- a/security/security-identity-credential/build.gradle
+++ b/security/security-identity-credential/build.gradle
@@ -45,7 +45,7 @@
}
androidx {
- name = "AndroidX Security"
+ name = "Security"
publish = Publish.SNAPSHOT_AND_RELEASE
runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
mavenVersion = LibraryVersions.SECURITY_IDENTITY_CREDENTIAL
diff --git a/settings.gradle b/settings.gradle
index 9abd3a2..0f11a3a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -472,7 +472,6 @@
includeProject(":benchmark:integration-tests:dry-run-benchmark", [BuildType.MAIN])
includeProject(":benchmark:integration-tests:macrobenchmark", [BuildType.MAIN])
includeProject(":benchmark:integration-tests:macrobenchmark-target", [BuildType.MAIN])
-includeProject(":benchmark:integration-tests:test-module-sample", [BuildType.MAIN])
includeProject(":benchmark:integration-tests:startup-benchmark", [BuildType.MAIN])
includeProject(":biometric:biometric", [BuildType.MAIN])
includeProject(":biometric:biometric-ktx", [BuildType.MAIN])
@@ -503,6 +502,7 @@
includeProject(":camera:camera-video", [BuildType.CAMERA])
includeProject(":camera:camera-view", [BuildType.CAMERA])
includeProject(":camera:camera-viewfinder", [BuildType.CAMERA])
+includeProject(":camera:camera-viewfinder-compose", [BuildType.CAMERA])
includeProject(":camera:camera-viewfinder-core", [BuildType.CAMERA])
includeProject(":camera:integration-tests:camera-testapp-avsync", "camera/integration-tests/avsynctestapp", [BuildType.CAMERA])
includeProject(":camera:integration-tests:camera-testapp-camera2-pipe", "camera/integration-tests/camerapipetestapp", [BuildType.CAMERA])
diff --git a/sharetarget/sharetarget/build.gradle b/sharetarget/sharetarget/build.gradle
index 233ff32..4c1c02f 100644
--- a/sharetarget/sharetarget/build.gradle
+++ b/sharetarget/sharetarget/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "AndroidX Share Target Support Library"
+ name = "Share Target"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "ShareTarget"
diff --git a/slice/slice-benchmark/build.gradle b/slice/slice-benchmark/build.gradle
index e353c79..6cfa1f1 100644
--- a/slice/slice-benchmark/build.gradle
+++ b/slice/slice-benchmark/build.gradle
@@ -40,12 +40,16 @@
}
androidx {
- name = "Slices Benchmarks"
+ name = "Slice Benchmarks"
publish = Publish.NONE // Library is deprecated pending removal.
- disableDeviceTests = true
mavenVersion = LibraryVersions.SLICE_BENCHMARK
inceptionYear = "2018"
description = "RecyclerView Benchmarks"
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-builders-ktx/build.gradle b/slice/slice-builders-ktx/build.gradle
index 7ef627a..c67b6c7 100644
--- a/slice/slice-builders-ktx/build.gradle
+++ b/slice/slice-builders-ktx/build.gradle
@@ -45,13 +45,17 @@
}
androidx {
- name = "Slice builders KTX"
+ name = "Slice Builders Kotlin Extensions"
publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
- disableDeviceTests = true // Pending removal, don't run tests.
runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
mavenVersion = LibraryVersions.SLICE_BUILDERS_KTX
inceptionYear = "2018"
description = "A set of Kotlin extension methods built on top of slice-builders APIs."
failOnDeprecationWarnings = false
legacyDisableKotlinStrictApiMode = true
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
diff --git a/slice/slice-builders-ktx/src/main/AndroidManifest.xml b/slice/slice-builders-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/slice/slice-builders-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/slice/slice-builders/build.gradle b/slice/slice-builders/build.gradle
index d0ba1a4..06f184e 100644
--- a/slice/slice-builders/build.gradle
+++ b/slice/slice-builders/build.gradle
@@ -31,14 +31,18 @@
}
androidx {
- name = "Slice builders"
+ name = "Slice Builders"
publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
- disableDeviceTests = true // Pending removal, don't run tests.
runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
mavenVersion = LibraryVersions.SLICE
inceptionYear = "2017"
description = "A set of builders to create templates using SliceProvider APIs"
failOnDeprecationWarnings = false
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-builders/src/main/AndroidManifest.xml b/slice/slice-builders/src/main/AndroidManifest.xml
deleted file mode 100644
index 95c4426..0000000
--- a/slice/slice-builders/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 />
diff --git a/slice/slice-core/build.gradle b/slice/slice-core/build.gradle
index 2bab0a9..33028b2 100644
--- a/slice/slice-core/build.gradle
+++ b/slice/slice-core/build.gradle
@@ -37,14 +37,18 @@
}
androidx {
- name = "Common utilities for slices"
+ name = "Slice Core"
publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
- disableDeviceTests = true // Pending removal, don't run tests.
runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
mavenVersion = LibraryVersions.SLICE
inceptionYear = "2017"
description = "The slices core library provides utilities for the slices view and provider libraries"
failOnDeprecationWarnings = false
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-remotecallback/build.gradle b/slice/slice-remotecallback/build.gradle
index 56db28d..edd99ea 100644
--- a/slice/slice-remotecallback/build.gradle
+++ b/slice/slice-remotecallback/build.gradle
@@ -39,12 +39,16 @@
androidx {
name = "Slice Remote Callback"
publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
- disableDeviceTests = true // Pending removal, don't run tests.
runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
mavenVersion = LibraryVersions.SLICE_REMOTECALLBACK
inceptionYear = "2019"
description = "A library that handles PendingIntents in slices as remote callbacks"
failOnDeprecationWarnings = false
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-remotecallback/src/main/AndroidManifest.xml b/slice/slice-remotecallback/src/main/AndroidManifest.xml
deleted file mode 100644
index dcf3758..0000000
--- a/slice/slice-remotecallback/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
- <!-- Copyright (C) 2019 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 />
-
diff --git a/slice/slice-test/build.gradle b/slice/slice-test/build.gradle
index ff04df0..6913178 100644
--- a/slice/slice-test/build.gradle
+++ b/slice/slice-test/build.gradle
@@ -38,14 +38,18 @@
}
androidx {
- name = "Slice test code"
+ name = "Slice Test Extensions"
type = LibraryType.INTERNAL_TEST_LIBRARY
publish = Publish.NONE // Library is deprecated pending removal.
- disableDeviceTests = true
mavenVersion = LibraryVersions.SLICE
inceptionYear = "2017"
description = "A library that holds common code for testing slices"
failOnDeprecationWarnings = false
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-view/build.gradle b/slice/slice-view/build.gradle
index 5dc4379..14f019d 100644
--- a/slice/slice-view/build.gradle
+++ b/slice/slice-view/build.gradle
@@ -41,14 +41,18 @@
}
androidx {
- name = "Slice views"
+ name = "Slice Views"
publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
- disableDeviceTests = true // Pending removal, don't run tests.
runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
mavenVersion = LibraryVersions.SLICE
inceptionYear = "2017"
description = "A library that handles rendering of slice content into supported templates"
failOnDeprecationWarnings = false
+
+ deviceTests {
+ // Pending removal, don't run tests.
+ enabled = false
+ }
}
android {
diff --git a/slice/slice-view/src/main/AndroidManifest.xml b/slice/slice-view/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/slice/slice-view/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/slidingpanelayout/slidingpanelayout/api/current.txt b/slidingpanelayout/slidingpanelayout/api/current.txt
index 9340904..eecf512 100644
--- a/slidingpanelayout/slidingpanelayout/api/current.txt
+++ b/slidingpanelayout/slidingpanelayout/api/current.txt
@@ -6,6 +6,7 @@
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?);
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?, int);
method public void addPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void addSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method protected boolean canScroll(android.view.View, boolean, int, int, int);
method @Deprecated public boolean canSlide();
method public void close();
@@ -19,6 +20,7 @@
method public void open();
method public boolean openPane();
method public void removePanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void removeSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method @Deprecated public void setCoveredFadeColor(@ColorInt int);
method public final void setLockMode(int);
method @Deprecated public void setPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener?);
@@ -61,5 +63,9 @@
method public void onPanelSlide(android.view.View, float);
}
+ public static interface SlidingPaneLayout.SlideableStateListener {
+ method public void onSlideableStateChanged(boolean);
+ }
+
}
diff --git a/slidingpanelayout/slidingpanelayout/api/public_plus_experimental_current.txt b/slidingpanelayout/slidingpanelayout/api/public_plus_experimental_current.txt
index 9340904..eecf512 100644
--- a/slidingpanelayout/slidingpanelayout/api/public_plus_experimental_current.txt
+++ b/slidingpanelayout/slidingpanelayout/api/public_plus_experimental_current.txt
@@ -6,6 +6,7 @@
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?);
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?, int);
method public void addPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void addSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method protected boolean canScroll(android.view.View, boolean, int, int, int);
method @Deprecated public boolean canSlide();
method public void close();
@@ -19,6 +20,7 @@
method public void open();
method public boolean openPane();
method public void removePanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void removeSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method @Deprecated public void setCoveredFadeColor(@ColorInt int);
method public final void setLockMode(int);
method @Deprecated public void setPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener?);
@@ -61,5 +63,9 @@
method public void onPanelSlide(android.view.View, float);
}
+ public static interface SlidingPaneLayout.SlideableStateListener {
+ method public void onSlideableStateChanged(boolean);
+ }
+
}
diff --git a/slidingpanelayout/slidingpanelayout/api/restricted_current.txt b/slidingpanelayout/slidingpanelayout/api/restricted_current.txt
index 9340904..eecf512 100644
--- a/slidingpanelayout/slidingpanelayout/api/restricted_current.txt
+++ b/slidingpanelayout/slidingpanelayout/api/restricted_current.txt
@@ -6,6 +6,7 @@
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?);
ctor public SlidingPaneLayout(android.content.Context, android.util.AttributeSet?, int);
method public void addPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void addSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method protected boolean canScroll(android.view.View, boolean, int, int, int);
method @Deprecated public boolean canSlide();
method public void close();
@@ -19,6 +20,7 @@
method public void open();
method public boolean openPane();
method public void removePanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener);
+ method public void removeSlideableStateListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener);
method @Deprecated public void setCoveredFadeColor(@ColorInt int);
method public final void setLockMode(int);
method @Deprecated public void setPanelSlideListener(androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener?);
@@ -61,5 +63,9 @@
method public void onPanelSlide(android.view.View, float);
}
+ public static interface SlidingPaneLayout.SlideableStateListener {
+ method public void onSlideableStateChanged(boolean);
+ }
+
}
diff --git a/slidingpanelayout/slidingpanelayout/build.gradle b/slidingpanelayout/slidingpanelayout/build.gradle
index 6a29dca..58cbeb8 100644
--- a/slidingpanelayout/slidingpanelayout/build.gradle
+++ b/slidingpanelayout/slidingpanelayout/build.gradle
@@ -23,7 +23,7 @@
}
androidx {
- name = "Android Support Library Sliding Pane Layout"
+ name = "Sliding Pane Layout"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "SlidingPaneLayout offers a responsive, two pane layout that automatically switches between overlapping panes on smaller devices to a side by side view on larger devices."
diff --git a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/LockModeTest.kt b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/LockModeTest.kt
index faf82fa..fe2cdae 100644
--- a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/LockModeTest.kt
+++ b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/LockModeTest.kt
@@ -17,9 +17,9 @@
package androidx.slidingpanelayout.widget
import androidx.slidingpanelayout.test.R
+import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_LOCKED
import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED
import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_LOCKED_OPEN
-import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_LOCKED
import androidx.slidingpanelayout.widget.SlidingPaneLayout.LOCK_MODE_UNLOCKED
import androidx.slidingpanelayout.widget.helpers.TestActivity
import androidx.slidingpanelayout.widget.helpers.addWaitForCloseLatch
@@ -39,10 +39,10 @@
import androidx.test.filters.SdkSuppress
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
/**
* Tests [SlidingPaneLayout.setLockMode] and [SlidingPaneLayout.getLockMode]
diff --git a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/PanelSlideListenerTest.kt b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/PanelSlideListenerTest.kt
index 027b5cd..a98a7d9 100644
--- a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/PanelSlideListenerTest.kt
+++ b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/PanelSlideListenerTest.kt
@@ -30,11 +30,11 @@
import androidx.testutils.withActivity
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
/**
* Tests [SlidingPaneLayout.PanelSlideListener]
diff --git a/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/SlideableStateListenerTest.kt b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/SlideableStateListenerTest.kt
new file mode 100644
index 0000000..490a911
--- /dev/null
+++ b/slidingpanelayout/slidingpanelayout/src/androidTest/java/androidx/slidingpanelayout/widget/SlideableStateListenerTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.slidingpanelayout.widget
+
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.slidingpanelayout.test.R
+import androidx.slidingpanelayout.widget.SlidingPaneLayout.SlideableStateListener
+import androidx.slidingpanelayout.widget.helpers.TestActivity
+import androidx.test.core.app.ActivityScenario
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.After
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+class SlideableStateListenerTest {
+
+ @After
+ public fun tearDown() {
+ TestActivity.onActivityCreated = {}
+ }
+
+ @Test
+ fun testAddSlideableStateListener() {
+ var isSlideableCalled = false
+ TestActivity.onActivityCreated = { activity ->
+ val container = FrameLayout(activity)
+ val layout = activity.layoutInflater.inflate(
+ R.layout.activity_test_layout, null, false
+ )
+ container.addView(
+ layout,
+ ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ )
+ val slidingPaneLayout = container
+ .findViewById<SlidingPaneLayout>(R.id.sliding_pane_layout)
+ slidingPaneLayout.addSlideableStateListener { _ ->
+ isSlideableCalled = true
+ }
+
+ activity.setContentView(container)
+ }
+
+ with(ActivityScenario.launch(TestActivity::class.java)) {
+ assertWithMessage(
+ "isSlideable should be called when measuring the layout has completed")
+ .that(isSlideableCalled)
+ .isTrue()
+ }
+ }
+
+ @Test
+ fun testRemoveSlideableStateListener() {
+ var isSlideableCalled: Boolean? = null
+
+ TestActivity.onActivityCreated = { activity ->
+ val container = FrameLayout(activity)
+ val layout = activity.layoutInflater.inflate(
+ R.layout.activity_test_layout, null, false
+ )
+ container.addView(
+ layout,
+ ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ )
+ )
+ val slideableStateListener = SlideableStateListener {
+ isSlideableCalled = true
+ }
+
+ val slidingPaneLayout = container
+ .findViewById<SlidingPaneLayout>(R.id.sliding_pane_layout)
+ slidingPaneLayout.addSlideableStateListener(slideableStateListener)
+
+ activity.setContentView(container)
+ slidingPaneLayout.removeSlideableStateListener(slideableStateListener)
+ }
+
+ with(ActivityScenario.launch(TestActivity::class.java)) {
+ assertWithMessage("isSlideable should not be called if the listener has been removed")
+ .that(isSlideableCalled)
+ .isNull()
+ }
+ }
+}
\ No newline at end of file
diff --git a/slidingpanelayout/slidingpanelayout/src/main/AndroidManifest.xml b/slidingpanelayout/slidingpanelayout/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/slidingpanelayout/slidingpanelayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/FoldingFeatureObserver.kt b/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/FoldingFeatureObserver.kt
index b3119aa..d4ae2e7 100644
--- a/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/FoldingFeatureObserver.kt
+++ b/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/FoldingFeatureObserver.kt
@@ -20,6 +20,7 @@
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher
@@ -27,7 +28,6 @@
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch
-import java.util.concurrent.Executor
/**
* A device folding feature observer is used to notify listener when there is a folding feature
diff --git a/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java b/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
index 27478c9..4c826d2 100644
--- a/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
+++ b/slidingpanelayout/slidingpanelayout/src/main/java/androidx/slidingpanelayout/widget/SlidingPaneLayout.java
@@ -178,6 +178,9 @@
private float mInitialMotionX;
private float mInitialMotionY;
+ private final List<SlideableStateListener> mSlideableStateListeners =
+ new CopyOnWriteArrayList<>();
+
private final List<PanelSlideListener> mPanelSlideListeners = new CopyOnWriteArrayList<>();
private @Nullable PanelSlideListener mPanelSlideListener;
@@ -249,6 +252,20 @@
}
/**
+ * Listener to whether the SlidingPaneLayout is slideable or is a fixed width.
+ */
+ public interface SlideableStateListener {
+
+ /**
+ * Called when onMeasure has measured out the total width of the added layouts
+ * within SlidingPaneLayout
+ * @param isSlideable Returns true if the current SlidingPaneLayout has the ability to
+ * slide, returns false if the SlidingPaneLayout is a fixed width.
+ */
+ void onSlideableStateChanged(boolean isSlideable);
+ }
+
+ /**
* Listener for monitoring events about sliding panes.
*/
public interface PanelSlideListener {
@@ -436,6 +453,25 @@
}
/**
+ * Adds the specified listener to the list of listeners that will be notified of sliding
+ * state events.
+ * @param listener Listener to notify when sliding state events occur.
+ * @see #removeSlideableStateListener(SlideableStateListener)
+ */
+ public void addSlideableStateListener(@NonNull SlideableStateListener listener) {
+ mSlideableStateListeners.add(listener);
+ }
+
+ /**
+ * Removes the specified listener from the list of listeners that will be notified of sliding
+ * state events.
+ * @param listener Listener to notify when sliding state events occur
+ */
+ public void removeSlideableStateListener(@NonNull SlideableStateListener listener) {
+ mSlideableStateListeners.remove(listener);
+ }
+
+ /**
* Adds the specified listener to the list of listeners that will be notified of
* panel slide events.
*
@@ -777,7 +813,12 @@
final int measuredHeight = layoutHeight + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(measuredWidth, measuredHeight);
- mCanSlide = canSlide;
+ if (canSlide != mCanSlide) {
+ mCanSlide = canSlide;
+ for (SlideableStateListener listener : mSlideableStateListeners) {
+ listener.onSlideableStateChanged(mCanSlide);
+ }
+ }
if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) {
// Cancel scrolling in progress, it's no longer relevant.
@@ -1056,6 +1097,15 @@
}
/**
+ * @return true if content in this layout can be slid open and closed
+ * @deprecated Renamed to {@link #isSlideable()} - this method is going away soon!
+ */
+ @Deprecated
+ public boolean canSlide() {
+ return mCanSlide;
+ }
+
+ /**
* @deprecated Renamed to {@link #closePane()} - this method is going away soon!
*/
@Deprecated
@@ -1094,15 +1144,6 @@
}
/**
- * @return true if content in this layout can be slid open and closed
- * @deprecated Renamed to {@link #isSlideable()} - this method is going away soon!
- */
- @Deprecated
- public boolean canSlide() {
- return mCanSlide;
- }
-
- /**
* Check if both the list and detail view panes in this layout can fully fit side-by-side. If
* not, the content pane has the capability to slide back and forth. Note that the lock mode
* is not taken into account in this method. This method is typically used to determine
diff --git a/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt b/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
index 57ef857..d69eee1 100644
--- a/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
+++ b/sqlite/integration-tests/inspection-room-testapp/src/androidTest/java/androidx/sqlite/inspection/RoomInvalidationHookTest.kt
@@ -30,6 +30,8 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.runBlocking
@@ -37,8 +39,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class RoomInvalidationHookTest {
diff --git a/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/Database.kt b/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/Database.kt
index bebc2ab..ca2c993 100644
--- a/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/Database.kt
+++ b/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/Database.kt
@@ -16,9 +16,9 @@
package androidx.sqlite.inspection.sqldeligttestapp
-import androidx.sqlite.inspection.test.TestEntityQueries
import androidx.sqlite.inspection.sqldeligttestapp.app.newInstance
import androidx.sqlite.inspection.sqldeligttestapp.app.schema
+import androidx.sqlite.inspection.test.TestEntityQueries
import com.squareup.sqldelight.Transacter
import com.squareup.sqldelight.db.SqlDriver
diff --git a/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/app/DatabaseImpl.kt b/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/app/DatabaseImpl.kt
index cb63403..675a5a1 100644
--- a/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/app/DatabaseImpl.kt
+++ b/sqlite/integration-tests/inspection-sqldelight-testapp/src/main/generated/androidx/sqlite/inspection/sqldeligttestapp/app/DatabaseImpl.kt
@@ -16,9 +16,9 @@
package androidx.sqlite.inspection.sqldeligttestapp.app
+import androidx.sqlite.inspection.sqldeligttestapp.Database
import androidx.sqlite.inspection.test.TestEntity
import androidx.sqlite.inspection.test.TestEntityQueries
-import androidx.sqlite.inspection.sqldeligttestapp.Database
import com.squareup.sqldelight.Query
import com.squareup.sqldelight.TransacterImpl
import com.squareup.sqldelight.db.SqlDriver
diff --git a/sqlite/sqlite-framework/build.gradle b/sqlite/sqlite-framework/build.gradle
index 0169f43..65eb1e4 100644
--- a/sqlite/sqlite-framework/build.gradle
+++ b/sqlite/sqlite-framework/build.gradle
@@ -37,7 +37,7 @@
}
androidx {
- name = "Android Support SQLite - Framework Implementation"
+ name = "SQLite Framework Integration"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "The implementation of Support SQLite library using the framework code."
diff --git a/sqlite/sqlite-inspection/build.gradle b/sqlite/sqlite-inspection/build.gradle
index da58266..3210e2c 100644
--- a/sqlite/sqlite-inspection/build.gradle
+++ b/sqlite/sqlite-inspection/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android SQLite Inspector"
+ name = "SQLite Inspector"
type = LibraryType.IDE_PLUGIN
// Decouple SQLITE_INSPECTOR because it depends on
// the inspection protocol, which is alpha
diff --git a/sqlite/sqlite-inspection/src/androidTest/AndroidManifest.xml b/sqlite/sqlite-inspection/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e95a361..0000000
--- a/sqlite/sqlite-inspection/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 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 />
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/CancellationQueryTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/CancellationQueryTest.kt
index 997730a..642fa58 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/CancellationQueryTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/CancellationQueryTest.kt
@@ -22,6 +22,8 @@
import androidx.test.filters.MediumTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
+import java.util.concurrent.Executors.newCachedThreadPool
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.channels.Channel
@@ -32,8 +34,6 @@
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
-import java.util.concurrent.Executor
-import java.util.concurrent.Executors.newCachedThreadPool
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseExtensions.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseExtensions.kt
index d72b712..d8ace8b 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseExtensions.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseExtensions.kt
@@ -20,8 +20,8 @@
import android.database.sqlite.SQLiteOpenHelper
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
-import org.junit.rules.TemporaryFolder
import java.io.File
+import org.junit.rules.TemporaryFolder
fun SQLiteDatabase.addTable(table: Table) = execSQL(table.toCreateString())
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseLockingTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseLockingTest.kt
index 67e4214..492b7b2 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseLockingTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/DatabaseLockingTest.kt
@@ -32,6 +32,13 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Callable
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors.newSingleThreadExecutor
+import java.util.concurrent.TimeUnit.SECONDS
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicInteger
+import java.util.regex.Pattern.CASE_INSENSITIVE
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.launch
@@ -40,13 +47,6 @@
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
-import java.util.concurrent.Callable
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executors.newSingleThreadExecutor
-import java.util.concurrent.TimeUnit.SECONDS
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.concurrent.atomic.AtomicInteger
-import java.util.regex.Pattern.CASE_INSENSITIVE
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/SqliteInspectorTestEnvironment.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/SqliteInspectorTestEnvironment.kt
index 706dced..92a93bf 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/SqliteInspectorTestEnvironment.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/SqliteInspectorTestEnvironment.kt
@@ -28,12 +28,12 @@
import androidx.sqlite.inspection.SqliteInspectorProtocol.Event
import androidx.sqlite.inspection.SqliteInspectorProtocol.Response
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.runBlocking
import org.junit.rules.ExternalResource
-import java.util.concurrent.Executor
private const val SQLITE_INSPECTOR_ID = "androidx.sqlite.inspection"
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
index 4efe8d8..cf8da8b 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
@@ -31,12 +31,12 @@
import androidx.test.filters.LargeTest
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.google.common.truth.Truth.assertThat
+import java.io.File
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
-import java.io.File
private const val OPEN_DATABASE_COMMAND_SIGNATURE_API11: String = "openDatabase" +
"(" +
diff --git a/sqlite/sqlite-inspection/src/main/AndroidManifest.xml b/sqlite/sqlite-inspection/src/main/AndroidManifest.xml
deleted file mode 100644
index e95a361..0000000
--- a/sqlite/sqlite-inspection/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2019 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 />
diff --git a/sqlite/sqlite-ktx/build.gradle b/sqlite/sqlite-ktx/build.gradle
index a793599..5698d49 100644
--- a/sqlite/sqlite-ktx/build.gradle
+++ b/sqlite/sqlite-ktx/build.gradle
@@ -31,7 +31,7 @@
}
androidx {
- name = "Android DB KTX"
+ name = "SQLite Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Kotlin extensions for DB"
diff --git a/sqlite/sqlite-ktx/src/main/AndroidManifest.xml b/sqlite/sqlite-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 29b496b..0000000
--- a/sqlite/sqlite-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- ~ Copyright (C) 2018 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 />
diff --git a/sqlite/sqlite/build.gradle b/sqlite/sqlite/build.gradle
index 580912e..5d64abf 100644
--- a/sqlite/sqlite/build.gradle
+++ b/sqlite/sqlite/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Android DB"
+ name = "SQLite"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android DB"
diff --git a/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/tasks/UpdateStableAidlApiTask.kt b/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/tasks/UpdateStableAidlApiTask.kt
index c12b84b..8a1bf84 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/tasks/UpdateStableAidlApiTask.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/main/java/androidx/stableaidl/tasks/UpdateStableAidlApiTask.kt
@@ -16,22 +16,22 @@
package androidx.stableaidl.tasks
+import java.io.File
+import java.security.MessageDigest
+import org.apache.commons.io.FileUtils
import org.gradle.api.DefaultTask
+import org.gradle.api.GradleException
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.logging.Logger
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.OutputDirectories
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
-import java.io.File
-import java.security.MessageDigest
-import org.gradle.api.GradleException
-import org.gradle.api.logging.Logger
-import org.gradle.api.tasks.InputDirectory
-import org.gradle.api.tasks.OutputDirectories
-import org.apache.commons.io.FileUtils
-import org.gradle.api.file.DirectoryProperty
/**
* Task for updating the public Android resource surface, e.g. `public.xml`.
diff --git a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleExecOperations.kt b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleExecOperations.kt
index a65ad83..80859ab 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleExecOperations.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleExecOperations.kt
@@ -16,6 +16,9 @@
package com.android.build.gradle.internal.fixtures
+import java.io.File
+import java.io.InputStream
+import java.io.OutputStream
import org.gradle.api.Action
import org.gradle.process.BaseExecSpec
import org.gradle.process.CommandLineArgumentProvider
@@ -24,9 +27,6 @@
import org.gradle.process.ExecSpec
import org.gradle.process.JavaExecSpec
import org.gradle.process.ProcessForkOptions
-import java.io.File
-import java.io.InputStream
-import java.io.OutputStream
/** This implementation only captures arguments used to launch process, it does not run it. */
class FakeGradleExecOperations : ExecOperations {
diff --git a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
index f64e355..bd198da 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleProperty.kt
@@ -16,10 +16,10 @@
package com.android.build.gradle.internal.fixtures
+import java.util.function.BiFunction
import org.gradle.api.Transformer
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
-import java.util.function.BiFunction
class FakeGradleProperty<T>(private var value: T? = null) : Property<T> {
diff --git a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleWorkExecutor.kt b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleWorkExecutor.kt
index 678696b..7a17b63 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleWorkExecutor.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeGradleWorkExecutor.kt
@@ -16,6 +16,10 @@
package com.android.build.gradle.internal.fixtures
+import java.io.File
+import java.lang.reflect.Method
+import java.lang.reflect.ParameterizedType
+import java.net.URLClassLoader
import org.gradle.api.Action
import org.gradle.api.model.ObjectFactory
import org.gradle.workers.ClassLoaderWorkerSpec
@@ -32,10 +36,6 @@
import org.objectweb.asm.FieldVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
-import java.io.File
-import java.lang.reflect.Method
-import java.lang.reflect.ParameterizedType
-import java.net.URLClassLoader
/**
* Fake implementation of [WorkerExecutor]. [ObjectFactory] is used to instantiate parameters,
diff --git a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeNoOpAnalyticsService.kt b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeNoOpAnalyticsService.kt
index 9de1d23..4bd73b8 100644
--- a/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeNoOpAnalyticsService.kt
+++ b/stableaidl/stableaidl-gradle-plugin/src/test/java/com/android/build/gradle/internal/fixtures/FakeNoOpAnalyticsService.kt
@@ -29,13 +29,13 @@
import com.google.wireless.android.sdk.stats.GradleBuildProject
import com.google.wireless.android.sdk.stats.GradleBuildVariant
import com.google.wireless.android.sdk.stats.GradleTransformExecution
+import java.io.File
+import java.util.Base64
+import java.util.concurrent.ConcurrentLinkedQueue
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.SetProperty
import org.gradle.tooling.events.FinishEvent
-import java.io.File
-import java.util.Base64
-import java.util.concurrent.ConcurrentLinkedQueue
/**
* A no-operation implementation of [AnalyticsService] for unit tests.
diff --git a/startup/startup-runtime-lint/build.gradle b/startup/startup-runtime-lint/build.gradle
index 0a10bc6..2ca037c 100644
--- a/startup/startup-runtime-lint/build.gradle
+++ b/startup/startup-runtime-lint/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android App Startup Runtime Lint Checks"
+ name = "Startup Runtime Lint Checks"
type = LibraryType.LINT
inceptionYear = "2020"
description = "Android App Startup Runtime"
diff --git a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/EnsureInitializerMetadataDetector.kt b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/EnsureInitializerMetadataDetector.kt
index 4da10fc..824b5fe 100644
--- a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/EnsureInitializerMetadataDetector.kt
+++ b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/EnsureInitializerMetadataDetector.kt
@@ -34,11 +34,11 @@
import com.android.tools.lint.detector.api.XmlContext
import com.android.tools.lint.detector.api.XmlScanner
import com.intellij.psi.impl.source.PsiClassReferenceType
+import java.util.EnumSet
import org.jetbrains.uast.UClass
import org.jetbrains.uast.UClassLiteralExpression
import org.jetbrains.uast.visitor.AbstractUastVisitor
import org.w3c.dom.Element
-import java.util.EnumSet
/**
* A [Detector] which ensures that every `ComponentInitializer` is accompanied by a corresponding
diff --git a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/InitializerConstructorDetector.kt b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/InitializerConstructorDetector.kt
index c99826d..87b8615 100644
--- a/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/InitializerConstructorDetector.kt
+++ b/startup/startup-runtime-lint/src/main/java/androidx/startup/lint/InitializerConstructorDetector.kt
@@ -27,8 +27,8 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.lang.java.JavaLanguage
-import org.jetbrains.uast.UClass
import java.util.EnumSet
+import org.jetbrains.uast.UClass
/**
* A [Detector] which ensures that every `ComponentInitializer` has a no argument constructor.
diff --git a/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/EnsureInitializerMetadataTest.kt b/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/EnsureInitializerMetadataTest.kt
index 23b8e36..8e5f981 100644
--- a/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/EnsureInitializerMetadataTest.kt
+++ b/startup/startup-runtime-lint/src/test/java/androidx/startup/lint/EnsureInitializerMetadataTest.kt
@@ -18,8 +18,8 @@
package androidx.startup.lint
-import androidx.startup.lint.Stubs.TEST_INITIALIZER
import androidx.startup.lint.Stubs.INITIALIZER
+import androidx.startup.lint.Stubs.TEST_INITIALIZER
import androidx.startup.lint.Stubs.TEST_INITIALIZER_2
import androidx.startup.lint.Stubs.TEST_INITIALIZER_WITH_DEPENDENCIES
import com.android.tools.lint.checks.infrastructure.TestFiles.manifest
diff --git a/startup/startup-runtime/build.gradle b/startup/startup-runtime/build.gradle
index 9cfaac9..d4f9766 100644
--- a/startup/startup-runtime/build.gradle
+++ b/startup/startup-runtime/build.gradle
@@ -49,7 +49,7 @@
}
androidx {
- name = "Android App Startup Runtime"
+ name = "Startup Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android App Startup Runtime"
diff --git a/startup/startup-runtime/src/androidTest/java/androidx/startup/AppInitializerTest.kt b/startup/startup-runtime/src/androidTest/java/androidx/startup/AppInitializerTest.kt
index 7b54f14f..d9501e8 100644
--- a/startup/startup-runtime/src/androidTest/java/androidx/startup/AppInitializerTest.kt
+++ b/startup/startup-runtime/src/androidTest/java/androidx/startup/AppInitializerTest.kt
@@ -20,8 +20,8 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.containsString
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Assert.fail
diff --git a/swiperefreshlayout/swiperefreshlayout/build.gradle b/swiperefreshlayout/swiperefreshlayout/build.gradle
index 8450677..a80a5e5 100644
--- a/swiperefreshlayout/swiperefreshlayout/build.gradle
+++ b/swiperefreshlayout/swiperefreshlayout/build.gradle
@@ -30,7 +30,7 @@
}
androidx {
- name = "Android Support Library Custom View"
+ name = "Swipe Refresh Layout"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/swiperefreshlayout/swiperefreshlayout/src/main/AndroidManifest.xml b/swiperefreshlayout/swiperefreshlayout/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/swiperefreshlayout/swiperefreshlayout/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/test/ext/junit-gtest/build.gradle b/test/ext/junit-gtest/build.gradle
index be6c1fd..868ab98 100644
--- a/test/ext/junit-gtest/build.gradle
+++ b/test/ext/junit-gtest/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX JUnit GTest"
+ name = "JUnit GTest"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Run GTest tests on Android devices"
diff --git a/test/screenshot/screenshot/build.gradle b/test/screenshot/screenshot/build.gradle
index 7147d25..69303c3 100644
--- a/test/screenshot/screenshot/build.gradle
+++ b/test/screenshot/screenshot/build.gradle
@@ -46,7 +46,7 @@
}
androidx {
- name = "AndroidX Library Screenshot Test"
+ name = "Screenshot Test"
type = LibraryType.INTERNAL_TEST_LIBRARY
}
diff --git a/test/screenshot/screenshot/src/androidTest/java/androidx/test/screenshot/ScreenshotTestRuleTest.kt b/test/screenshot/screenshot/src/androidTest/java/androidx/test/screenshot/ScreenshotTestRuleTest.kt
index 0275075..3dc6acb 100644
--- a/test/screenshot/screenshot/src/androidTest/java/androidx/test/screenshot/ScreenshotTestRuleTest.kt
+++ b/test/screenshot/screenshot/src/androidTest/java/androidx/test/screenshot/ScreenshotTestRuleTest.kt
@@ -25,12 +25,12 @@
import androidx.test.screenshot.matchers.PixelPerfectMatcher
import androidx.test.screenshot.utils.loadBitmap
import com.google.common.truth.Truth.assertThat
+import java.lang.AssertionError
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.AssertionError
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/test/screenshot/screenshot/src/main/AndroidManifest.xml b/test/screenshot/screenshot/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/test/screenshot/screenshot/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/test/screenshot/screenshot/src/main/java/androidx/test/screenshot/ScreenshotTestRule.kt b/test/screenshot/screenshot/src/main/java/androidx/test/screenshot/ScreenshotTestRule.kt
index 132b215..7cbd8db 100644
--- a/test/screenshot/screenshot/src/main/java/androidx/test/screenshot/ScreenshotTestRule.kt
+++ b/test/screenshot/screenshot/src/main/java/androidx/test/screenshot/ScreenshotTestRule.kt
@@ -28,15 +28,15 @@
import androidx.test.screenshot.matchers.PixelPerfectMatcher
import androidx.test.screenshot.proto.ScreenshotResultProto
import androidx.test.screenshot.proto.ScreenshotResultProto.ScreenshotResult.Status
+import java.io.File
+import java.io.FileNotFoundException
+import java.io.FileOutputStream
+import java.io.IOException
import org.junit.Assume
import org.junit.rules.TestRule
import org.junit.rules.TestWatcher
import org.junit.runner.Description
import org.junit.runners.model.Statement
-import java.io.File
-import java.io.FileNotFoundException
-import java.io.FileOutputStream
-import java.io.IOException
/**
* Config for [ScreenshotTestRule].
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/BaseTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/BaseTest.java
index 67decb1..da92d0f 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/BaseTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/BaseTest.java
@@ -22,6 +22,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.util.Log;
import androidx.annotation.NonNull;
import androidx.test.core.app.ApplicationProvider;
@@ -34,9 +35,14 @@
import androidx.test.uiautomator.Until;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.function.ThrowingRunnable;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
import org.junit.runner.RunWith;
+import java.io.ByteArrayOutputStream;
+
@RunWith(AndroidJUnit4.class)
public abstract class BaseTest {
@@ -45,6 +51,20 @@
protected static final int DEFAULT_FLAGS =
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK;
+ // Dumps the UI hierarchy to logcat on failure.
+ @Rule
+ public TestWatcher mDumpHierarchyWatcher = new TestWatcher() {
+ @Override
+ protected void failed(Throwable t, Description description) {
+ try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
+ mDevice.dumpWindowHierarchy(stream);
+ Log.w(description.getTestClass().getSimpleName(), stream.toString());
+ } catch (Exception e) {
+ Log.e(description.getTestClass().getSimpleName(), "Failed to dump hierarchy", e);
+ }
+ }
+ };
+
protected UiDevice mDevice;
@Before
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
index 54717f6..0e7dd93 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiDeviceTest.java
@@ -59,7 +59,6 @@
public class UiDeviceTest extends BaseTest {
private static final long TIMEOUT_MS = 5_000;
- private static final int GESTURE_MARGIN = 50;
private static final String PACKAGE_NAME = "androidx.test.uiautomator.testapp";
// Defined in 'AndroidManifest.xml'.
private static final String APP_NAME = "UiAutomator Test App";
@@ -300,7 +299,6 @@
assertEquals("I've been clicked!", button.getText());
}
- @Ignore // b/266617096
@Test
public void testSwipe() {
launchTestActivity(SwipeTestActivity.class);
@@ -309,7 +307,7 @@
int width = mDevice.getDisplayWidth();
int height = mDevice.getDisplayHeight();
- mDevice.swipe(GESTURE_MARGIN, height / 2, width - GESTURE_MARGIN, height / 2, 10);
+ mDevice.swipe(width / 10, height / 2, 9 * width / 10, height / 2, 10);
assertTrue(swipeRegion.wait(Until.textEquals("swipe_right"), TIMEOUT_MS));
}
@@ -330,7 +328,6 @@
assertTrue(dragDestination.wait(Until.textEquals("drag_received"), TIMEOUT_MS));
}
- @Ignore // b/266617096
@Test
public void testSwipe_withPointArray() {
launchTestActivity(SwipeTestActivity.class);
@@ -340,9 +337,9 @@
int width = mDevice.getDisplayWidth();
int height = mDevice.getDisplayHeight();
- Point point1 = new Point(GESTURE_MARGIN, height / 2);
+ Point point1 = new Point(width / 10, height / 2);
Point point2 = new Point(width / 2, height / 2);
- Point point3 = new Point(width - GESTURE_MARGIN, height / 2);
+ Point point3 = new Point(9 * width / 10, height / 2);
mDevice.swipe(new Point[]{point1, point2, point3}, 10);
@@ -357,6 +354,7 @@
}
@Test
+ @Ignore("b/280669851")
public void testSetOrientationLeft() throws Exception {
launchTestActivity(KeycodeTestActivity.class);
try {
@@ -375,6 +373,7 @@
}
@Test
+ @Ignore("b/280669851")
public void testSetOrientationRight() throws Exception {
launchTestActivity(KeycodeTestActivity.class);
try {
@@ -404,6 +403,7 @@
}
@Test
+ @Ignore("b/280669851")
public void testSetOrientationLandscape() throws Exception {
launchTestActivity(KeycodeTestActivity.class);
try {
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
index c91c791..bb9f70b 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObject2Test.java
@@ -551,7 +551,6 @@
+ "but got [%f]", scaleValueAfterPinch), scaleValueAfterPinch > 1f);
}
- @Ignore // b/266617335
@Test
public void testSwipe() {
launchTestActivity(SwipeTestActivity.class);
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
index 36aaeb6..f74a13b 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiObjectTest.java
@@ -24,12 +24,10 @@
import android.graphics.Point;
import android.graphics.Rect;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SdkSuppress;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiSelector;
-import org.junit.Ignore;
import org.junit.Test;
public class UiObjectTest extends BaseTest {
@@ -119,7 +117,6 @@
assertTrue(expectedDragDest.waitForExists(TIMEOUT_MS));
}
- @Ignore // b/266617747
@Test
public void testSwipeUp() throws Exception {
launchTestActivity(SwipeTestActivity.class);
@@ -141,7 +138,6 @@
assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
- @Ignore // b/266617747
@Test
public void testSwipeDown() throws Exception {
launchTestActivity(SwipeTestActivity.class);
@@ -161,7 +157,6 @@
assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
- @FlakyTest(bugId = 242761733)
@Test
public void testSwipeLeft() throws Exception {
launchTestActivity(SwipeTestActivity.class);
@@ -181,7 +176,6 @@
assertTrue(expectedSwipeRegion.waitForExists(TIMEOUT_MS));
}
- @Ignore // b/266617747
@Test
public void testSwipeRight() throws Exception {
launchTestActivity(SwipeTestActivity.class);
diff --git a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiScrollableTest.java b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiScrollableTest.java
index 765aab1..3384042 100644
--- a/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiScrollableTest.java
+++ b/test/uiautomator/integration-tests/testapp/src/androidTest/java/androidx/test/uiautomator/testapp/UiScrollableTest.java
@@ -273,7 +273,6 @@
assertUiObjectNotFound(noNode::flingBackward);
}
- @Ignore // b/266965027
@Test
public void testScrollBackward_vertical() throws Exception {
launchTestActivity(SwipeTestActivity.class);
@@ -285,7 +284,6 @@
assertEquals("swipe_down", scrollRegion.getText());
}
- @Ignore // b/266965027
@Test
public void testScrollBackward_horizontal() throws Exception {
launchTestActivity(SwipeTestActivity.class);
diff --git a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/SwipeTestActivity.java b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/SwipeTestActivity.java
index fda840d..9a1fe18 100644
--- a/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/SwipeTestActivity.java
+++ b/test/uiautomator/integration-tests/testapp/src/main/java/androidx/test/uiautomator/testapp/SwipeTestActivity.java
@@ -22,6 +22,7 @@
import android.view.MotionEvent;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class SwipeTestActivity extends Activity {
@@ -31,23 +32,20 @@
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
setContentView(R.layout.swipe_test_activity);
TextView swipeRegion = findViewById(R.id.swipe_region);
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float vX, float vY) {
- // Swipe is using the same logic as fling, except that their directions are
- // opposite under the same finger movement.
- boolean horizontal = Math.abs(vX) > Math.abs(vY);
+ public boolean onScroll(@Nullable MotionEvent e1, @NonNull MotionEvent e2,
+ float distanceX, float distanceY) {
+ boolean horizontal = Math.abs(distanceX) > Math.abs(distanceY);
if (horizontal) {
- swipeRegion.setText(vX < 0 ? "swipe_left" : "swipe_right");
+ swipeRegion.setText(distanceX > 0 ? "swipe_left" : "swipe_right");
} else {
- swipeRegion.setText(vY < 0 ? "swipe_up" : "swipe_down");
+ swipeRegion.setText(distanceY > 0 ? "swipe_up" : "swipe_down");
}
-
return true;
}
});
diff --git a/test/uiautomator/uiautomator/build.gradle b/test/uiautomator/uiautomator/build.gradle
index ef6ca7c..b1dd210 100644
--- a/test/uiautomator/uiautomator/build.gradle
+++ b/test/uiautomator/uiautomator/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "Android UIAutomator"
+ name = "UIAutomator"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2012"
description = "UI testing framework suitable for cross-app functional UI testing"
diff --git a/test/uiautomator/uiautomator/src/main/AndroidManifest.xml b/test/uiautomator/uiautomator/src/main/AndroidManifest.xml
deleted file mode 100644
index 6f49e23..0000000
--- a/test/uiautomator/uiautomator/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 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 />
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/BySelector.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/BySelector.java
index 63a0a49..b818481 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/BySelector.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/BySelector.java
@@ -16,6 +16,8 @@
package androidx.test.uiautomator;
+import static java.util.Objects.requireNonNull;
+
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
@@ -106,8 +108,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector clazz(@NonNull String className) {
- checkNotNull(className, "className cannot be null");
-
+ requireNonNull(className, "className cannot be null");
// If className starts with a period, assume the package is 'android.widget'
if (className.charAt(0) == '.') {
return clazz("android.widget", className.substring(1));
@@ -126,9 +127,8 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector clazz(@NonNull String packageName, @NonNull String className) {
- checkNotNull(packageName, "packageName cannot be null");
- checkNotNull(className, "className cannot be null");
-
+ requireNonNull(packageName, "packageName cannot be null");
+ requireNonNull(className, "className cannot be null");
return clazz(Pattern.compile(Pattern.quote(
String.format("%s.%s", packageName, className))));
}
@@ -141,8 +141,7 @@
* @return A reference to this {@link BySelector}
*/
public @NonNull BySelector clazz(@NonNull Class clazz) {
- checkNotNull(clazz, "clazz cannot be null");
-
+ requireNonNull(clazz, "clazz cannot be null");
return clazz(Pattern.compile(Pattern.quote(clazz.getName())));
}
@@ -155,8 +154,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector clazz(@NonNull Pattern className) {
- checkNotNull(className, "className cannot be null");
-
+ requireNonNull(className, "className cannot be null");
if (mClazz != null) {
throw new IllegalStateException("Class selector is already defined");
}
@@ -173,8 +171,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector desc(@NonNull String contentDescription) {
- checkNotNull(contentDescription, "contentDescription cannot be null");
-
+ requireNonNull(contentDescription, "contentDescription cannot be null");
return desc(Pattern.compile(Pattern.quote(contentDescription)));
}
@@ -187,8 +184,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector descContains(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return desc(RegexHelper.getPatternContains(substring));
}
@@ -201,8 +197,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector descStartsWith(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return desc(RegexHelper.getPatternStartsWith(substring));
}
@@ -215,8 +210,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector descEndsWith(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return desc(RegexHelper.getPatternEndsWith(substring));
}
@@ -229,8 +223,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector desc(@NonNull Pattern contentDescription) {
- checkNotNull(contentDescription, "contentDescription cannot be null");
-
+ requireNonNull(contentDescription, "contentDescription cannot be null");
if (mDesc != null) {
throw new IllegalStateException("Description selector is already defined");
}
@@ -247,8 +240,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector pkg(@NonNull String applicationPackage) {
- checkNotNull(applicationPackage, "applicationPackage cannot be null");
-
+ requireNonNull(applicationPackage, "applicationPackage cannot be null");
return pkg(Pattern.compile(Pattern.quote(applicationPackage)));
}
@@ -261,8 +253,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector pkg(@NonNull Pattern applicationPackage) {
- checkNotNull(applicationPackage, "applicationPackage cannot be null");
-
+ requireNonNull(applicationPackage, "applicationPackage cannot be null");
if (mPkg != null) {
throw new IllegalStateException("Package selector is already defined");
}
@@ -279,8 +270,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector res(@NonNull String resourceName) {
- checkNotNull(resourceName, "resourceName cannot be null");
-
+ requireNonNull(resourceName, "resourceName cannot be null");
return res(Pattern.compile(Pattern.quote(resourceName)));
}
@@ -294,9 +284,8 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector res(@NonNull String resourcePackage, @NonNull String resourceId) {
- checkNotNull(resourcePackage, "resourcePackage cannot be null");
- checkNotNull(resourceId, "resourceId cannot be null");
-
+ requireNonNull(resourcePackage, "resourcePackage cannot be null");
+ requireNonNull(resourceId, "resourceId cannot be null");
return res(Pattern.compile(Pattern.quote(
String.format("%s:id/%s", resourcePackage, resourceId))));
}
@@ -310,8 +299,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector res(@NonNull Pattern resourceName) {
- checkNotNull(resourceName, "resourceName cannot be null");
-
+ requireNonNull(resourceName, "resourceName cannot be null");
if (mRes != null) {
throw new IllegalStateException("Resource name selector is already defined");
}
@@ -328,8 +316,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector text(@NonNull String textValue) {
- checkNotNull(textValue, "textValue cannot be null");
-
+ requireNonNull(textValue, "textValue cannot be null");
return text(Pattern.compile(Pattern.quote(textValue)));
}
@@ -342,8 +329,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector textContains(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return text(RegexHelper.getPatternContains(substring));
}
@@ -356,8 +342,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector textStartsWith(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return text(RegexHelper.getPatternStartsWith(substring));
}
@@ -370,8 +355,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector textEndsWith(@NonNull String substring) {
- checkNotNull(substring, "substring cannot be null");
-
+ requireNonNull(substring, "substring cannot be null");
return text(RegexHelper.getPatternEndsWith(substring));
}
@@ -383,8 +367,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector text(@NonNull Pattern textValue) {
- checkNotNull(textValue, "textValue cannot be null");
-
+ requireNonNull(textValue, "textValue cannot be null");
if (mText != null) {
throw new IllegalStateException("Text selector is already defined");
}
@@ -581,7 +564,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector hasParent(@NonNull BySelector parentSelector) {
- checkNotNull(parentSelector, "parentSelector cannot be null");
+ requireNonNull(parentSelector, "parentSelector cannot be null");
return hasAncestor(parentSelector, 1);
}
@@ -594,7 +577,7 @@
* @return A reference to this {@link BySelector}.
*/
public @NonNull BySelector hasAncestor(@NonNull BySelector ancestorSelector) {
- checkNotNull(ancestorSelector, "ancestorSelector cannot be null");
+ requireNonNull(ancestorSelector, "ancestorSelector cannot be null");
if (mAncestorSelector != null) {
throw new IllegalStateException("Parent/ancestor selector is already defined");
}
@@ -631,7 +614,7 @@
* @throws IllegalArgumentException if the selector has a parent/ancestor selector
*/
public @NonNull BySelector hasChild(@NonNull BySelector childSelector) {
- checkNotNull(childSelector, "childSelector cannot be null");
+ requireNonNull(childSelector, "childSelector cannot be null");
return hasDescendant(childSelector, 1);
}
@@ -646,7 +629,7 @@
* @throws IllegalArgumentException if the selector has a parent/ancestor selector
*/
public @NonNull BySelector hasDescendant(@NonNull BySelector descendantSelector) {
- checkNotNull(descendantSelector, "descendantSelector cannot be null");
+ requireNonNull(descendantSelector, "descendantSelector cannot be null");
if (descendantSelector.mAncestorSelector != null) {
// Search root is ambiguous with nested parent selectors.
throw new IllegalArgumentException(
@@ -735,11 +718,4 @@
builder.append("]");
return builder.toString();
}
-
- private static <T> T checkNotNull(T value, @NonNull String message) {
- if (value == null) {
- throw new NullPointerException(message);
- }
- return value;
- }
}
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiSelector.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiSelector.java
index 5cb978a..0eda6d6 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiSelector.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiSelector.java
@@ -16,6 +16,8 @@
package androidx.test.uiautomator;
+import static java.util.Objects.requireNonNull;
+
import android.util.SparseArray;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -109,7 +111,7 @@
*/
@NonNull
public UiSelector text(@NonNull String text) {
- checkNotNull(text, "text cannot be null");
+ requireNonNull(text, "text cannot be null");
return buildSelector(SELECTOR_TEXT, text);
}
@@ -125,7 +127,7 @@
*/
@NonNull
public UiSelector textMatches(@NonNull String regex) {
- checkNotNull(regex, "regex cannot be null");
+ requireNonNull(regex, "regex cannot be null");
return buildSelector(SELECTOR_TEXT_REGEX, Pattern.compile(regex, Pattern.DOTALL));
}
@@ -140,7 +142,7 @@
*/
@NonNull
public UiSelector textStartsWith(@NonNull String text) {
- checkNotNull(text, "text cannot be null");
+ requireNonNull(text, "text cannot be null");
return buildSelector(SELECTOR_START_TEXT, text);
}
@@ -155,7 +157,7 @@
*/
@NonNull
public UiSelector textContains(@NonNull String text) {
- checkNotNull(text, "text cannot be null");
+ requireNonNull(text, "text cannot be null");
return buildSelector(SELECTOR_CONTAINS_TEXT, text);
}
@@ -168,7 +170,7 @@
*/
@NonNull
public UiSelector className(@NonNull String className) {
- checkNotNull(className, "className cannot be null");
+ requireNonNull(className, "className cannot be null");
return buildSelector(SELECTOR_CLASS, className);
}
@@ -181,7 +183,7 @@
*/
@NonNull
public UiSelector classNameMatches(@NonNull String regex) {
- checkNotNull(regex, "regex cannot be null");
+ requireNonNull(regex, "regex cannot be null");
return buildSelector(SELECTOR_CLASS_REGEX, Pattern.compile(regex));
}
@@ -194,7 +196,7 @@
*/
@NonNull
public <T> UiSelector className(@NonNull Class<T> type) {
- checkNotNull(type, "type cannot be null");
+ requireNonNull(type, "type cannot be null");
return buildSelector(SELECTOR_CLASS, type.getName());
}
@@ -216,7 +218,7 @@
*/
@NonNull
public UiSelector description(@NonNull String desc) {
- checkNotNull(desc, "desc cannot be null");
+ requireNonNull(desc, "desc cannot be null");
return buildSelector(SELECTOR_DESCRIPTION, desc);
}
@@ -236,7 +238,7 @@
*/
@NonNull
public UiSelector descriptionMatches(@NonNull String regex) {
- checkNotNull(regex, "regex cannot be null");
+ requireNonNull(regex, "regex cannot be null");
return buildSelector(SELECTOR_DESCRIPTION_REGEX, Pattern.compile(regex, Pattern.DOTALL));
}
@@ -258,7 +260,7 @@
*/
@NonNull
public UiSelector descriptionStartsWith(@NonNull String desc) {
- checkNotNull(desc, "desc cannot be null");
+ requireNonNull(desc, "desc cannot be null");
return buildSelector(SELECTOR_START_DESCRIPTION, desc);
}
@@ -280,7 +282,7 @@
*/
@NonNull
public UiSelector descriptionContains(@NonNull String desc) {
- checkNotNull(desc, "desc cannot be null");
+ requireNonNull(desc, "desc cannot be null");
return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc);
}
@@ -292,7 +294,7 @@
*/
@NonNull
public UiSelector resourceId(@NonNull String id) {
- checkNotNull(id, "id cannot be null");
+ requireNonNull(id, "id cannot be null");
return buildSelector(SELECTOR_RESOURCE_ID, id);
}
@@ -305,7 +307,7 @@
*/
@NonNull
public UiSelector resourceIdMatches(@NonNull String regex) {
- checkNotNull(regex, "regex cannot be null");
+ requireNonNull(regex, "regex cannot be null");
return buildSelector(SELECTOR_RESOURCE_ID_REGEX, Pattern.compile(regex));
}
@@ -537,7 +539,7 @@
*/
@NonNull
public UiSelector childSelector(@NonNull UiSelector selector) {
- checkNotNull(selector, "selector cannot be null");
+ requireNonNull(selector, "selector cannot be null");
return buildSelector(SELECTOR_CHILD, selector);
}
@@ -561,7 +563,7 @@
*/
@NonNull
public UiSelector fromParent(@NonNull UiSelector selector) {
- checkNotNull(selector, "selector cannot be null");
+ requireNonNull(selector, "selector cannot be null");
return buildSelector(SELECTOR_PARENT, selector);
}
@@ -574,7 +576,7 @@
*/
@NonNull
public UiSelector packageName(@NonNull String name) {
- checkNotNull(name, "name cannot be null");
+ requireNonNull(name, "name cannot be null");
return buildSelector(SELECTOR_PACKAGE_NAME, name);
}
@@ -587,7 +589,7 @@
*/
@NonNull
public UiSelector packageNameMatches(@NonNull String regex) {
- checkNotNull(regex, "regex cannot be null");
+ requireNonNull(regex, "regex cannot be null");
return buildSelector(SELECTOR_PACKAGE_NAME_REGEX, Pattern.compile(regex));
}
@@ -1022,11 +1024,4 @@
builder.append("]");
return builder.toString();
}
-
- private static <T> T checkNotNull(T value, @NonNull String message) {
- if (value == null) {
- throw new NullPointerException(message);
- }
- return value;
- }
}
diff --git a/testutils/testutils-appcompat/src/main/AndroidManifest.xml b/testutils/testutils-appcompat/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/testutils/testutils-appcompat/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/testutils/testutils-appcompat/src/main/java/androidx/testutils/RecreatedAppCompatActivity.kt b/testutils/testutils-appcompat/src/main/java/androidx/testutils/RecreatedAppCompatActivity.kt
index ea23c83..5d5694e 100644
--- a/testutils/testutils-appcompat/src/main/java/androidx/testutils/RecreatedAppCompatActivity.kt
+++ b/testutils/testutils-appcompat/src/main/java/androidx/testutils/RecreatedAppCompatActivity.kt
@@ -19,9 +19,9 @@
import android.os.Bundle
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
-import org.junit.Assert.assertTrue
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Assert.assertTrue
/**
* Extension of [AppCompatActivity] that keeps track of when it is recreated.
diff --git a/testutils/testutils-common/src/main/java/androidx/testutils/FilteringExecutor.kt b/testutils/testutils-common/src/main/java/androidx/testutils/FilteringExecutor.kt
index e981829..3d5618a1 100644
--- a/testutils/testutils-common/src/main/java/androidx/testutils/FilteringExecutor.kt
+++ b/testutils/testutils-common/src/main/java/androidx/testutils/FilteringExecutor.kt
@@ -15,17 +15,17 @@
*/
package androidx.testutils
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.withTimeout
import java.util.concurrent.Executor
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.withTimeout
/**
* An executor that can block some known runnables. We use it to slow down database
diff --git a/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/OkioTestIO.kt b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/OkioTestIO.kt
index 733d614..84705fc 100644
--- a/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/OkioTestIO.kt
+++ b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/OkioTestIO.kt
@@ -22,8 +22,8 @@
import kotlin.random.Random
import kotlin.reflect.KClass
import okio.FileSystem
-import okio.Path
import okio.IOException
+import okio.Path
import okio.Path.Companion.toPath
open class OkioTestIO(dirName: String = "test-dir") : TestIO<OkioPath, IOException>(dirName) {
diff --git a/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/TestIO.kt b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/TestIO.kt
index bddb036..021e629 100644
--- a/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/TestIO.kt
+++ b/testutils/testutils-datastore/src/commonMain/kotlin/androidx/datastore/TestIO.kt
@@ -17,9 +17,9 @@
package androidx.datastore
import androidx.datastore.core.DataStore
-import androidx.datastore.core.Storage
import androidx.datastore.core.DataStoreFactory.create
import androidx.datastore.core.InterProcessCoordinator
+import androidx.datastore.core.Storage
import kotlin.reflect.KClass
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/testutils/testutils-espresso/src/main/AndroidManifest.xml b/testutils/testutils-espresso/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/testutils/testutils-espresso/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/testutils/testutils-fonts/build.gradle b/testutils/testutils-fonts/build.gradle
index dffd039..911cf9b 100644
--- a/testutils/testutils-fonts/build.gradle
+++ b/testutils/testutils-fonts/build.gradle
@@ -14,12 +14,20 @@
* limitations under the License.
*/
+
+import androidx.build.KmpPlatformsKt
import androidx.build.LibraryType
plugins {
id("AndroidXPlugin")
id("com.android.library")
- id("kotlin-android")
+}
+
+def desktopEnabled = KmpPlatformsKt.enableDesktop(project)
+
+androidXMultiplatform {
+ android()
+ if (desktopEnabled) desktop()
}
dependencies {
diff --git a/testutils/testutils-fonts/src/androidMain/AndroidManifest.xml b/testutils/testutils-fonts/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index ee19b21..0000000
--- a/testutils/testutils-fonts/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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 />
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Kruth.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Kruth.kt
index f842714..89114369 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Kruth.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/Kruth.kt
@@ -42,3 +42,6 @@
fun <T> assertThat(actual: Iterable<T>?): IterableSubject<T> =
IterableSubject(actual)
+
+fun <K, V> assertThat(actual: Map<K, V>?): MapSubject<K, V> =
+ MapSubject(actual)
diff --git a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/KruthExt.kt b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/KruthExt.kt
index a55d4e0..e44dc61 100644
--- a/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/KruthExt.kt
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/KruthExt.kt
@@ -16,8 +16,8 @@
package androidx.kruth
-import kotlin.test.assertFailsWith
import kotlin.reflect.KClass
+import kotlin.test.assertFailsWith
// Commonized extensions on top of Truth. These are kept separate for book-keeping in case we end up
// promoting Kruth.
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/MapSubject.kt
similarity index 62%
copy from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
copy to testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/MapSubject.kt
index c325c57..c24141c 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/testutils/testutils-kmp/src/commonMain/kotlin/androidx/kruth/MapSubject.kt
@@ -14,10 +14,18 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+package androidx.kruth
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
+import kotlin.test.fail
+
+class MapSubject<K, V>(actual: Map<K, V>?) : Subject<Map<K, V>>(actual) {
+
+ /** Fails if the map is not empty. */
+ fun isEmpty() {
+ requireNonNull(actual) { "Expected to be empty, but was null" }
+
+ if (actual.isNotEmpty()) {
+ fail("Expected to be empty, but was $actual")
+ }
+ }
}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectTest.kt
similarity index 64%
copy from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
copy to testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectTest.kt
index c325c57..586efc9 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/testutils/testutils-kmp/src/commonTest/kotlin/androidx/kruth/MapSubjectTest.kt
@@ -14,10 +14,22 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+package androidx.kruth
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
+import kotlin.test.Test
+import kotlin.test.assertFailsWith
+
+class MapSubjectTest {
+
+ @Test
+ fun isEmpty() {
+ assertThat(mapOf<Any, Any>()).isEmpty()
+ }
+
+ @Test
+ fun isEmptyWithFailure() {
+ assertFailsWith<AssertionError> {
+ assertThat(mapOf(1 to 5)).isEmpty()
+ }
+ }
}
diff --git a/testutils/testutils-ktx/build.gradle b/testutils/testutils-ktx/build.gradle
index 499d1ed..21ef343d 100644
--- a/testutils/testutils-ktx/build.gradle
+++ b/testutils/testutils-ktx/build.gradle
@@ -15,18 +15,35 @@
*/
import androidx.build.LibraryType
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("AndroidXPlugin")
- id("kotlin")
}
-dependencies {
- api(libs.kotlinStdlib)
- api(libs.kotlinCoroutinesCore)
- api(libs.kotlinCoroutinesTest)
- api(libs.junit)
+androidXMultiplatform {
+ ios()
+ js {
+ nodejs()
+ binaries.executable()
+ }
+ jvm()
+ linux()
+ mac()
+
+ sourceSets {
+ commonMain {
+ dependencies {
+ api(libs.kotlinStdlib)
+ api(libs.kotlinCoroutinesCore)
+ api(libs.kotlinCoroutinesTest)
+ }
+ }
+ jvmMain {
+ dependencies {
+ api(libs.junit)
+ }
+ }
+ }
}
androidx {
diff --git a/testutils/testutils-ktx/src/main/java/androidx/testutils/DirectDispatcher.kt b/testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/DirectDispatcher.kt
similarity index 95%
rename from testutils/testutils-ktx/src/main/java/androidx/testutils/DirectDispatcher.kt
rename to testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/DirectDispatcher.kt
index 6c961b7..150d68a 100644
--- a/testutils/testutils-ktx/src/main/java/androidx/testutils/DirectDispatcher.kt
+++ b/testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/DirectDispatcher.kt
@@ -16,8 +16,9 @@
package androidx.testutils
-import kotlinx.coroutines.CoroutineDispatcher
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Runnable
object DirectDispatcher : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
diff --git a/testutils/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt b/testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/TestDispatcher.kt
similarity index 81%
rename from testutils/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt
rename to testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/TestDispatcher.kt
index be8b54f..5c84e3c 100644
--- a/testutils/testutils-ktx/src/main/java/androidx/testutils/TestDispatcher.kt
+++ b/testutils/testutils-ktx/src/commonMain/kotlin/androidx/testutils/TestDispatcher.kt
@@ -16,24 +16,24 @@
package androidx.testutils
-import kotlinx.coroutines.CoroutineDispatcher
-import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Runnable
/**
* [CoroutineDispatcher] which keeps track of all its queued jobs.
*/
class TestDispatcher : CoroutineDispatcher() {
- val queue = ConcurrentLinkedQueue<Runnable>()
+ val queue = ArrayDeque<Runnable>()
override fun dispatch(context: CoroutineContext, block: Runnable) {
queue.add(block)
}
fun executeAll() {
- do {
- val runnable = queue.poll()
- runnable?.run()
- } while (runnable != null)
+ while (queue.isNotEmpty()) {
+ val runnable = queue.removeFirst()
+ runnable.run()
+ }
}
}
diff --git a/testutils/testutils-ktx/src/main/java/androidx/testutils/MainDispatcherRule.kt b/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/MainDispatcherRule.kt
similarity index 100%
rename from testutils/testutils-ktx/src/main/java/androidx/testutils/MainDispatcherRule.kt
rename to testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/MainDispatcherRule.kt
diff --git a/testutils/testutils-ktx/src/main/java/androidx/testutils/VerifyWithPolling.kt b/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt
similarity index 93%
rename from testutils/testutils-ktx/src/main/java/androidx/testutils/VerifyWithPolling.kt
rename to testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt
index c6155b2..258a218 100644
--- a/testutils/testutils-ktx/src/main/java/androidx/testutils/VerifyWithPolling.kt
+++ b/testutils/testutils-ktx/src/jvmMain/kotlin/androidx/testutils/VerifyWithPolling.kt
@@ -16,8 +16,10 @@
package androidx.testutils
+import java.lang.SuppressWarnings
import org.junit.Assert
+@SuppressWarnings("BanThreadSleep")
fun verifyWithPolling(
message: String,
periodMs: Long,
diff --git a/testutils/testutils-macrobenchmark/src/main/AndroidManifest.xml b/testutils/testutils-macrobenchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/testutils/testutils-macrobenchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/testutils/testutils-mockito/src/main/AndroidManifest.xml b/testutils/testutils-mockito/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/testutils/testutils-mockito/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
index ab49a11..5dbff64 100644
--- a/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
+++ b/testutils/testutils-runtime/src/androidTest/java/androidx/testutils/LocaleTestUtilsTest.kt
@@ -25,13 +25,13 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.Locale
import org.hamcrest.CoreMatchers
import org.hamcrest.MatcherAssert.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.Locale
// Fetch default locale as early as possible (e.g., before initializing LocaleTestUtilsTest class)
private val DEFAULT_LANGUAGE = Locale.getDefault().toString()
diff --git a/testutils/testutils-runtime/src/main/AndroidManifest.xml b/testutils/testutils-runtime/src/main/AndroidManifest.xml
deleted file mode 100644
index c7003d8..0000000
--- a/testutils/testutils-runtime/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2017 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 />
diff --git a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
index ee33b44..02a1cd5 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/testutils/AnimationActivityTestRule.kt
@@ -16,16 +16,15 @@
package androidx.testutils
-import android.app.Activity
import android.animation.ValueAnimator
import android.annotation.SuppressLint
+import android.app.Activity
import android.os.Build
import androidx.test.runner.intercepting.SingleActivityFactory
-
-import org.junit.runner.Description
-import org.junit.runners.model.Statement
import java.lang.RuntimeException
import java.lang.reflect.Method
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
/**
* To solve the issue that androidx changes system settings to make animation duration to 0:
diff --git a/testutils/testutils-runtime/src/main/java/androidx/testutils/RecreatedActivity.kt b/testutils/testutils-runtime/src/main/java/androidx/testutils/RecreatedActivity.kt
index 8ddecfe..2296e75 100644
--- a/testutils/testutils-runtime/src/main/java/androidx/testutils/RecreatedActivity.kt
+++ b/testutils/testutils-runtime/src/main/java/androidx/testutils/RecreatedActivity.kt
@@ -19,9 +19,9 @@
import android.os.Bundle
import androidx.annotation.LayoutRes
import androidx.fragment.app.FragmentActivity
-import org.junit.Assert
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
+import org.junit.Assert
/**
* Extension of [FragmentActivity] that keeps track of when it is recreated.
diff --git a/testutils/testutils-truth/src/test/java/androidx/testutils/AssertionsTest.kt b/testutils/testutils-truth/src/test/java/androidx/testutils/AssertionsTest.kt
index b65e977..f517604 100644
--- a/testutils/testutils-truth/src/test/java/androidx/testutils/AssertionsTest.kt
+++ b/testutils/testutils-truth/src/test/java/androidx/testutils/AssertionsTest.kt
@@ -16,8 +16,8 @@
package androidx.testutils
-import org.junit.Test
import java.io.IOException
+import org.junit.Test
class AssertionsTest {
@Test
diff --git a/text/text/src/androidTest/AndroidManifest.xml b/text/text/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/text/text/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
index fba9e8f..cfae5f2 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/BoringLayoutFactoryTest.kt
@@ -27,11 +27,11 @@
import android.text.style.LeadingMarginSpan
import androidx.compose.ui.text.android.BoringLayoutFactory.create
import androidx.compose.ui.text.android.BoringLayoutFactory.measure
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
index c5c6cee..edef78c 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/FontPaddingWithCustomFallbackTest.kt
@@ -12,12 +12,12 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.spy
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Test
-import org.junit.runner.RunWith
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutCompatTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutCompatTest.kt
index 9355f82..21af3cf 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutCompatTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutCompatTest.kt
@@ -20,11 +20,11 @@
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@OptIn(InternalPlatformTextApi::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalMultiLineTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalMultiLineTest.kt
index 22f1976..212c5e4 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalMultiLineTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalMultiLineTest.kt
@@ -18,13 +18,13 @@
import android.text.TextPaint
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@OptIn(InternalPlatformTextApi::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalTest.kt
index 023c89a..4108cbf 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutGetHorizontalTest.kt
@@ -20,13 +20,13 @@
import android.text.TextDirectionHeuristics
import android.text.TextPaint
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
/**
* In this test cases, use following notations:
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutHelperParagraphTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutHelperParagraphTest.kt
index d8d1305..4c53a41 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutHelperParagraphTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutHelperParagraphTest.kt
@@ -20,11 +20,11 @@
import android.text.Layout
import android.text.StaticLayout
import android.text.TextPaint
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@SmallTest
@OptIn(InternalPlatformTextApi::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutIntrinsicsTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutIntrinsicsTest.kt
index 733de18..3e47f8f 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutIntrinsicsTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/LayoutIntrinsicsTest.kt
@@ -22,13 +22,13 @@
import android.text.TextPaint
import android.text.style.BulletSpan
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/SegmentBreakerTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/SegmentBreakerTest.kt
index e8eb3b8..ae9f92f 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/SegmentBreakerTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/SegmentBreakerTest.kt
@@ -22,13 +22,13 @@
import androidx.compose.ui.text.android.animation.SegmentBreaker
import androidx.compose.ui.text.android.animation.SegmentType
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
/**
* In this test cases, use following notations:
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/StaticLayoutFactoryTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/StaticLayoutFactoryTest.kt
index e67a9d2..6324d42 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/StaticLayoutFactoryTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/StaticLayoutFactoryTest.kt
@@ -22,16 +22,16 @@
import android.text.TextPaint
import android.text.TextUtils
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
+import kotlin.math.floor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import kotlin.math.floor
@RunWith(AndroidJUnit4::class)
@OptIn(InternalPlatformTextApi::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
index c12d1a3..fb80db9 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextAndroidCanvasTest.kt
@@ -19,10 +19,10 @@
import android.graphics.Canvas
import android.graphics.Rect
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
-import org.junit.Test
class TextAndroidCanvasTest {
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutFillBoundingBoxesTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutFillBoundingBoxesTest.kt
index 5bacbb2..0af5ddc 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutFillBoundingBoxesTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutFillBoundingBoxesTest.kt
@@ -22,15 +22,15 @@
import android.text.TextPaint
import android.text.style.AbsoluteSizeSpan
import androidx.core.content.res.ResourcesCompat
-import androidx.test.filters.SmallTest
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
+import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
+import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import com.google.common.truth.Truth.assertThat
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutIsLineEllipsizedTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutIsLineEllipsizedTest.kt
index 42f6f2f..26f1373 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutIsLineEllipsizedTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutIsLineEllipsizedTest.kt
@@ -19,13 +19,13 @@
import android.text.TextPaint
import android.text.TextUtils.TruncateAt
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
index 8a8387f..9945d9a 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutSpanTest.kt
@@ -29,12 +29,12 @@
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
-import org.mockito.kotlin.any
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.spy
+import org.mockito.kotlin.any
import org.mockito.stubbing.Answer
@OptIn(InternalPlatformTextApi::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutTest.kt
index 4de574f..945d772 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/TextLayoutTest.kt
@@ -26,6 +26,7 @@
import androidx.compose.ui.text.android.style.BaselineShiftSpan
import androidx.compose.ui.text.android.style.LineHeightStyleSpan
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
@@ -33,7 +34,6 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/animation/SegmentBreakerBreakSegmentTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/animation/SegmentBreakerBreakSegmentTest.kt
index 424b8d0..9c9b2ad 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/animation/SegmentBreakerBreakSegmentTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/animation/SegmentBreakerBreakSegmentTest.kt
@@ -23,13 +23,13 @@
import androidx.compose.ui.text.android.LayoutHelper
import androidx.compose.ui.text.android.StaticLayoutFactory
import androidx.core.content.res.ResourcesCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.testutils.fonts.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
/**
* In this test cases, use following notations:
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordBoundaryTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordBoundaryTest.kt
index 21dac62..a7794c2 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordBoundaryTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordBoundaryTest.kt
@@ -16,13 +16,13 @@
package androidx.compose.ui.text.android.selection
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
import java.text.BreakIterator
import java.util.Locale
+import org.junit.Test
+import org.junit.runner.RunWith
@OptIn(InternalPlatformTextApi::class)
@SmallTest
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordIteratorTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordIteratorTest.kt
index d75f35e..c18022b 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordIteratorTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/selection/WordIteratorTest.kt
@@ -16,13 +16,13 @@
package androidx.compose.ui.text.android.selection
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
import java.text.BreakIterator
import java.util.Locale
+import org.junit.Test
+import org.junit.runner.RunWith
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/BaselineShiftSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/BaselineShiftSpanTest.kt
index 0affcc1..87e6cbc 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/BaselineShiftSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/BaselineShiftSpanTest.kt
@@ -18,11 +18,11 @@
import android.text.TextPaint
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/FontFeatureSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/FontFeatureSpanTest.kt
index c32713b..03d1202 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/FontFeatureSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/FontFeatureSpanTest.kt
@@ -17,11 +17,11 @@
import android.text.TextPaint
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEmTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEmTest.kt
index 4791812..5cfe34d 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEmTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanEmTest.kt
@@ -17,11 +17,11 @@
import android.text.TextPaint
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
index e40871d..bd98830 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/LetterSpacingSpanPxTest.kt
@@ -20,13 +20,13 @@
import androidx.compose.ui.text.android.InternalPlatformTextApi
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
-import org.junit.Test
-import org.junit.runner.RunWith
@OptIn(InternalPlatformTextApi::class)
@MediumTest
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/PlaceholderSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/PlaceholderSpanTest.kt
index 944a467..9069271 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/PlaceholderSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/PlaceholderSpanTest.kt
@@ -19,12 +19,12 @@
import android.graphics.Paint
import android.text.TextPaint
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.abs
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import kotlin.math.abs
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/SkewXSpanTest.kt b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/SkewXSpanTest.kt
index dedb532..3d8eb63 100644
--- a/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/SkewXSpanTest.kt
+++ b/text/text/src/androidTest/java/androidx/compose/ui/text/android/style/SkewXSpanTest.kt
@@ -17,11 +17,11 @@
import android.text.TextPaint
import androidx.compose.ui.text.android.InternalPlatformTextApi
+import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
import org.junit.Test
import org.junit.runner.RunWith
-import androidx.test.ext.junit.runners.AndroidJUnit4
@OptIn(InternalPlatformTextApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/text/text/src/main/AndroidManifest.xml b/text/text/src/main/AndroidManifest.xml
deleted file mode 100644
index 7535bfb..0000000
--- a/text/text/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 2018 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 />
diff --git a/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt b/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
index 20c751f..35a275e 100644
--- a/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
+++ b/text/text/src/main/java/androidx/compose/ui/text/android/TextLayout.kt
@@ -38,8 +38,6 @@
import androidx.compose.ui.text.android.LayoutCompat.ALIGN_OPPOSITE
import androidx.compose.ui.text.android.LayoutCompat.ALIGN_RIGHT
import androidx.compose.ui.text.android.LayoutCompat.BreakStrategy
-import androidx.compose.ui.text.android.LayoutCompat.LineBreakStyle
-import androidx.compose.ui.text.android.LayoutCompat.LineBreakWordStyle
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_ALIGNMENT
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_BREAK_STRATEGY
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_HYPHENATION_FREQUENCY
@@ -52,6 +50,8 @@
import androidx.compose.ui.text.android.LayoutCompat.DEFAULT_TEXT_DIRECTION
import androidx.compose.ui.text.android.LayoutCompat.HyphenationFrequency
import androidx.compose.ui.text.android.LayoutCompat.JustificationMode
+import androidx.compose.ui.text.android.LayoutCompat.LineBreakStyle
+import androidx.compose.ui.text.android.LayoutCompat.LineBreakWordStyle
import androidx.compose.ui.text.android.LayoutCompat.TEXT_DIRECTION_ANY_RTL_LTR
import androidx.compose.ui.text.android.LayoutCompat.TEXT_DIRECTION_FIRST_STRONG_LTR
import androidx.compose.ui.text.android.LayoutCompat.TEXT_DIRECTION_FIRST_STRONG_RTL
diff --git a/tracing/tracing-ktx/build.gradle b/tracing/tracing-ktx/build.gradle
index 9cfe63d..a40116c 100644
--- a/tracing/tracing-ktx/build.gradle
+++ b/tracing/tracing-ktx/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "Android Tracing Runtime Kotlin Extensions"
+ name = "Tracing Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Tracing"
diff --git a/tracing/tracing-perfetto-binary/build.gradle b/tracing/tracing-perfetto-binary/build.gradle
index 6a2f998..c663488 100644
--- a/tracing/tracing-perfetto-binary/build.gradle
+++ b/tracing/tracing-perfetto-binary/build.gradle
@@ -82,7 +82,7 @@
}
androidx {
- name = "AndroidX Tracing: Perfetto SDK Native Dependencies"
+ name = "Tracing Perfetto Binary"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.TRACING_PERFETTO
inceptionYear = "2022"
diff --git a/tracing/tracing-perfetto-common/build.gradle b/tracing/tracing-perfetto-common/build.gradle
index 4d9548c..ac22d616 100644
--- a/tracing/tracing-perfetto-common/build.gradle
+++ b/tracing/tracing-perfetto-common/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "AndroidX Tracing: Perfetto Common"
+ name = "Tracing Perfetto Common"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.TRACING_PERFETTO
inceptionYear = "2022"
diff --git a/tracing/tracing-perfetto/build.gradle b/tracing/tracing-perfetto/build.gradle
index 9e6c8fb..5632eb7 100644
--- a/tracing/tracing-perfetto/build.gradle
+++ b/tracing/tracing-perfetto/build.gradle
@@ -58,7 +58,7 @@
}
androidx {
- name = "AndroidX Tracing: Perfetto SDK"
+ name = "Tracing Perfetto"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.TRACING_PERFETTO
inceptionYear = "2022"
diff --git a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
index d6f95cd..1dce783 100644
--- a/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
+++ b/tracing/tracing-perfetto/src/androidTest/java/androidx/tracing/perfetto/test/TracingTest.kt
@@ -20,9 +20,9 @@
import androidx.annotation.RequiresApi
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import androidx.tracing.perfetto.PerfettoHandshake.RequestKeys.RECEIVER_CLASS_NAME
import androidx.tracing.perfetto.Tracing
import androidx.tracing.perfetto.TracingReceiver
-import androidx.tracing.perfetto.PerfettoHandshake.RequestKeys.RECEIVER_CLASS_NAME
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
index 0ca316b..bca33d3 100644
--- a/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
+++ b/tracing/tracing-perfetto/src/main/java/androidx/tracing/perfetto/TracingReceiver.kt
@@ -23,12 +23,12 @@
import android.util.JsonWriter
import androidx.annotation.RestrictTo
import androidx.annotation.RestrictTo.Scope.LIBRARY
-import androidx.tracing.perfetto.Tracing.EnableTracingResponse
import androidx.tracing.perfetto.PerfettoHandshake.EnableTracingResponse
import androidx.tracing.perfetto.PerfettoHandshake.RequestKeys.ACTION_ENABLE_TRACING
import androidx.tracing.perfetto.PerfettoHandshake.RequestKeys.KEY_PATH
import androidx.tracing.perfetto.PerfettoHandshake.ResponseExitCodes.RESULT_CODE_ERROR_OTHER
import androidx.tracing.perfetto.PerfettoHandshake.ResponseKeys
+import androidx.tracing.perfetto.Tracing.EnableTracingResponse
import java.io.File
import java.io.StringWriter
import java.util.concurrent.LinkedBlockingQueue
diff --git a/tracing/tracing/build.gradle b/tracing/tracing/build.gradle
index 032edf2..1f0851b 100644
--- a/tracing/tracing/build.gradle
+++ b/tracing/tracing/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Tracing"
+ name = "Tracing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android Tracing"
diff --git a/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java b/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
index 1e55554..08ea852 100644
--- a/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
+++ b/tracing/tracing/src/androidTest/java/androidx/tracing/TraceTest.java
@@ -37,6 +37,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
@@ -68,6 +69,7 @@
}
@Test
+ @Ignore("b/280041271")
public void beginAndEndSection() throws IOException {
startTrace();
Trace.beginSection("beginAndEndSection");
@@ -79,6 +81,7 @@
}
@Test
+ @Ignore("b/280041271")
public void beginAndEndTraceSectionLongLabel() throws IOException {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 20; i++) {
@@ -120,6 +123,7 @@
}
@Test
+ @Ignore("b/280041271")
public void isEnabledDuringTrace() throws IOException {
startTrace();
boolean enabled = Trace.isEnabled();
diff --git a/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt b/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
index 915ecb6..0f42fdc 100644
--- a/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
+++ b/transition/transition-ktx/src/androidTest/java/androidx/transition/TransitionTest.kt
@@ -24,13 +24,13 @@
import androidx.test.filters.SdkSuppress
import androidx.test.platform.app.InstrumentationRegistry
import androidx.transition.ktx.test.R
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.atomic.AtomicBoolean
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.atomic.AtomicBoolean
@SdkSuppress(minSdkVersion = 19)
@MediumTest
diff --git a/transition/transition-ktx/src/main/AndroidManifest.xml b/transition/transition-ktx/src/main/AndroidManifest.xml
deleted file mode 100644
index 61b6811..0000000
--- a/transition/transition-ktx/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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 />
diff --git a/transition/transition/build.gradle b/transition/transition/build.gradle
index e1080ed..1518fbe 100644
--- a/transition/transition/build.gradle
+++ b/transition/transition/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "Android Transition Support Library"
+ name = "Transition"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2016"
description = "Android Transition Support Library"
diff --git a/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionTest.kt b/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionTest.kt
index db5d385..245fde8 100644
--- a/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionTest.kt
+++ b/transition/transition/src/androidTest/java/androidx/transition/FragmentTransitionTest.kt
@@ -31,6 +31,8 @@
import androidx.transition.test.R
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Assert.fail
import org.junit.Before
@@ -42,8 +44,6 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.reset
import org.mockito.Mockito.verify
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@MediumTest
@RunWith(Parameterized::class)
diff --git a/transition/transition/src/main/AndroidManifest.xml b/transition/transition/src/main/AndroidManifest.xml
deleted file mode 100644
index 6136621..0000000
--- a/transition/transition/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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 />
diff --git a/tv/samples/src/main/java/androidx/tv/samples/ButtonSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/ButtonSamples.kt
new file mode 100644
index 0000000..0b3501b
--- /dev/null
+++ b/tv/samples/src/main/java/androidx/tv/samples/ButtonSamples.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.tv.material3.Button
+import androidx.tv.material3.ButtonDefaults
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Icon
+import androidx.tv.material3.OutlinedButton
+import androidx.tv.material3.Text
+
+@Sampled
+@Composable
+fun ButtonSample() {
+ Button(onClick = { }) {
+ Text("Button")
+ }
+}
+
+@Sampled
+@Composable
+fun OutlinedButtonSample() {
+ OutlinedButton(onClick = {}) {
+ Text("Outlined Button")
+ }
+}
+
+@Sampled
+@Composable
+fun LikeButtonSample() {
+ Button(
+ onClick = { /* Do something! */ },
+ contentPadding = ButtonDefaults.ButtonWithIconContentPadding
+ ) {
+ Icon(
+ Icons.Filled.Favorite,
+ contentDescription = "Localized description",
+ modifier = Modifier.size(ButtonDefaults.IconSize)
+ )
+ Spacer(Modifier.size(ButtonDefaults.IconSpacing))
+ Text("Like")
+ }
+}
diff --git a/tv/samples/src/main/java/androidx/tv/samples/CardLayoutSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/CardLayoutSamples.kt
new file mode 100644
index 0000000..c4eed33
--- /dev/null
+++ b/tv/samples/src/main/java/androidx/tv/samples/CardLayoutSamples.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import androidx.tv.material3.CardLayoutDefaults
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.StandardCardLayout
+import androidx.tv.material3.Text
+import androidx.tv.material3.WideCardLayout
+
+@Sampled
+@Composable
+fun StandardCardLayoutSample() {
+ StandardCardLayout(
+ modifier = Modifier.size(150.dp, 120.dp),
+ imageCard = { interactionSource ->
+ CardLayoutDefaults.ImageCard(
+ onClick = { },
+ interactionSource = interactionSource
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(80.dp)
+ .background(Color.Blue)
+ )
+ }
+ },
+ title = { Text("Standard Card") }
+ )
+}
+
+@Sampled
+@Composable
+fun WideCardLayoutSample() {
+ WideCardLayout(
+ modifier = Modifier.size(180.dp, 100.dp),
+ imageCard = { interactionSource ->
+ CardLayoutDefaults.ImageCard(
+ onClick = { },
+ interactionSource = interactionSource
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(90.dp)
+ .background(Color.Blue)
+ )
+ }
+ },
+ title = { Text("Wide Card", Modifier.padding(start = 8.dp)) },
+ )
+}
diff --git a/tv/samples/src/main/java/androidx/tv/samples/CardSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/CardSamples.kt
new file mode 100644
index 0000000..ae8440b
--- /dev/null
+++ b/tv/samples/src/main/java/androidx/tv/samples/CardSamples.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.unit.dp
+import androidx.tv.material3.Card
+import androidx.tv.material3.ClassicCard
+import androidx.tv.material3.CompactCard
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Text
+import androidx.tv.material3.WideClassicCard
+
+@Sampled
+@Composable
+fun CardSample() {
+ Card(
+ modifier = Modifier.size(150.dp, 120.dp),
+ onClick = { }
+ ) {
+ Box(Modifier.fillMaxSize()) {
+ Text(
+ text = "Card",
+ modifier = Modifier.align(Alignment.Center)
+ )
+ }
+ }
+}
+
+@Sampled
+@Composable
+fun ClassicCardSample() {
+ ClassicCard(
+ modifier = Modifier.size(150.dp, 120.dp),
+ image = {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(80.dp)
+ .background(Color.Blue)
+ )
+ },
+ title = {
+ Text("Classic Card")
+ },
+ contentPadding = PaddingValues(8.dp),
+ onClick = { }
+ )
+}
+
+@Sampled
+@Composable
+fun CompactCardSample() {
+ CompactCard(
+ modifier = Modifier.size(150.dp, 120.dp),
+ image = {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(80.dp)
+ .background(Color.Blue)
+ )
+ },
+ title = {
+ Text(
+ text = "Compact Card",
+ modifier = Modifier.padding(8.dp)
+ )
+ },
+ onClick = { }
+ )
+}
+
+@Sampled
+@Composable
+fun WideClassicCardSample() {
+ WideClassicCard(
+ modifier = Modifier.size(180.dp, 100.dp),
+ image = {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(80.dp)
+ .background(Color.Blue)
+ )
+ },
+ title = {
+ Text(
+ text = "Wide Classic Card",
+ modifier = Modifier.padding(start = 8.dp)
+ )
+ },
+ contentPadding = PaddingValues(8.dp),
+ onClick = { }
+ )
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/tv/samples/src/main/java/androidx/tv/samples/CheckboxSamples.kt
similarity index 63%
copy from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
copy to tv/samples/src/main/java/androidx/tv/samples/CheckboxSamples.kt
index c325c57..f6af570 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/tv/samples/src/main/java/androidx/tv/samples/CheckboxSamples.kt
@@ -14,10 +14,17 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+@file:OptIn(ExperimentalTvMaterial3Api::class)
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
-}
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.runtime.Composable
+import androidx.tv.material3.Checkbox
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+
+@Sampled
+@Composable
+fun CheckboxSample() {
+ Checkbox(checked = true, onCheckedChange = { })
+}
\ No newline at end of file
diff --git a/tv/samples/src/main/java/androidx/tv/samples/IconButtonSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/IconButtonSamples.kt
new file mode 100644
index 0000000..8694f8f
--- /dev/null
+++ b/tv/samples/src/main/java/androidx/tv/samples/IconButtonSamples.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Favorite
+import androidx.compose.material.icons.outlined.FavoriteBorder
+import androidx.compose.runtime.Composable
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Icon
+import androidx.tv.material3.IconButton
+import androidx.tv.material3.OutlinedIconButton
+
+@Sampled
+@Composable
+fun IconButtonSample() {
+ IconButton(onClick = { /* doSomething() */ }) {
+ Icon(Icons.Filled.Favorite, contentDescription = "Localized description")
+ }
+}
+
+@Sampled
+@Composable
+fun OutlinedIconButtonSample() {
+ OutlinedIconButton(onClick = { /* doSomething() */ }) {
+ Icon(
+ Icons.Outlined.FavoriteBorder,
+ contentDescription = "Localized description"
+ )
+ }
+}
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/tv/samples/src/main/java/androidx/tv/samples/RadioButtonSamples.kt
similarity index 63%
copy from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
copy to tv/samples/src/main/java/androidx/tv/samples/RadioButtonSamples.kt
index c325c57..e9896b5 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/tv/samples/src/main/java/androidx/tv/samples/RadioButtonSamples.kt
@@ -14,10 +14,17 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+@file:OptIn(ExperimentalTvMaterial3Api::class)
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
-}
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.runtime.Composable
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.RadioButton
+
+@Sampled
+@Composable
+fun RadioButtonSample() {
+ RadioButton(selected = true, onClick = {})
+}
\ No newline at end of file
diff --git a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java b/tv/samples/src/main/java/androidx/tv/samples/SwitchSamples.kt
similarity index 63%
copy from appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
copy to tv/samples/src/main/java/androidx/tv/samples/SwitchSamples.kt
index c325c57..2e6b5da 100644
--- a/appactions/interaction/interaction-capabilities-core/src/test/java/androidx/appactions/interaction/capabilities/core/testing/spec/TestEnum.java
+++ b/tv/samples/src/main/java/androidx/tv/samples/SwitchSamples.kt
@@ -14,10 +14,17 @@
* limitations under the License.
*/
-package androidx.appactions.interaction.capabilities.core.testing.spec;
+@file:OptIn(ExperimentalTvMaterial3Api::class)
-/** Sample enum value for testing. */
-public enum TestEnum {
- VALUE_1,
- VALUE_2,
-}
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.runtime.Composable
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Switch
+
+@Sampled
+@Composable
+fun SwitchSample() {
+ Switch(checked = true, onCheckedChange = { })
+}
\ No newline at end of file
diff --git a/tv/samples/src/main/java/androidx/tv/samples/WideButtonSamples.kt b/tv/samples/src/main/java/androidx/tv/samples/WideButtonSamples.kt
new file mode 100644
index 0000000..46e2f94
--- /dev/null
+++ b/tv/samples/src/main/java/androidx/tv/samples/WideButtonSamples.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+@file:OptIn(ExperimentalTvMaterial3Api::class)
+
+package androidx.tv.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.runtime.Composable
+import androidx.tv.material3.ExperimentalTvMaterial3Api
+import androidx.tv.material3.Icon
+import androidx.tv.material3.Text
+import androidx.tv.material3.WideButton
+
+@Sampled
+@Composable
+fun WideButtonSample() {
+ WideButton(onClick = { }) {
+ Text("Settings")
+ }
+}
+
+@Sampled
+@Composable
+fun WideButtonWithIcon() {
+ WideButton(
+ onClick = { },
+ title = { Text("Settings") },
+ icon = {
+ Icon(
+ imageVector = Icons.Default.Settings,
+ contentDescription = "Settings"
+ )
+ }
+ )
+}
+
+@Sampled
+@Composable
+fun WideButtonWithSubtitle() {
+ WideButton(
+ onClick = { },
+ title = { Text("Settings") },
+ subtitle = { Text(text = "Update device preferences") },
+ )
+}
+
+@Sampled
+@Composable
+fun WideButtonWithIconAndSubtitle() {
+ WideButton(
+ onClick = { },
+ title = { Text("Settings") },
+ subtitle = { Text(text = "Update device preferences") },
+ icon = {
+ Icon(
+ imageVector = Icons.Default.Settings,
+ contentDescription = "Settings"
+ )
+ }
+ )
+}
\ No newline at end of file
diff --git a/tv/tv-foundation/build.gradle b/tv/tv-foundation/build.gradle
index a53a44ee..eace93c 100644
--- a/tv/tv-foundation/build.gradle
+++ b/tv/tv-foundation/build.gradle
@@ -67,7 +67,7 @@
}
androidx {
- name = "androidx.tv:tv-foundation"
+ name = "TV Foundation"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "This library makes it easier for developers" +
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsIndexedTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsIndexedTest.kt
index 7bc39fb..1376532 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsIndexedTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsIndexedTest.kt
@@ -17,8 +17,8 @@
package androidx.tv.foundation.lazy.grid
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
index 5cf5c36..4d8ad86 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyGridsReverseLayoutTest.kt
@@ -22,7 +22,6 @@
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
-import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@@ -35,6 +34,7 @@
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyNestedScrollingTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyNestedScrollingTest.kt
index ed9df04..f988a2d2 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyNestedScrollingTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyNestedScrollingTest.kt
@@ -17,18 +17,16 @@
package androidx.tv.foundation.lazy.grid
import androidx.compose.foundation.focusable
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.ui.input.key.NativeKeyEvent
-import androidx.tv.foundation.lazy.list.TestTouchSlop
-import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
@@ -36,6 +34,8 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.tv.foundation.lazy.list.TestTouchSlop
+import androidx.tv.foundation.lazy.list.setContentWithTestViewConfiguration
import com.google.common.truth.Truth
import kotlinx.coroutines.runBlocking
import org.junit.Rule
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyScrollTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyScrollTest.kt
index fc4e60f..57639cd 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyScrollTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/LazyScrollTest.kt
@@ -22,8 +22,8 @@
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.test.filters.MediumTest
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/TvLazyGridLayoutInfoTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/TvLazyGridLayoutInfoTest.kt
index c1ef2fb9e..55b2cef 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/TvLazyGridLayoutInfoTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/grid/TvLazyGridLayoutInfoTest.kt
@@ -21,7 +21,6 @@
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
-import androidx.tv.foundation.lazy.list.LayoutInfoTestParam
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
@@ -32,6 +31,7 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.test.filters.MediumTest
+import androidx.tv.foundation.lazy.list.LayoutInfoTestParam
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.runBlocking
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyColumnTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyColumnTest.kt
index db1f1eb..f26d36e 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyColumnTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyColumnTest.kt
@@ -17,7 +17,6 @@
package androidx.tv.foundation.lazy.list
import android.os.Build
-import androidx.tv.foundation.lazy.AutoTestFrameClock
import androidx.compose.foundation.background
import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.scrollBy
@@ -58,6 +57,7 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.tv.foundation.PivotOffsets
+import androidx.tv.foundation.lazy.AutoTestFrameClock
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.runBlocking
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
index fb1bf65..2e9e5c9 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
@@ -59,14 +59,14 @@
import androidx.tv.foundation.ExperimentalTvFoundationApi
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import kotlin.math.roundToInt
import kotlinx.coroutines.runBlocking
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.junit.runners.Parameterized
-import kotlin.math.roundToInt
import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@LargeTest
@RunWith(Parameterized::class)
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPrefetcherTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPrefetcherTest.kt
index 13f31cf..688fe7f 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPrefetcherTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListPrefetcherTest.kt
@@ -16,7 +16,6 @@
package androidx.tv.foundation.lazy.list
-import androidx.tv.foundation.lazy.AutoTestFrameClock
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.PaddingValues
@@ -32,6 +31,7 @@
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.dp
import androidx.test.filters.LargeTest
+import androidx.tv.foundation.lazy.AutoTestFrameClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import org.junit.Test
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsIndexedTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsIndexedTest.kt
index 9eab54b..2faff75 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsIndexedTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyListsIndexedTest.kt
@@ -18,10 +18,10 @@
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.requiredHeight
import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.BasicText
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyNestedScrollingTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyNestedScrollingTest.kt
index 02ba39f..1a6000df 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyNestedScrollingTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyNestedScrollingTest.kt
@@ -17,6 +17,7 @@
package androidx.tv.foundation.lazy.list
import androidx.compose.foundation.focusable
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.ScrollableState
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
@@ -24,7 +25,6 @@
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.input.key.NativeKeyEvent
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.createComposeRule
diff --git a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyScrollTest.kt b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyScrollTest.kt
index 638985f..6ed7d6c 100644
--- a/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyScrollTest.kt
+++ b/tv/tv-foundation/src/androidTest/java/androidx/tv/foundation/lazy/list/LazyScrollTest.kt
@@ -17,21 +17,23 @@
package androidx.tv.foundation.lazy.list
import androidx.compose.animation.core.FloatSpringSpec
-import androidx.tv.foundation.lazy.AutoTestFrameClock
+import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.animateScrollBy
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.foundation.gestures.Orientation
import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.unit.Dp
import androidx.test.filters.MediumTest
import androidx.tv.foundation.PivotOffsets
+import androidx.tv.foundation.lazy.AutoTestFrameClock
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.TimeUnit
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -42,8 +44,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit
-import kotlin.math.roundToInt
@MediumTest
@RunWith(Parameterized::class)
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridItemProvider.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridItemProvider.kt
index b9589a3..c310814 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridItemProvider.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridItemProvider.kt
@@ -18,7 +18,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
-import androidx.compose.foundation.lazy.layout.PinnableItem
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -66,10 +66,10 @@
override fun getContentType(index: Int): Any? = gridContent.getContentType(index)
@Composable
- override fun Item(index: Int) {
- gridContent.PinnableItem(index, state.pinnedItems) { localIndex ->
- with(TvLazyGridItemScopeImpl) {
- item(localIndex)
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedItems) {
+ gridContent.withInterval(index) { localIndex, content ->
+ content.item(TvLazyGridItemScopeImpl, localIndex)
}
}
}
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridScrollPosition.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridScrollPosition.kt
index b787f26..f713db2 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridScrollPosition.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyGridScrollPosition.kt
@@ -18,6 +18,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
@@ -35,7 +36,7 @@
var index by mutableStateOf(ItemIndex(initialIndex))
private set
- var scrollOffset by mutableStateOf(initialScrollOffset)
+ var scrollOffset by mutableIntStateOf(initialScrollOffset)
private set
private var hadFirstNotEmptyLayout = false
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredItemProvider.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredItemProvider.kt
index 4e5c1df..4e1cabc 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredItemProvider.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredItemProvider.kt
@@ -17,10 +17,10 @@
package androidx.tv.foundation.lazy.grid
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
+import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
/**
* Abstracts away the subcomposition from the measuring logic.
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredLineProvider.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredLineProvider.kt
index 1d8433df..6b68329 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredLineProvider.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/LazyMeasuredLineProvider.kt
@@ -17,8 +17,8 @@
package androidx.tv.foundation.lazy.grid
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
import androidx.compose.ui.unit.Constraints
+import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
/**
* Abstracts away subcomposition and span calculation from the measuring logic of entire lines.
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
index 3d9873f..037afba 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/grid/TvLazyGridState.kt
@@ -29,6 +29,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.collection.mutableVectorOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.listSaver
@@ -135,7 +136,7 @@
/**
* Needed for [animateScrollToItem]. Updated on every measure.
*/
- internal var slotsPerLine: Int by mutableStateOf(0)
+ internal var slotsPerLine: Int by mutableIntStateOf(0)
/**
* Needed for [animateScrollToItem]. Updated on every measure.
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemPlacementAnimator.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemPlacementAnimator.kt
index 6cde370..431d51a 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemPlacementAnimator.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemPlacementAnimator.kt
@@ -23,7 +23,6 @@
import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
@@ -31,6 +30,7 @@
import androidx.compose.ui.util.fastAny
import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed
+import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemProvider.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemProvider.kt
index 2780fac..d50cd62 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemProvider.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListItemProvider.kt
@@ -18,7 +18,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
-import androidx.compose.foundation.lazy.layout.PinnableItem
+import androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@@ -67,9 +67,11 @@
override val itemCount: Int get() = listContent.itemCount
@Composable
- override fun Item(index: Int) {
- listContent.PinnableItem(index, state.pinnedItems) { localIndex ->
- with(itemScope) { item(localIndex) }
+ override fun Item(index: Int, key: Any) {
+ LazyLayoutPinnableItem(key, index, state.pinnedItems) {
+ listContent.withInterval(index) { localIndex, content ->
+ content.item(itemScope, localIndex)
+ }
}
}
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListScrollPosition.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListScrollPosition.kt
index 20eb9e9..f1c7352 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListScrollPosition.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyListScrollPosition.kt
@@ -19,6 +19,7 @@
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.Snapshot
@@ -34,7 +35,7 @@
) {
var index by mutableStateOf(DataIndex(initialIndex))
- var scrollOffset by mutableStateOf(initialScrollOffset)
+ var scrollOffset by mutableIntStateOf(initialScrollOffset)
private set
private var hadFirstNotEmptyLayout = false
diff --git a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyMeasuredItemProvider.kt b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyMeasuredItemProvider.kt
index cd3a131..a291b8a 100644
--- a/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyMeasuredItemProvider.kt
+++ b/tv/tv-foundation/src/main/java/androidx/tv/foundation/lazy/list/LazyMeasuredItemProvider.kt
@@ -17,10 +17,10 @@
package androidx.tv.foundation.lazy.list
import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
+import androidx.tv.foundation.lazy.layout.LazyLayoutKeyIndexMap
/**
* Abstracts away the subcomposition from the measuring logic.
diff --git a/tv/tv-material/api/public_plus_experimental_current.txt b/tv/tv-material/api/public_plus_experimental_current.txt
index 093044e..16c8b91 100644
--- a/tv/tv-material/api/public_plus_experimental_current.txt
+++ b/tv/tv-material/api/public_plus_experimental_current.txt
@@ -141,13 +141,12 @@
@androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceBorder {
}
- @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceColor {
+ @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceColors {
}
@androidx.tv.material3.ExperimentalTvMaterial3Api public final class ClickableSurfaceDefaults {
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ClickableSurfaceBorder border(optional androidx.tv.material3.Border border, optional androidx.tv.material3.Border focusedBorder, optional androidx.tv.material3.Border pressedBorder, optional androidx.tv.material3.Border disabledBorder, optional androidx.tv.material3.Border focusedDisabledBorder);
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ClickableSurfaceColor color(optional long color, optional long focusedColor, optional long pressedColor, optional long disabledColor);
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ClickableSurfaceColor contentColor(optional long color, optional long focusedColor, optional long pressedColor, optional long disabledColor);
+ method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ClickableSurfaceColors colors(optional long containerColor, optional long contentColor, optional long focusedContainerColor, optional long focusedContentColor, optional long pressedContainerColor, optional long pressedContentColor, optional long disabledContainerColor, optional long disabledContentColor);
method public androidx.tv.material3.ClickableSurfaceGlow glow(optional androidx.tv.material3.Glow glow, optional androidx.tv.material3.Glow focusedGlow, optional androidx.tv.material3.Glow pressedGlow);
method public androidx.tv.material3.ClickableSurfaceScale scale(optional @FloatRange(from=0.0) float scale, optional @FloatRange(from=0.0) float focusedScale, optional @FloatRange(from=0.0) float pressedScale, optional @FloatRange(from=0.0) float disabledScale, optional @FloatRange(from=0.0) float focusedDisabledScale);
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ClickableSurfaceShape shape(optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.graphics.Shape focusedShape, optional androidx.compose.ui.graphics.Shape pressedShape, optional androidx.compose.ui.graphics.Shape disabledShape, optional androidx.compose.ui.graphics.Shape focusedDisabledShape);
@@ -356,12 +355,12 @@
method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static androidx.tv.material3.DrawerState rememberDrawerState(androidx.tv.material3.DrawerValue initialValue);
}
+ @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class NonInteractiveSurfaceColors {
+ }
+
@androidx.tv.material3.ExperimentalTvMaterial3Api public final class NonInteractiveSurfaceDefaults {
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getColor();
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public long getContentColor();
+ method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.NonInteractiveSurfaceColors colors(optional long containerColor, optional long contentColor);
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.compose.ui.graphics.Shape getShape();
- property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long color;
- property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final long contentColor;
property @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public final androidx.compose.ui.graphics.Shape shape;
field public static final androidx.tv.material3.NonInteractiveSurfaceDefaults INSTANCE;
}
@@ -450,9 +449,9 @@
}
public final class SurfaceKt {
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(optional androidx.compose.ui.Modifier modifier, optional float tonalElevation, optional androidx.compose.ui.graphics.Shape shape, optional long color, optional long contentColor, optional androidx.tv.material3.Border border, optional androidx.tv.material3.Glow glow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional float tonalElevation, optional androidx.tv.material3.ClickableSurfaceShape shape, optional androidx.tv.material3.ClickableSurfaceColor color, optional androidx.tv.material3.ClickableSurfaceColor contentColor, optional androidx.tv.material3.ClickableSurfaceScale scale, optional androidx.tv.material3.ClickableSurfaceBorder border, optional androidx.tv.material3.ClickableSurfaceGlow glow, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional float tonalElevation, optional androidx.tv.material3.ToggleableSurfaceShape shape, optional androidx.tv.material3.ToggleableSurfaceColor color, optional androidx.tv.material3.ToggleableSurfaceColor contentColor, optional androidx.tv.material3.ToggleableSurfaceScale scale, optional androidx.tv.material3.ToggleableSurfaceBorder border, optional androidx.tv.material3.ToggleableSurfaceGlow glow, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable @androidx.compose.runtime.NonRestartableComposable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(optional androidx.compose.ui.Modifier modifier, optional float tonalElevation, optional androidx.compose.ui.graphics.Shape shape, optional androidx.tv.material3.NonInteractiveSurfaceColors colors, optional androidx.tv.material3.Border border, optional androidx.tv.material3.Glow glow, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional float tonalElevation, optional androidx.tv.material3.ClickableSurfaceShape shape, optional androidx.tv.material3.ClickableSurfaceColors colors, optional androidx.tv.material3.ClickableSurfaceScale scale, optional androidx.tv.material3.ClickableSurfaceBorder border, optional androidx.tv.material3.ClickableSurfaceGlow glow, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable @androidx.tv.material3.ExperimentalTvMaterial3Api public static void Surface(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onCheckedChange, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional float tonalElevation, optional androidx.tv.material3.ToggleableSurfaceShape shape, optional androidx.tv.material3.ToggleableSurfaceColors colors, optional androidx.tv.material3.ToggleableSurfaceScale scale, optional androidx.tv.material3.ToggleableSurfaceBorder border, optional androidx.tv.material3.ToggleableSurfaceGlow glow, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit> content);
method public static androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> getLocalAbsoluteTonalElevation();
property public static final androidx.compose.runtime.ProvidableCompositionLocal<androidx.compose.ui.unit.Dp> LocalAbsoluteTonalElevation;
}
@@ -509,13 +508,12 @@
@androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceBorder {
}
- @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceColor {
+ @androidx.compose.runtime.Immutable @androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceColors {
}
@androidx.tv.material3.ExperimentalTvMaterial3Api public final class ToggleableSurfaceDefaults {
method public androidx.tv.material3.ToggleableSurfaceBorder border(optional androidx.tv.material3.Border border, optional androidx.tv.material3.Border focusedBorder, optional androidx.tv.material3.Border pressedBorder, optional androidx.tv.material3.Border selectedBorder, optional androidx.tv.material3.Border disabledBorder, optional androidx.tv.material3.Border focusedSelectedBorder, optional androidx.tv.material3.Border focusedDisabledBorder, optional androidx.tv.material3.Border pressedSelectedBorder, optional androidx.tv.material3.Border selectedDisabledBorder, optional androidx.tv.material3.Border focusedSelectedDisabledBorder);
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ToggleableSurfaceColor color(optional long color, optional long focusedColor, optional long pressedColor, optional long selectedColor, optional long disabledColor, optional long focusedSelectedColor, optional long pressedSelectedColor);
- method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ToggleableSurfaceColor contentColor(optional long color, optional long focusedColor, optional long pressedColor, optional long selectedColor, optional long disabledColor, optional long focusedSelectedColor, optional long pressedSelectedColor);
+ method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ToggleableSurfaceColors colors(optional long containerColor, optional long contentColor, optional long focusedContainerColor, optional long focusedContentColor, optional long pressedContainerColor, optional long pressedContentColor, optional long selectedContainerColor, optional long selectedContentColor, optional long disabledContainerColor, optional long disabledContentColor, optional long focusedSelectedContainerColor, optional long focusedSelectedContentColor, optional long pressedSelectedContainerColor, optional long pressedSelectedContentColor);
method public androidx.tv.material3.ToggleableSurfaceGlow glow(optional androidx.tv.material3.Glow glow, optional androidx.tv.material3.Glow focusedGlow, optional androidx.tv.material3.Glow pressedGlow, optional androidx.tv.material3.Glow selectedGlow, optional androidx.tv.material3.Glow focusedSelectedGlow, optional androidx.tv.material3.Glow pressedSelectedGlow);
method public androidx.tv.material3.ToggleableSurfaceScale scale(optional float scale, optional float focusedScale, optional float pressedScale, optional float selectedScale, optional float disabledScale, optional float focusedSelectedScale, optional float focusedDisabledScale, optional float pressedSelectedScale, optional float selectedDisabledScale, optional float focusedSelectedDisabledScale);
method @androidx.compose.runtime.Composable @androidx.compose.runtime.ReadOnlyComposable public androidx.tv.material3.ToggleableSurfaceShape shape(optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.ui.graphics.Shape focusedShape, optional androidx.compose.ui.graphics.Shape pressedShape, optional androidx.compose.ui.graphics.Shape selectedShape, optional androidx.compose.ui.graphics.Shape disabledShape, optional androidx.compose.ui.graphics.Shape focusedSelectedShape, optional androidx.compose.ui.graphics.Shape focusedDisabledShape, optional androidx.compose.ui.graphics.Shape pressedSelectedShape, optional androidx.compose.ui.graphics.Shape selectedDisabledShape, optional androidx.compose.ui.graphics.Shape focusedSelectedDisabledShape);
diff --git a/tv/tv-material/build.gradle b/tv/tv-material/build.gradle
index 334a3f1..760e574 100644
--- a/tv/tv-material/build.gradle
+++ b/tv/tv-material/build.gradle
@@ -57,7 +57,7 @@
}
androidx {
- name = "androidx.tv:tv-material"
+ name = "TV Material"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "build TV applications using controls that adhere to Material Design Language."
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/NonInteractiveSurfaceScreenshotTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/NonInteractiveSurfaceScreenshotTest.kt
index c23e30b..f317957 100644
--- a/tv/tv-material/src/androidTest/java/androidx/tv/material3/NonInteractiveSurfaceScreenshotTest.kt
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/NonInteractiveSurfaceScreenshotTest.kt
@@ -96,7 +96,10 @@
fun nonInteractiveSurface_containerColor() {
rule.setMaterialContent(scheme.colorScheme) {
Box(containerModifier.testTag(wrapperTestTag)) {
- Surface(surfaceModifier(), color = Color.Green) {}
+ Surface(
+ surfaceModifier(),
+ colors = NonInteractiveSurfaceDefaults.colors(containerColor = Color.Green)
+ ) {}
}
}
assertAgainstGolden("non_interactive_surface_${scheme.name}_containerColor")
@@ -106,7 +109,10 @@
fun nonInteractiveSurface_contentColor() {
rule.setMaterialContent(scheme.colorScheme) {
Box(containerModifier.testTag(wrapperTestTag)) {
- Surface(surfaceModifier(), contentColor = Color.Red) {}
+ Surface(
+ surfaceModifier(),
+ colors = NonInteractiveSurfaceDefaults.colors(contentColor = Color.Red)
+ ) {}
}
}
assertAgainstGolden("non_interactive_surface_${scheme.name}_contentColor")
diff --git a/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt b/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
index 9f25017..9684230 100644
--- a/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
+++ b/tv/tv-material/src/androidTest/java/androidx/tv/material3/SurfaceTest.kt
@@ -112,8 +112,8 @@
shape = ClickableSurfaceDefaults.shape(
shape = RectangleShape
),
- color = ClickableSurfaceDefaults.color(
- color = Color.Yellow
+ colors = ClickableSurfaceDefaults.colors(
+ containerColor = Color.Yellow
)
) {
Box(Modifier.fillMaxSize())
@@ -123,8 +123,8 @@
shape = ClickableSurfaceDefaults.shape(
shape = RectangleShape
),
- color = ClickableSurfaceDefaults.color(
- color = Color.Green
+ colors = ClickableSurfaceDefaults.colors(
+ containerColor = Color.Green
)
) {
Box(Modifier.fillMaxSize())
@@ -180,7 +180,7 @@
},
onClick = {},
tonalElevation = 2.toDp(),
- contentColor = ClickableSurfaceDefaults.color(color = expectedColor)
+ colors = ClickableSurfaceDefaults.colors(contentColor = expectedColor)
) {}
}
}
@@ -379,9 +379,9 @@
.testTag("surface")
.size(100.toDp()),
onClick = {},
- color = ClickableSurfaceDefaults.color(
- color = Color.Transparent,
- focusedColor = Color.Transparent
+ colors = ClickableSurfaceDefaults.colors(
+ containerColor = Color.Transparent,
+ focusedContainerColor = Color.Transparent
),
glow = ClickableSurfaceDefaults.glow(
glow = Glow(
@@ -447,9 +447,9 @@
border = BorderStroke(width = 5.toDp(), color = Color.Magenta)
)
),
- color = ClickableSurfaceDefaults.color(
- color = Color.Transparent,
- focusedColor = Color.Transparent
+ colors = ClickableSurfaceDefaults.colors(
+ containerColor = Color.Transparent,
+ focusedContainerColor = Color.Transparent
)
) {}
}
@@ -661,9 +661,9 @@
.testTag("surface")
.size(100.toDp()),
onCheckedChange = { isChecked = it },
- color = ToggleableSurfaceDefaults.color(
- color = Color.Transparent,
- selectedColor = Color.Transparent
+ colors = ToggleableSurfaceDefaults.colors(
+ containerColor = Color.Transparent,
+ selectedContainerColor = Color.Transparent
),
glow = ToggleableSurfaceDefaults.glow(
glow = Glow(
@@ -746,9 +746,9 @@
border = BorderStroke(width = 5.toDp(), color = Color.Magenta)
)
),
- color = ToggleableSurfaceDefaults.color(
- color = Color.Transparent,
- selectedColor = Color.Transparent
+ colors = ToggleableSurfaceDefaults.colors(
+ containerColor = Color.Transparent,
+ selectedContainerColor = Color.Transparent
)
) {}
}
@@ -779,9 +779,9 @@
.testTag("surface"),
onClick = {},
enabled = surfaceEnabled,
- color = ClickableSurfaceDefaults.color(
- color = Color.Green,
- disabledColor = Color.Red
+ colors = ClickableSurfaceDefaults.colors(
+ containerColor = Color.Green,
+ disabledContainerColor = Color.Red
)
) {}
}
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Button.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Button.kt
index b547d9d..6d4dee9 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Button.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Button.kt
@@ -48,6 +48,10 @@
*
* The default text style for internal [Text] components will be set to [Typography.labelLarge].
*
+ * Samples:
+ * @sample androidx.tv.samples.ButtonSample
+ * @sample androidx.tv.samples.LikeButtonSample
+ *
* @param onClick called when this button is clicked
* @param modifier the [Modifier] to be applied to this button
* @param enabled controls the enabled state of this button. When `false`, this component will not
@@ -115,6 +119,9 @@
*
* The default text style for internal [Text] components will be set to [Typography.labelLarge].
*
+ * Samples:
+ * @sample androidx.tv.samples.OutlinedButtonSample
+ *
* @param onClick called when this button is clicked
* @param modifier the [Modifier] to be applied to this button
* @param enabled controls the enabled state of this button. When `false`, this component will not
@@ -190,8 +197,7 @@
scale = scale.toClickableSurfaceScale(),
glow = glow.toClickableSurfaceGlow(),
shape = shape.toClickableSurfaceShape(),
- color = colors.toClickableSurfaceContainerColor(),
- contentColor = colors.toClickableSurfaceContentColor(),
+ colors = colors.toClickableSurfaceColors(),
tonalElevation = tonalElevation,
border = border.toClickableSurfaceBorder(),
interactionSource = interactionSource
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/ButtonStyles.kt b/tv/tv-material/src/main/java/androidx/tv/material3/ButtonStyles.kt
index 560ad85..3661d23 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/ButtonStyles.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/ButtonStyles.kt
@@ -285,6 +285,8 @@
}
}
+private val WideButtonContainerColor = Color.Transparent
+
@OptIn(ExperimentalTvMaterial3Api::class)
internal fun ButtonShape.toClickableSurfaceShape(): ClickableSurfaceShape = ClickableSurfaceShape(
shape = shape,
@@ -295,30 +297,29 @@
)
@OptIn(ExperimentalTvMaterial3Api::class)
-internal fun ButtonColors.toClickableSurfaceContainerColor(): ClickableSurfaceColor =
- ClickableSurfaceColor(
- color = containerColor,
- focusedColor = focusedContainerColor,
- pressedColor = pressedContainerColor,
- disabledColor = disabledContainerColor,
+internal fun ButtonColors.toClickableSurfaceColors(): ClickableSurfaceColors =
+ ClickableSurfaceColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ focusedContainerColor = focusedContainerColor,
+ focusedContentColor = focusedContentColor,
+ pressedContainerColor = pressedContainerColor,
+ pressedContentColor = pressedContentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
)
@OptIn(ExperimentalTvMaterial3Api::class)
-internal fun ButtonColors.toClickableSurfaceContentColor(): ClickableSurfaceColor =
- ClickableSurfaceColor(
- color = contentColor,
- focusedColor = focusedContentColor,
- pressedColor = pressedContentColor,
- disabledColor = disabledContentColor,
- )
-
-@OptIn(ExperimentalTvMaterial3Api::class)
-internal fun WideButtonContentColor.toClickableSurfaceContentColor(): ClickableSurfaceColor =
- ClickableSurfaceColor(
- color = contentColor,
- focusedColor = focusedContentColor,
- pressedColor = pressedContentColor,
- disabledColor = disabledContentColor,
+internal fun WideButtonContentColor.toClickableSurfaceColors(): ClickableSurfaceColors =
+ ClickableSurfaceColors(
+ containerColor = WideButtonContainerColor,
+ contentColor = contentColor,
+ focusedContainerColor = WideButtonContainerColor,
+ focusedContentColor = focusedContentColor,
+ pressedContainerColor = WideButtonContainerColor,
+ pressedContentColor = pressedContentColor,
+ disabledContainerColor = WideButtonContainerColor,
+ disabledContentColor = disabledContentColor
)
@OptIn(ExperimentalTvMaterial3Api::class)
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Card.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Card.kt
index 1c1fc72..38550b6 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Card.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Card.kt
@@ -46,6 +46,8 @@
*
* This Card handles click events, calling its [onClick] lambda.
*
+ * @sample androidx.tv.samples.CardSample
+ *
* @param onClick called when this card is clicked
* @param modifier the [Modifier] to be applied to this card
* @param shape [CardShape] defines the shape of this card's container in different interaction
@@ -80,8 +82,7 @@
onClick = onClick,
modifier = modifier,
shape = shape.toClickableSurfaceShape(),
- color = colors.toClickableSurfaceContainerColor(),
- contentColor = colors.toClickableSurfaceContentColor(),
+ colors = colors.toClickableSurfaceColors(),
scale = scale.toClickableSurfaceScale(),
border = border.toClickableSurfaceBorder(),
glow = glow.toClickableSurfaceGlow(),
@@ -100,6 +101,8 @@
*
* This Card handles click events, calling its [onClick] lambda.
*
+ * @sample androidx.tv.samples.ClassicCardSample
+ *
* @param onClick called when this card is clicked
* @param image defines the [Composable] image to be displayed on top of the Card.
* @param title defines the [Composable] title placed below the image in the Card.
@@ -176,6 +179,8 @@
*
* This Card handles click events, calling its [onClick] lambda.
*
+ * @sample androidx.tv.samples.CompactCardSample
+ *
* @param onClick called when this card is clicked
* @param image defines the [Composable] image to be displayed on top of the Card.
* @param title defines the [Composable] title placed below the image in the Card.
@@ -257,6 +262,8 @@
*
* This Card handles click events, calling its [onClick] lambda.
*
+ * @sample androidx.tv.samples.WideClassicCardSample
+ *
* @param onClick called when this card is clicked
* @param image defines the [Composable] image to be displayed on top of the Card.
* @param title defines the [Composable] title placed below the image in the Card.
@@ -526,21 +533,16 @@
private const val DescriptionAlpha = 0.8f
@OptIn(ExperimentalTvMaterial3Api::class)
-private fun CardColors.toClickableSurfaceContainerColor() =
- ClickableSurfaceColor(
- color = containerColor,
- focusedColor = focusedContainerColor,
- pressedColor = pressedContainerColor,
- disabledColor = containerColor
- )
-
-@OptIn(ExperimentalTvMaterial3Api::class)
-private fun CardColors.toClickableSurfaceContentColor() =
- ClickableSurfaceColor(
- color = contentColor,
- focusedColor = focusedContentColor,
- pressedColor = pressedContentColor,
- disabledColor = contentColor
+private fun CardColors.toClickableSurfaceColors() =
+ ClickableSurfaceColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ focusedContainerColor = focusedContainerColor,
+ focusedContentColor = focusedContentColor,
+ pressedContainerColor = pressedContainerColor,
+ pressedContentColor = pressedContentColor,
+ disabledContainerColor = containerColor,
+ disabledContentColor = contentColor
)
@OptIn(ExperimentalTvMaterial3Api::class)
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/CardLayout.kt b/tv/tv-material/src/main/java/androidx/tv/material3/CardLayout.kt
index 92aa581..df431a3 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/CardLayout.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/CardLayout.kt
@@ -40,6 +40,8 @@
* It provides a vertical layout with an image card slot at the top. And below that, there are
* slots for the title, subtitle and description.
*
+ * @sample androidx.tv.samples.StandardCardLayoutSample
+ *
* @param imageCard defines the [Composable] to be used for the image card. See
* [CardLayoutDefaults.ImageCard] to create an image card. The `interactionSource` param provided
* in the lambda function should be forwarded and used with the image card composable.
@@ -101,6 +103,8 @@
* It provides a horizontal layout with an image card slot at the start, followed by the title,
* subtitle and description at the end.
*
+ * @sample androidx.tv.samples.WideCardLayoutSample
+ *
* @param imageCard defines the [Composable] to be used for the image card. See
* [CardLayoutDefaults.ImageCard] to create an image card. The `interactionSource` param provided
* in the lambda function should to be forwarded and used with the image card composable.
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
index 001aed4..5fbfc80c 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Carousel.kt
@@ -38,6 +38,7 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -339,12 +340,12 @@
@Stable
@ExperimentalTvMaterial3Api
class CarouselState(initialActiveItemIndex: Int = 0) {
- internal var activePauseHandlesCount by mutableStateOf(0)
+ internal var activePauseHandlesCount by mutableIntStateOf(0)
/**
* The index of the item that is currently displayed by the carousel
*/
- var activeItemIndex by mutableStateOf(initialActiveItemIndex)
+ var activeItemIndex by mutableIntStateOf(initialActiveItemIndex)
internal set
/**
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
index 960df60..d6900dd 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Checkbox.kt
@@ -64,6 +64,8 @@
*
* @see [TriStateCheckbox] if you require support for an indeterminate state.
*
+ * @sample androidx.tv.samples.CheckboxSample
+ *
* @param checked whether this checkbox is checked or unchecked
* @param onCheckedChange called when this checkbox is clicked. If `null`, then this checkbox will
* not be interactable, unless something else handles its input events and updates its state.
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/IconButton.kt b/tv/tv-material/src/main/java/androidx/tv/material3/IconButton.kt
index 1c66a17..bc0b098 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/IconButton.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/IconButton.kt
@@ -16,8 +16,8 @@
package androidx.tv.material3
-import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
@@ -42,6 +42,8 @@
*
* The default text style for internal [Text] components will be set to [Typography.labelLarge].
*
+ * @sample androidx.tv.samples.IconButtonSample
+ *
* @param onClick called when this button is clicked
* @param modifier the [Modifier] to be applied to this button
* @param enabled controls the enabled state of this button. When `false`, this component will not
@@ -79,8 +81,7 @@
onClick = onClick,
enabled = enabled,
shape = shape.toClickableSurfaceShape(),
- color = colors.toClickableSurfaceContainerColor(),
- contentColor = colors.toClickableSurfaceContentColor(),
+ colors = colors.toClickableSurfaceColors(),
scale = scale.toClickableSurfaceScale(),
border = border.toClickableSurfaceBorder(),
glow = glow.toClickableSurfaceGlow(),
@@ -107,6 +108,8 @@
*
* The default text style for internal [Text] components will be set to [Typography.labelLarge].
*
+ * @sample androidx.tv.samples.OutlinedIconButtonSample
+ *
* @param onClick called when this button is clicked
* @param modifier the [Modifier] to be applied to this button
* @param enabled controls the enabled state of this button. When `false`, this component will not
@@ -144,8 +147,7 @@
onClick = onClick,
enabled = enabled,
shape = shape.toClickableSurfaceShape(),
- color = colors.toClickableSurfaceContainerColor(),
- contentColor = colors.toClickableSurfaceContentColor(),
+ colors = colors.toClickableSurfaceColors(),
scale = scale.toClickableSurfaceScale(),
border = border.toClickableSurfaceBorder(),
glow = glow.toClickableSurfaceGlow(),
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/IconButtonDefaults.kt b/tv/tv-material/src/main/java/androidx/tv/material3/IconButtonDefaults.kt
index c56fd82..d2a3f17 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/IconButtonDefaults.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/IconButtonDefaults.kt
@@ -16,9 +16,9 @@
package androidx.tv.material3
-import androidx.compose.foundation.interaction.Interaction
import androidx.annotation.FloatRange
import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt b/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
index f55c49d..e10af5a 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/ImmersiveList.kt
@@ -30,6 +30,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -66,7 +67,7 @@
listAlignment: Alignment = Alignment.BottomEnd,
list: @Composable ImmersiveListScope.() -> Unit,
) {
- var currentItemIndex by remember { mutableStateOf(0) }
+ var currentItemIndex by remember { mutableIntStateOf(0) }
var listHasFocus by remember { mutableStateOf(false) }
Box(modifier.bringIntoViewIfChildrenAreFocused()) {
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/RadioButton.kt b/tv/tv-material/src/main/java/androidx/tv/material3/RadioButton.kt
index 33e5a85..bf6c3fc 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/RadioButton.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/RadioButton.kt
@@ -47,6 +47,8 @@
*
* ![Radio button image](https://developer.android.com/images/reference/androidx/compose/material3/radio-button.png)
*
+ * @sample androidx.tv.samples.RadioButtonSample
+ *
* @param selected whether this radio button is selected or not
* @param onClick called when this radio button is clicked. If `null`, then this radio button will
* not be interactable, unless something else handles its input events and updates its state.
@@ -72,7 +74,8 @@
) {
val dotRadius = animateDpAsState(
targetValue = if (selected) RadioButtonDotSize / 2 else 0.dp,
- animationSpec = tween(durationMillis = RadioAnimationDuration)
+ animationSpec = tween(durationMillis = RadioAnimationDuration),
+ label = "radioButton_dotRadius"
)
val radioColor = colors.radioColor(enabled, selected)
val selectableModifier =
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
index 16f3dcc..2b563e7 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Surface.kt
@@ -65,8 +65,8 @@
* @param tonalElevation When [color] is [ColorScheme.surface], a higher the elevation will result
* in a darker color in light theme and lighter color in dark theme.
* @param shape Defines the surface's shape.
- * @param color Color to be used on background of the Surface
- * @param contentColor The preferred content color provided by this Surface to its children.
+ * @param colors Defines the background & content color to be used in this Surface.
+ * See [NonInteractiveSurfaceDefaults.colors].
* @param border Defines a border around the Surface.
* @param glow Diffused shadow to be shown behind the Surface.
* @param content defines the [Composable] content inside the surface
@@ -78,8 +78,7 @@
modifier: Modifier = Modifier,
tonalElevation: Dp = 0.dp,
shape: Shape = NonInteractiveSurfaceDefaults.shape,
- color: Color = NonInteractiveSurfaceDefaults.color,
- contentColor: Color = NonInteractiveSurfaceDefaults.contentColor,
+ colors: NonInteractiveSurfaceColors = NonInteractiveSurfaceDefaults.colors(),
border: Border = NonInteractiveSurfaceDefaults.border,
glow: Glow = NonInteractiveSurfaceDefaults.glow,
content: @Composable (BoxScope.() -> Unit)
@@ -90,8 +89,8 @@
enabled = true,
tonalElevation = tonalElevation,
shape = shape,
- color = color,
- contentColor = contentColor,
+ color = colors.containerColor,
+ contentColor = colors.contentColor,
scale = 1.0f,
border = border,
glow = glow,
@@ -114,8 +113,8 @@
* @param tonalElevation When [color] is [ColorScheme.surface], a higher the elevation will result
* in a darker color in light theme and lighter color in dark theme.
* @param shape Defines the surface's shape.
- * @param color Color to be used on background of the Surface
- * @param contentColor The preferred content color provided by this Surface to its children.
+ * @param colors Defines the background & content colors to be used in this surface for different
+ * interaction states. See [ClickableSurfaceDefaults.colors].
* @param scale Defines size of the Surface relative to its original size.
* @param border Defines a border around the Surface.
* @param glow Diffused shadow to be shown behind the Surface.
@@ -133,8 +132,7 @@
enabled: Boolean = true,
tonalElevation: Dp = 0.dp,
shape: ClickableSurfaceShape = ClickableSurfaceDefaults.shape(),
- color: ClickableSurfaceColor = ClickableSurfaceDefaults.color(),
- contentColor: ClickableSurfaceColor = ClickableSurfaceDefaults.contentColor(),
+ colors: ClickableSurfaceColors = ClickableSurfaceDefaults.colors(),
scale: ClickableSurfaceScale = ClickableSurfaceDefaults.scale(),
border: ClickableSurfaceBorder = ClickableSurfaceDefaults.border(),
glow: ClickableSurfaceGlow = ClickableSurfaceDefaults.glow(),
@@ -158,17 +156,17 @@
pressed = pressed,
shape = shape
),
- color = ClickableSurfaceDefaults.color(
+ color = ClickableSurfaceDefaults.containerColor(
enabled = enabled,
focused = focused,
pressed = pressed,
- color = color
+ colors = colors
),
- contentColor = ClickableSurfaceDefaults.color(
+ contentColor = ClickableSurfaceDefaults.contentColor(
enabled = enabled,
focused = focused,
pressed = pressed,
- color = contentColor
+ colors = colors
),
scale = ClickableSurfaceDefaults.scale(
enabled = enabled,
@@ -215,8 +213,8 @@
* @param tonalElevation When [color] is [ColorScheme.surface], a higher the elevation will result
* in a darker color in light theme and lighter color in dark theme.
* @param shape Defines the surface's shape.
- * @param color Color to be used on background of the Surface
- * @param contentColor The preferred content color provided by this Surface to its children.
+ * @param colors Defines the background & content colors to be used in this surface for different
+ * interaction states. See [ToggleableSurfaceDefaults.colors].
* @param scale Defines size of the Surface relative to its original size.
* @param border Defines a border around the Surface.
* @param glow Diffused shadow to be shown behind the Surface.
@@ -235,8 +233,7 @@
enabled: Boolean = true,
tonalElevation: Dp = Elevation.Level0,
shape: ToggleableSurfaceShape = ToggleableSurfaceDefaults.shape(),
- color: ToggleableSurfaceColor = ToggleableSurfaceDefaults.color(),
- contentColor: ToggleableSurfaceColor = ToggleableSurfaceDefaults.contentColor(),
+ colors: ToggleableSurfaceColors = ToggleableSurfaceDefaults.colors(),
scale: ToggleableSurfaceScale = ToggleableSurfaceDefaults.scale(),
border: ToggleableSurfaceBorder = ToggleableSurfaceDefaults.border(),
glow: ToggleableSurfaceGlow = ToggleableSurfaceDefaults.glow(),
@@ -263,19 +260,19 @@
selected = checked,
shape = shape
),
- color = ToggleableSurfaceDefaults.color(
+ color = ToggleableSurfaceDefaults.containerColor(
enabled = enabled,
focused = focused,
pressed = pressed,
selected = checked,
- color = color
+ colors = colors
),
- contentColor = ToggleableSurfaceDefaults.color(
+ contentColor = ToggleableSurfaceDefaults.contentColor(
enabled = enabled,
focused = focused,
pressed = pressed,
selected = checked,
- color = contentColor
+ colors = colors
),
scale = ToggleableSurfaceDefaults.scale(
enabled = enabled,
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceDefaults.kt b/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceDefaults.kt
index 8dc31ea..10cbe4c 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceDefaults.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceDefaults.kt
@@ -36,15 +36,21 @@
val shape: Shape @ReadOnlyComposable @Composable get() = MaterialTheme.shapes.medium
/**
- * Represents the default container color used by a non-interactive [Surface]
+ * Creates a [NonInteractiveSurfaceColors] that represents the default container & content
+ * colors used by a non-interactive [Surface].
+ *
+ * @param containerColor the container color of this Surface
+ * @param contentColor the content color of this Surface
*/
- val color: Color @ReadOnlyComposable @Composable get() = MaterialTheme.colorScheme.surface
-
- /**
- * Represents the default content color used by a non-interactive [Surface]
- */
- val contentColor: Color @ReadOnlyComposable @Composable get() =
- MaterialTheme.colorScheme.onSurface
+ @ReadOnlyComposable
+ @Composable
+ fun colors(
+ containerColor: Color = MaterialTheme.colorScheme.surface,
+ contentColor: Color = contentColorFor(containerColor)
+ ) = NonInteractiveSurfaceColors(
+ containerColor = containerColor,
+ contentColor = contentColor
+ )
/**
* Represents the default border used by a non-interactive [Surface]
@@ -104,66 +110,68 @@
focusedDisabledShape = focusedDisabledShape
)
- internal fun color(
+ internal fun containerColor(
enabled: Boolean,
focused: Boolean,
pressed: Boolean,
- color: ClickableSurfaceColor
+ colors: ClickableSurfaceColors
): Color {
return when {
- pressed && enabled -> color.pressedColor
- focused && enabled -> color.focusedColor
- enabled -> color.color
- else -> color.disabledColor
+ pressed && enabled -> colors.pressedContainerColor
+ focused && enabled -> colors.focusedContainerColor
+ enabled -> colors.containerColor
+ else -> colors.disabledContainerColor
+ }
+ }
+
+ internal fun contentColor(
+ enabled: Boolean,
+ focused: Boolean,
+ pressed: Boolean,
+ colors: ClickableSurfaceColors
+ ): Color {
+ return when {
+ pressed && enabled -> colors.pressedContentColor
+ focused && enabled -> colors.focusedContentColor
+ enabled -> colors.contentColor
+ else -> colors.disabledContentColor
}
}
/**
- * Creates a [ClickableSurfaceColor] that represents the default container colors used in a
- * Surface.
+ * Creates a [ClickableSurfaceColors] that represents the default container & content colors
+ * used in a Surface.
*
- * @param color the container color of this Surface when enabled
- * @param focusedColor the container color of this Surface when enabled and focused
- * @param pressedColor the container color of this Surface when enabled and pressed
- * @param disabledColor the container color of this Surface when not enabled
+ * @param containerColor the container color of this Surface when enabled
+ * @param contentColor the content color of this Surface when enabled
+ * @param focusedContainerColor the container color of this Surface when enabled and focused
+ * @param focusedContentColor the content color of this Surface when enabled and focused
+ * @param pressedContainerColor the container color of this Surface when enabled and pressed
+ * @param pressedContentColor the content color of this Surface when enabled and pressed
+ * @param disabledContainerColor the container color of this Surface when not enabled
+ * @param disabledContentColor the content color of this Surface when not enabled
*/
@ReadOnlyComposable
@Composable
- fun color(
- color: Color = MaterialTheme.colorScheme.surface,
- focusedColor: Color = MaterialTheme.colorScheme.inverseSurface,
- pressedColor: Color = MaterialTheme.colorScheme.inverseSurface,
- disabledColor: Color = MaterialTheme.colorScheme.surfaceVariant.copy(
- alpha = DisabledBackgroundAlpha
- )
- ) = ClickableSurfaceColor(
- color = color,
- focusedColor = focusedColor,
- pressedColor = pressedColor,
- disabledColor = disabledColor
- )
-
- /**
- * Creates a [ClickableSurfaceColor] that represents the default content colors used in a
- * Surface.
- *
- * @param color the content color of this Surface when enabled
- * @param focusedColor the content color of this Surface when enabled and focused
- * @param pressedColor the content color of this Surface when enabled and pressed
- * @param disabledColor the content color of this Surface when not enabled
- */
- @ReadOnlyComposable
- @Composable
- fun contentColor(
- color: Color = MaterialTheme.colorScheme.onSurface,
- focusedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- pressedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- disabledColor: Color = MaterialTheme.colorScheme.onSurface
- ) = ClickableSurfaceColor(
- color = color,
- focusedColor = focusedColor,
- pressedColor = pressedColor,
- disabledColor = disabledColor
+ fun colors(
+ containerColor: Color = MaterialTheme.colorScheme.surface,
+ contentColor: Color = contentColorFor(containerColor),
+ focusedContainerColor: Color = MaterialTheme.colorScheme.inverseSurface,
+ focusedContentColor: Color = contentColorFor(focusedContainerColor),
+ pressedContainerColor: Color = focusedContainerColor,
+ pressedContentColor: Color = contentColorFor(pressedContainerColor),
+ disabledContainerColor: Color = MaterialTheme.colorScheme.surfaceVariant
+ .copy(alpha = DisabledContainerAlpha),
+ disabledContentColor: Color = MaterialTheme.colorScheme.onSurface
+ ) = ClickableSurfaceColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ focusedContainerColor = focusedContainerColor,
+ focusedContentColor = focusedContentColor,
+ pressedContainerColor = pressedContainerColor,
+ pressedContentColor = pressedContentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor
)
internal fun scale(
@@ -342,69 +350,71 @@
)
/**
- * Creates a [ToggleableSurfaceColor] that represents the default container colors used in a
- * toggleable Surface.
+ * Creates a [ToggleableSurfaceColors] that represents the default container & content colors
+ * used in a toggleable Surface.
*
- * @param color the color used when the Surface is enabled, and has no other [Interaction]s.
- * @param focusedColor the color used when the Surface is enabled and focused.
- * @param pressedColor the color used when the Surface is enabled and pressed.
- * @param selectedColor the color used when the Surface is enabled and selected.
- * @param disabledColor the color used when the Surface is not enabled.
- * @param focusedSelectedColor the color used when the Surface is enabled, focused and selected.
- * @param pressedSelectedColor the color used when the Surface is enabled, pressed and selected.
+ * @param containerColor the container color used when the Surface is enabled, and has no other
+ * [Interaction]s.
+ * @param contentColor the content color used when the Surface is enabled, and has no other
+ * [Interaction]s.
+ * @param focusedContainerColor the container color used when the Surface is enabled and
+ * focused.
+ * @param focusedContentColor the content color used when the Surface is enabled and
+ * focused.
+ * @param pressedContainerColor the container color used when the Surface is enabled and
+ * pressed.
+ * @param pressedContentColor the content color used when the Surface is enabled and
+ * pressed.
+ * @param selectedContainerColor the container color used when the Surface is enabled and
+ * selected.
+ * @param selectedContentColor the content color used when the Surface is enabled and
+ * selected.
+ * @param disabledContainerColor the container color used when the Surface is not enabled.
+ * @param disabledContentColor the content color used when the Surface is not enabled.
+ * @param focusedSelectedContainerColor the container color used when the Surface is enabled,
+ * focused and selected.
+ * @param focusedSelectedContentColor the content color used when the Surface is enabled,
+ * focused and selected.
+ * @param pressedSelectedContainerColor the container color used when the Surface is enabled,
+ * pressed and selected.
+ * @param pressedSelectedContentColor the content color used when the Surface is enabled,
+ * pressed and selected.
*/
@ReadOnlyComposable
@Composable
- fun color(
- color: Color = MaterialTheme.colorScheme.surface,
- focusedColor: Color = MaterialTheme.colorScheme.inverseSurface,
- pressedColor: Color = MaterialTheme.colorScheme.inverseSurface,
- selectedColor: Color = MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.5f),
- disabledColor: Color = MaterialTheme.colorScheme.surfaceVariant.copy(
- alpha = DisabledBackgroundAlpha
- ),
- focusedSelectedColor: Color = MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.5f),
- pressedSelectedColor: Color = MaterialTheme.colorScheme.inverseSurface.copy(alpha = 0.5f)
- ) = ToggleableSurfaceColor(
- color = color,
- focusedColor = focusedColor,
- pressedColor = pressedColor,
- selectedColor = selectedColor,
- disabledColor = disabledColor,
- focusedSelectedColor = focusedSelectedColor,
- pressedSelectedColor = pressedSelectedColor
- )
-
- /**
- * Creates a [ToggleableSurfaceColor] that represents the default content colors used in a
- * toggleable Surface.
- *
- * @param color the color used when the Surface is enabled, and has no other [Interaction]s.
- * @param focusedColor the color used when the Surface is enabled and focused.
- * @param pressedColor the color used when the Surface is enabled and pressed.
- * @param selectedColor the color used when the Surface is enabled and selected.
- * @param disabledColor the color used when the Surface is not enabled.
- * @param focusedSelectedColor the color used when the Surface is enabled, focused and selected.
- * @param pressedSelectedColor the color used when the Surface is enabled, pressed and selected.
- */
- @ReadOnlyComposable
- @Composable
- fun contentColor(
- color: Color = MaterialTheme.colorScheme.onSurface,
- focusedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- pressedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- selectedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- disabledColor: Color = MaterialTheme.colorScheme.onSurface,
- focusedSelectedColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
- pressedSelectedColor: Color = MaterialTheme.colorScheme.inverseOnSurface
- ) = ToggleableSurfaceColor(
- color = color,
- focusedColor = focusedColor,
- pressedColor = pressedColor,
- selectedColor = selectedColor,
- disabledColor = disabledColor,
- focusedSelectedColor = focusedSelectedColor,
- pressedSelectedColor = pressedSelectedColor
+ fun colors(
+ containerColor: Color = MaterialTheme.colorScheme.surface,
+ contentColor: Color = contentColorFor(containerColor),
+ focusedContainerColor: Color = MaterialTheme.colorScheme.inverseSurface,
+ focusedContentColor: Color = contentColorFor(focusedContainerColor),
+ pressedContainerColor: Color = focusedContainerColor,
+ pressedContentColor: Color = contentColorFor(pressedContainerColor),
+ selectedContainerColor: Color = MaterialTheme.colorScheme.inverseSurface
+ .copy(alpha = SelectedContainerAlpha),
+ selectedContentColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
+ disabledContainerColor: Color = MaterialTheme.colorScheme.surfaceVariant
+ .copy(alpha = DisabledContainerAlpha),
+ disabledContentColor: Color = MaterialTheme.colorScheme.onSurface,
+ focusedSelectedContainerColor: Color = MaterialTheme.colorScheme.inverseSurface
+ .copy(alpha = SelectedContainerAlpha),
+ focusedSelectedContentColor: Color = MaterialTheme.colorScheme.inverseOnSurface,
+ pressedSelectedContainerColor: Color = focusedSelectedContainerColor,
+ pressedSelectedContentColor: Color = focusedSelectedContentColor
+ ) = ToggleableSurfaceColors(
+ containerColor = containerColor,
+ contentColor = contentColor,
+ focusedContainerColor = focusedContainerColor,
+ focusedContentColor = focusedContentColor,
+ pressedContainerColor = pressedContainerColor,
+ pressedContentColor = pressedContentColor,
+ selectedContainerColor = selectedContainerColor,
+ selectedContentColor = selectedContentColor,
+ disabledContainerColor = disabledContainerColor,
+ disabledContentColor = disabledContentColor,
+ focusedSelectedContainerColor = focusedSelectedContainerColor,
+ focusedSelectedContentColor = focusedSelectedContentColor,
+ pressedSelectedContainerColor = pressedSelectedContainerColor,
+ pressedSelectedContentColor = pressedSelectedContentColor
)
/**
@@ -546,21 +556,39 @@
}
}
- internal fun color(
+ internal fun containerColor(
enabled: Boolean,
focused: Boolean,
pressed: Boolean,
selected: Boolean,
- color: ToggleableSurfaceColor
+ colors: ToggleableSurfaceColors
): Color {
return when {
- enabled && selected && pressed -> color.pressedSelectedColor
- enabled && selected && focused -> color.focusedSelectedColor
- enabled && selected -> color.selectedColor
- enabled && pressed -> color.pressedColor
- enabled && focused -> color.focusedColor
- enabled -> color.color
- else -> color.disabledColor
+ enabled && selected && pressed -> colors.pressedSelectedContainerColor
+ enabled && selected && focused -> colors.focusedSelectedContainerColor
+ enabled && selected -> colors.selectedContainerColor
+ enabled && pressed -> colors.pressedContainerColor
+ enabled && focused -> colors.focusedContainerColor
+ enabled -> colors.containerColor
+ else -> colors.disabledContainerColor
+ }
+ }
+
+ internal fun contentColor(
+ enabled: Boolean,
+ focused: Boolean,
+ pressed: Boolean,
+ selected: Boolean,
+ colors: ToggleableSurfaceColors
+ ): Color {
+ return when {
+ enabled && selected && pressed -> colors.pressedSelectedContentColor
+ enabled && selected && focused -> colors.focusedSelectedContentColor
+ enabled && selected -> colors.selectedContentColor
+ enabled && pressed -> colors.pressedContentColor
+ enabled && focused -> colors.focusedContentColor
+ enabled -> colors.contentColor
+ else -> colors.disabledContentColor
}
}
@@ -625,4 +653,5 @@
}
}
-private const val DisabledBackgroundAlpha = 0.4f
+private const val DisabledContainerAlpha = 0.4f
+private const val SelectedContainerAlpha = 0.5f
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceStyles.kt b/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceStyles.kt
index c8d929a..2da15cf 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceStyles.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/SurfaceStyles.kt
@@ -134,38 +134,56 @@
*/
@ExperimentalTvMaterial3Api
@Immutable
-class ClickableSurfaceColor internal constructor(
- internal val color: Color,
- internal val focusedColor: Color,
- internal val pressedColor: Color,
- internal val disabledColor: Color
+class ClickableSurfaceColors internal constructor(
+ internal val containerColor: Color,
+ internal val contentColor: Color,
+ internal val focusedContainerColor: Color,
+ internal val focusedContentColor: Color,
+ internal val pressedContainerColor: Color,
+ internal val pressedContentColor: Color,
+ internal val disabledContainerColor: Color,
+ internal val disabledContentColor: Color
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
- other as ClickableSurfaceColor
+ other as ClickableSurfaceColors
- if (color != other.color) return false
- if (focusedColor != other.focusedColor) return false
- if (pressedColor != other.pressedColor) return false
- if (disabledColor != other.disabledColor) return false
+ if (containerColor != other.containerColor) return false
+ if (contentColor != other.contentColor) return false
+ if (focusedContainerColor != other.focusedContainerColor) return false
+ if (focusedContentColor != other.focusedContentColor) return false
+ if (pressedContainerColor != other.pressedContainerColor) return false
+ if (pressedContentColor != other.pressedContentColor) return false
+ if (disabledContainerColor != other.disabledContainerColor) return false
+ if (disabledContentColor != other.disabledContentColor) return false
return true
}
override fun hashCode(): Int {
- var result = color.hashCode()
- result = 31 * result + focusedColor.hashCode()
- result = 31 * result + pressedColor.hashCode()
- result = 31 * result + disabledColor.hashCode()
-
+ var result = containerColor.hashCode()
+ result = 31 * result + contentColor.hashCode()
+ result = 31 * result + focusedContainerColor.hashCode()
+ result = 31 * result + focusedContentColor.hashCode()
+ result = 31 * result + pressedContainerColor.hashCode()
+ result = 31 * result + pressedContentColor.hashCode()
+ result = 31 * result + disabledContainerColor.hashCode()
+ result = 31 * result + disabledContentColor.hashCode()
return result
}
override fun toString(): String {
- return "ClickableSurfaceColor(color=$color, focusedColor=$focusedColor, " +
- "pressedColor=$pressedColor, disabledColor=$disabledColor)"
+ return "ClickableSurfaceColors(" +
+ "containerColor=$containerColor, " +
+ "contentColor=$contentColor, " +
+ "focusedContainerColor=$focusedContainerColor, " +
+ "focusedContentColor=$focusedContentColor, " +
+ "pressedContainerColor=$pressedContainerColor, " +
+ "pressedContentColor=$pressedContentColor, " +
+ "disabledContainerColor=$disabledContainerColor, " +
+ "disabledContentColor=$disabledContentColor)"
}
}
@@ -174,49 +192,80 @@
*/
@ExperimentalTvMaterial3Api
@Immutable
-class ToggleableSurfaceColor internal constructor(
- internal val color: Color,
- internal val focusedColor: Color,
- internal val pressedColor: Color,
- internal val selectedColor: Color,
- internal val disabledColor: Color,
- internal val focusedSelectedColor: Color,
- internal val pressedSelectedColor: Color
+class ToggleableSurfaceColors internal constructor(
+ internal val containerColor: Color,
+ internal val contentColor: Color,
+ internal val focusedContainerColor: Color,
+ internal val focusedContentColor: Color,
+ internal val pressedContainerColor: Color,
+ internal val pressedContentColor: Color,
+ internal val selectedContainerColor: Color,
+ internal val selectedContentColor: Color,
+ internal val disabledContainerColor: Color,
+ internal val disabledContentColor: Color,
+ internal val focusedSelectedContainerColor: Color,
+ internal val focusedSelectedContentColor: Color,
+ internal val pressedSelectedContainerColor: Color,
+ internal val pressedSelectedContentColor: Color
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
- other as ToggleableSurfaceColor
+ other as ToggleableSurfaceColors
- if (color != other.color) return false
- if (focusedColor != other.focusedColor) return false
- if (pressedColor != other.pressedColor) return false
- if (selectedColor != other.selectedColor) return false
- if (disabledColor != other.disabledColor) return false
- if (focusedSelectedColor != other.focusedSelectedColor) return false
- if (pressedSelectedColor != other.pressedSelectedColor) return false
+ if (containerColor != other.containerColor) return false
+ if (contentColor != other.contentColor) return false
+ if (focusedContainerColor != other.focusedContainerColor) return false
+ if (focusedContentColor != other.focusedContentColor) return false
+ if (pressedContainerColor != other.pressedContainerColor) return false
+ if (pressedContentColor != other.pressedContentColor) return false
+ if (selectedContainerColor != other.selectedContainerColor) return false
+ if (selectedContentColor != other.selectedContentColor) return false
+ if (disabledContainerColor != other.disabledContainerColor) return false
+ if (disabledContentColor != other.disabledContentColor) return false
+ if (focusedSelectedContainerColor != other.focusedSelectedContainerColor) return false
+ if (focusedSelectedContentColor != other.focusedSelectedContentColor) return false
+ if (pressedSelectedContainerColor != other.pressedSelectedContainerColor) return false
+ if (pressedSelectedContentColor != other.pressedSelectedContentColor) return false
return true
}
override fun hashCode(): Int {
- var result = color.hashCode()
- result = 31 * result + focusedColor.hashCode()
- result = 31 * result + pressedColor.hashCode()
- result = 31 * result + selectedColor.hashCode()
- result = 31 * result + disabledColor.hashCode()
- result = 31 * result + focusedSelectedColor.hashCode()
- result = 31 * result + pressedSelectedColor.hashCode()
-
+ var result = containerColor.hashCode()
+ result = 31 * result + contentColor.hashCode()
+ result = 31 * result + focusedContainerColor.hashCode()
+ result = 31 * result + focusedContentColor.hashCode()
+ result = 31 * result + pressedContainerColor.hashCode()
+ result = 31 * result + pressedContentColor.hashCode()
+ result = 31 * result + selectedContainerColor.hashCode()
+ result = 31 * result + selectedContentColor.hashCode()
+ result = 31 * result + disabledContainerColor.hashCode()
+ result = 31 * result + disabledContentColor.hashCode()
+ result = 31 * result + focusedSelectedContainerColor.hashCode()
+ result = 31 * result + focusedSelectedContentColor.hashCode()
+ result = 31 * result + pressedSelectedContainerColor.hashCode()
+ result = 31 * result + pressedSelectedContentColor.hashCode()
return result
}
override fun toString(): String {
- return "ToggleableSurfaceColor(color=$color, focusedColor=$focusedColor," +
- "pressedColor=$pressedColor, selectedColor=$selectedColor," +
- "disabledColor=$disabledColor, focusedSelectedColor=$focusedSelectedColor, " +
- "pressedSelectedColor=$pressedSelectedColor)"
+ return "ToggleableSurfaceColors(" +
+ "containerColor=$containerColor, " +
+ "contentColor=$contentColor, " +
+ "focusedContainerColor=$focusedContainerColor, " +
+ "focusedContentColor=$focusedContentColor, " +
+ "pressedContainerColor=$pressedContainerColor, " +
+ "pressedContentColor=$pressedContentColor, " +
+ "selectedContainerColor=$selectedContainerColor, " +
+ "selectedContentColor=$selectedContentColor, " +
+ "disabledContainerColor=$disabledContainerColor, " +
+ "disabledContentColor=$disabledContentColor, " +
+ "focusedSelectedContainerColor=$focusedSelectedContainerColor, " +
+ "focusedSelectedContentColor=$focusedSelectedContentColor, " +
+ "pressedSelectedContainerColor=$pressedSelectedContainerColor, " +
+ "pressedSelectedContentColor=$pressedSelectedContentColor)"
}
}
@@ -381,8 +430,10 @@
}
override fun toString(): String {
- return "${this.javaClass.simpleName}(border=$border, focusedBorder=$focusedBorder, " +
- "pressedBorder=$pressedBorder, disabledBorder=$disabledBorder, " +
+ return "ClickableSurfaceBorder(border=$border, " +
+ "focusedBorder=$focusedBorder, " +
+ "pressedBorder=$pressedBorder, " +
+ "disabledBorder=$disabledBorder, " +
"focusedDisabledBorder=$focusedDisabledBorder)"
}
}
@@ -533,3 +584,36 @@
"focusedSelectedGlow=$focusedSelectedGlow, pressedSelectedGlow=$pressedSelectedGlow)"
}
}
+
+/**
+ * Defines the container & content color [Color] for a non interactive surface.
+ */
+@ExperimentalTvMaterial3Api
+@Immutable
+class NonInteractiveSurfaceColors internal constructor(
+ internal val containerColor: Color,
+ internal val contentColor: Color
+) {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || this::class != other::class) return false
+
+ other as NonInteractiveSurfaceColors
+
+ if (containerColor != other.containerColor) return false
+ if (contentColor != other.contentColor) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = containerColor.hashCode()
+ result = 31 * result + contentColor.hashCode()
+ return result
+ }
+
+ override fun toString(): String {
+ return "NonInteractiveSurfaceColors(containerColor=$containerColor, " +
+ "contentColor=$contentColor)"
+ }
+}
\ No newline at end of file
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt b/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
index 936056a..d71168a 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/Switch.kt
@@ -66,6 +66,8 @@
*
* Switch can be used with a custom icon via [thumbContent] parameter
*
+ * @sample androidx.tv.samples.SwitchSample
+ *
* @param checked whether or not this switch is checked
* @param onCheckedChange called when this switch is clicked. If `null`, then this switch will not
* be interactable, unless something else handles its input events and updates its state.
diff --git a/tv/tv-material/src/main/java/androidx/tv/material3/WideButton.kt b/tv/tv-material/src/main/java/androidx/tv/material3/WideButton.kt
index 30f4d67..5e59fbc 100644
--- a/tv/tv-material/src/main/java/androidx/tv/material3/WideButton.kt
+++ b/tv/tv-material/src/main/java/androidx/tv/material3/WideButton.kt
@@ -35,7 +35,6 @@
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.semantics.Role
@@ -48,6 +47,9 @@
/**
* Material Design wide button for TV.
*
+ * Samples:
+ * @sample androidx.tv.samples.WideButtonSample
+ *
* @param onClick called when this button is clicked
* @param modifier the [Modifier] to be applied to this button
* @param enabled controls the enabled state of this button. When `false`, this component will not
@@ -111,6 +113,11 @@
/**
* Material Design wide button for TV.
*
+ * Samples:
+ * @sample androidx.tv.samples.WideButtonWithIcon
+ * @sample androidx.tv.samples.WideButtonWithSubtitle
+ * @sample androidx.tv.samples.WideButtonWithIconAndSubtitle
+ *
* @param onClick called when this button is clicked
* @param title the title content of the button, typically a [Text]
* @param modifier the [Modifier] to be applied to this button
@@ -238,8 +245,7 @@
scale = scale.toClickableSurfaceScale(),
glow = glow.toClickableSurfaceGlow(),
shape = shape.toClickableSurfaceShape(),
- color = wideButtonContainerColor(),
- contentColor = contentColor.toClickableSurfaceContentColor(),
+ colors = contentColor.toClickableSurfaceColors(),
tonalElevation = tonalElevation,
border = border.toClickableSurfaceBorder(),
interactionSource = interactionSource
@@ -273,12 +279,3 @@
}
}
}
-
-@OptIn(ExperimentalTvMaterial3Api::class)
-@Composable
-private fun wideButtonContainerColor() = ClickableSurfaceDefaults.color(
- color = Color.Transparent,
- focusedColor = Color.Transparent,
- pressedColor = Color.Transparent,
- disabledColor = Color.Transparent,
-)
diff --git a/tvprovider/tvprovider/build.gradle b/tvprovider/tvprovider/build.gradle
index 3ca9e91..4c19140 100644
--- a/tvprovider/tvprovider/build.gradle
+++ b/tvprovider/tvprovider/build.gradle
@@ -24,7 +24,7 @@
}
androidx {
- name = "Android Support TV Provider"
+ name = "TV Provider"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "Android Support Library for TV Provider"
diff --git a/vectordrawable/vectordrawable-animated/build.gradle b/vectordrawable/vectordrawable-animated/build.gradle
index 2217ba2..8fd4fa3 100644
--- a/vectordrawable/vectordrawable-animated/build.gradle
+++ b/vectordrawable/vectordrawable-animated/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "Android Support AnimatedVectorDrawable"
+ name = "AnimatedVectorDrawable"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.VECTORDRAWABLE_ANIMATED
inceptionYear = "2015"
diff --git a/vectordrawable/vectordrawable-animated/src/main/AndroidManifest.xml b/vectordrawable/vectordrawable-animated/src/main/AndroidManifest.xml
deleted file mode 100644
index 3bae3b9..0000000
--- a/vectordrawable/vectordrawable-animated/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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 />
diff --git a/vectordrawable/vectordrawable-seekable/build.gradle b/vectordrawable/vectordrawable-seekable/build.gradle
index aac1763..fa14340 100644
--- a/vectordrawable/vectordrawable-seekable/build.gradle
+++ b/vectordrawable/vectordrawable-seekable/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Android SeekableAnimatedVectorDrawable"
+ name = "SeekableAnimatedVectorDrawable"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.VECTORDRAWABLE_SEEKABLE
inceptionYear = "2020"
diff --git a/vectordrawable/vectordrawable-seekable/src/androidTest/AndroidManifest.xml b/vectordrawable/vectordrawable-seekable/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 4de3d50..0000000
--- a/vectordrawable/vectordrawable-seekable/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/vectordrawable/vectordrawable-seekable/src/main/AndroidManifest.xml b/vectordrawable/vectordrawable-seekable/src/main/AndroidManifest.xml
deleted file mode 100644
index 4de3d50..0000000
--- a/vectordrawable/vectordrawable-seekable/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2020 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 />
diff --git a/vectordrawable/vectordrawable/build.gradle b/vectordrawable/vectordrawable/build.gradle
index 9a818af..1d61639 100644
--- a/vectordrawable/vectordrawable/build.gradle
+++ b/vectordrawable/vectordrawable/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "Android Support VectorDrawable"
+ name = "VectorDrawable"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.VECTORDRAWABLE
inceptionYear = "2015"
diff --git a/vectordrawable/vectordrawable/src/main/AndroidManifest.xml b/vectordrawable/vectordrawable/src/main/AndroidManifest.xml
deleted file mode 100644
index 3bae3b9..0000000
--- a/vectordrawable/vectordrawable/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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 />
diff --git a/viewpager/viewpager/build.gradle b/viewpager/viewpager/build.gradle
index 583c085..0bf2230 100644
--- a/viewpager/viewpager/build.gradle
+++ b/viewpager/viewpager/build.gradle
@@ -21,7 +21,7 @@
}
androidx {
- name = "Android Support Library View Pager"
+ name = "ViewPager"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/viewpager/viewpager/src/main/AndroidManifest.xml b/viewpager/viewpager/src/main/AndroidManifest.xml
deleted file mode 100644
index dd3d3a3..0000000
--- a/viewpager/viewpager/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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 />
diff --git a/viewpager2/integration-tests/targetsdk-tests/src/androidTest/kotlin/androidx/viewpager2/integration/targetsdktests/OnApplyWindowInsetsListenerTest.kt b/viewpager2/integration-tests/targetsdk-tests/src/androidTest/kotlin/androidx/viewpager2/integration/targetsdktests/OnApplyWindowInsetsListenerTest.kt
index 6e8f5e1..1a6f6cb 100644
--- a/viewpager2/integration-tests/targetsdk-tests/src/androidTest/kotlin/androidx/viewpager2/integration/targetsdktests/OnApplyWindowInsetsListenerTest.kt
+++ b/viewpager2/integration-tests/targetsdk-tests/src/androidTest/kotlin/androidx/viewpager2/integration/targetsdktests/OnApplyWindowInsetsListenerTest.kt
@@ -38,14 +38,14 @@
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.WindowInsetsApplier
+import java.lang.reflect.Field
import org.hamcrest.CoreMatchers.equalTo
-import org.junit.Assert.assertNotNull
import org.hamcrest.MatcherAssert.assertThat
+import org.junit.Assert.assertNotNull
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.lang.reflect.Field
@LargeTest
@SdkSuppress(minSdkVersion = 30) // TODO(b/273945673): fix test on API 21..30
diff --git a/viewpager2/integration-tests/targetsdk-tests/src/main/AndroidManifest.xml b/viewpager2/integration-tests/targetsdk-tests/src/main/AndroidManifest.xml
deleted file mode 100644
index a270226..0000000
--- a/viewpager2/integration-tests/targetsdk-tests/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 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.
--->
-
-<manifest />
\ No newline at end of file
diff --git a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
index 04b9043..b211aef 100644
--- a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
+++ b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/BaseTest.kt
@@ -40,12 +40,12 @@
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import java.util.Locale
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.Matcher
import org.junit.After
import org.junit.Before
import org.junit.Rule
-import java.util.Locale
/**
* Base class for all tests. Contains common functionality, like finding the [ViewPager2] under
diff --git a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/FakeDragTest.kt b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/FakeDragTest.kt
index 95aee13..f94204a 100644
--- a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/FakeDragTest.kt
+++ b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/FakeDragTest.kt
@@ -42,14 +42,14 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING
+import java.lang.reflect.Field
+import kotlin.math.sign
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.lang.reflect.Field
-import kotlin.math.sign
@LargeTest
@RunWith(Parameterized::class)
diff --git a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/MarginPageTransformerTest.kt b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/MarginPageTransformerTest.kt
index aba8db8..44c7c81 100644
--- a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/MarginPageTransformerTest.kt
+++ b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/MarginPageTransformerTest.kt
@@ -30,16 +30,16 @@
import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers
+import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.closeTo
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.greaterThan
-import org.hamcrest.MatcherAssert.assertThat
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
private const val LABEL_NONE = "None"
private const val LABEL_50_PX = "Margin 50px"
diff --git a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/util/AnimationVerifier.kt b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/util/AnimationVerifier.kt
index 920657f..6884e9e 100644
--- a/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/util/AnimationVerifier.kt
+++ b/viewpager2/integration-tests/testapp/src/androidTest/java/androidx/viewpager2/integration/testapp/test/util/AnimationVerifier.kt
@@ -21,10 +21,10 @@
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.matcher.ViewMatchers.assertThat
import androidx.viewpager2.widget.ViewPager2
-import org.hamcrest.CoreMatchers.equalTo
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.math.abs
+import org.hamcrest.CoreMatchers.equalTo
/**
* Verifies if animation happened in the given [ViewPager2]. It listens to
diff --git a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/CardFragmentActivity.kt b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/CardFragmentActivity.kt
index cc02c2f..843322b 100644
--- a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/CardFragmentActivity.kt
+++ b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/CardFragmentActivity.kt
@@ -22,7 +22,6 @@
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
-
import androidx.viewpager2.integration.testapp.cards.Card
import androidx.viewpager2.integration.testapp.cards.CardView
diff --git a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/PageTransformerActivity.kt b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/PageTransformerActivity.kt
index e01899c..fe0c4ed 100644
--- a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/PageTransformerActivity.kt
+++ b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/PageTransformerActivity.kt
@@ -19,8 +19,8 @@
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.integration.testapp.cards.CardViewAdapter
-import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager2.widget.MarginPageTransformer
+import androidx.viewpager2.widget.ViewPager2
/**
* Shows examples of [ViewPager2.PageTransformer], e.g. [MarginPageTransformer].
diff --git a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/cards/CardView.kt b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/cards/CardView.kt
index a079f44..2ad388f 100644
--- a/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/cards/CardView.kt
+++ b/viewpager2/integration-tests/testapp/src/main/java/androidx/viewpager2/integration/testapp/cards/CardView.kt
@@ -20,9 +20,7 @@
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
-
import androidx.annotation.ColorRes
-
import androidx.viewpager2.integration.testapp.R
/** Inflates and populates a [View] representing a [Card] */
diff --git a/viewpager2/viewpager2/build.gradle b/viewpager2/viewpager2/build.gradle
index 7397c66..fcba271 100644
--- a/viewpager2/viewpager2/build.gradle
+++ b/viewpager2/viewpager2/build.gradle
@@ -52,7 +52,7 @@
}
androidx {
- name = "AndroidX Widget ViewPager2"
+ name = "ViewPager2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
description = "AndroidX Widget ViewPager2"
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
index afd41feb..f3ba3a4 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AccessibilityTest.kt
@@ -27,12 +27,12 @@
import androidx.testutils.LocaleTestUtils
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit
@RunWith(Parameterized::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeTest.kt
index 24b8bf3..d5f29f4 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeTest.kt
@@ -27,14 +27,14 @@
import androidx.viewpager2.widget.AdapterDataSetChangeTest.Action.ReplaceWith
import androidx.viewpager2.widget.AdapterDataSetChangeTest.TestConfig
import androidx.viewpager2.widget.swipe.ViewAdapter
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit.SECONDS
@RunWith(Parameterized::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
index 227a1f0..3f7aa14 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterDataSetChangeWhileSmoothScrollTest.kt
@@ -33,16 +33,16 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.math.roundToInt
+import kotlin.math.sign
import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.Matchers.greaterThan
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.greaterThan
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit.SECONDS
-import kotlin.math.roundToInt
-import kotlin.math.sign
/** Number of pages */
private const val pageCount = 25
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
index 45aca4c..2625d59 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/AdapterTest.kt
@@ -24,14 +24,14 @@
import androidx.viewpager2.widget.BaseTest.Context.SwipeMethod
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.CoreMatchers.nullValue
-import org.hamcrest.Matchers.greaterThan
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.greaterThan
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit.SECONDS
@LargeTest
@RunWith(AndroidJUnit4::class)
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
index 1ac998c..aaa96c9 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -62,20 +62,20 @@
import androidx.viewpager2.widget.swipe.TestActivity
import androidx.viewpager2.widget.swipe.ViewAdapter
import androidx.viewpager2.widget.swipe.WaitForInjectMotionEventsAction.Companion.waitForInjectMotionEvents
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.math.abs
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.Matcher
+import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.greaterThanOrEqualTo
import org.hamcrest.Matchers.lessThan
import org.hamcrest.Matchers.lessThanOrEqualTo
import org.junit.After
-import org.hamcrest.MatcherAssert.assertThat
+import org.junit.Assert.fail
import org.junit.Before
import org.junit.Rule
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-import kotlin.math.abs
-import org.junit.Assert.fail
open class BaseTest {
companion object {
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
index 045de41..f4df49a 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/CanScrollTest.kt
@@ -22,11 +22,11 @@
import androidx.testutils.LocaleTestUtils
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit.SECONDS
/**
* Tests [ViewPager2.canScrollHorizontally] and [ViewPager2.canScrollVertically]
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
index 1be5e31..887553a 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DisableUserInputTest.kt
@@ -28,13 +28,13 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.swipe.ViewAdapter
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.math.roundToInt
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit.SECONDS
-import kotlin.math.roundToInt
/**
* Tests what happens when a smooth scroll is interrupted by a drag
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
index 1879ee12..40f6183 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/DragWhileSmoothScrollTest.kt
@@ -30,6 +30,10 @@
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.math.ceil
+import kotlin.math.floor
+import kotlin.math.max
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.not
import org.hamcrest.MatcherAssert.assertThat
@@ -39,10 +43,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit.SECONDS
-import kotlin.math.ceil
-import kotlin.math.floor
-import kotlin.math.max
/**
* Tests what happens when a smooth scroll is interrupted by a drag
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/EditTextFocusTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/EditTextFocusTest.kt
index 882aa67..18c63e4 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/EditTextFocusTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/EditTextFocusTest.kt
@@ -34,11 +34,11 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.allOf
import org.junit.Assert.assertFalse
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit.SECONDS
/** Regression test for an issue when focusing on an EditText would cause a scroll to page 0. */
@RunWith(AndroidJUnit4::class)
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
index 79e4f0d..10dbbd5 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FakeDragTest.kt
@@ -35,16 +35,11 @@
import androidx.viewpager2.widget.FakeDragTest.TestConfig
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING as DRAGGING
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE as IDLE
+import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING as SETTLING
import androidx.viewpager2.widget.swipe.PageSwiperFakeDrag
import androidx.viewpager2.widget.swipe.PageSwiperManual
-import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.CoreMatchers.notNullValue
-import org.hamcrest.Matchers.greaterThan
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Assume.assumeThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.concurrent.CountDownLatch
@@ -53,9 +48,15 @@
import java.util.concurrent.TimeUnit.SECONDS
import kotlin.math.min
import kotlin.math.roundToInt
-import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING as DRAGGING
-import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE as IDLE
-import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING as SETTLING
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.notNullValue
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.greaterThan
+import org.junit.Assume.assumeThat
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@LargeTest
@@ -128,6 +129,7 @@
}
@Test
+ @Ignore("b/280670752")
fun test_peekNextAndMoveBack() {
// Roughly interpolates like this:
// |
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
index 3e6ff55..9d271f9 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentLifecycleTest.kt
@@ -22,13 +22,13 @@
import androidx.test.filters.LargeTest
import androidx.viewpager2.widget.ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.MILLISECONDS
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit.MILLISECONDS
private const val STATE_RESUMED = "RESUMED"
private const val STATE_STARTED = "STARTED"
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentTransactionCallbackTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentTransactionCallbackTest.kt
index 7bc0900..737b33f 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentTransactionCallbackTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/FragmentTransactionCallbackTest.kt
@@ -30,13 +30,13 @@
import androidx.viewpager2.adapter.FragmentStateAdapter.FragmentTransactionCallback
import androidx.viewpager2.adapter.FragmentStateAdapter.FragmentTransactionCallback.OnPostEventListener
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit.SECONDS
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/HostFragmentBackStackTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/HostFragmentBackStackTest.kt
index 2d17809..4ca8cf5 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/HostFragmentBackStackTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/HostFragmentBackStackTest.kt
@@ -36,11 +36,11 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.swipe.FragmentAdapter
import androidx.viewpager2.widget.swipe.PageFragment
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit.SECONDS
/**
* Regression test for an issue when recreating a [ViewPager2]'s host [Fragment]'s [View] causes
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
index ebfc7b0..ccf9bbb 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/ItemDecorationTest.kt
@@ -24,14 +24,14 @@
import androidx.test.filters.LargeTest
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.Matchers.greaterThan
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.greaterThan
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit.SECONDS
private const val operationTimeoutSeconds = 5L
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
index 6eb2463..e39d5e7 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/MutableCollectionsTest.kt
@@ -30,15 +30,15 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.swipe.PageView
import androidx.viewpager2.widget.swipe.SelfChecking
-import org.hamcrest.Matchers.equalTo
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.util.Random
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.equalTo
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
private const val RANDOM_TESTS_PER_CONFIG = 0 // increase to have random tests generated
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
index b4b3c85..2a05ec3 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/OffscreenPageLimitTest.kt
@@ -29,21 +29,21 @@
import androidx.viewpager2.widget.OffscreenPageLimitTest.TestConfig
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
-import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.CoreMatchers.hasItem
-import org.hamcrest.Matchers.greaterThanOrEqualTo
-import org.hamcrest.Matchers.lessThan
-import org.hamcrest.Matchers.lessThanOrEqualTo
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.util.concurrent.TimeUnit.SECONDS
import kotlin.math.ceil
import kotlin.math.floor
import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.hasItem
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.greaterThanOrEqualTo
+import org.hamcrest.Matchers.lessThan
+import org.hamcrest.Matchers.lessThanOrEqualTo
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class OffscreenPageLimitTest(private val config: TestConfig) : BaseTest() {
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
index 40fb085..fee2599 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PaddingMarginDecorationTest.kt
@@ -33,13 +33,13 @@
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
import androidx.viewpager2.widget.swipe.ViewAdapter
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.math.roundToInt
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit.SECONDS
-import kotlin.math.roundToInt
@RunWith(Parameterized::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
index 355402c..ec95b53 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageChangeCallbackTest.kt
@@ -40,20 +40,20 @@
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING
import androidx.viewpager2.widget.swipe.PageSwiperManual
-import org.hamcrest.CoreMatchers.equalTo
-import org.hamcrest.CoreMatchers.not
-import org.hamcrest.Matchers.allOf
-import org.hamcrest.Matchers.greaterThan
-import org.hamcrest.Matchers.greaterThanOrEqualTo
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors.newSingleThreadExecutor
import java.util.concurrent.TimeUnit.SECONDS
import kotlin.math.roundToInt
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.not
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.allOf
+import org.hamcrest.Matchers.greaterThan
+import org.hamcrest.Matchers.greaterThanOrEqualTo
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageFillTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageFillTest.kt
index adeff10..63bfb25 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageFillTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageFillTest.kt
@@ -25,8 +25,8 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
-import org.hamcrest.Matchers.containsString
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.containsString
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
index 5fbbc06..0909f67 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/PageTransformerTest.kt
@@ -30,17 +30,17 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback
import androidx.viewpager2.widget.ViewPager2.PageTransformer
+import java.util.concurrent.TimeUnit.SECONDS
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.not
+import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.greaterThan
import org.hamcrest.Matchers.lessThan
import org.junit.Assert.assertFalse
-import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.TimeUnit.SECONDS
@RunWith(Parameterized::class)
@LargeTest
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
index fc0b05d1..c505b33 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SetItemWhileScrollInProgressTest.kt
@@ -26,6 +26,7 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING
+import java.util.Random
import org.hamcrest.CoreMatchers.anyOf
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.CoreMatchers.instanceOf
@@ -36,7 +37,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.Random
private const val RANDOM_TESTS_PER_CONFIG = 0 // increase to have random tests generated
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
index d669298..0bfdab5 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/SwipeTest.kt
@@ -23,11 +23,11 @@
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_VERTICAL
import androidx.viewpager2.widget.ViewPager2.Orientation
import androidx.viewpager2.widget.swipe.PageView
+import java.util.Random
+import java.util.concurrent.TimeUnit
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.Random
-import java.util.concurrent.TimeUnit
// region test
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
index ec89330..f9e4951 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/TransientStateFragmentTest.kt
@@ -24,9 +24,9 @@
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.viewpager2.widget.ViewPager2.ORIENTATION_HORIZONTAL
+import java.util.concurrent.TimeUnit.MILLISECONDS
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit.MILLISECONDS
/**
* Verifies that [androidx.viewpager2.adapter.FragmentStateAdapter] can handle [Fragment]s
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/FragmentAdapter.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/FragmentAdapter.kt
index 6cfa14f..da365fc 100644
--- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/FragmentAdapter.kt
+++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/swipe/FragmentAdapter.kt
@@ -25,11 +25,11 @@
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.viewpager2.adapter.FragmentStateAdapter
+import java.util.concurrent.atomic.AtomicInteger
+import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.greaterThanOrEqualTo
import org.hamcrest.Matchers.lessThanOrEqualTo
-import org.hamcrest.MatcherAssert.assertThat
-import java.util.concurrent.atomic.AtomicInteger
private const val ARG_KEY = "key"
diff --git a/viewpager2/viewpager2/src/main/AndroidManifest.xml b/viewpager2/viewpager2/src/main/AndroidManifest.xml
deleted file mode 100644
index b6d5627..0000000
--- a/viewpager2/viewpager2/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2017 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 />
\ No newline at end of file
diff --git a/wear/benchmark/integration-tests/macrobenchmark/build.gradle b/wear/benchmark/integration-tests/macrobenchmark/build.gradle
index 1708504..e7fc8f1 100644
--- a/wear/benchmark/integration-tests/macrobenchmark/build.gradle
+++ b/wear/benchmark/integration-tests/macrobenchmark/build.gradle
@@ -16,7 +16,7 @@
plugins {
id("AndroidXPlugin")
- id 'com.android.library'
+ id 'com.android.test'
id 'kotlin-android'
}
@@ -25,25 +25,22 @@
minSdkVersion 29
}
namespace "androidx.wear.benchmark.integration.macrobenchmark"
+ targetProjectPath = ":wear:benchmark:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":wear:benchmark:integration-tests:macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":wear:benchmark:integration-tests:macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":benchmark:benchmark-junit4"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
}
diff --git a/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/wear/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index f734545..0000000
--- a/wear/benchmark/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
\ No newline at end of file
diff --git a/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/ScrollBenchmark.kt b/wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/ScrollBenchmark.kt
similarity index 100%
rename from wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/ScrollBenchmark.kt
rename to wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/ScrollBenchmark.kt
diff --git a/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/StartupBenchmark.kt b/wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/StartupBenchmark.kt
similarity index 100%
rename from wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/StartupBenchmark.kt
rename to wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/StartupBenchmark.kt
diff --git a/wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/SwipeBenchmark.kt b/wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/SwipeBenchmark.kt
similarity index 100%
rename from wear/benchmark/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/benchmark/integration/macrobenchmark/SwipeBenchmark.kt
rename to wear/benchmark/integration-tests/macrobenchmark/src/main/java/androidx/wear/benchmark/integration/macrobenchmark/SwipeBenchmark.kt
diff --git a/wear/compose/compose-foundation/benchmark/src/androidTest/AndroidManifest.xml b/wear/compose/compose-foundation/benchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 39f7fc3..0000000
--- a/wear/compose/compose-foundation/benchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
\ No newline at end of file
diff --git a/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyColumnTest.kt b/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyColumnTest.kt
index bee6208..a13ef30 100644
--- a/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyColumnTest.kt
+++ b/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyColumnTest.kt
@@ -52,13 +52,13 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import androidx.wear.compose.foundation.TEST_TAG
+import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
+import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
-import kotlin.math.roundToInt
-import kotlinx.coroutines.runBlocking
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyListLayoutInfoTest.kt b/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyListLayoutInfoTest.kt
index 9f42158..1b894ff 100644
--- a/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyListLayoutInfoTest.kt
+++ b/wear/compose/compose-foundation/src/androidAndroidTest/kotlin/androidx/wear/compose/foundation/lazy/ScalingLazyListLayoutInfoTest.kt
@@ -41,6 +41,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@@ -48,7 +49,6 @@
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
@MediumTest
@RunWith(AndroidJUnit4::class)
diff --git a/wear/compose/compose-foundation/src/androidMain/AndroidManifest.xml b/wear/compose/compose-foundation/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/compose-foundation/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/compose-foundation/src/androidMain/kotlin/androidx/wear/compose/foundation/CurvedTextDelegate.android.kt b/wear/compose/compose-foundation/src/androidMain/kotlin/androidx/wear/compose/foundation/CurvedTextDelegate.android.kt
index d781ba1..fcc21e2 100644
--- a/wear/compose/compose-foundation/src/androidMain/kotlin/androidx/wear/compose/foundation/CurvedTextDelegate.android.kt
+++ b/wear/compose/compose-foundation/src/androidMain/kotlin/androidx/wear/compose/foundation/CurvedTextDelegate.android.kt
@@ -24,6 +24,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -50,8 +51,8 @@
private var clockwise: Boolean = true
private var fontSizePx: Float = 0f
- actual var textWidth by mutableStateOf(0f)
- actual var textHeight by mutableStateOf(0f)
+ actual var textWidth by mutableFloatStateOf(0f)
+ actual var textHeight by mutableFloatStateOf(0f)
actual var baseLinePosition = 0f
private var typeFace: State<Typeface?> = mutableStateOf(null)
diff --git a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeToReveal.kt b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeToReveal.kt
index 50764ab..724c367 100644
--- a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeToReveal.kt
+++ b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeToReveal.kt
@@ -32,7 +32,7 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -360,7 +360,7 @@
/**
* The total width of the overlay content in float.
*/
- val width = mutableStateOf(0.0f)
+ val width = mutableFloatStateOf(0.0f)
override val revealOffset: Float
get() = width.value * (revealState.swipeAnchors[RevealValue.Revealing] ?: 0.0f)
diff --git a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeableV2.kt b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeableV2.kt
index 788ff21..273c59b 100644
--- a/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeableV2.kt
+++ b/wear/compose/compose-foundation/src/commonMain/kotlin/androidx/wear/compose/foundation/SwipeableV2.kt
@@ -32,6 +32,7 @@
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
@@ -273,7 +274,7 @@
* You can use this value to provide smooth reconciliation behavior when re-targeting an
* animation.
*/
- var lastVelocity: Float by mutableStateOf(0f)
+ var lastVelocity: Float by mutableFloatStateOf(0f)
private set
/**
diff --git a/wear/compose/compose-foundation/src/test/kotlin/androidx/wear/compose/foundation/CurvedTextStyleTest.kt b/wear/compose/compose-foundation/src/test/kotlin/androidx/wear/compose/foundation/CurvedTextStyleTest.kt
index 53d704d..3c9dab3 100644
--- a/wear/compose/compose-foundation/src/test/kotlin/androidx/wear/compose/foundation/CurvedTextStyleTest.kt
+++ b/wear/compose/compose-foundation/src/test/kotlin/androidx/wear/compose/foundation/CurvedTextStyleTest.kt
@@ -25,8 +25,8 @@
import androidx.compose.ui.unit.isUnspecified
import androidx.compose.ui.unit.sp
import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
import org.junit.Assert.assertNull
+import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
diff --git a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
index 81ec14c..756d558 100644
--- a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
+++ b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/ChipTest.kt
@@ -32,14 +32,14 @@
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.State
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.testTag
diff --git a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/IconTest.kt b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/IconTest.kt
index ce31b5d..1c76ba7 100644
--- a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/IconTest.kt
+++ b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/IconTest.kt
@@ -29,8 +29,8 @@
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
-import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
diff --git a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/TextTest.kt b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/TextTest.kt
index 7215c15..d1c8fad 100644
--- a/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/TextTest.kt
+++ b/wear/compose/compose-material-core/src/androidAndroidTest/kotlin/androidx/wear/compose/materialcore/TextTest.kt
@@ -43,10 +43,10 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
+import java.lang.IllegalArgumentException
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.IllegalArgumentException
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/wear/compose/compose-material-core/src/androidMain/AndroidManifest.xml b/wear/compose/compose-material-core/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/compose-material-core/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/compose-material-core/src/commonMain/kotlin/androidx/wear/compose/materialcore/Card.kt b/wear/compose/compose-material-core/src/commonMain/kotlin/androidx/wear/compose/materialcore/Card.kt
new file mode 100644
index 0000000..7994fe3
--- /dev/null
+++ b/wear/compose/compose-material-core/src/commonMain/kotlin/androidx/wear/compose/materialcore/Card.kt
@@ -0,0 +1,312 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.compose.materialcore
+
+import androidx.annotation.RestrictTo
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.ripple.rememberRipple
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.paint
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.unit.dp
+
+/**
+ * Base level Wear Material [Card] that offers a single slot to take any content.
+ *
+ * Is used as the container for more opinionated [Card] components that take specific content such
+ * as icons, images, titles, subtitles and labels.
+ *
+ * Cards can be enabled or disabled. A disabled card will not respond to click events.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * Wear OS Material design guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param modifier Modifier to be applied to the card
+ * @param border A BorderStroke object which is used for the outline drawing.
+ * Can be null - then outline will not be drawn
+ * @param containerPainter A painter used to paint the background of the card. A card will
+ * normally have a gradient background. Use [CardDefaults.cardBackgroundPainter()] to obtain an
+ * appropriate painter
+ * @param containerPainter A Painter which is used for background drawing.
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param role The type of user interface element. Accessibility services might use this
+ * to describe the element or do customizations
+ * @param content A main slot for a content of this card
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@Composable
+public fun Card(
+ onClick: () -> Unit,
+ modifier: Modifier,
+ border: BorderStroke?,
+ containerPainter: Painter,
+ enabled: Boolean,
+ contentPadding: PaddingValues,
+ shape: Shape,
+ interactionSource: MutableInteractionSource,
+ role: Role?,
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ Column(
+ modifier = modifier
+ .fillMaxWidth()
+ .height(IntrinsicSize.Min)
+ .clip(shape = shape)
+ .paint(
+ painter = containerPainter,
+ contentScale = ContentScale.Crop
+ )
+ .clickable(
+ enabled = enabled,
+ onClick = onClick,
+ role = role,
+ indication = rememberRipple(),
+ interactionSource = interactionSource,
+ )
+ .then(
+ border?.let { Modifier.border(border = border, shape = shape) } ?: Modifier
+ )
+ .padding(contentPadding),
+ content = content
+ )
+}
+
+/**
+ * Opinionated Wear Material [Card] that offers a specific 5 slot layout to show information about
+ * an application, e.g. a notification. AppCards are designed to show interactive elements from
+ * multiple applications. They will typically be used by the system UI, e.g. for showing a list of
+ * notifications from different applications. However it could also be adapted by individual
+ * application developers to show information about different parts of their application.
+ *
+ * The first row of the layout has three slots, 1) a small optional application [Image] or [Icon],
+ * 2) an application name, it is expected to be a short start-aligned [Text] composable,
+ * and 3) the optional time that the application activity has occurred which will be
+ * shown on the top row of the card, this is expected to be an end aligned [Text] composable
+ * showing a time relevant to the contents of the [Card].
+ *
+ * The second row shows a title, this is expected to be a single row of start aligned [Text].
+ *
+ * The rest of the [Card] contains the content which can be either [Text] or an [Image].
+ * If the content is text it can be single or multiple line and is expected to be Top and Start
+ * aligned.
+ *
+ * If more than one composable is provided in the content slot it is the responsibility of the
+ * caller to determine how to layout the contents, e.g. provide either a row or a column.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param border A BorderStroke object which is used for the outline drawing.
+ * Can be null - then outline will not be drawn
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param containerPainter A Painter which is used for background drawing.
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param appImage A slot for a small [Image] associated with the application.
+ * @param appName A slot for displaying the application name, expected to be a single line of start
+ * aligned text.
+ * @param time A slot for displaying the time relevant to the contents of the card, expected to be a
+ * short piece of end aligned text.
+ * @param title A slot for displaying the title of the card, expected to be one or two lines of
+ * start aligned text.
+ * @param content A main slot for a content of this card
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@Composable
+public fun AppCard(
+ onClick: () -> Unit,
+ modifier: Modifier,
+ enabled: Boolean,
+ border: BorderStroke?,
+ contentPadding: PaddingValues,
+ containerPainter: Painter,
+ interactionSource: MutableInteractionSource,
+ shape: Shape,
+ appImage: @Composable (RowScope.() -> Unit)?,
+ appName: @Composable RowScope.() -> Unit,
+ time: @Composable (RowScope.() -> Unit)?,
+ title: @Composable RowScope.() -> Unit,
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ Card(
+ onClick = onClick,
+ modifier = modifier,
+ enabled = enabled,
+ containerPainter = containerPainter,
+ border = border,
+ contentPadding = contentPadding,
+ interactionSource = interactionSource,
+ role = null,
+ shape = shape
+ ) {
+ Column {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ appImage?.let {
+ appImage()
+ Spacer(Modifier.width(6.dp))
+ }
+ appName()
+ Spacer(modifier = Modifier.weight(1.0f))
+
+ time?.let {
+ time()
+ }
+ }
+ Spacer(modifier = Modifier.height(4.dp))
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ content = title
+ )
+ content()
+ }
+ }
+}
+
+/**
+ * Opinionated Wear Material [Card] that offers a specific 3 slot layout to show interactive
+ * information about an application, e.g. a message. TitleCards are designed for use within an
+ * application.
+ *
+ * The first row of the layout has two slots. 1. a start aligned title. The title text is
+ * expected to be a maximum of 2 lines of text.
+ * 2. An optional time that the application activity has occurred shown at the
+ * end of the row, expected to be an end aligned [Text] composable showing a time relevant to the
+ * contents of the [Card].
+ *
+ * The rest of the [Card] contains the content which is expected to be [Text] or a contained
+ * [Image].
+ *
+ * If the content is text it can be single or multiple line and is expected to be Top and Start
+ * aligned.
+ *
+ * Overall the [title] and [content] text should be no more than 5 rows of text combined.
+ *
+ * If more than one composable is provided in the content slot it is the responsibility of the
+ * caller to determine how to layout the contents, e.g. provide either a row or a column.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param border A BorderStroke object which is used for the outline drawing.
+ * Can be null - then outline will not be drawn
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param containerPainter A Painter which is used for background drawing.
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param title A slot for displaying the title of the card, expected to be one or two
+ * lines of text.
+ * @param time An optional slot for displaying the time relevant to the contents of the card,
+ * expected to be a short piece of end aligned text.
+ * @param content A main slot for a content of this card.
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+@Composable
+public fun TitleCard(
+ onClick: () -> Unit,
+ modifier: Modifier,
+ enabled: Boolean,
+ border: BorderStroke?,
+ contentPadding: PaddingValues,
+ containerPainter: Painter,
+ interactionSource: MutableInteractionSource,
+ shape: Shape,
+ title: @Composable RowScope.() -> Unit,
+ time: @Composable (RowScope.() -> Unit)?,
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ Card(
+ onClick = onClick,
+ modifier = modifier,
+ enabled = enabled,
+ containerPainter = containerPainter,
+ border = border,
+ contentPadding = contentPadding,
+ interactionSource = interactionSource,
+ role = null,
+ shape = shape
+ ) {
+ Column {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ title()
+ time?.let {
+ Spacer(modifier = Modifier.weight(1.0f))
+ time()
+ }
+ }
+ content()
+ }
+ }
+}
diff --git a/wear/compose/compose-material/benchmark/src/androidTest/AndroidManifest.xml b/wear/compose/compose-material/benchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 39f7fc3..0000000
--- a/wear/compose/compose-material/benchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
\ No newline at end of file
diff --git a/wear/compose/compose-material/samples/src/androidTest/AndroidManifest.xml b/wear/compose/compose-material/samples/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 8e90956..0000000
--- a/wear/compose/compose-material/samples/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
- -->
-<manifest />
diff --git a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CircularProgressIndicatorSample.kt b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CircularProgressIndicatorSample.kt
index ac90813..e70e08c 100644
--- a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CircularProgressIndicatorSample.kt
+++ b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CircularProgressIndicatorSample.kt
@@ -32,8 +32,8 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
-import androidx.wear.compose.material.CompactChip
import androidx.wear.compose.material.CircularProgressIndicator
+import androidx.wear.compose.material.CompactChip
import androidx.wear.compose.material.ProgressIndicatorDefaults
import androidx.wear.compose.material.Text
diff --git a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CurvedTextSample.kt b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CurvedTextSample.kt
index 653eab7..aff1014 100644
--- a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CurvedTextSample.kt
+++ b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/CurvedTextSample.kt
@@ -33,11 +33,11 @@
import androidx.wear.compose.foundation.curvedColumn
import androidx.wear.compose.foundation.curvedRow
import androidx.wear.compose.foundation.padding
-import androidx.wear.compose.material.curvedText
import androidx.wear.compose.material.LocalContentAlpha
import androidx.wear.compose.material.LocalContentColor
import androidx.wear.compose.material.LocalTextStyle
import androidx.wear.compose.material.ProvideTextStyle
+import androidx.wear.compose.material.curvedText
@Sampled
@Composable
diff --git a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/ScaffoldSample.kt b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/ScaffoldSample.kt
index 9aa2006..92c9d1f 100644
--- a/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/ScaffoldSample.kt
+++ b/wear/compose/compose-material/samples/src/main/java/androidx/wear/compose/material/samples/ScaffoldSample.kt
@@ -24,16 +24,16 @@
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.TimeText
import androidx.wear.compose.material.Vignette
import androidx.wear.compose.material.VignettePosition
-import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
@SuppressLint("UnrememberedMutableState")
@Sampled
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
index c0dfbe8..d2b7da4 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ChipTest.kt
@@ -31,8 +31,8 @@
import androidx.compose.testutils.assertShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.testTag
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/IconTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/IconTest.kt
index 0f1d9c4..50d241b 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/IconTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/IconTest.kt
@@ -26,8 +26,8 @@
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
-import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.BitmapPainter
+import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PlaceholderTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PlaceholderTest.kt
index 37e074b..913b5b1 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PlaceholderTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PlaceholderTest.kt
@@ -34,10 +34,10 @@
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.Dp
-import org.junit.Rule
-import org.junit.Test
import com.google.common.truth.Truth.assertThat
import kotlin.math.max
+import org.junit.Rule
+import org.junit.Test
class PlaceholderTest {
@get:Rule
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PositionIndicatorTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PositionIndicatorTest.kt
index 246fd6a..586cb58 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PositionIndicatorTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/PositionIndicatorTest.kt
@@ -16,13 +16,6 @@
package androidx.wear.compose.material
-import androidx.wear.compose.foundation.lazy.ScalingLazyListLayoutInfo as ScalingLazyListLayoutInfo
-import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
-import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState as rememberScalingLazyListState
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults as ScalingLazyColumnDefaults
-import androidx.wear.compose.foundation.lazy.AutoCenteringParams as AutoCenteringParams
-import androidx.wear.compose.foundation.lazy.ScalingLazyListScope as ScalingLazyListScope
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
@@ -55,6 +48,13 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.wear.compose.foundation.lazy.AutoCenteringParams as AutoCenteringParams
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults as ScalingLazyColumnDefaults
+import androidx.wear.compose.foundation.lazy.ScalingLazyListLayoutInfo as ScalingLazyListLayoutInfo
+import androidx.wear.compose.foundation.lazy.ScalingLazyListScope as ScalingLazyListScope
+import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
+import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState as rememberScalingLazyListState
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.runBlocking
import org.junit.Before
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
index a0ef0e1..d5dfb4c 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyColumnTest.kt
@@ -49,13 +49,13 @@
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
+import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
-import kotlin.math.roundToInt
-import kotlinx.coroutines.runBlocking
@Suppress("DEPRECATION")
@MediumTest
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyListLayoutInfoTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyListLayoutInfoTest.kt
index 82dcfc3..7a88093 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyListLayoutInfoTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/ScalingLazyListLayoutInfoTest.kt
@@ -40,15 +40,15 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
+import kotlin.math.roundToInt
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import kotlin.math.roundToInt
-import org.junit.Ignore
@Suppress("DEPRECATION")
@MediumTest
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeToDismissBoxTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeToDismissBoxTest.kt
index d5bd277..da64262 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeToDismissBoxTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/SwipeToDismissBoxTest.kt
@@ -47,9 +47,9 @@
import androidx.compose.ui.test.swipe
import androidx.compose.ui.test.swipeLeft
import androidx.compose.ui.test.swipeRight
+import com.google.common.truth.Truth.assertThat
import java.lang.Math.sin
import org.junit.Assert.assertEquals
-import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
diff --git a/wear/compose/compose-material/src/androidMain/AndroidManifest.xml b/wear/compose/compose-material/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/compose-material/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/DefaultTimeSource.kt b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/DefaultTimeSource.kt
index 5f3393d..9ee204f 100644
--- a/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/DefaultTimeSource.kt
+++ b/wear/compose/compose-material/src/androidMain/kotlin/androidx/wear/compose/material/DefaultTimeSource.kt
@@ -27,6 +27,7 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
@@ -50,7 +51,7 @@
): State<String> {
var calendar by remember { mutableStateOf(Calendar.getInstance()) }
- var currentTime by remember { mutableStateOf(time()) }
+ var currentTime by remember { mutableLongStateOf(time()) }
val timeText = remember {
derivedStateOf { formatTime(calendar, currentTime, timeFormat) }
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Card.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Card.kt
index 596a2f2..2b09353 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Card.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Card.kt
@@ -17,29 +17,18 @@
package androidx.wear.compose.material
import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.Interaction
import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
-import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
-import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.draw.paint
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Brush
@@ -53,7 +42,6 @@
import androidx.compose.ui.graphics.painter.BrushPainter
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.Painter
-import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.Dp
@@ -113,23 +101,16 @@
role: Role? = null,
content: @Composable ColumnScope.() -> Unit,
) {
- Column(
- modifier = modifier
- .fillMaxWidth()
- .height(IntrinsicSize.Min)
- .clip(shape = shape)
- .paint(
- painter = backgroundPainter,
- contentScale = ContentScale.Crop
- )
- .clickable(
- enabled = enabled,
- onClick = onClick,
- role = role,
- indication = rememberRipple(),
- interactionSource = interactionSource,
- )
- .padding(contentPadding)
+ androidx.wear.compose.materialcore.Card(
+ onClick = onClick,
+ modifier = modifier,
+ border = null,
+ containerPainter = backgroundPainter,
+ enabled = enabled,
+ contentPadding = contentPadding,
+ shape = shape,
+ interactionSource = interactionSource,
+ role = role,
) {
CompositionLocalProvider(
LocalContentColor provides contentColor,
@@ -208,53 +189,46 @@
titleColor: Color = MaterialTheme.colors.onSurface,
content: @Composable ColumnScope.() -> Unit,
) {
- Card(
+ androidx.wear.compose.materialcore.AppCard(
onClick = onClick,
modifier = modifier,
- backgroundPainter = backgroundPainter,
enabled = enabled,
- ) {
- Column {
- Row(
- modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically
- ) {
- CompositionLocalProvider(
- LocalTextStyle provides MaterialTheme.typography.caption1
- ) {
- if (appImage != null) {
- appImage()
- Spacer(modifier = Modifier.width(6.dp))
- }
- CompositionLocalProvider(
- LocalContentColor provides appColor,
- ) {
- appName()
- }
- }
- Spacer(modifier = Modifier.weight(1.0f))
- CompositionLocalProvider(
- LocalContentColor provides timeColor,
- LocalTextStyle provides MaterialTheme.typography.caption1,
- ) {
- time()
- }
- }
- Spacer(modifier = Modifier.height(4.dp))
- Row {
- CompositionLocalProvider(
- LocalContentColor provides titleColor,
- LocalTextStyle provides MaterialTheme.typography.title3,
- ) {
- title()
- }
- }
+ border = null,
+ contentPadding = CardDefaults.ContentPadding,
+ containerPainter = backgroundPainter,
+ interactionSource = remember { MutableInteractionSource() },
+ shape = MaterialTheme.shapes.large,
+ appImage = appImage?.let { { appImage() } },
+ appName = {
CompositionLocalProvider(
- LocalContentColor provides contentColor,
- LocalTextStyle provides MaterialTheme.typography.body1,
+ LocalContentColor provides appColor,
+ LocalTextStyle provides MaterialTheme.typography.caption1
) {
- content()
+ appName()
}
+ },
+ time = {
+ CompositionLocalProvider(
+ LocalContentColor provides timeColor,
+ LocalTextStyle provides MaterialTheme.typography.caption1,
+ ) {
+ time()
+ }
+ },
+ title = {
+ CompositionLocalProvider(
+ LocalContentColor provides titleColor,
+ LocalTextStyle provides MaterialTheme.typography.title3
+ ) {
+ title()
+ }
+ }
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides contentColor,
+ LocalTextStyle provides MaterialTheme.typography.body1,
+ ) {
+ content()
}
}
}
@@ -321,33 +295,35 @@
timeColor: Color = contentColor,
content: @Composable ColumnScope.() -> Unit,
) {
- Card(
+ androidx.wear.compose.materialcore.TitleCard(
onClick = onClick,
modifier = modifier,
- backgroundPainter = backgroundPainter,
enabled = enabled,
- ) {
- Column {
- Row(
- modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically
+ border = null,
+ contentPadding = CardDefaults.ContentPadding,
+ containerPainter = backgroundPainter,
+ interactionSource = remember { MutableInteractionSource() },
+ shape = MaterialTheme.shapes.large,
+ title = {
+ CompositionLocalProvider(
+ LocalContentColor provides titleColor,
+ LocalTextStyle provides MaterialTheme.typography.title3,
) {
+ title()
+ }
+ },
+ time = {
+ time?.let {
+ Spacer(modifier = Modifier.weight(1.0f))
CompositionLocalProvider(
- LocalContentColor provides titleColor,
- LocalTextStyle provides MaterialTheme.typography.title3,
+ LocalContentColor provides timeColor,
+ LocalTextStyle provides MaterialTheme.typography.caption1,
) {
- title()
- }
- if (time != null) {
- Spacer(modifier = Modifier.weight(1.0f))
- CompositionLocalProvider(
- LocalContentColor provides timeColor,
- LocalTextStyle provides MaterialTheme.typography.caption1,
- ) {
- time()
- }
+ time()
}
}
+ },
+ content = {
Spacer(modifier = Modifier.height(2.dp))
CompositionLocalProvider(
LocalContentColor provides contentColor,
@@ -356,7 +332,7 @@
content()
}
}
- }
+ )
}
/**
@@ -387,12 +363,14 @@
.compositeOver(MaterialTheme.colors.background),
gradientDirection: LayoutDirection = LocalLayoutDirection.current
): Painter {
- return BrushPainter(FortyFiveDegreeLinearGradient(
- colors = listOf(
- startBackgroundColor,
- endBackgroundColor
- ),
- ltr = gradientDirection == LayoutDirection.Ltr)
+ return BrushPainter(
+ FortyFiveDegreeLinearGradient(
+ colors = listOf(
+ startBackgroundColor,
+ endBackgroundColor
+ ),
+ ltr = gradientDirection == LayoutDirection.Ltr
+ )
)
}
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/MaterialTextSelectionColors.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/MaterialTextSelectionColors.kt
index 2838258..fe1151e 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/MaterialTextSelectionColors.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/MaterialTextSelectionColors.kt
@@ -15,13 +15,13 @@
*/
package androidx.wear.compose.material
+import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.graphics.takeOrElse
-import androidx.compose.foundation.text.selection.TextSelectionColors
import kotlin.math.max
import kotlin.math.min
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Picker.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Picker.kt
index 963051d..2aaa04b 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Picker.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Picker.kt
@@ -15,11 +15,6 @@
*/
package androidx.wear.compose.material
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
-import androidx.wear.compose.foundation.lazy.ScalingParams as ScalingParams
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults as ScalingLazyColumnDefaults
-import androidx.wear.compose.foundation.lazy.AutoCenteringParams as AutoCenteringParams
-import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.DecayAnimationSpec
import androidx.compose.animation.core.Easing
@@ -38,6 +33,7 @@
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -63,6 +59,11 @@
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.wear.compose.foundation.lazy.AutoCenteringParams as AutoCenteringParams
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumnDefaults as ScalingLazyColumnDefaults
+import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
+import androidx.wear.compose.foundation.lazy.ScalingParams as ScalingParams
import kotlinx.coroutines.launch
/**
@@ -486,7 +487,7 @@
verifyNumberOfOptions(initialNumberOfOptions)
}
- private var _numberOfOptions by mutableStateOf(initialNumberOfOptions)
+ private var _numberOfOptions by mutableIntStateOf(initialNumberOfOptions)
var numberOfOptions
get() = _numberOfOptions
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
index d31497f..8588ee8 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PickerGroup.kt
@@ -16,16 +16,16 @@
package androidx.wear.compose.material
+import androidx.compose.foundation.focusable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@@ -199,7 +199,7 @@
/**
* The current selected [Picker] index.
*/
- var selectedIndex by mutableStateOf(initiallySelectedIndex)
+ var selectedIndex by mutableIntStateOf(initiallySelectedIndex)
public companion object {
val Saver = listSaver<PickerGroupState, Any?>(
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
index 2daae1d..74be61a 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/PositionIndicator.kt
@@ -16,10 +16,6 @@
package androidx.wear.compose.material
-import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
-import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
-import androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo as ScalingLazyListItemInfo
-import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType as ScalingLazyListAnchorType
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.AnimationVector
@@ -74,6 +70,10 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
+import androidx.wear.compose.foundation.lazy.ScalingLazyColumn as ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.ScalingLazyListAnchorType as ScalingLazyListAnchorType
+import androidx.wear.compose.foundation.lazy.ScalingLazyListItemInfo as ScalingLazyListItemInfo
+import androidx.wear.compose.foundation.lazy.ScalingLazyListState as ScalingLazyListState
import kotlin.math.PI
import kotlin.math.asin
import kotlin.math.max
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ProgressIndicator.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ProgressIndicator.kt
index e784c13..9a1ffd1 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ProgressIndicator.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ProgressIndicator.kt
@@ -29,8 +29,8 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.ProgressIndicatorDefaults.BaseRotationAngle
-import androidx.wear.compose.material.ProgressIndicatorDefaults.CircularEasing
import androidx.wear.compose.material.ProgressIndicatorDefaults.ButtonCircularIndicatorDiameter
+import androidx.wear.compose.material.ProgressIndicatorDefaults.CircularEasing
import androidx.wear.compose.material.ProgressIndicatorDefaults.HeadAndTailAnimationDuration
import androidx.wear.compose.material.ProgressIndicatorDefaults.HeadAndTailDelayDuration
import androidx.wear.compose.material.ProgressIndicatorDefaults.IndeterminateCircularIndicatorDiameter
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScrollAway.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScrollAway.kt
index d577f3e..c15fd01 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScrollAway.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ScrollAway.kt
@@ -31,8 +31,8 @@
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
-import androidx.wear.compose.foundation.lazy.ScalingLazyListState
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
+import androidx.wear.compose.foundation.lazy.ScalingLazyListState
/**
* Scroll an item vertically in/out of view based on a [ScrollState].
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
index ed29bf9..5430358 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/SwipeToDismissBox.kt
@@ -32,6 +32,7 @@
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -108,7 +109,7 @@
) {
// Will be updated in onSizeChanged, initialise to any value other than zero
// so that it is different to the other anchor used for the swipe gesture.
- var maxWidth by remember { mutableStateOf(1f) }
+ var maxWidth by remember { mutableFloatStateOf(1f) }
Box(
modifier = modifier
.fillMaxSize()
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
index 52ed98b..9a6fda0 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Swipeable.kt
@@ -203,7 +203,7 @@
internal var thresholds: (Float, Float) -> Float by mutableStateOf({ _, _ -> 0f })
- internal var velocityThreshold by mutableStateOf(0f)
+ internal var velocityThreshold by mutableFloatStateOf(0f)
internal var resistance: ResistanceConfig? by mutableStateOf(null)
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ToggleControl.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ToggleControl.kt
index d129aba..88c3b0de 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ToggleControl.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/ToggleControl.kt
@@ -17,10 +17,10 @@
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.AnimationSpec
-import androidx.compose.animation.core.animateFloat
-import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.core.Transition
+import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.tween
+import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.Indication
import androidx.compose.foundation.interaction.Interaction
@@ -33,8 +33,8 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
-import androidx.compose.runtime.remember
import androidx.compose.runtime.State
+import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
@@ -42,12 +42,12 @@
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.drawscope.DrawScope
-import androidx.compose.ui.graphics.drawscope.Fill
-import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.lerp
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/TouchExplorationStateProvider.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/TouchExplorationStateProvider.kt
index e8a261e..564b2df 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/TouchExplorationStateProvider.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/TouchExplorationStateProvider.kt
@@ -25,9 +25,9 @@
import androidx.compose.runtime.State
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
diff --git a/wear/compose/compose-material3/api/current.txt b/wear/compose/compose-material3/api/current.txt
index cf3b196..ffc5824 100644
--- a/wear/compose/compose-material3/api/current.txt
+++ b/wear/compose/compose-material3/api/current.txt
@@ -2,6 +2,8 @@
package androidx.wear.compose.material3 {
@androidx.compose.runtime.Immutable public final class ButtonColors {
+ ctor public ButtonColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long secondaryContentColor, long iconColor, androidx.compose.ui.graphics.painter.Painter disabledContainerPainter, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
+ ctor public ButtonColors(long containerColor, long contentColor, long secondaryContentColor, long iconColor, long disabledContainerColor, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
}
public final class ButtonDefaults {
@@ -22,14 +24,38 @@
}
public final class ButtonKt {
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ }
+
+ @androidx.compose.runtime.Immutable public final class CardColors {
+ ctor public CardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long appNameColor, long timeColor, long titleColor);
+ }
+
+ public final class CardDefaults {
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method public float getAppImageSize();
+ method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors imageCardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.painter.Painter imageWithScrimBackgroundPainter(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional long outlineColor, optional float borderWidth);
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors outlinedCardColors(optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ property public final float AppImageSize;
+ property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+ field public static final androidx.wear.compose.material3.CardDefaults INSTANCE;
+ }
+
+ public final class CardKt {
+ method @androidx.compose.runtime.Composable public static void AppCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> appName, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? appImage, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void TitleCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
@androidx.compose.runtime.Stable public final class ColorScheme {
@@ -116,6 +142,7 @@
}
@androidx.compose.runtime.Immutable public final class IconButtonColors {
+ ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
}
public final class IconButtonDefaults {
diff --git a/wear/compose/compose-material3/api/public_plus_experimental_current.txt b/wear/compose/compose-material3/api/public_plus_experimental_current.txt
index a23926c..bbe675a 100644
--- a/wear/compose/compose-material3/api/public_plus_experimental_current.txt
+++ b/wear/compose/compose-material3/api/public_plus_experimental_current.txt
@@ -2,6 +2,8 @@
package androidx.wear.compose.material3 {
@androidx.compose.runtime.Immutable public final class ButtonColors {
+ ctor public ButtonColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long secondaryContentColor, long iconColor, androidx.compose.ui.graphics.painter.Painter disabledContainerPainter, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
+ ctor public ButtonColors(long containerColor, long contentColor, long secondaryContentColor, long iconColor, long disabledContainerColor, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
}
public final class ButtonDefaults {
@@ -22,14 +24,38 @@
}
public final class ButtonKt {
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ }
+
+ @androidx.compose.runtime.Immutable public final class CardColors {
+ ctor public CardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long appNameColor, long timeColor, long titleColor);
+ }
+
+ public final class CardDefaults {
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method public float getAppImageSize();
+ method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors imageCardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.painter.Painter imageWithScrimBackgroundPainter(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional long outlineColor, optional float borderWidth);
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors outlinedCardColors(optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ property public final float AppImageSize;
+ property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+ field public static final androidx.wear.compose.material3.CardDefaults INSTANCE;
+ }
+
+ public final class CardKt {
+ method @androidx.compose.runtime.Composable public static void AppCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> appName, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? appImage, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void TitleCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
@androidx.compose.runtime.Stable public final class ColorScheme {
@@ -119,6 +145,7 @@
}
@androidx.compose.runtime.Immutable public final class IconButtonColors {
+ ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
}
public final class IconButtonDefaults {
diff --git a/wear/compose/compose-material3/api/restricted_current.txt b/wear/compose/compose-material3/api/restricted_current.txt
index cf3b196..ffc5824 100644
--- a/wear/compose/compose-material3/api/restricted_current.txt
+++ b/wear/compose/compose-material3/api/restricted_current.txt
@@ -2,6 +2,8 @@
package androidx.wear.compose.material3 {
@androidx.compose.runtime.Immutable public final class ButtonColors {
+ ctor public ButtonColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long secondaryContentColor, long iconColor, androidx.compose.ui.graphics.painter.Painter disabledContainerPainter, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
+ ctor public ButtonColors(long containerColor, long contentColor, long secondaryContentColor, long iconColor, long disabledContainerColor, long disabledContentColor, long disabledSecondaryContentColor, long disabledIconColor);
}
public final class ButtonDefaults {
@@ -22,14 +24,38 @@
}
public final class ButtonKt {
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
- method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional androidx.compose.ui.semantics.Role? role);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void ChildButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void FilledTonalButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? secondaryLabel, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.BoxScope,kotlin.Unit>? icon, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.ButtonColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> label);
+ }
+
+ @androidx.compose.runtime.Immutable public final class CardColors {
+ ctor public CardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, long contentColor, long appNameColor, long timeColor, long titleColor);
+ }
+
+ public final class CardDefaults {
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors cardColors(optional long containerColor, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method public float getAppImageSize();
+ method public androidx.compose.foundation.layout.PaddingValues getContentPadding();
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors imageCardColors(androidx.compose.ui.graphics.painter.Painter containerPainter, optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ method @androidx.compose.runtime.Composable public androidx.compose.ui.graphics.painter.Painter imageWithScrimBackgroundPainter(androidx.compose.ui.graphics.painter.Painter backgroundImagePainter, optional androidx.compose.ui.graphics.Brush backgroundImageScrimBrush);
+ method @androidx.compose.runtime.Composable public androidx.compose.foundation.BorderStroke outlinedCardBorder(optional long outlineColor, optional float borderWidth);
+ method @androidx.compose.runtime.Composable public androidx.wear.compose.material3.CardColors outlinedCardColors(optional long contentColor, optional long appNameColor, optional long timeColor, optional long titleColor);
+ property public final float AppImageSize;
+ property public final androidx.compose.foundation.layout.PaddingValues ContentPadding;
+ field public static final androidx.wear.compose.material3.CardDefaults INSTANCE;
+ }
+
+ public final class CardKt {
+ method @androidx.compose.runtime.Composable public static void AppCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> appName, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? appImage, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void Card(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void OutlinedCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+ method @androidx.compose.runtime.Composable public static void TitleCard(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit> title, optional androidx.compose.ui.Modifier modifier, optional boolean enabled, optional androidx.compose.ui.graphics.Shape shape, optional androidx.wear.compose.material3.CardColors colors, optional androidx.compose.foundation.BorderStroke? border, optional androidx.compose.foundation.layout.PaddingValues contentPadding, optional androidx.compose.foundation.interaction.MutableInteractionSource interactionSource, optional kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.RowScope,kotlin.Unit>? time, kotlin.jvm.functions.Function0<kotlin.Unit> content);
}
@androidx.compose.runtime.Stable public final class ColorScheme {
@@ -116,6 +142,7 @@
}
@androidx.compose.runtime.Immutable public final class IconButtonColors {
+ ctor public IconButtonColors(long containerColor, long contentColor, long disabledContainerColor, long disabledContentColor);
}
public final class IconButtonDefaults {
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardScreenshotTest.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardScreenshotTest.kt
new file mode 100644
index 0000000..6684dec
--- /dev/null
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardScreenshotTest.kt
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.compose.material3.test
+
+import android.os.Build
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import androidx.wear.compose.material3.AppCard
+import androidx.wear.compose.material3.Card
+import androidx.wear.compose.material3.CardColors
+import androidx.wear.compose.material3.CardDefaults
+import androidx.wear.compose.material3.OutlinedCard
+import androidx.wear.compose.material3.SCREENSHOT_GOLDEN_PATH
+import androidx.wear.compose.material3.TEST_TAG
+import androidx.wear.compose.material3.TestIcon
+import androidx.wear.compose.material3.Text
+import androidx.wear.compose.material3.TitleCard
+import androidx.wear.compose.material3.setContentWithTheme
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+class CardScreenshotTest {
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ @get:Rule
+ val screenshotRule = AndroidXScreenshotTestRule(SCREENSHOT_GOLDEN_PATH)
+
+ @get:Rule
+ val testName = TestName()
+
+ @Test
+ fun card_ltr() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleCard()
+ }
+
+ @Test
+ fun card_disabled() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleCard(enabled = false)
+ }
+
+ @Test
+ fun card_rtl() = verifyScreenshot(layoutDirection = LayoutDirection.Rtl) {
+ sampleCard()
+ }
+
+ @Test
+ fun card_image_background() = verifyScreenshot {
+ sampleCard(
+ colors = CardDefaults.imageCardColors(
+ containerPainter = CardDefaults.imageWithScrimBackgroundPainter(
+ backgroundImagePainter = painterResource(id = R.drawable.backgroundimage1)
+ )
+ )
+ )
+ }
+
+ @Test
+ fun outlined_card_ltr() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleOutlinedCard()
+ }
+
+ @Test
+ fun outlined_card_disabled() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleOutlinedCard(enabled = false)
+ }
+
+ @Test
+ fun outlined_card_rtl() = verifyScreenshot(layoutDirection = LayoutDirection.Rtl) {
+ sampleOutlinedCard()
+ }
+
+ @Test
+ fun app_card_ltr() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleAppCard()
+ }
+
+ @Test
+ fun app_card_disabled() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleAppCard(enabled = false)
+ }
+
+ @Test
+ fun app_card_rtl() = verifyScreenshot(layoutDirection = LayoutDirection.Rtl) {
+ sampleAppCard()
+ }
+
+ @Test
+ fun app_card_image_background() = verifyScreenshot {
+ sampleAppCard(
+ colors = CardDefaults.imageCardColors(
+ containerPainter = CardDefaults.imageWithScrimBackgroundPainter(
+ backgroundImagePainter = painterResource(id = R.drawable.backgroundimage1)
+ )
+ )
+ )
+ }
+
+ @Test
+ fun title_card_ltr() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleTitleCard()
+ }
+
+ @Test
+ fun title_card_disabled() = verifyScreenshot(layoutDirection = LayoutDirection.Ltr) {
+ sampleTitleCard(enabled = false)
+ }
+
+ @Test
+ fun title_card_rtl() = verifyScreenshot(layoutDirection = LayoutDirection.Rtl) {
+ sampleTitleCard()
+ }
+
+ @Test
+ fun title_card_image_background() = verifyScreenshot {
+ sampleTitleCard(
+ colors = CardDefaults.imageCardColors(
+ containerPainter = CardDefaults.imageWithScrimBackgroundPainter(
+ backgroundImagePainter = painterResource(id = R.drawable.backgroundimage1)
+ )
+ )
+ )
+ }
+
+ @Composable
+ private fun sampleCard(
+ enabled: Boolean = true,
+ colors: CardColors = CardDefaults.cardColors()
+ ) {
+ Card(
+ enabled = enabled,
+ onClick = {},
+ colors = colors,
+ modifier = Modifier.testTag(TEST_TAG),
+ ) {
+ Text("Card: Some body content")
+ }
+ }
+
+ @Composable
+ private fun sampleOutlinedCard(
+ enabled: Boolean = true,
+ ) {
+ OutlinedCard(
+ enabled = enabled,
+ onClick = {},
+ modifier = Modifier.testTag(TEST_TAG),
+ ) {
+ Text("Outlined Card: Some body content")
+ }
+ }
+
+ @Composable
+ private fun sampleAppCard(
+ enabled: Boolean = true,
+ colors: CardColors = CardDefaults.cardColors()
+ ) {
+ AppCard(
+ enabled = enabled,
+ onClick = {},
+ appName = { Text("AppName") },
+ appImage = { TestIcon() },
+ title = { Text("AppCard") },
+ colors = colors,
+ time = { Text("now") },
+ modifier = Modifier.testTag(TEST_TAG),
+ ) {
+ Text("Some body content")
+ Text("and some more body content")
+ }
+ }
+
+ @Composable
+ private fun sampleTitleCard(
+ enabled: Boolean = true,
+ colors: CardColors = CardDefaults.cardColors()
+ ) {
+ TitleCard(
+ enabled = enabled,
+ onClick = {},
+ title = { Text("TitleCard") },
+ time = { Text("now") },
+ colors = colors,
+ modifier = Modifier.testTag(TEST_TAG),
+ ) {
+ Text("Some body content")
+ Text("and some more body content")
+ }
+ }
+
+ private fun verifyScreenshot(
+ layoutDirection: LayoutDirection = LayoutDirection.Ltr,
+ content: @Composable () -> Unit
+ ) {
+ rule.setContentWithTheme {
+ CompositionLocalProvider(LocalLayoutDirection provides layoutDirection) {
+ content()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG)
+ .captureToImage()
+ .assertAgainstGolden(screenshotRule, testName.methodName)
+ }
+}
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardTest.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardTest.kt
new file mode 100644
index 0000000..6b01051
--- /dev/null
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/CardTest.kt
@@ -0,0 +1,565 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.compose.material3
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.requiredHeight
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.assertContainsColor
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.SemanticsProperties
+import androidx.compose.ui.semantics.role
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.test.SemanticsMatcher
+import androidx.compose.ui.test.assert
+import androidx.compose.ui.test.assertHasClickAction
+import androidx.compose.ui.test.assertIsEnabled
+import androidx.compose.ui.test.assertIsNotEnabled
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.ComposeContentTestRule
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import org.junit.Assert.assertEquals
+import org.junit.Rule
+import org.junit.Test
+
+public class CardTest {
+ @get:Rule
+ public val rule: ComposeContentTestRule = createComposeRule()
+
+ @Test
+ public fun supports_test_tag() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).assertExists()
+ }
+
+ @Test
+ public fun has_clickaction_when_enabled() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ enabled = true,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
+ }
+
+ @Test
+ public fun has_clickaction_when_disabled() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).assertHasClickAction()
+ }
+
+ @Test
+ public fun is_correctly_enabled_when_enabled_equals_true() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ enabled = true,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).assertIsEnabled()
+ }
+
+ @Test
+ public fun is_correctly_disabled_when_enabled_equals_false() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).assertIsNotEnabled()
+ }
+
+ @Test
+ public fun responds_to_click_when_enabled() {
+ var clicked = false
+
+ rule.setContentWithTheme {
+ Card(
+ onClick = { clicked = true },
+ enabled = true,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).performClick()
+
+ rule.runOnIdle {
+ assertEquals(true, clicked)
+ }
+ }
+
+ @Test
+ public fun does_not_respond_to_click_when_disabled() {
+ var clicked = false
+
+ rule.setContentWithTheme {
+ Card(
+ onClick = { clicked = true },
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG).performClick()
+
+ rule.runOnIdle {
+ assertEquals(false, clicked)
+ }
+ }
+
+ @Test
+ public fun has_role_button_if_explicitly_set() {
+ rule.setContentWithTheme {
+ Card(
+ onClick = {},
+ enabled = false,
+ modifier = Modifier.testTag(TEST_TAG)
+ .semantics { role = Role.Button },
+ ) {
+ TestImage()
+ }
+ }
+
+ rule.onNodeWithTag(TEST_TAG)
+ .assert(
+ SemanticsMatcher.expectValue(
+ SemanticsProperties.Role,
+ Role.Button
+ )
+ )
+ }
+
+ @Test
+ public fun gives_base_card_correct_default_max_height(): Unit =
+ verifyHeight(
+ expectedHeight = 100.dp +
+ CardDefaults.ContentPadding.calculateBottomPadding() +
+ CardDefaults.ContentPadding.calculateTopPadding(),
+ imageModifier = Modifier.requiredHeight(100.dp)
+ )
+
+ @Test
+ public fun gives_enabled_default_colors(): Unit =
+ verifyColors(
+ CardStatus.Enabled,
+ ) { MaterialTheme.colorScheme.onSurfaceVariant }
+
+ @Test
+ public fun gives_disabled_default_colors(): Unit =
+ verifyColors(
+ CardStatus.Disabled,
+ ) { MaterialTheme.colorScheme.onSurfaceVariant }
+
+ @Test
+ public fun app_card_gives_default_colors() {
+ var expectedAppColor = Color.Transparent
+ var expectedTimeColor = Color.Transparent
+ var expectedTitleColor = Color.Transparent
+ var expectedContentColor = Color.Transparent
+ var actualContentColor = Color.Transparent
+ var actualTitleColor = Color.Transparent
+ var actualTimeColor = Color.Transparent
+ var actualAppColor = Color.Transparent
+ val testBackground = Color.White
+
+ rule.setContentWithTheme {
+ expectedAppColor = MaterialTheme.colorScheme.onSurfaceVariant
+ expectedTimeColor = MaterialTheme.colorScheme.onSurfaceVariant
+ expectedTitleColor = MaterialTheme.colorScheme.onSurface
+ expectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ AppCard(
+ onClick = {},
+ appName = { actualAppColor = LocalContentColor.current },
+ time = { actualTimeColor = LocalContentColor.current },
+ title = { actualTitleColor = LocalContentColor.current },
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ actualContentColor = LocalContentColor.current
+ }
+ }
+ }
+
+ assertEquals(expectedAppColor, actualAppColor)
+ assertEquals(expectedTimeColor, actualTimeColor)
+ assertEquals(expectedTitleColor, actualTitleColor)
+ assertEquals(expectedContentColor, actualContentColor)
+ }
+
+ @Test
+ public fun title_card_gives_default_colors() {
+ var expectedTimeColor = Color.Transparent
+ var expectedTitleColor = Color.Transparent
+ var expectedContentColor = Color.Transparent
+ var actualContentColor = Color.Transparent
+ var actualTitleColor = Color.Transparent
+ var actualTimeColor = Color.Transparent
+ val testBackground = Color.White
+
+ rule.setContentWithTheme {
+ expectedTimeColor = MaterialTheme.colorScheme.onSurfaceVariant
+ expectedTitleColor = MaterialTheme.colorScheme.onSurface
+ expectedContentColor = MaterialTheme.colorScheme.onSurfaceVariant
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ TitleCard(
+ onClick = {},
+ time = { actualTimeColor = LocalContentColor.current },
+ title = { actualTitleColor = LocalContentColor.current },
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ actualContentColor = LocalContentColor.current
+ }
+ }
+ }
+
+ assertEquals(expectedTimeColor, actualTimeColor)
+ assertEquals(expectedTitleColor, actualTitleColor)
+ assertEquals(expectedContentColor, actualContentColor)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ @Test
+ public fun outlined_card_has_outlined_border_and_transparent() {
+ val outlineColor = Color.Red
+ val testBackground = Color.Green
+
+ rule.setContentWithTheme {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ OutlinedCard(
+ onClick = {},
+ border = CardDefaults.outlinedCardBorder(outlineColor),
+ modifier = Modifier
+ .testTag(TEST_TAG)
+ .size(100.dp)
+ .align(Alignment.Center)
+ ) {
+ }
+ }
+ }
+ rule.onNodeWithTag(TEST_TAG).captureToImage().assertContainsColor(outlineColor)
+ // As the color of the OutlinedCard is transparent, we expect to see a
+ // testBackground color covering everything except border.
+ rule.onNodeWithTag(TEST_TAG).captureToImage()
+ .assertColorInPercentageRange(testBackground, 93f..97f)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ @Test
+ public fun outlined_titlecard_has_outlined_border_and_transparent() {
+ val outlineColor = Color.Red
+ val testBackground = Color.Green
+
+ rule.setContentWithTheme {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ TitleCard(
+ onClick = {},
+ title = {},
+ border = CardDefaults.outlinedCardBorder(outlineColor),
+ colors = CardDefaults.outlinedCardColors(),
+ modifier = Modifier
+ .testTag(TEST_TAG)
+ .size(100.dp)
+ .align(Alignment.Center)
+ ) {
+ }
+ }
+ }
+ rule.onNodeWithTag(TEST_TAG).captureToImage().assertContainsColor(outlineColor)
+ // As the color of the OutlinedCard is transparent, we expect to see a
+ // testBackground color covering everything except border.
+ rule.onNodeWithTag(TEST_TAG).captureToImage()
+ .assertColorInPercentageRange(testBackground, 93f..97f)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ @Test
+ public fun outlined_appcard_has_outlined_border_and_transparent() {
+ val outlineColor = Color.Red
+ val testBackground = Color.Green
+
+ rule.setContentWithTheme {
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ AppCard(
+ onClick = {},
+ appName = {},
+ title = {},
+ border = CardDefaults.outlinedCardBorder(outlineColor),
+ colors = CardDefaults.outlinedCardColors(),
+ modifier = Modifier
+ .testTag(TEST_TAG)
+ .size(100.dp)
+ .align(Alignment.Center)
+ ) {
+ }
+ }
+ }
+ rule.onNodeWithTag(TEST_TAG).captureToImage().assertContainsColor(outlineColor)
+ // As the color of the OutlinedCard is transparent, we expect to see a
+ // testBackground color covering everything except border.
+ rule.onNodeWithTag(TEST_TAG).captureToImage()
+ .assertColorInPercentageRange(testBackground, 93f..97f)
+ }
+
+ @Test
+ public fun gives_correct_text_style_base() {
+ var actualTextStyle = TextStyle.Default
+ var expectedTextStyle = TextStyle.Default
+ rule.setContentWithTheme {
+ expectedTextStyle = MaterialTheme.typography.bodyLarge
+ Card(
+ onClick = {},
+ content = {
+ actualTextStyle = LocalTextStyle.current
+ },
+ enabled = true,
+ modifier = Modifier.testTag(TEST_TAG)
+ )
+ }
+ assertEquals(expectedTextStyle, actualTextStyle)
+ }
+
+ @Test
+ public fun app_card_gives_correct_text_style_base() {
+ var actualAppTextStyle = TextStyle.Default
+ var actualTimeTextStyle = TextStyle.Default
+ var actualTitleTextStyle = TextStyle.Default
+ var actuaContentTextStyle = TextStyle.Default
+ var expectedAppTextStyle = TextStyle.Default
+ var expectedTimeTextStyle = TextStyle.Default
+ var expectedTitleTextStyle = TextStyle.Default
+ var expectedContentTextStyle = TextStyle.Default
+
+ rule.setContentWithTheme {
+ expectedAppTextStyle = MaterialTheme.typography.captionLarge
+ expectedTimeTextStyle = MaterialTheme.typography.captionLarge
+ expectedTitleTextStyle = MaterialTheme.typography.titleSmall
+ expectedContentTextStyle = MaterialTheme.typography.bodyLarge
+
+ AppCard(
+ onClick = {},
+ appName = {
+ actualAppTextStyle = LocalTextStyle.current
+ },
+ time = {
+ actualTimeTextStyle = LocalTextStyle.current
+ },
+ title = {
+ actualTitleTextStyle = LocalTextStyle.current
+ },
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ actuaContentTextStyle = LocalTextStyle.current
+ }
+ }
+ assertEquals(expectedAppTextStyle, actualAppTextStyle)
+ assertEquals(expectedTimeTextStyle, actualTimeTextStyle)
+ assertEquals(expectedTitleTextStyle, actualTitleTextStyle)
+ assertEquals(expectedContentTextStyle, actuaContentTextStyle)
+ }
+
+ @Test
+ public fun title_card_gives_correct_text_style_base() {
+ var actualTimeTextStyle = TextStyle.Default
+ var actualTitleTextStyle = TextStyle.Default
+ var actuaContentTextStyle = TextStyle.Default
+ var expectedTimeTextStyle = TextStyle.Default
+ var expectedTitleTextStyle = TextStyle.Default
+ var expectedContentTextStyle = TextStyle.Default
+
+ rule.setContentWithTheme {
+ expectedTimeTextStyle = MaterialTheme.typography.captionLarge
+ expectedTitleTextStyle = MaterialTheme.typography.titleSmall
+ expectedContentTextStyle = MaterialTheme.typography.bodyLarge
+
+ TitleCard(
+ onClick = {},
+ time = {
+ actualTimeTextStyle = LocalTextStyle.current
+ },
+ title = {
+ actualTitleTextStyle = LocalTextStyle.current
+ },
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ actuaContentTextStyle = LocalTextStyle.current
+ }
+ }
+ assertEquals(expectedTimeTextStyle, actualTimeTextStyle)
+ assertEquals(expectedTitleTextStyle, actualTitleTextStyle)
+ assertEquals(expectedContentTextStyle, actuaContentTextStyle)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.O)
+ @Test
+ public fun outlined_app_card_gives_correct_text_style_base() {
+ var actualAppTextStyle = TextStyle.Default
+ var actualTimeTextStyle = TextStyle.Default
+ var actualTitleTextStyle = TextStyle.Default
+ var actuaContentTextStyle = TextStyle.Default
+ var expectedAppTextStyle = TextStyle.Default
+ var expectedTimeTextStyle = TextStyle.Default
+ var expectedTitleTextStyle = TextStyle.Default
+ var expectedContentTextStyle = TextStyle.Default
+
+ rule.setContentWithTheme {
+ expectedAppTextStyle = MaterialTheme.typography.captionLarge
+ expectedTimeTextStyle = MaterialTheme.typography.captionLarge
+ expectedTitleTextStyle = MaterialTheme.typography.titleSmall
+ expectedContentTextStyle = MaterialTheme.typography.bodyLarge
+
+ AppCard(
+ onClick = {},
+ appName = {
+ actualAppTextStyle = LocalTextStyle.current
+ },
+ time = {
+ actualTimeTextStyle = LocalTextStyle.current
+ },
+ title = {
+ actualTitleTextStyle = LocalTextStyle.current
+ },
+ modifier = Modifier.testTag(TEST_TAG)
+ ) {
+ actuaContentTextStyle = LocalTextStyle.current
+ }
+ }
+ rule.onNodeWithTag(TEST_TAG).captureToImage()
+ assertEquals(expectedAppTextStyle, actualAppTextStyle)
+ assertEquals(expectedTimeTextStyle, actualTimeTextStyle)
+ assertEquals(expectedTitleTextStyle, actualTitleTextStyle)
+ assertEquals(expectedContentTextStyle, actuaContentTextStyle)
+ }
+
+ private fun verifyHeight(expectedHeight: Dp, imageModifier: Modifier = Modifier) {
+ rule.verifyHeight(expectedHeight) {
+ Card(
+ onClick = {},
+ ) {
+ TestIcon(modifier = imageModifier)
+ }
+ }
+ }
+
+ private fun verifyColors(
+ status: CardStatus,
+ contentColor: @Composable () -> Color
+ ) {
+ var expectedContent = Color.Transparent
+ var actualContent = Color.Transparent
+ val testBackground = Color.White
+
+ rule.setContentWithTheme {
+ expectedContent = contentColor()
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(testBackground)
+ ) {
+ Card(
+ onClick = {},
+ content = { actualContent = LocalContentColor.current },
+ enabled = status.enabled(),
+ modifier = Modifier.testTag(TEST_TAG)
+ )
+ }
+ }
+
+ assertEquals(expectedContent, actualContent)
+ }
+}
+
+private fun ComposeContentTestRule.verifyHeight(expected: Dp, content: @Composable () -> Unit) {
+ setContentWithThemeForSizeAssertions {
+ content()
+ }.assertHeightIsEqualTo(expected, Dp(1.0f))
+}
+
+private enum class CardStatus {
+ Enabled,
+ Disabled;
+
+ fun enabled() = this == Enabled
+}
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/Material3Test.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/Material3Test.kt
index 750e25e..afa5a80 100644
--- a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/Material3Test.kt
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/Material3Test.kt
@@ -33,10 +33,14 @@
import androidx.compose.testutils.assertContainsColor
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.compositeOver
+import androidx.compose.ui.graphics.toPixelMap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.semantics.SemanticsNode
import androidx.compose.ui.test.SemanticsNodeInteraction
import androidx.compose.ui.test.assertTouchHeightIsEqualTo
import androidx.compose.ui.test.assertTouchWidthIsEqualTo
@@ -44,9 +48,17 @@
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpRect
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.height
+import androidx.compose.ui.unit.isUnspecified
+import androidx.compose.ui.unit.toSize
+import kotlin.math.abs
import org.junit.Assert
+/**
+ * Constant to emulate very big but finite constraints
+ */
val BigTestMaxWidth = 5000.dp
val BigTestMaxHeight = 5000.dp
@@ -95,20 +107,17 @@
): SemanticsNodeInteraction {
setContent {
MaterialTheme {
- Box {
- Box(
- Modifier
- .sizeIn(
- maxWidth = parentMaxWidth,
- maxHeight = parentMaxHeight
- )
- .testTag("containerForSizeAssertion")
- ) {
- content()
- }
+ Box(
+ Modifier.sizeIn(
+ maxWidth = parentMaxWidth,
+ maxHeight = parentMaxHeight
+ ).testTag("containerForSizeAssertion")
+ ) {
+ content()
}
}
}
+
return onNodeWithTag("containerForSizeAssertion", useUnmergedTree)
}
@@ -176,8 +185,115 @@
.assertContainsColor(finalExpectedContainerColor)
}
+/**
+ * Checks that [expectedColor] is in the percentage [range] of an [ImageBitmap] color histogram
+ */
+fun ImageBitmap.assertColorInPercentageRange(
+ expectedColor: Color,
+ range: ClosedFloatingPointRange<Float> = 50.0f..100.0f
+) {
+ val histogram = histogram()
+ if (!histogram.containsKey(expectedColor)) {
+ throw AssertionError("Expected color $expectedColor was not found in the bitmap.")
+ }
+
+ ((histogram[expectedColor]!! * 100f) / (width * height)).let { actualPercent ->
+ if (actualPercent !in range) {
+ throw AssertionError(
+ "Expected color $expectedColor found " +
+ "$actualPercent%, not in the percentage range $range"
+ )
+ }
+ }
+}
+
+/**
+ * Asserts that the layout of this node has height equal to [expectedHeight].
+ *
+ * @throws AssertionError if comparison fails.
+ */
+internal fun SemanticsNodeInteraction.assertHeightIsEqualTo(
+ expectedHeight: Dp,
+ tolerance: Dp = Dp(0.5f)
+): SemanticsNodeInteraction {
+ return withUnclippedBoundsInRoot {
+ it.height.assertIsEqualTo(expectedHeight, "height", tolerance)
+ }
+}
+
+private fun SemanticsNodeInteraction.withUnclippedBoundsInRoot(
+ assertion: (DpRect) -> Unit
+): SemanticsNodeInteraction {
+ val node = fetchSemanticsNode("Failed to retrieve bounds of the node.")
+ val bounds = with(node.root!!.density) {
+ node.unclippedBoundsInRoot.let {
+ DpRect(it.left.toDp(), it.top.toDp(), it.right.toDp(), it.bottom.toDp())
+ }
+ }
+ assertion.invoke(bounds)
+ return this
+}
+
+private val SemanticsNode.unclippedBoundsInRoot: Rect
+ get() {
+ return if (layoutInfo.isPlaced) {
+ Rect(positionInRoot, size.toSize())
+ } else {
+ Dp.Unspecified.value.let { Rect(it, it, it, it) }
+ }
+ }
+
+/**
+ * Returns if this value is equal to the [reference], within a given [tolerance]. If the
+ * reference value is [Float.NaN], [Float.POSITIVE_INFINITY] or [Float.NEGATIVE_INFINITY], this
+ * only returns true if this value is exactly the same (tolerance is disregarded).
+ */
+private fun Dp.isWithinTolerance(reference: Dp, tolerance: Dp): Boolean {
+ return when {
+ reference.isUnspecified -> this.isUnspecified
+ reference.value.isInfinite() -> this.value == reference.value
+ else -> abs(this.value - reference.value) <= tolerance.value
+ }
+}
+
+/**
+ * Asserts that this value is equal to the given [expected] value.
+ *
+ * Performs the comparison with the given [tolerance] or the default one if none is provided. It is
+ * recommended to use tolerance when comparing positions and size coming from the framework as there
+ * can be rounding operation performed by individual layouts so the values can be slightly off from
+ * the expected ones.
+ *
+ * @param expected The expected value to which this one should be equal to.
+ * @param subject Used in the error message to identify which item this assertion failed on.
+ * @param tolerance The tolerance within which the values should be treated as equal.
+ *
+ * @throws AssertionError if comparison fails.
+ */
+internal fun Dp.assertIsEqualTo(expected: Dp, subject: String, tolerance: Dp = Dp(.5f)) {
+ if (!isWithinTolerance(expected, tolerance)) {
+ // Comparison failed, report the error in DPs
+ throw AssertionError(
+ "Actual $subject is $this, expected $expected (tolerance: $tolerance)"
+ )
+ }
+}
+
+private fun ImageBitmap.histogram(): MutableMap<Color, Long> {
+ val pixels = this.toPixelMap()
+ val histogram = mutableMapOf<Color, Long>()
+ for (x in 0 until width) {
+ for (y in 0 until height) {
+ val color = pixels[x, y]
+ histogram[color] = histogram.getOrDefault(color, 0) + 1
+ }
+ }
+ return histogram
+}
+
internal enum class Status {
Enabled,
Disabled;
+
fun enabled() = this == Enabled
}
diff --git a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/TextTest.kt b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/TextTest.kt
index a61944f..2596530 100644
--- a/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/TextTest.kt
+++ b/wear/compose/compose-material3/src/androidAndroidTest/kotlin/androidx/wear/compose/material3/TextTest.kt
@@ -35,10 +35,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.google.common.truth.Truth
+import java.lang.IllegalArgumentException
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.lang.IllegalArgumentException
@SmallTest
@RunWith(AndroidJUnit4::class)
diff --git a/wear/compose/compose-material3/src/androidMain/AndroidManifest.xml b/wear/compose/compose-material3/src/androidMain/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/compose-material3/src/androidMain/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Button.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Button.kt
index fa6786f..7503da4 100644
--- a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Button.kt
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Button.kt
@@ -77,8 +77,6 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
*/
@Composable
fun Button(
@@ -90,7 +88,6 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
content: @Composable RowScope.() -> Unit,
) {
androidx.wear.compose.materialcore.Chip(
@@ -102,7 +99,7 @@
contentPadding = contentPadding,
shape = shape,
interactionSource = interactionSource,
- role = role,
+ role = Role.Button,
content = provideScopeContent(
colors.contentColor(enabled = enabled),
MaterialTheme.typography.buttonMedium,
@@ -151,8 +148,6 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
*/
@Composable
fun FilledTonalButton(
@@ -164,11 +159,9 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
content: @Composable RowScope.() -> Unit,
) = Button(
- onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, role,
- content
+ onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, content
)
/**
@@ -210,8 +203,6 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
*/
@Composable
fun OutlinedButton(
@@ -223,11 +214,9 @@
border: BorderStroke? = ButtonDefaults.outlinedButtonBorder(enabled),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
content: @Composable RowScope.() -> Unit,
) = Button(
- onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, role,
- content
+ onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, content
)
/**
@@ -269,8 +258,6 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
*/
@Composable
fun ChildButton(
@@ -282,11 +269,9 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
content: @Composable RowScope.() -> Unit,
) = Button(
- onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, role,
- content
+ onClick, modifier, enabled, shape, colors, border, contentPadding, interactionSource, content
)
/**
@@ -316,8 +301,6 @@
*
* TODO(b/261838497) Add Material3 samples and UX guidance links
*
- * @param label A slot for providing the button's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
* @param onClick Will be called when the user clicks the button
* @param modifier Modifier to be applied to the button
* @param secondaryLabel A slot for providing the button's secondary label. The contents are
@@ -343,12 +326,11 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
+ * @param label A slot for providing the button's main label. The contents are expected to be text
+ * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
*/
@Composable
fun Button(
- label: @Composable RowScope.() -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
secondaryLabel: (@Composable RowScope.() -> Unit)? = null,
@@ -359,7 +341,7 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
+ label: @Composable RowScope.() -> Unit,
) {
androidx.wear.compose.materialcore.Chip(
modifier = modifier.height(ButtonDefaults.Height),
@@ -384,7 +366,7 @@
provideScopeContent(colors.iconColor(enabled), icon)
},
defaultIconSpacing = ButtonDefaults.IconSpacing,
- role = role
+ role = Role.Button
)
}
@@ -418,8 +400,6 @@
*
* TODO(b/261838497) Add Material3 samples and UX guidance links
*
- * @param label A slot for providing the button's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
* @param onClick Will be called when the user clicks the button
* @param modifier Modifier to be applied to the button
* @param secondaryLabel A slot for providing the button's secondary label. The contents are
@@ -444,12 +424,11 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
+ * @param label A slot for providing the button's main label. The contents are expected to be text
+ * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
*/
@Composable
fun FilledTonalButton(
- label: @Composable RowScope.() -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
secondaryLabel: (@Composable RowScope.() -> Unit)? = null,
@@ -460,9 +439,8 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
+ label: @Composable RowScope.() -> Unit,
) = Button(
- label,
onClick,
modifier,
secondaryLabel,
@@ -473,7 +451,7 @@
border,
contentPadding,
interactionSource,
- role
+ label
)
/**
@@ -503,8 +481,6 @@
*
* TODO(b/261838497) Add Material3 samples and UX guidance links
*
- * @param label A slot for providing the button's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
* @param onClick Will be called when the user clicks the button
* @param modifier Modifier to be applied to the button
* @param secondaryLabel A slot for providing the button's secondary label. The contents are
@@ -529,12 +505,11 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
+ * @param label A slot for providing the button's main label. The contents are expected to be text
+ * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
*/
@Composable
fun OutlinedButton(
- label: @Composable RowScope.() -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
secondaryLabel: (@Composable RowScope.() -> Unit)? = null,
@@ -545,9 +520,8 @@
border: BorderStroke? = ButtonDefaults.outlinedButtonBorder(enabled),
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
+ label: @Composable RowScope.() -> Unit,
) = Button(
- label,
onClick,
modifier,
secondaryLabel,
@@ -558,7 +532,7 @@
border,
contentPadding,
interactionSource,
- role
+ label,
)
/**
@@ -587,8 +561,6 @@
*
* TODO(b/261838497) Add Material3 samples and UX guidance links
*
- * @param label A slot for providing the button's main label. The contents are expected to be text
- * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
* @param onClick Will be called when the user clicks the button
* @param modifier Modifier to be applied to the button
* @param secondaryLabel A slot for providing the button's secondary label. The contents are
@@ -613,12 +585,11 @@
* [Interaction]s for this Button. You can create and pass in your own remembered
* [MutableInteractionSource] if you want to observe [Interaction]s and customize the
* appearance / behavior of this Button in different [Interaction]s.
- * @param role Role semantics that accessibility services can use to provide more
- * context to users.
+ * @param label A slot for providing the button's main label. The contents are expected to be text
+ * which is "start" aligned if there is an icon preset and "start" or "center" aligned if not.
*/
@Composable
fun ChildButton(
- label: @Composable RowScope.() -> Unit,
onClick: () -> Unit,
modifier: Modifier = Modifier,
secondaryLabel: (@Composable RowScope.() -> Unit)? = null,
@@ -629,9 +600,8 @@
border: BorderStroke? = null,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
- role: Role? = Role.Button,
+ label: @Composable RowScope.() -> Unit,
) = Button(
- label,
onClick,
modifier,
secondaryLabel,
@@ -642,7 +612,7 @@
border,
contentPadding,
interactionSource,
- role
+ label,
)
/**
@@ -924,7 +894,7 @@
* in different states.
*/
@Immutable
-class ButtonColors internal constructor(
+class ButtonColors constructor(
private val containerPainter: Painter,
private val contentColor: Color,
private val secondaryContentColor: Color,
@@ -946,7 +916,7 @@
* @param disabledSecondaryContentColor The content color of this [Button] when not enabled
* @param disabledIconColor The content color of this [Button] when not enabled
*/
- internal constructor(
+ constructor(
containerColor: Color,
contentColor: Color,
secondaryContentColor: Color,
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Card.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Card.kt
new file mode 100644
index 0000000..5454a04
--- /dev/null
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/Card.kt
@@ -0,0 +1,552 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.compose.material3
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.interaction.Interaction
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.Immutable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Brush
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.painter.ColorPainter
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.wear.compose.materialcore.ImageWithScrimPainter
+import androidx.wear.compose.materialcore.Text
+
+/**
+ * Base level Wear Material 3 [Card] that offers a single slot to take any content.
+ *
+ * Is used as the container for more opinionated [Card] components that take specific content such
+ * as icons, images, titles, subtitles and labels.
+ *
+ * The [Card] is Rectangle shaped rounded corners by default.
+ *
+ * Cards can be enabled or disabled. A disabled card will not respond to click events.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * Wear OS Material design guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param colors [CardColors] that will be used to resolve the colors used for this card in
+ * different states. See [CardDefaults.cardColors].
+ * @param border A BorderStroke object which is used for drawing outlines.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param content The main slot for a content of this card
+ */
+@Composable
+fun Card(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ shape: Shape = MaterialTheme.shapes.large,
+ colors: CardColors = CardDefaults.cardColors(),
+ border: BorderStroke? = null,
+ contentPadding: PaddingValues = CardDefaults.ContentPadding,
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ androidx.wear.compose.materialcore.Card(
+ onClick = onClick,
+ modifier = modifier,
+ border = border,
+ containerPainter = colors.containerPainter,
+ enabled = enabled,
+ contentPadding = contentPadding,
+ interactionSource = interactionSource,
+ role = null,
+ shape = shape,
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.contentColor,
+ LocalTextStyle provides MaterialTheme.typography.bodyLarge,
+ ) {
+ content()
+ }
+ }
+}
+
+/**
+ * Opinionated Wear Material 3 [Card] that offers a specific 5 slot layout to show information about
+ * an application, e.g. a notification. AppCards are designed to show interactive elements from
+ * multiple applications. They will typically be used by the system UI, e.g. for showing a list of
+ * notifications from different applications. However it could also be adapted by individual
+ * application developers to show information about different parts of their application.
+ *
+ * The first row of the layout has three slots, 1) a small optional application [Image] or [Icon] of
+ * size [CardDefaults.AppImageSize]x[CardDefaults.AppImageSize] dp, 2) an application name
+ * (emphasised with the [CardColors.appColor()] color), it is expected to be a short start aligned
+ * [Text] composable, and 3) the time that the application activity has occurred which will be
+ * shown on the top row of the card, this is expected to be an end aligned [Text] composable
+ * showing a time relevant to the contents of the [Card].
+ *
+ * The second row shows a title, this is expected to be a single row of start aligned [Text].
+ *
+ * The rest of the [Card] contains the content which can be either [Text] or an [Image].
+ * If the content is text it can be single or multiple line and is expected to be Top and Start
+ * aligned.
+ *
+ * If more than one composable is provided in the content slot it is the responsibility of the
+ * caller to determine how to layout the contents, e.g. provide either a row or a column.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param appName A slot for displaying the application name, expected to be a single line of start
+ * aligned text of [Typography.captionLarge]
+ * @param title A slot for displaying the title of the card, expected to be one or two lines of
+ * start aligned text of [Typography.titleSmall]
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param colors [CardColors] that will be used to resolve the colors used for this card in
+ * different states. See [CardDefaults.cardColors].
+ * @param border A BorderStroke object which is used for drawing outlines.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param appImage A slot for a small ([CardDefaults.AppImageSize]x[CardDefaults.AppImageSize] )
+ * [Image] associated with the application.
+ * @param time A slot for displaying the time relevant to the contents of the card, expected to be a
+ * short piece of end aligned text of [Typography.captionLarge].
+ * @param content The main slot for a content of this card
+ */
+@Composable
+fun AppCard(
+ onClick: () -> Unit,
+ appName: @Composable RowScope.() -> Unit,
+ title: @Composable RowScope.() -> Unit,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ shape: Shape = MaterialTheme.shapes.large,
+ colors: CardColors = CardDefaults.cardColors(),
+ border: BorderStroke? = null,
+ contentPadding: PaddingValues = CardDefaults.ContentPadding,
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+ appImage: @Composable (RowScope.() -> Unit)? = null,
+ time: @Composable (RowScope.() -> Unit)? = null,
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ androidx.wear.compose.materialcore.AppCard(
+ onClick = onClick,
+ modifier = modifier,
+ enabled = enabled,
+ shape = shape,
+ containerPainter = colors.containerPainter,
+ border = border,
+ contentPadding = contentPadding,
+ appImage = appImage?.let { { appImage() } },
+ interactionSource = interactionSource,
+ appName = {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.appNameColor,
+ LocalTextStyle provides MaterialTheme.typography.captionLarge,
+ ) {
+ appName()
+ }
+ },
+ time = time?.let {
+ {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.timeColor,
+ LocalTextStyle provides MaterialTheme.typography.captionLarge,
+ ) {
+ time()
+ }
+ }
+ },
+ title = {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.titleColor,
+ LocalTextStyle provides MaterialTheme.typography.titleSmall,
+ ) {
+ title()
+ }
+ },
+ content = {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.contentColor,
+ LocalTextStyle provides MaterialTheme.typography.bodyLarge,
+ ) {
+ content()
+ }
+ }
+ )
+}
+
+/**
+ * Opinionated Wear Material 3 [Card] that offers a specific 3 slot layout to show interactive
+ * information about an application, e.g. a message. TitleCards are designed for use within an
+ * application.
+ *
+ * The first row of the layout has two slots. 1. a start aligned title. The title text is
+ * expected to be a maximum of 2 lines of text.
+ * 2. An optional time that the application activity has occurred shown at the
+ * end of the row, expected to be an end aligned [Text] composable showing a time relevant to the
+ * contents of the [Card].
+ *
+ * The rest of the [Card] contains the content which is expected to be [Text] or a contained
+ * [Image].
+ *
+ * If the content is text it can be single or multiple line and is expected to be Top and Start
+ * aligned and of type of [Typography.bodyMedium].
+ *
+ * Overall the [title] and [content] text should be no more than 5 rows of text combined.
+ *
+ * If more than one composable is provided in the content slot it is the responsibility of the
+ * caller to determine how to layout the contents, e.g. provide either a row or a column.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param title A slot for displaying the title of the card, expected to be one or two lines of text
+ * of [Typography.buttonMedium]
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param colors [CardColors] that will be used to resolve the colors used for this card in
+ * different states. See [CardDefaults.cardColors].
+ * @param border A BorderStroke object which is used for drawing outlines.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param time An optional slot for displaying the time relevant to the contents of the card,
+ * expected to be a short piece of end aligned text.
+ * @param content The main slot for a content of this card
+ */
+@Composable
+fun TitleCard(
+ onClick: () -> Unit,
+ title: @Composable RowScope.() -> Unit,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ shape: Shape = MaterialTheme.shapes.large,
+ colors: CardColors = CardDefaults.cardColors(),
+ border: BorderStroke? = null,
+ contentPadding: PaddingValues = CardDefaults.ContentPadding,
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+ time: @Composable (RowScope.() -> Unit)? = null,
+ content: @Composable () -> Unit,
+) {
+ androidx.wear.compose.materialcore.TitleCard(
+ onClick = onClick,
+ modifier = modifier,
+ enabled = enabled,
+ shape = shape,
+ border = border,
+ contentPadding = contentPadding,
+ containerPainter = colors.containerPainter,
+ interactionSource = interactionSource,
+ title = {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.titleColor,
+ LocalTextStyle provides MaterialTheme.typography.titleSmall,
+ ) {
+ title()
+ }
+ },
+ time = {
+ time?.let {
+ Spacer(modifier = Modifier.weight(1.0f))
+ CompositionLocalProvider(
+ LocalContentColor provides colors.timeColor,
+ LocalTextStyle provides MaterialTheme.typography.captionLarge,
+ ) {
+ time()
+ }
+ }
+ },
+ content = {
+ CompositionLocalProvider(
+ values = arrayOf(
+ LocalContentColor provides colors.contentColor,
+ LocalTextStyle provides MaterialTheme.typography.bodyLarge
+ ),
+ content = content
+ )
+ }
+ )
+}
+
+/**
+ * Outlined Wear Material 3 [Card] that offers a single slot to take any content.
+ *
+ * Outlined [Card] components that take specific content such
+ * as icons, images, titles, subtitles and labels. Outlined Cards have a
+ * visual boundary around the container. This can emphasise the content of this card.
+ *
+ * The [Card] is Rectangle shaped with rounded corners by default.
+ *
+ * Cards can be enabled or disabled. A disabled card will not respond to click events.
+ *
+ * For more information, see the
+ * [Cards](https://developer.android.com/training/wearables/components/cards)
+ * Wear OS Material design guide.
+ *
+ * @param onClick Will be called when the user clicks the card
+ * @param modifier Modifier to be applied to the card
+ * @param enabled Controls the enabled state of the card. When false, this card will not
+ * be clickable and there will be no ripple effect on click. Wear cards do not have any specific
+ * elevation or alpha differences when not enabled - they are simply not clickable.
+ * @param shape Defines the card's shape. It is strongly recommended to use the default as this
+ * shape is a key characteristic of the Wear Material Theme
+ * @param colors [CardColors] that will be used to resolve the colors used for this card in
+ * different states. See [CardDefaults.cardColors].
+ * @param border A BorderStroke object which is used for the outline drawing.
+ * @param contentPadding The spacing values to apply internally between the container and the
+ * content
+ * @param interactionSource The [MutableInteractionSource] representing the stream of
+ * [Interaction]s for this card. You can create and pass in your own remembered
+ * [MutableInteractionSource] if you want to observe [Interaction]s and customize the
+ * appearance / behavior of this card in different [Interaction]s.
+ * @param content The main slot for a content of this card
+ */
+@Composable
+fun OutlinedCard(
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ shape: Shape = MaterialTheme.shapes.large,
+ colors: CardColors = CardDefaults.outlinedCardColors(),
+ border: BorderStroke = CardDefaults.outlinedCardBorder(),
+ contentPadding: PaddingValues = CardDefaults.ContentPadding,
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
+ content: @Composable ColumnScope.() -> Unit,
+) {
+ Card(
+ onClick = onClick,
+ modifier = modifier,
+ enabled = enabled,
+ colors = colors,
+ border = border,
+ interactionSource = interactionSource,
+ contentPadding = contentPadding,
+ shape = shape,
+ content = content
+ )
+}
+
+/**
+ * Contains the default values used by [Card]
+ */
+public object CardDefaults {
+
+ /**
+ * Creates a [CardColors] that represents the default container and content colors used in a
+ * [Card], [AppCard] or [TitleCard].
+ *
+ * @param containerColor the container color of this [Card].
+ * @param contentColor the content color of this [Card].
+ * @param appNameColor the color used for appName, only applies to [AppCard].
+ * @param timeColor the color used for time, applies to [AppCard] and [TitleCard].
+ * @param titleColor the color used for title, applies to [AppCard] and [TitleCard].
+ */
+ @Composable
+ public fun cardColors(
+ containerColor: Color = MaterialTheme.colorScheme.surface,
+ contentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
+ appNameColor: Color = contentColor,
+ timeColor: Color = contentColor,
+ titleColor: Color = MaterialTheme.colorScheme.onSurface,
+ ): CardColors = CardColors(
+ containerPainter = remember(containerColor) { ColorPainter(containerColor) },
+ contentColor = contentColor,
+ appNameColor = appNameColor,
+ timeColor = timeColor,
+ titleColor = titleColor
+ )
+
+ /**
+ * Creates a [CardColors] that represents the default container and content colors used in an
+ * [OutlinedCard], outlined [AppCard] or [TitleCard].
+ *
+ * @param contentColor the content color of this [OutlinedCard].
+ * @param appNameColor the color used for appName, only applies to [AppCard].
+ * @param timeColor the color used for time, applies to [AppCard] and [TitleCard].
+ * @param titleColor the color used for title, applies to [AppCard] and [TitleCard].
+ */
+ @Composable
+ public fun outlinedCardColors(
+ contentColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
+ appNameColor: Color = contentColor,
+ timeColor: Color = contentColor,
+ titleColor: Color = MaterialTheme.colorScheme.onSurface,
+ ): CardColors = CardColors(
+ containerPainter = remember { ColorPainter(Color.Transparent) },
+ contentColor = contentColor,
+ appNameColor = appNameColor,
+ timeColor = timeColor,
+ titleColor = titleColor
+ )
+
+ /**
+ * Creates a [CardColors] that represents the default container and content colors
+ * used in a [Card], [AppCard] or [TitleCard] with Image set as a background.
+ *
+ * @param containerPainter a Painter which is used for background drawing.
+ * @param contentColor the content color of this [Card].
+ * @param appNameColor the color used for appName, only applies to [AppCard].
+ * @param timeColor the color used for time, applies to [AppCard] and [TitleCard].
+ * @param titleColor the color used for title, applies to [AppCard] and [TitleCard].
+ */
+ @Composable
+ public fun imageCardColors(
+ containerPainter: Painter,
+ contentColor: Color = MaterialTheme.colorScheme.onBackground,
+ appNameColor: Color = contentColor,
+ timeColor: Color = contentColor,
+ titleColor: Color = contentColor,
+ ): CardColors = CardColors(
+ containerPainter = containerPainter,
+ contentColor = contentColor,
+ appNameColor = appNameColor,
+ timeColor = timeColor,
+ titleColor = titleColor
+ )
+
+ /**
+ * Creates a [Painter] for the background of a [Card] that displays an Image with a scrim over
+ * the image to make sure that any content above the background will be legible.
+ *
+ * An Image background is a means to reinforce the meaning of information in a Card, e.g. To
+ * help to contextualize the information in a TitleCard
+ *
+ * Cards should have a content color that contrasts with the background image and scrim
+ *
+ * @param backgroundImagePainter The [Painter] to use to draw the background of the [Card]
+ * @param backgroundImageScrimBrush The [Brush] to use to paint a scrim over the background
+ * image to ensure that any text drawn over the image is legible
+ */
+ @Composable
+ public fun imageWithScrimBackgroundPainter(
+ backgroundImagePainter: Painter,
+ backgroundImageScrimBrush: Brush = SolidColor(OverlayScrimColor)
+ ): Painter {
+ return ImageWithScrimPainter(
+ imagePainter = backgroundImagePainter,
+ brush = backgroundImageScrimBrush
+ )
+ }
+
+ /**
+ * Creates a [BorderStroke] that represents the default border used in Outlined Cards.
+ * @param outlineColor The color to be used for drawing an outline.
+ * @param borderWidth width of the border in [Dp].
+ */
+ @Composable
+ public fun outlinedCardBorder(
+ outlineColor: Color = MaterialTheme.colorScheme.outline,
+ borderWidth: Dp = 1.dp
+ ): BorderStroke =
+ BorderStroke(borderWidth, outlineColor)
+
+ private val CardHorizontalPadding = 10.dp
+ private val CardVerticalPadding = 10.dp
+
+ private val OverlayScrimColor: Color = Color(0x99202124)
+
+ /**
+ * The default content padding used by [Card]
+ */
+ public val ContentPadding: PaddingValues = PaddingValues(
+ start = CardHorizontalPadding,
+ top = CardVerticalPadding,
+ end = CardHorizontalPadding,
+ bottom = CardVerticalPadding
+ )
+
+ /**
+ * The default size of the app icon/image when used inside a [AppCard].
+ */
+ public val AppImageSize: Dp = 16.dp
+}
+
+/**
+ * Represents Colors used in [Card].
+ * Unlike other Material 3 components, Cards do not change their color appearance when
+ * they are disabled. All colors remain the same in enabled and disabled states
+ */
+@Immutable
+public class CardColors(
+ internal val containerPainter: Painter,
+ internal val contentColor: Color,
+ internal val appNameColor: Color,
+ internal val timeColor: Color,
+ internal val titleColor: Color,
+) {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other == null || other !is CardColors) return false
+
+ if (containerPainter != other.containerPainter) return false
+ if (contentColor != other.contentColor) return false
+ if (appNameColor != other.appNameColor) return false
+ if (timeColor != other.timeColor) return false
+ if (titleColor != other.titleColor) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = containerPainter.hashCode()
+ result = 31 * result + contentColor.hashCode()
+ result = 31 * result + appNameColor.hashCode()
+ result = 31 * result + timeColor.hashCode()
+ result = 31 * result + titleColor.hashCode()
+ return result
+ }
+}
\ No newline at end of file
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/IconButton.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/IconButton.kt
index 087dd93..d4b2a43 100644
--- a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/IconButton.kt
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/IconButton.kt
@@ -423,7 +423,7 @@
* [OutlinedIconButton].
*/
@Immutable
-class IconButtonColors internal constructor(
+class IconButtonColors constructor(
private val containerColor: Color,
private val contentColor: Color,
private val disabledContainerColor: Color,
diff --git a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/MaterialTextSelectionColors.kt b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/MaterialTextSelectionColors.kt
index 8939ee4..cfd8d63 100644
--- a/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/MaterialTextSelectionColors.kt
+++ b/wear/compose/compose-material3/src/commonMain/kotlin/androidx/wear/compose/material3/MaterialTextSelectionColors.kt
@@ -15,13 +15,13 @@
*/
package androidx.wear.compose.material3
+import androidx.compose.foundation.text.selection.TextSelectionColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.graphics.takeOrElse
-import androidx.compose.foundation.text.selection.TextSelectionColors
import kotlin.math.max
import kotlin.math.min
diff --git a/wear/compose/compose-navigation/src/androidTest/AndroidManifest.xml b/wear/compose/compose-navigation/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index 3c3c224..0000000
--- a/wear/compose/compose-navigation/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-<manifest />
diff --git a/wear/compose/compose-navigation/src/androidTest/kotlin/androidx/wear/compose/navigation/SwipeDismissableNavHostTest.kt b/wear/compose/compose-navigation/src/androidTest/kotlin/androidx/wear/compose/navigation/SwipeDismissableNavHostTest.kt
index 68f68b5..655e7bc 100644
--- a/wear/compose/compose-navigation/src/androidTest/kotlin/androidx/wear/compose/navigation/SwipeDismissableNavHostTest.kt
+++ b/wear/compose/compose-navigation/src/androidTest/kotlin/androidx/wear/compose/navigation/SwipeDismissableNavHostTest.kt
@@ -25,8 +25,8 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.State
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.runtime.setValue
diff --git a/wear/compose/compose-navigation/src/main/AndroidManifest.xml b/wear/compose/compose-navigation/src/main/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/compose-navigation/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
index 1a5e97a..95f6fbe 100644
--- a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
+++ b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHost.kt
@@ -25,10 +25,10 @@
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.SaveableStateHolder
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
@@ -40,13 +40,13 @@
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.Navigator
-import androidx.navigation.createGraph
import androidx.navigation.compose.LocalOwnersProvider
+import androidx.navigation.createGraph
import androidx.navigation.get
-import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.SwipeToDismissBox
import androidx.wear.compose.material.SwipeToDismissBoxState
import androidx.wear.compose.material.SwipeToDismissKeys
+import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.edgeSwipeToDismiss
import androidx.wear.compose.material.rememberSwipeToDismissBoxState
diff --git a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHostController.kt b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHostController.kt
index 6407471..42c64b5 100644
--- a/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHostController.kt
+++ b/wear/compose/compose-navigation/src/main/java/androidx/wear/compose/navigation/SwipeDismissableNavHostController.kt
@@ -16,10 +16,10 @@
package androidx.wear.compose.navigation
-import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
import androidx.compose.runtime.State
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.remember
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavController
import androidx.navigation.NavHostController
diff --git a/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml b/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e865f27..0000000
--- a/wear/compose/integration-tests/demos/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright 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.
- -->
-<manifest />
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
index 00e8d98..c54950a 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/FoundationDemos.kt
@@ -17,8 +17,8 @@
package androidx.wear.compose.integration.demos
import androidx.wear.compose.foundation.samples.CurvedAndNormalText
-import androidx.wear.compose.foundation.samples.CurvedBottomLayout
import androidx.wear.compose.foundation.samples.CurvedBackground
+import androidx.wear.compose.foundation.samples.CurvedBottomLayout
import androidx.wear.compose.foundation.samples.CurvedFixedSize
import androidx.wear.compose.foundation.samples.CurvedFontWeight
import androidx.wear.compose.foundation.samples.CurvedFonts
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/HorizontalPageIndicatorDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/HorizontalPageIndicatorDemo.kt
index 24fa8b8..163277e 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/HorizontalPageIndicatorDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/HorizontalPageIndicatorDemo.kt
@@ -24,7 +24,7 @@
import androidx.compose.foundation.shape.GenericShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@@ -37,7 +37,7 @@
@Composable
fun CustomizedHorizontalPageIndicator() {
val maxPages = 6
- var selectedPage by remember { mutableStateOf(0) }
+ var selectedPage by remember { mutableIntStateOf(0) }
val animatedSelectedPage by animateFloatAsState(
targetValue = selectedPage.toFloat(),
animationSpec = TweenSpec(durationMillis = 500)
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt
index 45ecbf2..205da0d 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/MaterialDemos.kt
@@ -36,9 +36,9 @@
import androidx.wear.compose.material.samples.ButtonWithIcon
import androidx.wear.compose.material.samples.ButtonWithText
import androidx.wear.compose.material.samples.ChipWithIconAndLabel
-import androidx.wear.compose.material.samples.ChipWithIconAndLabelsAndOverlaidPlaceholder
import androidx.wear.compose.material.samples.ChipWithIconAndLabelAndPlaceholders
import androidx.wear.compose.material.samples.ChipWithIconAndLabels
+import androidx.wear.compose.material.samples.ChipWithIconAndLabelsAndOverlaidPlaceholder
import androidx.wear.compose.material.samples.CircularProgressIndicatorFullscreenWithGap
import androidx.wear.compose.material.samples.CircularProgressIndicatorWithAnimation
import androidx.wear.compose.material.samples.CompactButtonWithIcon
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PositionIndicatorDemos.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PositionIndicatorDemos.kt
index d8f3599..27633f6 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PositionIndicatorDemos.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/PositionIndicatorDemos.kt
@@ -32,6 +32,8 @@
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -109,9 +111,9 @@
@Composable
fun ControllablePositionIndicator() {
- val position = remember { mutableStateOf(0.2f) }
- val size = remember { mutableStateOf(0.5f) }
- var alignment by remember { mutableStateOf(0) }
+ val position = remember { mutableFloatStateOf(0.2f) }
+ val size = remember { mutableFloatStateOf(0.5f) }
+ var alignment by remember { mutableIntStateOf(0) }
var reverseDirection by remember { mutableStateOf(false) }
var layoutDirection by remember { mutableStateOf(false) }
val actualLayoutDirection =
@@ -148,17 +150,17 @@
Text("Position")
DefaultInlineSlider(
modifier = Modifier.height(40.dp),
- value = position.value,
+ value = position.floatValue,
valueRange = 0f..1f,
steps = 9,
- onValueChange = { position.value = it })
+ onValueChange = { position.floatValue = it })
Text("Size")
DefaultInlineSlider(
modifier = Modifier.height(40.dp),
- value = size.value,
+ value = size.floatValue,
valueRange = 0f..1f,
steps = 9,
- onValueChange = { size.value = it })
+ onValueChange = { size.floatValue = it })
Row(modifier = Modifier.align(Alignment.CenterHorizontally)) {
Button(onClick = { alignment = (alignment + 1) % 3 }) {
Text(alignmentNames[alignment])
@@ -186,10 +188,10 @@
@Composable
fun SharedPositionIndicator() {
val listStates = listOf(rememberScrollState(), rememberScrollState())
- val selected = remember { mutableStateOf(0) }
+ val selected = remember { mutableIntStateOf(0) }
Scaffold(
positionIndicator = {
- PositionIndicator(listStates[selected.value])
+ PositionIndicator(listStates[selected.intValue])
}
) {
Row(modifier = Modifier.fillMaxSize()) {
@@ -203,7 +205,7 @@
) {
repeat(10) {
Chip(
- onClick = { selected.value = listIndex },
+ onClick = { selected.intValue = listIndex },
label = { Text("#$it") }
)
}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
index 93789b3..23056f3 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/ProgressIndicatorDemo.kt
@@ -23,6 +23,7 @@
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -50,9 +51,9 @@
@Composable
public fun ProgressWithCustomAngles() {
- var startAngle by remember { mutableStateOf(292.5f) }
- var endAngle by remember { mutableStateOf(247.5f) }
- var progress by remember { mutableStateOf(0.5f) }
+ var startAngle by remember { mutableFloatStateOf(292.5f) }
+ var endAngle by remember { mutableFloatStateOf(247.5f) }
+ var progress by remember { mutableFloatStateOf(0.5f) }
val animatedProgress: Float by animateFloatAsState(targetValue = progress)
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
index df5330a..8e038f0 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SliderDemo.kt
@@ -23,6 +23,8 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -42,8 +44,8 @@
@Composable
fun InlineSliderDemo() {
- var valueWithoutSegments by remember { mutableStateOf(5f) }
- var valueWithSegments by remember { mutableStateOf(2f) }
+ var valueWithoutSegments by remember { mutableFloatStateOf(5f) }
+ var valueWithSegments by remember { mutableFloatStateOf(2f) }
var enabled by remember { mutableStateOf(true) }
ScalingLazyColumnWithRSB(
@@ -99,8 +101,8 @@
@Composable
fun InlineSliderWithIntegersDemo() {
- var valueWithoutSegments by remember { mutableStateOf(5) }
- var valueWithSegments by remember { mutableStateOf(2) }
+ var valueWithoutSegments by remember { mutableIntStateOf(5) }
+ var valueWithSegments by remember { mutableIntStateOf(2) }
ScalingLazyColumnWithRSB(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -140,7 +142,7 @@
@Composable
fun InlineSliderCustomColorsDemo() {
- var value by remember { mutableStateOf(4.5f) }
+ var value by remember { mutableFloatStateOf(4.5f) }
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
@@ -161,8 +163,8 @@
@Composable
fun InlineSliderSegmented() {
- var numberOfSegments by remember { mutableStateOf(5f) }
- var progress by remember { mutableStateOf(10f) }
+ var numberOfSegments by remember { mutableFloatStateOf(5f) }
+ var progress by remember { mutableFloatStateOf(10f) }
ScalingLazyColumnWithRSB(
horizontalAlignment = Alignment.CenterHorizontally,
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
index 8b3db7e..3f6af0a 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/StepperDemo.kt
@@ -19,7 +19,8 @@
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
@@ -35,7 +36,7 @@
@Composable
fun StepperDemo() {
- var value by remember { mutableStateOf(2f) }
+ var value by remember { mutableFloatStateOf(2f) }
Stepper(
value = value,
onValueChange = { value = it },
@@ -48,7 +49,7 @@
@Composable
fun StepperWithIntegerDemo() {
- var value by remember { mutableStateOf(2) }
+ var value by remember { mutableIntStateOf(2) }
Stepper(
value = value,
onValueChange = { value = it },
@@ -60,26 +61,26 @@
@Composable
fun StepperWithScrollBarDemo() {
- val valueState = remember { mutableStateOf(4f) }
+ var valueState by remember { mutableFloatStateOf(4f) }
val range = 0f..10f
Stepper(
- value = valueState.value,
- onValueChange = { valueState.value = it },
+ value = valueState,
+ onValueChange = { valueState = it },
increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
valueRange = range,
steps = 9
) {
Chip(
- onClick = { valueState.value = if (valueState.value == 0f) 4f else 0f },
+ onClick = { valueState = if (valueState == 0f) 4f else 0f },
modifier = Modifier.width(146.dp),
colors = ChipDefaults.secondaryChipColors(),
- label = { Text("Volume : ${valueState.value}") },
+ label = { Text("Volume : $valueState") },
icon = {
Icon(
painter = painterResource(
- id = if (valueState.value > 0)
+ id = if (valueState > 0)
R.drawable.ic_volume_up_24px
else R.drawable.ic_volume_off_24px
),
@@ -90,30 +91,30 @@
}
PositionIndicator(
- value = { valueState.value },
+ value = { valueState },
range = range
)
}
@Composable
fun StepperWithCustomColors() {
- val valueState = remember { mutableStateOf(4f) }
+ var valueState by remember { mutableFloatStateOf(4f) }
val range = 0f..10f
Stepper(
- value = valueState.value,
- onValueChange = { valueState.value = it },
+ value = valueState,
+ onValueChange = { valueState = it },
valueRange = range,
increaseIcon = { Icon(StepperDefaults.Increase, "Increase") },
decreaseIcon = { Icon(StepperDefaults.Decrease, "Decrease") },
steps = 9,
contentColor = AlternatePrimaryColor2,
) {
- Text("Volume : ${valueState.value}")
+ Text("Volume : $valueState")
}
PositionIndicator(
- value = { valueState.value },
+ value = { valueState },
range = range
)
}
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToDismissDemoWithState.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToDismissDemoWithState.kt
index 56e01fb..2e61b3f 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToDismissDemoWithState.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToDismissDemoWithState.kt
@@ -23,6 +23,7 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
@@ -32,8 +33,8 @@
import androidx.compose.ui.Modifier
import androidx.wear.compose.material.Button
import androidx.wear.compose.material.MaterialTheme
-import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.SwipeToDismissBox
+import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.ToggleButton
import androidx.wear.compose.material.rememberSwipeToDismissBoxState
@@ -66,7 +67,7 @@
content = { isBackground ->
if (showCounterForContent.value xor isBackground)
saveableStateHolder.SaveableStateProvider(counterKey) {
- var counter by rememberSaveable { mutableStateOf(0) }
+ var counter by rememberSaveable { mutableIntStateOf(0) }
Column(
modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.primary),
horizontalAlignment = Alignment.CenterHorizontally,
diff --git a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToRevealDemo.kt b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToRevealDemo.kt
index e0f9d24..0d06716 100644
--- a/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToRevealDemo.kt
+++ b/wear/compose/integration-tests/demos/src/main/java/androidx/wear/compose/integration/demos/SwipeToRevealDemo.kt
@@ -47,21 +47,21 @@
import androidx.wear.compose.foundation.ExpandableState
import androidx.wear.compose.foundation.ExperimentalWearFoundationApi
import androidx.wear.compose.foundation.RevealScope
+import androidx.wear.compose.foundation.RevealState
+import androidx.wear.compose.foundation.RevealValue
+import androidx.wear.compose.foundation.SwipeToReveal
+import androidx.wear.compose.foundation.createAnchors
import androidx.wear.compose.foundation.expandableItem
import androidx.wear.compose.foundation.fractionalPositionalThreshold
import androidx.wear.compose.foundation.lazy.ScalingLazyColumn
import androidx.wear.compose.foundation.rememberExpandableState
+import androidx.wear.compose.foundation.rememberRevealState
import androidx.wear.compose.material.AppCard
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.MaterialTheme
-import androidx.wear.compose.foundation.SwipeToReveal
-import androidx.wear.compose.foundation.RevealState
-import androidx.wear.compose.foundation.RevealValue
import androidx.wear.compose.material.Text
-import androidx.wear.compose.foundation.createAnchors
-import androidx.wear.compose.foundation.rememberRevealState
import kotlin.math.abs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
diff --git a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/BaselineActivity.kt b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/BaselineActivity.kt
index 6d3441f..7c60533 100644
--- a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/BaselineActivity.kt
+++ b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/BaselineActivity.kt
@@ -37,6 +37,7 @@
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
@@ -527,7 +528,7 @@
horizontalAlignment = Alignment.CenterHorizontally
) {
ListHeader { Text("Sliders") }
- var value by remember { mutableStateOf(4.5f) }
+ var value by remember { mutableFloatStateOf(4.5f) }
InlineSlider(
value = value,
onValueChange = { value = it },
@@ -552,7 +553,7 @@
@Composable
fun Stepper() {
- var value by remember { mutableStateOf(2f) }
+ var value by remember { mutableFloatStateOf(2f) }
Stepper(
value = value,
onValueChange = { value = it },
diff --git a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/StartupActivity.kt b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/StartupActivity.kt
index 315a00a..db764c8 100644
--- a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/StartupActivity.kt
+++ b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/StartupActivity.kt
@@ -16,8 +16,8 @@
package androidx.wear.compose.integration.macrobenchmark.target
-import androidx.activity.ComponentActivity
import android.os.Bundle
+import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.wear.compose.material.Text
diff --git a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/SwipeActivity.kt b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/SwipeActivity.kt
index 1b3ae2f..26990fc 100644
--- a/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/SwipeActivity.kt
+++ b/wear/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/wear/compose/integration/macrobenchmark/target/SwipeActivity.kt
@@ -16,8 +16,8 @@
package androidx.wear.compose.integration.macrobenchmark.target
-import androidx.activity.ComponentActivity
import android.os.Bundle
+import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -29,8 +29,8 @@
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
-import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.SwipeToDismissBox
+import androidx.wear.compose.material.SwipeToDismissValue
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.rememberSwipeToDismissBoxState
diff --git a/wear/compose/integration-tests/macrobenchmark/build.gradle b/wear/compose/integration-tests/macrobenchmark/build.gradle
index 1e07985..414dd2b 100644
--- a/wear/compose/integration-tests/macrobenchmark/build.gradle
+++ b/wear/compose/integration-tests/macrobenchmark/build.gradle
@@ -1,5 +1,3 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-
/*
* Copyright 2021 The Android Open Source Project
*
@@ -18,7 +16,7 @@
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.test")
id("kotlin-android")
}
@@ -27,25 +25,22 @@
minSdkVersion 29
}
namespace "androidx.wear.compose.integration.macrobenchmark"
+ targetProjectPath = ":wear:compose:integration-tests:macrobenchmark-target"
+ experimentalProperties["android.experimental.self-instrumenting"] = true
}
+// Create a release build type and make sure it's the only one enabled.
+// This is needed because we benchmark the release build type only.
+android.buildTypes { release {} }
+androidComponents { beforeVariants(selector().all()) { enabled = buildType == 'release' } }
+
dependencies {
- androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation(project(":benchmark:benchmark-macro-junit4"))
- androidTestImplementation(project(":internal-testutils-macrobenchmark"))
- androidTestImplementation(libs.testRules)
- androidTestImplementation(libs.testExtJunit)
- androidTestImplementation(libs.testCore)
- androidTestImplementation(libs.testRunner)
- androidTestImplementation(libs.testUiautomator)
-}
-
-// Define a task dependency so the app is installed before we run macro benchmarks.
-afterEvaluate {
- tasks.getByPath(":wear:compose:integration-tests:macrobenchmark:connectedDebugAndroidTest")
- .dependsOn(
- tasks.getByPath(
- ":wear:compose:integration-tests:macrobenchmark-target:installRelease"
- )
- )
+ implementation(project(":benchmark:benchmark-junit4"))
+ implementation(project(":benchmark:benchmark-macro-junit4"))
+ implementation(project(":internal-testutils-macrobenchmark"))
+ implementation(libs.testRules)
+ implementation(libs.testExtJunit)
+ implementation(libs.testCore)
+ implementation(libs.testRunner)
+ implementation(libs.testUiautomator)
}
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/wear/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
deleted file mode 100644
index e0788d6..0000000
--- a/wear/compose/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 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.
- -->
-
-<manifest />
diff --git a/wear/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/wear/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
index f734545..e0788d6 100644
--- a/wear/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
+++ b/wear/compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
@@ -15,4 +15,4 @@
limitations under the License.
-->
-<manifest />
\ No newline at end of file
+<manifest />
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/BaselineProfile.kt b/wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/BaselineProfile.kt
similarity index 100%
rename from wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/BaselineProfile.kt
rename to wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/BaselineProfile.kt
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/Common.kt b/wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/Common.kt
similarity index 100%
rename from wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/Common.kt
rename to wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/Common.kt
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/ScrollBenchmark.kt b/wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/ScrollBenchmark.kt
similarity index 100%
rename from wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/ScrollBenchmark.kt
rename to wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/ScrollBenchmark.kt
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/StartupBenchmark.kt b/wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/StartupBenchmark.kt
similarity index 100%
rename from wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/StartupBenchmark.kt
rename to wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/StartupBenchmark.kt
diff --git a/wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/SwipeBenchmark.kt b/wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/SwipeBenchmark.kt
similarity index 100%
rename from wear/compose/integration-tests/macrobenchmark/src/androidTest/java/androidx/wear/compose/integration/macrobenchmark/SwipeBenchmark.kt
rename to wear/compose/integration-tests/macrobenchmark/src/main/java/androidx/wear/compose/integration/macrobenchmark/SwipeBenchmark.kt
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/current.txt b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
index 814cdba..df7ffb0 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
@@ -24,17 +24,17 @@
public static final class DynamicTypeEvaluator.Config {
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
- method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+ method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
}
public static final class DynamicTypeEvaluator.Config.Builder {
ctor public DynamicTypeEvaluator.Config.Builder();
+ method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
- method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
}
@@ -48,14 +48,25 @@
method public void onInvalidated();
}
+ public interface PlatformDataProvider {
+ method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+ method public void unregisterForData();
+ }
+
+ public interface PlatformDataReceiver {
+ method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+ }
+
public interface QuotaManager {
method public void releaseQuota(int);
method public boolean tryAcquireQuota(int);
}
public class StateStore {
- method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
- method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
+ method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
}
public interface TimeGateway {
@@ -70,22 +81,3 @@
}
-package androidx.wear.protolayout.expression.pipeline.sensor {
-
- public interface SensorGateway {
- method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
- field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
- field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
- }
-
- public static interface SensorGateway.Consumer {
- method @AnyThread public void onData(double);
- method @AnyThread public default void onInvalidated();
- method @AnyThread public default void onPreUpdate();
- }
-
-}
-
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
index 814cdba..df7ffb0 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
@@ -24,17 +24,17 @@
public static final class DynamicTypeEvaluator.Config {
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
- method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+ method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
}
public static final class DynamicTypeEvaluator.Config.Builder {
ctor public DynamicTypeEvaluator.Config.Builder();
+ method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
- method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
}
@@ -48,14 +48,25 @@
method public void onInvalidated();
}
+ public interface PlatformDataProvider {
+ method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+ method public void unregisterForData();
+ }
+
+ public interface PlatformDataReceiver {
+ method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+ }
+
public interface QuotaManager {
method public void releaseQuota(int);
method public boolean tryAcquireQuota(int);
}
public class StateStore {
- method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
- method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
+ method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
}
public interface TimeGateway {
@@ -70,22 +81,3 @@
}
-package androidx.wear.protolayout.expression.pipeline.sensor {
-
- public interface SensorGateway {
- method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
- field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
- field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
- }
-
- public static interface SensorGateway.Consumer {
- method @AnyThread public void onData(double);
- method @AnyThread public default void onInvalidated();
- method @AnyThread public default void onPreUpdate();
- }
-
-}
-
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
index 62aa8aa..8d2f955 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
@@ -24,17 +24,17 @@
public static final class DynamicTypeEvaluator.Config {
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
- method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+ method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
}
public static final class DynamicTypeEvaluator.Config.Builder {
ctor public DynamicTypeEvaluator.Config.Builder();
+ method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
- method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
}
@@ -48,16 +48,33 @@
method public void onInvalidated();
}
+ public interface PlatformDataProvider {
+ method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+ method public void unregisterForData();
+ }
+
+ public interface PlatformDataReceiver {
+ method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+ }
+
public interface QuotaManager {
method public void releaseQuota(int);
method public boolean tryAcquireQuota(int);
}
+ @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SensorGatewaySingleDataProvider implements androidx.wear.protolayout.expression.pipeline.PlatformDataProvider {
+ ctor public SensorGatewaySingleDataProvider(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway, androidx.wear.protolayout.expression.PlatformDataKey<?>);
+ method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+ method public void unregisterForData();
+ }
+
public class StateStore {
- ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public StateStore(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue!>);
- method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
- method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
- method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @UiThread public void setStateEntryValuesProto(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue!>);
+ ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public StateStore(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
+ method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+ method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @UiThread public void setAppStateEntryValuesProto(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
+ field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
}
public interface TimeGateway {
@@ -74,15 +91,12 @@
package androidx.wear.protolayout.expression.pipeline.sensor {
- public interface SensorGateway {
+ @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SensorGateway {
method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void disableUpdates();
method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void enableUpdates();
- method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
- field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
- field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
- field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
+ method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
+ method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
+ method @UiThread public void unregisterSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
}
public static interface SensorGateway.Consumer {
diff --git a/wear/protolayout/protolayout-expression-pipeline/build.gradle b/wear/protolayout/protolayout-expression-pipeline/build.gradle
index d9db9ac..4f92627 100644
--- a/wear/protolayout/protolayout-expression-pipeline/build.gradle
+++ b/wear/protolayout/protolayout-expression-pipeline/build.gradle
@@ -50,7 +50,7 @@
}
androidx {
- name = "ProtoLayout Dynamic Expression Evaluation Pipeline"
+ name = "ProtoLayout Expression Pipeline"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Evaluate dynamic expressions."
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
index c95560c..1651688 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
@@ -19,6 +19,7 @@
import android.util.Log;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
import androidx.wear.protolayout.expression.proto.DynamicProto;
import androidx.wear.protolayout.expression.proto.DynamicProto.ComparisonFloatOp;
import androidx.wear.protolayout.expression.proto.DynamicProto.ComparisonInt32Op;
@@ -65,7 +66,8 @@
DynamicTypeValueReceiverWithPreUpdate<Boolean> downstream) {
super(
stateStore,
- protoNode.getSourceKey(),
+ StateSourceNode.<DynamicBool>createKey(
+ protoNode.getSourceNamespace(), protoNode.getSourceKey()),
se -> se.getBoolVal().getValue(),
downstream);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
index 315eaf7..ed1d027 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
@@ -19,6 +19,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor;
import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedColor;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateColorSource;
@@ -64,7 +65,8 @@
DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
super(
stateStore,
- protoNode.getSourceKey(),
+ StateSourceNode.<DynamicColor>createKey(
+ protoNode.getSourceNamespace(), protoNode.getSourceKey()),
se -> se.getColorVal().getArgb(),
downstream);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
index 068ce4b..a247482 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
@@ -18,6 +18,7 @@
import static java.util.Collections.emptyMap;
+import android.annotation.SuppressLint;
import android.icu.util.ULocale;
import android.os.Handler;
import android.os.Looper;
@@ -26,7 +27,9 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
+import androidx.collection.ArrayMap;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
import androidx.wear.protolayout.expression.pipeline.BoolNodes.ComparisonFloatNode;
import androidx.wear.protolayout.expression.pipeline.BoolNodes.ComparisonInt32Node;
import androidx.wear.protolayout.expression.pipeline.BoolNodes.FixedBoolNode;
@@ -53,7 +56,7 @@
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FloatToInt32Node;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
-import androidx.wear.protolayout.expression.pipeline.Int32Nodes.PlatformInt32SourceNode;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.LegacyPlatformInt32SourceNode;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
import androidx.wear.protolayout.expression.pipeline.StringNodes.FixedStringNode;
import androidx.wear.protolayout.expression.pipeline.StringNodes.FloatFormatNode;
@@ -82,6 +85,8 @@
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -133,27 +138,28 @@
@NonNull private final QuotaManager mAnimationQuotaManager;
@NonNull private final QuotaManager mDynamicTypesQuotaManager;
@NonNull private final EpochTimePlatformDataSource mTimeDataSource;
- @Nullable private final SensorGatewayPlatformDataSource mSensorGatewayDataSource;
/** Configuration for creating {@link DynamicTypeEvaluator}. */
public static final class Config {
@Nullable private final StateStore mStateStore;
@Nullable private final QuotaManager mAnimationQuotaManager;
@Nullable private final TimeGateway mTimeGateway;
- @Nullable private final SensorGateway mSensorGateway;
@Nullable private final QuotaManager mDynamicTypesQuotaManager;
+ @NonNull private final Map<PlatformDataKey<?>, PlatformDataProvider>
+ mSourceKeyToDataProviders = new ArrayMap<>();
Config(
@Nullable StateStore stateStore,
@Nullable QuotaManager animationQuotaManager,
@Nullable QuotaManager dynamicTypesQuotaManager,
@Nullable TimeGateway timeGateway,
- @Nullable SensorGateway sensorGateway) {
+ @NonNull Map<PlatformDataKey<?>, PlatformDataProvider>
+ sourceKeyToDataProviders) {
this.mStateStore = stateStore;
this.mAnimationQuotaManager = animationQuotaManager;
this.mTimeGateway = timeGateway;
- this.mSensorGateway = sensorGateway;
this.mDynamicTypesQuotaManager = dynamicTypesQuotaManager;
+ this.mSourceKeyToDataProviders.putAll(sourceKeyToDataProviders);
}
/** Builds a {@link DynamicTypeEvaluator.Config}. */
@@ -162,8 +168,8 @@
@Nullable private QuotaManager mAnimationQuotaManager = null;
@Nullable private QuotaManager mDynamicTypesQuotaManager;
@Nullable private TimeGateway mTimeGateway = null;
-
- @Nullable private SensorGateway mSensorGateway = null;
+ @NonNull private final Map<PlatformDataKey<?>, PlatformDataProvider>
+ mSourceKeyToDataProviders = new ArrayMap<>();
/**
* Sets the state store that will be used for dereferencing the state keys in the
@@ -216,14 +222,34 @@
}
/**
- * Sets the gateway used for sensor data.
+ * Add a platform data provider and specify the keys it can provide dynamic data for.
*
- * <p>If not set, sensor data will not be available (sensor bindings will trigger {@link
- * DynamicTypeValueReceiver#onInvalidated()}).
+ * <p> The provider must support at least one key. If the provider supports multiple
+ * keys, they should not be independent, as their values should always update together.
+ * One data key must not have multiple providers, or an exception will be thrown.
+ *
+ * @throws IllegalArgumentException If a PlatformDataProvider supports an empty key
+ * set or if a key has multiple data providers.
*/
+ @SuppressLint("MissingGetterMatchingBuilder")
@NonNull
- public Builder setSensorGateway(@NonNull SensorGateway value) {
- mSensorGateway = value;
+ public Builder addPlatformDataProvider(
+ @NonNull PlatformDataProvider platformDataProvider,
+ @NonNull Set<PlatformDataKey<?>> supportedDataKeys
+ ) {
+ if (supportedDataKeys.isEmpty()) {
+ throw new IllegalArgumentException(
+ "The PlatformDataProvider must support at least one key");
+ }
+ for (PlatformDataKey<?> dataKey : supportedDataKeys) {
+ // Throws exception when one data key has multiple providers.
+ if (mSourceKeyToDataProviders.containsKey(dataKey)) {
+ throw new IllegalArgumentException(String.format(
+ "Multiple data providers for PlatformDataKey (%s)", dataKey));
+ }
+ mSourceKeyToDataProviders.put(dataKey, platformDataProvider);
+ }
+
return this;
}
@@ -234,7 +260,7 @@
mAnimationQuotaManager,
mDynamicTypesQuotaManager,
mTimeGateway,
- mSensorGateway);
+ mSourceKeyToDataProviders);
}
}
@@ -250,8 +276,8 @@
/**
* Gets the quota manager used for limiting the total number of dynamic types in the
- * pipeline, or {@code null} if there are no restriction on the number of dynamic types.
- * If present, the quota manager is used to prevent unreasonably expensive expressions.
+ * pipeline, or {@code null} if there are no restriction on the number of dynamic types. If
+ * present, the quota manager is used to prevent unreasonably expensive expressions.
*/
@Nullable
public QuotaManager getDynamicTypesQuotaManager() {
@@ -269,15 +295,6 @@
}
/**
- * Gets the gateway used for sensor data, or {@code null} if sensor data is unavailable
- * (sensor bindings will trigger {@link DynamicTypeValueReceiver#onInvalidated()}).
- */
- @Nullable
- public SensorGateway getSensorGateway() {
- return mSensorGateway;
- }
-
- /**
* Gets the gateway used for time data, or {@code null} if a default 1hz {@link TimeGateway}
* that utilizes a main-thread {@code Handler} to trigger is used.
*/
@@ -285,6 +302,15 @@
public TimeGateway getTimeGateway() {
return mTimeGateway;
}
+
+ /**
+ * Returns any available mapping between source key and its data provider.
+ */
+ @NonNull
+ public Map<PlatformDataKey<?>, PlatformDataProvider> getPlatformDataProviders() {
+ return new ArrayMap<>(
+ (ArrayMap<PlatformDataKey<?>, PlatformDataProvider>) mSourceKeyToDataProviders);
+ }
}
/** Constructs a {@link DynamicTypeEvaluator}. */
@@ -303,16 +329,12 @@
MainThreadExecutor uiExecutor = new MainThreadExecutor(uiHandler);
TimeGateway timeGateway = config.getTimeGateway();
if (timeGateway == null) {
- timeGateway = new TimeGatewayImpl(uiHandler);
- ((TimeGatewayImpl) timeGateway).enableUpdates();
+ timeGateway = new TimeGatewayImpl(uiHandler);
+ ((TimeGatewayImpl) timeGateway).enableUpdates();
}
this.mTimeDataSource = new EpochTimePlatformDataSource(uiExecutor, timeGateway);
- if (config.getSensorGateway() != null) {
- this.mSensorGatewayDataSource =
- new SensorGatewayPlatformDataSource(uiExecutor, config.getSensorGateway());
- } else {
- this.mSensorGatewayDataSource = null;
- }
+
+ this.mStateStore.putAllPlatformProviders(config.getPlatformDataProviders());
}
/**
@@ -331,7 +353,7 @@
if (!mDynamicTypesQuotaManager.tryAcquireQuota(boundDynamicType.getDynamicNodeCount())) {
throw new EvaluationException(
"Dynamic type expression limit reached. Try making the dynamic type expression"
- + " shorter or reduce the number of dynamic type expressions.");
+ + " shorter or reduce the number of dynamic type expressions.");
}
return boundDynamicType;
}
@@ -528,10 +550,8 @@
}
case STATE_SOURCE:
{
- node =
- new StateStringNode(
- mStateStore, stringSource.getStateSource(), consumer);
- break;
+ node = new StateStringNode(mStateStore, stringSource.getStateSource(), consumer);
+ break;
}
case CONDITIONAL_OP:
{
@@ -595,13 +615,13 @@
case FIXED:
node = new FixedInt32Node(int32Source.getFixed(), consumer);
break;
- case PLATFORM_SOURCE:
- node =
- new PlatformInt32SourceNode(
- int32Source.getPlatformSource(),
- mSensorGatewayDataSource,
- consumer);
+ case PLATFORM_SOURCE: {
+ node = new LegacyPlatformInt32SourceNode(
+ mStateStore,
+ int32Source.getPlatformSource(),
+ consumer);
break;
+ }
case ARITHMETIC_OPERATION:
{
ArithmeticInt32Node arithmeticNode =
@@ -621,9 +641,8 @@
}
case STATE_SOURCE:
{
- node =
- new StateInt32SourceNode(
- mStateStore, int32Source.getStateSource(), consumer);
+ node = new StateInt32SourceNode(
+ mStateStore, int32Source.getStateSource(), consumer);
break;
}
case CONDITIONAL_OP:
@@ -819,9 +838,8 @@
node = new FixedFloatNode(floatSource.getFixed(), consumer);
break;
case STATE_SOURCE:
- node =
- new StateFloatSourceNode(
- mStateStore, floatSource.getStateSource(), consumer);
+ node = new StateFloatSourceNode(
+ mStateStore, floatSource.getStateSource(), consumer);
break;
case ARITHMETIC_OPERATION:
{
@@ -920,9 +938,8 @@
node = new FixedColorNode(colorSource.getFixed(), consumer);
break;
case STATE_SOURCE:
- node =
- new StateColorSourceNode(
- mStateStore, colorSource.getStateSource(), consumer);
+ node = new StateColorSourceNode(
+ mStateStore, colorSource.getStateSource(), consumer);
break;
case ANIMATABLE_FIXED:
// We don't have to check if enableAnimations is true, because if it's false and
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
index 71ddbd09..9ebd1b1 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
@@ -21,6 +21,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedFloat;
import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticFloatOp;
@@ -72,7 +73,8 @@
DynamicTypeValueReceiverWithPreUpdate<Float> downstream) {
super(
stateStore,
- protoNode.getSourceKey(),
+ StateSourceNode.<DynamicFloat>createKey(
+ protoNode.getSourceNamespace(), protoNode.getSourceKey()),
se -> se.getFloatVal().getValue(),
downstream);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
index d542928..5893701 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
@@ -23,6 +23,10 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
+import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedInt32;
import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticInt32Op;
@@ -70,61 +74,31 @@
}
/** Dynamic integer node that gets value from the platform source. */
- static class PlatformInt32SourceNode implements DynamicDataSourceNode<Integer> {
- private static final String TAG = "PlatformInt32SourceNode";
+ static class LegacyPlatformInt32SourceNode extends StateSourceNode<Integer> {
- @Nullable private final SensorGatewayPlatformDataSource mSensorGatewaySource;
- private final PlatformInt32SourceType mPlatformSourceType;
- private final DynamicTypeValueReceiverWithPreUpdate<Integer> mDownstream;
-
- PlatformInt32SourceNode(
+ LegacyPlatformInt32SourceNode(
+ StateStore stateStore,
PlatformInt32Source protoNode,
- @Nullable SensorGatewayPlatformDataSource sensorGatewaySource,
DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
- this.mPlatformSourceType = protoNode.getSourceType();
- if (mPlatformSourceType
- == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE
- || mPlatformSourceType
- == PlatformInt32SourceType
- .PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT) {
- this.mSensorGatewaySource = sensorGatewaySource;
- } else {
- this.mSensorGatewaySource = null;
- Log.w(TAG, "Unknown PlatformInt32SourceType: " + mPlatformSourceType);
- }
- this.mDownstream = downstream;
+ super(
+ stateStore,
+ getDataKey(protoNode.getSourceType()),
+ se -> se.getInt32Val().getValue(),
+ downstream);
}
- @Override
- @UiThread
- public void preInit() {
- if (mSensorGatewaySource != null) {
- mDownstream.onPreUpdate();
+ @NonNull
+ private static DynamicDataKey<?> getDataKey(PlatformInt32SourceType type) {
+ if (type == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE) {
+ return PlatformHealthSources.HEART_RATE_BPM;
}
- }
- @Override
- @UiThread
- public void init() {
- if (mSensorGatewaySource != null) {
- try {
- mSensorGatewaySource.registerForData(mPlatformSourceType, mDownstream);
- } catch (SecurityException e) {
- // Package does not have the permission to request the health data.
- Log.w(TAG, e.getMessage(), e);
- mDownstream.onInvalidated();
- }
- } else {
- mDownstream.onInvalidated();
+ if (type == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT) {
+ return PlatformHealthSources.DAILY_STEPS;
}
- }
- @Override
- @UiThread
- public void destroy() {
- if (mSensorGatewaySource != null) {
- mSensorGatewaySource.unregisterForData(mPlatformSourceType, mDownstream);
- }
+ throw new IllegalArgumentException(
+ "Unknown DynamicInt32 platform source type: " + type);
}
}
@@ -175,7 +149,8 @@
DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
super(
stateStore,
- protoNode.getSourceKey(),
+ StateSourceNode.<DynamicInt32>createKey(
+ protoNode.getSourceNamespace(), protoNode.getSourceKey()),
se -> se.getInt32Val().getValue(),
downstream);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java
new file mode 100644
index 0000000..6380561
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * This interface is used by platform data providers to yield dynamic data for their supported data
+ * keys.
+ *
+ * <p> It's up to the implementations to check if the expression provider has the required
+ * permission before sending data with {@link PlatformDataReceiver#onData(Map)} )}. If a required
+ * permission is not granted or is revoked they should stop sending more data and call
+ * {@link DynamicTypeValueReceiver#onInvalidated()} instead.
+ */
+public interface PlatformDataProvider {
+ /**
+ * Registers a callback for receiving the platform data from this provider.
+ *
+ * <p> The implementation should periodically send the dynamic data values for the set of
+ * {@link PlatformDataKey}s specified when registering this {@link PlatformDataProvider} in
+ * {@link DynamicTypeEvaluator.Config.Builder#addPlatformDataProvider}
+ */
+ void registerForData(@NonNull Executor executor, @NonNull PlatformDataReceiver callback);
+
+ /**
+ * Unregister from the provider.
+ */
+ void unregisterForData();
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java
new file mode 100644
index 0000000..f50e2a2
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Callback for receiving a PlatformDataProvider's new data.
+ */
+public interface PlatformDataReceiver {
+ /**
+ * Called when the registered data provider is sending new values.
+ */
+ void onData(@NonNull Map<PlatformDataKey<?>, DynamicDataValue> newData);
+
+ /** Called when the data provider has an invalid result. */
+ void onInvalidated(@NonNull Set<PlatformDataKey<?>> keys);
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java
deleted file mode 100644
index 9297ea7..0000000
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * 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 androidx.wear.protolayout.expression.pipeline;
-
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-
-import androidx.annotation.DoNotInline;
-import androidx.annotation.RequiresApi;
-import androidx.collection.ArrayMap;
-import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
-import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.SensorDataType;
-import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
-
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/** Utility for sensor data source. */
-class SensorGatewayPlatformDataSource {
- private static final String TAG = "SensorGtwPltDataSource";
- final Executor mUiExecutor;
- private final SensorGateway mSensorGateway;
- private final Map<
- DynamicTypeValueReceiverWithPreUpdate<Integer>, SensorGateway.Consumer>
- mCallbackToRegisteredSensorConsumer = new ArrayMap<>();
-
- SensorGatewayPlatformDataSource(Executor uiExecutor, SensorGateway sensorGateway) {
- this.mUiExecutor = uiExecutor;
- this.mSensorGateway = sensorGateway;
- }
-
- @SensorDataType
- private static int mapSensorPlatformSource(PlatformInt32SourceType platformSource) {
- switch (platformSource) {
- case PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE:
- return SensorGateway.SENSOR_DATA_TYPE_HEART_RATE;
- case PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT:
- if (VERSION.SDK_INT >= VERSION_CODES.Q) {
- return Api29Impl.getSensorDataTypeDailyStepCount();
- } else {
- return SensorGateway.SENSOR_DATA_TYPE_INVALID;
- }
- default:
- throw new IllegalArgumentException("Unknown PlatformSourceType");
- }
- }
-
- @SuppressWarnings("ExecutorTaskName")
- public void registerForData(
- PlatformInt32SourceType sourceType,
- DynamicTypeValueReceiverWithPreUpdate<Integer> callback) {
- @SensorDataType int sensorDataType = mapSensorPlatformSource(sourceType);
- SensorGateway.Consumer sensorConsumer =
- new SensorGateway.Consumer() {
- @Override
- public void onPreUpdate() {
- mUiExecutor.execute(callback::onPreUpdate);
- }
-
- @Override
- public void onData(double value) {
- mUiExecutor.execute(() -> callback.onData((int) value));
- }
-
- @Override
- public void onInvalidated() {
- mUiExecutor.execute(callback::onInvalidated);
- }
- };
- mCallbackToRegisteredSensorConsumer.put(callback, sensorConsumer);
- mSensorGateway.registerSensorGatewayConsumer(sensorDataType, sensorConsumer);
- }
-
- public void unregisterForData(
- PlatformInt32SourceType sourceType,
- DynamicTypeValueReceiverWithPreUpdate<Integer> consumer) {
- @SensorDataType int sensorDataType = mapSensorPlatformSource(sourceType);
- SensorGateway.Consumer sensorConsumer = mCallbackToRegisteredSensorConsumer.get(consumer);
- if (sensorConsumer != null) {
- mSensorGateway.unregisterSensorGatewayConsumer(sensorDataType, sensorConsumer);
- }
- }
-
- @RequiresApi(VERSION_CODES.Q)
- private static class Api29Impl {
- @DoNotInline
- static int getSensorDataTypeDailyStepCount() {
- return SensorGateway.SENSOR_DATA_TYPE_DAILY_STEP_COUNT;
- }
- }
-}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java
new file mode 100644
index 0000000..ee1671e
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.RestrictTo.Scope;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/** This provider provides sensor data as state value. */
+@RestrictTo(Scope.LIBRARY_GROUP_PREFIX)
+public class SensorGatewaySingleDataProvider implements PlatformDataProvider {
+ @NonNull private final SensorGateway mSensorGateway;
+ @NonNull final PlatformDataKey<?> mSupportedKey;
+ @Nullable private SensorGateway.Consumer mSensorGatewayConsumer = null;
+
+ public SensorGatewaySingleDataProvider(
+ @NonNull SensorGateway sensorGateway,
+ @NonNull PlatformDataKey<?> supportedKey
+ ) {
+ this.mSensorGateway = sensorGateway;
+ this.mSupportedKey = supportedKey;
+ }
+
+ @Override
+ @SuppressWarnings("HiddenTypeParameters")
+ public void registerForData(
+ @NonNull Executor executor, @NonNull PlatformDataReceiver callback) {
+ SensorGateway.Consumer sensorConsumer =
+ new SensorGateway.Consumer() {
+ @Override
+ public void onData(double value) {
+ executor.execute(() -> callback.onData(
+ Map.of(mSupportedKey, DynamicDataValue.fromFloat((float) value)))
+ );
+ }
+
+ @Override
+ public void onInvalidated() {
+ executor.execute(() -> callback.onInvalidated(
+ Collections.singleton(mSupportedKey)));
+ }
+ };
+ mSensorGatewayConsumer = sensorConsumer;
+ mSensorGateway.registerSensorGatewayConsumer(mSupportedKey, sensorConsumer);
+ }
+
+ @Override
+ public void unregisterForData() {
+ if (mSensorGatewayConsumer != null) {
+ mSensorGateway.unregisterSensorGatewayConsumer(mSupportedKey, mSensorGatewayConsumer);
+ mSensorGatewayConsumer = null;
+ }
+ }
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
index 3645fef..1cd0634 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
@@ -18,25 +18,29 @@
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicType;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import java.util.function.Function;
class StateSourceNode<T>
implements DynamicDataSourceNode<T>,
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> {
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> {
private final StateStore mStateStore;
- private final String mBindKey;
- private final Function<StateEntryValue, T> mStateExtractor;
+ private final DynamicDataKey<?> mKey;
+ private final Function<DynamicDataValue, T> mStateExtractor;
private final DynamicTypeValueReceiverWithPreUpdate<T> mDownstream;
StateSourceNode(
StateStore stateStore,
- String bindKey,
- Function<StateEntryValue, T> stateExtractor,
+ DynamicDataKey<?> key,
+ Function<DynamicDataValue, T> stateExtractor,
DynamicTypeValueReceiverWithPreUpdate<T> downstream) {
this.mStateStore = stateStore;
- this.mBindKey = bindKey;
+ this.mKey = key;
this.mStateExtractor = stateExtractor;
this.mDownstream = downstream;
}
@@ -50,8 +54,8 @@
@Override
@UiThread
public void init() {
- mStateStore.registerCallback(mBindKey, this);
- StateEntryValue item = mStateStore.getStateEntryValuesProto(mBindKey);
+ mStateStore.registerCallback(mKey, this);
+ DynamicDataValue item = mStateStore.getDynamicDataValuesProto(mKey);
if (item != null) {
this.onData(item);
@@ -63,7 +67,7 @@
@Override
@UiThread
public void destroy() {
- mStateStore.unregisterCallback(mBindKey, this);
+ mStateStore.unregisterCallback(mKey, this);
}
@Override
@@ -72,7 +76,7 @@
}
@Override
- public void onData(@NonNull StateEntryValue newData) {
+ public void onData(@NonNull DynamicDataValue newData) {
T actualValue = mStateExtractor.apply(newData);
mDownstream.onData(actualValue);
}
@@ -81,4 +85,13 @@
public void onInvalidated() {
mDownstream.onInvalidated();
}
+
+ @NonNull
+ static <T extends DynamicType> DynamicDataKey<T> createKey(
+ @NonNull String namespace, @NonNull String key) {
+ if (namespace.isEmpty()) {
+ return new AppDataKey<T>(key);
+ }
+ return new PlatformDataKey<T>(namespace, key);
+ }
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
index c2ce371..c42ba8f 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
@@ -18,19 +18,27 @@
import static java.util.stream.Collectors.toMap;
+import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.Looper;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.UiThread;
import androidx.collection.ArrayMap;
import androidx.collection.ArraySet;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.stream.Stream;
/**
@@ -41,131 +49,328 @@
* must only be used from the UI thread.
*/
public class StateStore {
- @NonNull private final Map<String, StateEntryValue> mCurrentState = new ArrayMap<>();
+ /**
+ * Maximum number for state entries allowed for this {@link StateStore}.
+ *
+ * <p>The ProtoLayout state model is not designed to handle large volumes of layout provided
+ * state. So we limit the number of state entries to keep the on-the-wire size and state
+ * store update times manageable.
+ */
+ @SuppressLint("MinMaxConstant")
+ public static final int MAX_STATE_ENTRY_COUNT = 100;
+
+ private final Executor mUiExecutor;
+ @NonNull private final Map<AppDataKey<?>, DynamicDataValue> mCurrentAppState
+ = new ArrayMap<>();
@NonNull
- private final Map<String, Set<DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>>>
+ private final Map<PlatformDataKey<?>, DynamicDataValue> mCurrentPlatformData
+ = new ArrayMap<>();
+
+ @NonNull
+ private final
+ Map<DynamicDataKey<?>,
+ Set<DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue>>>
mRegisteredCallbacks = new ArrayMap<>();
- /** Creates a {@link StateStore}. */
+ @NonNull
+ private final Map<PlatformDataKey<?>, PlatformDataProvider>
+ mSourceKeyToDataProviders = new ArrayMap<>();
+
+ @NonNull
+ private final Map<PlatformDataProvider, Integer> mProviderToRegisteredKeyCount
+ = new ArrayMap<>();
+
+ /**
+ * Creates a {@link StateStore}.
+ *
+ * @throws IllegalStateException if number of initialState entries is greater than
+ * {@link StateStore#MAX_STATE_ENTRY_COUNT}.
+ */
@NonNull
public static StateStore create(
- @NonNull Map<String, StateEntryBuilders.StateEntryValue> initialState) {
+ @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue>
+ initialState) {
return new StateStore(toProto(initialState));
}
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
- public StateStore(@NonNull Map<String, StateEntryValue> initialState) {
- mCurrentState.putAll(initialState);
+ public StateStore(
+ @NonNull Map<AppDataKey<?>, DynamicDataValue> initialState) {
+ if (initialState.size() > MAX_STATE_ENTRY_COUNT) {
+ throw stateTooLargeException(initialState.size());
+ }
+ mCurrentAppState.putAll(initialState);
+ mUiExecutor = new MainThreadExecutor(new Handler(Looper.getMainLooper()));
+ }
+
+ void putAllPlatformProviders(
+ @NonNull Map<PlatformDataKey<?>, PlatformDataProvider> sourceKeyToDataProviders) {
+ mSourceKeyToDataProviders.putAll(sourceKeyToDataProviders);
}
/**
- * Sets the given state, replacing the current state.
+ * Sets the given app state, replacing the current app state.
*
* <p>Informs registered listeners of changed values, invalidates removed values.
+ *
+ * @throws IllegalStateException if number of state entries is greater than
+ * {@link StateStore#MAX_STATE_ENTRY_COUNT}. The state will not update and old state entries
+ * will stay in place.
*/
@UiThread
- public void setStateEntryValues(
- @NonNull Map<String, StateEntryBuilders.StateEntryValue> newState) {
- setStateEntryValuesProto(toProto(newState));
+ public void setAppStateEntryValues(
+ @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> newState) {
+ setAppStateEntryValuesProto(toProto(newState));
}
/**
- * Sets the given state, replacing the current state.
+ * Sets the given app state, replacing the current app state.
*
* <p>Informs registered listeners of changed values, invalidates removed values.
+ *
+ * @throws IllegalStateException if number of state entries is larger than
+ * {@link StateStore#MAX_STATE_ENTRY_COUNT}. The state will not update and old state entries
+ * will stay in place.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
@UiThread
- public void setStateEntryValuesProto(@NonNull Map<String, StateEntryValue> newState) {
+ public void setAppStateEntryValuesProto(
+ @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
+ if (newState.size() > MAX_STATE_ENTRY_COUNT) {
+ throw stateTooLargeException(newState.size());
+ }
+
// Figure out which nodes have actually changed.
- Set<String> removedKeys = getRemovedKeys(newState);
- Map<String, StateEntryValue> changedEntries = getChangedEntries(newState);
+ Set<AppDataKey<?>> removedKeys = getRemovedAppKeys(newState);
+ Map<AppDataKey<?>, DynamicDataValue> changedEntries = getChangedAppEntries(newState);
Stream.concat(removedKeys.stream(), changedEntries.keySet().stream())
.forEach(
key -> {
- for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>
- callback :
- mRegisteredCallbacks.getOrDefault(
- key, Collections.emptySet())) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+ mRegisteredCallbacks.getOrDefault(
+ key, Collections.emptySet())) {
callback.onPreUpdate();
}
});
- mCurrentState.clear();
- mCurrentState.putAll(newState);
+ mCurrentAppState.clear();
+ mCurrentAppState.putAll(newState);
- for (String key : removedKeys) {
- for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback :
+ for (AppDataKey<?> key : removedKeys) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
callback.onInvalidated();
}
}
- for (Entry<String, StateEntryValue> entry : changedEntries.entrySet()) {
- for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback :
+ for (Entry<AppDataKey<?>, DynamicDataValue> entry
+ : changedEntries.entrySet()) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
callback.onData(entry.getValue());
}
}
}
- /** Gets state with the given key. */
- @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
- @UiThread
- @Nullable
- public StateEntryValue getStateEntryValuesProto(@NonNull String key) {
- return mCurrentState.get(key);
+ /**
+ * Update the given platform data item.
+ *
+ * <p>Informs registered listeners of changed values.
+ */
+ void updatePlatformDataEntries(
+ @NonNull Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue> newData) {
+ updatePlatformDataEntryProto(
+ newData.entrySet().stream().collect(
+ toMap(Entry::getKey, entry -> entry.getValue().toDynamicDataValueProto()))
+ );
}
/**
- * Registers the given callback for updates to the state for the given key.
+ * Update the given platform data item.
+ *
+ * <p>Informs registered listeners of changed values.
+ */
+ void updatePlatformDataEntryProto(
+ @NonNull Map<PlatformDataKey<?>, DynamicDataValue> newData) {
+ Map<PlatformDataKey<?>, DynamicDataValue> changedEntries = new ArrayMap<>();
+ for (Entry<PlatformDataKey<?>, DynamicDataValue> newEntry : newData.entrySet()) {
+ DynamicDataValue currentEntry = mCurrentPlatformData.get(newEntry.getKey());
+ if (currentEntry == null || !currentEntry.equals(newEntry.getValue())) {
+ changedEntries.put(newEntry.getKey(), newEntry.getValue());
+ }
+ }
+
+ for (Entry<PlatformDataKey<?>, DynamicDataValue> entry : changedEntries.entrySet()) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+ mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
+ callback.onPreUpdate();
+ }
+ }
+
+ for (Entry<PlatformDataKey<?>, DynamicDataValue> entry : changedEntries.entrySet()) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+ mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
+ callback.onData(entry.getValue());
+ }
+ mCurrentPlatformData.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ /**
+ * Remove the platform data item with the given key.
+ *
+ * <p>Informs registered listeners by invalidating removed values.
+ */
+ void removePlatformDataEntry(@NonNull Set<PlatformDataKey<?>> keys) {
+ for (PlatformDataKey<?> key : keys) {
+ if (mCurrentPlatformData.get(key) != null) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+ mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
+ callback.onPreUpdate();
+ }
+ }
+ }
+
+ for (PlatformDataKey<?> key : keys) {
+ if (mCurrentPlatformData.get(key) != null) {
+ for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+ mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
+ callback.onInvalidated();
+ }
+ mCurrentPlatformData.remove(key);
+ }
+ }
+ }
+
+ /** Gets dynamic value with the given {@code key}. */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ @UiThread
+ @Nullable
+ public DynamicDataValue getDynamicDataValuesProto(@NonNull DynamicDataKey<?> key) {
+ if (key instanceof AppDataKey) {
+ return mCurrentAppState.get(key);
+ }
+
+ if (key instanceof PlatformDataKey) {
+ return mCurrentPlatformData.get(key);
+ }
+
+ return null;
+ }
+
+ /**
+ * Registers the given callback for updates to the data item for the given {@code key}.
*
* <p>Note that the callback will be executed on the UI thread.
*/
@UiThread
void registerCallback(
- @NonNull String key,
- @NonNull DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback) {
+ @NonNull DynamicDataKey<?> key,
+ @NonNull DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback) {
mRegisteredCallbacks.computeIfAbsent(key, k -> new ArraySet<>()).add(callback);
+
+ if (!(key instanceof PlatformDataKey) ||
+ (mRegisteredCallbacks.containsKey(key) && mRegisteredCallbacks.get(key).size() > 1)
+ ) {
+ return;
+ }
+
+ PlatformDataProvider platformDataProvider = mSourceKeyToDataProviders.get(key);
+ if (platformDataProvider != null) {
+ int registeredKeyCount =
+ mProviderToRegisteredKeyCount.getOrDefault(platformDataProvider, 0);
+
+ if (registeredKeyCount == 0) {
+ platformDataProvider.registerForData(
+ mUiExecutor,
+ new PlatformDataReceiver() {
+ @Override
+ public void onData(
+ @NonNull
+ Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue>
+ newData) {
+ updatePlatformDataEntries(newData);
+ }
+
+ @Override
+ public void onInvalidated(@NonNull Set<PlatformDataKey<?>> keys) {
+ removePlatformDataEntry(keys);
+ }
+ });
+ }
+
+ mProviderToRegisteredKeyCount.put(platformDataProvider, registeredKeyCount + 1);
+ } else {
+ throw new IllegalArgumentException(
+ String.format("No platform data provider for %s", key));
+ }
}
- /** Unregisters from receiving the updates. */
+ /** Unregisters the callback for the given {@code key} from receiving the updates. */
@UiThread
void unregisterCallback(
- @NonNull String key,
- @NonNull DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback) {
- Set<DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>> callbackSet =
+ @NonNull DynamicDataKey<?> key,
+ @NonNull DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback) {
+
+ Set<DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue>> callbackSet =
mRegisteredCallbacks.get(key);
if (callbackSet != null) {
callbackSet.remove(callback);
+
+ if (!(key instanceof PlatformDataKey) || !callbackSet.isEmpty()) {
+ return;
+ }
+
+ PlatformDataProvider platformDataProvider = mSourceKeyToDataProviders.get(key);
+ if (platformDataProvider != null) {
+ int registeredKeyCount =
+ mProviderToRegisteredKeyCount.getOrDefault(platformDataProvider, 0);
+ if (registeredKeyCount == 1) {
+ platformDataProvider.unregisterForData();
+ }
+ mProviderToRegisteredKeyCount.put(platformDataProvider, registeredKeyCount - 1);
+ } else {
+ throw new IllegalArgumentException(
+ String.format("No platform data provider for %s", key));
+ }
}
}
@NonNull
- private static Map<String, StateEntryValue> toProto(
- @NonNull Map<String, StateEntryBuilders.StateEntryValue> value) {
+ private static Map<AppDataKey<?>, DynamicDataValue> toProto(
+ @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> value) {
return value.entrySet().stream()
- .collect(toMap(Entry::getKey, entry -> entry.getValue().toStateEntryValueProto()));
+ .collect(toMap(Entry::getKey, entry -> entry.getValue().toDynamicDataValueProto()));
}
@NonNull
- private Set<String> getRemovedKeys(@NonNull Map<String, StateEntryValue> newState) {
- Set<String> result = new ArraySet<>(mCurrentState.keySet());
+ private Set<AppDataKey<?>> getRemovedAppKeys(
+ @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
+ Set<AppDataKey<?>> result = new ArraySet<>(mCurrentAppState.keySet());
result.removeAll(newState.keySet());
return result;
}
@NonNull
- private Map<String, StateEntryValue> getChangedEntries(
- @NonNull Map<String, StateEntryValue> newState) {
- Map<String, StateEntryValue> result = new ArrayMap<>();
- for (Entry<String, StateEntryValue> newEntry : newState.entrySet()) {
- StateEntryValue currentEntry = mCurrentState.get(newEntry.getKey());
+ private Map<AppDataKey<?>, DynamicDataValue> getChangedAppEntries(
+ @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
+ Map<AppDataKey<?>, DynamicDataValue> result = new ArrayMap<>();
+ for (Entry<AppDataKey<?>, DynamicDataValue> newEntry
+ : newState.entrySet()) {
+ DynamicDataValue currentEntry = mCurrentAppState.get(newEntry.getKey());
if (currentEntry == null || !currentEntry.equals(newEntry.getValue())) {
result.put(newEntry.getKey(), newEntry.getValue());
}
}
return result;
}
+
+ static IllegalStateException stateTooLargeException(int stateSize) {
+ return new IllegalStateException(
+ String.format(
+ "Too many state entries: %d. The maximum number of allowed state entries "
+ + "is %d.",
+ stateSize, MAX_STATE_ENTRY_COUNT));
+ }
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
index e168776..77dcfc4 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
@@ -19,6 +19,7 @@
import static java.lang.Math.min;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateStringSource;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
@@ -104,7 +105,8 @@
DynamicTypeValueReceiverWithPreUpdate<String> downstream) {
super(
stateStore,
- protoNode.getSourceKey(),
+ StateSourceNode.<DynamicString>createKey(
+ protoNode.getSourceNamespace(), protoNode.getSourceKey()),
se -> truncate(se.getStringVal().getValue()),
downstream);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
index d6f656d..b6eef40 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
@@ -16,58 +16,23 @@
package androidx.wear.protolayout.expression.pipeline.sensor;
-import android.Manifest;
-import android.os.Build.VERSION_CODES;
-
import androidx.annotation.AnyThread;
-import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RequiresPermission;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
/**
* Gateway for proto layout expression library to be able to access sensor data, e.g. health data.
*/
+@RestrictTo(Scope.LIBRARY_GROUP_PREFIX)
public interface SensorGateway {
- /** Sensor data types that can be subscribed to from {@link SensorGateway}. */
- @RestrictTo(Scope.LIBRARY_GROUP)
- @Retention(RetentionPolicy.SOURCE)
- @RequiresApi(VERSION_CODES.Q)
- @IntDef({
- SENSOR_DATA_TYPE_INVALID,
- SENSOR_DATA_TYPE_HEART_RATE,
- SENSOR_DATA_TYPE_DAILY_STEP_COUNT
- })
- public @interface SensorDataType {};
-
- /** Invalid data type. Used to return error states. */
- int SENSOR_DATA_TYPE_INVALID = -1;
-
- /**
- * The user's current heart rate. This is an instantaneous reading from the last time it was
- * sampled. Note that this means that apps which subscribe to passive heart rate data may not
- * receive exact heart rate data; it will be batched to a given period.
- */
- @RequiresPermission(Manifest.permission.BODY_SENSORS)
- int SENSOR_DATA_TYPE_HEART_RATE = 0;
-
- /**
- * The user's current daily step count. Note that this data type will reset to zero at midnight.
- * each day, and any subscriptions to this data type will log the number of steps the user has
- * done since 12:00AM local time.
- */
- @RequiresApi(VERSION_CODES.Q)
- @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
- int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1;
-
/**
* Consumer for sensor data.
*
@@ -147,15 +112,15 @@
* type.
*
* <p>Note that the callback will be executed on the single background thread (implementation
- * dependent). To specify the execution thread, use {@link #registerSensorGatewayConsumer(int,
- * Executor, Consumer)}.
+ * dependent). To specify the execution thread, use {@link #registerSensorGatewayConsumer(
+ * PlatformDataKey, Executor, Consumer)}.
*
* @throws SecurityException if the provider does not have permission to provide requested data
* type.
*/
@UiThread
void registerSensorGatewayConsumer(
- @SensorDataType int requestedDataType, @NonNull Consumer consumer);
+ @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer);
/**
* Register for updates for the given data type. This may cause {@link Consumer} to immediately
@@ -172,12 +137,12 @@
*/
@UiThread
void registerSensorGatewayConsumer(
- @SensorDataType int requestedDataType,
+ @NonNull PlatformDataKey<?> key,
@NonNull /* @CallbackExecutor */ Executor executor,
@NonNull Consumer consumer);
/** Unregister for updates for the given data type. */
@UiThread
void unregisterSensorGatewayConsumer(
- @SensorDataType int requestedDataType, @NonNull Consumer consumer);
+ @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer);
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
index e5f987c..bf04b5e 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
@@ -23,13 +23,15 @@
import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
import androidx.wear.protolayout.expression.pipeline.BoolNodes.FixedBoolNode;
import androidx.wear.protolayout.expression.pipeline.BoolNodes.StateBoolNode;
import androidx.wear.protolayout.expression.proto.DynamicProto;
import androidx.wear.protolayout.expression.proto.DynamicProto.LogicalBoolOp;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateBoolSource;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedBool;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
@@ -57,8 +59,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBool>("foo"),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(true))
.build()));
@@ -77,8 +79,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBool>("foo"),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(true))
.build()));
@@ -90,10 +92,10 @@
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBool>("foo"),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(false))
.build()));
@@ -103,11 +105,12 @@
@Test
public void stateBoolNoUpdatesAfterDestroy() {
List<Boolean> results = new ArrayList<>();
+ AppDataKey<DynamicBool> keyFoo = new AppDataKey<>("foo");
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(false))
.build()));
@@ -120,10 +123,10 @@
results.clear();
node.destroy();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(true))
.build()));
assertThat(results).isEmpty();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
index 20e1177..cbf06ed 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
@@ -25,6 +25,8 @@
import android.os.Looper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.expression.pipeline.ColorNodes.AnimatableFixedColorNode;
import androidx.wear.protolayout.expression.pipeline.ColorNodes.DynamicAnimatedColorNode;
import androidx.wear.protolayout.expression.pipeline.ColorNodes.FixedColorNode;
@@ -33,7 +35,7 @@
import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedColor;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateColorSource;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedColor;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -49,6 +51,7 @@
private static final int FROM_COLOR = 0xFF00FF00;
private static final int TO_COLOR = 0xFFFF00FF;
+ private static final AppDataKey<DynamicColor> KEY_FOO = new AppDataKey<>("foo");
@Test
public void fixedColorNode() {
@@ -69,8 +72,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
.build()));
@@ -90,8 +93,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
.build()));
StateColorSource protoNode = StateColorSource.newBuilder().setSourceKey("foo").build();
@@ -100,10 +103,10 @@
node.preInit();
node.init();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
.build()));
@@ -116,8 +119,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
.build()));
StateColorSource protoNode = StateColorSource.newBuilder().setSourceKey("foo").build();
@@ -130,10 +133,10 @@
results.clear();
node.destroy();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
.build()));
assertThat(results).isEmpty();
@@ -213,8 +216,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(
FixedColor.newBuilder().setArgb(FROM_COLOR).build())
.build()));
@@ -233,10 +236,10 @@
stateNode.preInit();
stateNode.init();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -256,8 +259,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(
FixedColor.newBuilder().setArgb(color1).build())
.build()));
@@ -277,10 +280,10 @@
stateNode.init();
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(color2))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -291,10 +294,10 @@
colorNode.setVisibility(true);
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(color3))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -316,8 +319,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(
FixedColor.newBuilder().setArgb(color1).build())
.build()));
@@ -339,10 +342,10 @@
stateNode.init();
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(color2))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -352,10 +355,10 @@
// Release the only quota
quotaManager.releaseQuota(1);
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(color3))
.build()));
shadowOf(Looper.getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
index 9a466a2..a1acb98 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
@@ -25,6 +25,8 @@
import android.os.Looper;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.expression.pipeline.FloatNodes.AnimatableFixedFloatNode;
import androidx.wear.protolayout.expression.pipeline.FloatNodes.ArithmeticFloatNode;
import androidx.wear.protolayout.expression.pipeline.FloatNodes.DynamicAnimatedFloatNode;
@@ -40,7 +42,7 @@
import androidx.wear.protolayout.expression.proto.DynamicProto.StateInt32Source;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -54,6 +56,8 @@
@RunWith(AndroidJUnit4.class)
public class FloatNodeTest {
+ private static final AppDataKey<DynamicFloat> KEY_FOO = new AppDataKey<>("foo");
+
@Test
public void fixedFloatNodesTest() {
List<Float> results = new ArrayList<>();
@@ -75,8 +79,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(testValue))
.build()));
@@ -99,8 +103,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(oldValue))
.build()));
@@ -112,10 +116,10 @@
node.init();
assertThat(results).containsExactly(oldValue);
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(newValue))
.build()));
@@ -131,8 +135,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(oldValue))
.build()));
@@ -147,10 +151,10 @@
results.clear();
node.destroy();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(newValue))
.build()));
@@ -177,8 +181,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(oldRhsValue))
.build()));
StateFloatSource rhsProtoNode = StateFloatSource.newBuilder().setSourceKey("foo").build();
@@ -191,10 +195,10 @@
assertThat(results).containsExactly(lhsValue + oldRhsValue);
float newRhsValue = 7.8f;
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(newRhsValue))
.build()));
assertThat(results)
@@ -211,8 +215,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(oldIntValue))
.build()));
@@ -226,10 +230,10 @@
assertThat(results).containsExactly((float) oldIntValue);
int newIntValue = 12;
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(newIntValue))
.build()));
@@ -319,8 +323,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(
FixedFloat.newBuilder().setValue(value1).build())
.build()));
@@ -340,10 +344,10 @@
stateNode.init();
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(value2))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -354,10 +358,10 @@
floatNode.setVisibility(true);
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(value3))
.build()));
shadowOf(Looper.getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
index 58f8fd6..2738f50 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
@@ -26,12 +26,17 @@
import android.os.Looper;
import androidx.annotation.NonNull;
+import androidx.collection.ArrayMap;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.AnimatableFixedInt32Node;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.DynamicAnimatedInt32Node;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
-import androidx.wear.protolayout.expression.pipeline.Int32Nodes.PlatformInt32SourceNode;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.LegacyPlatformInt32SourceNode;
import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
@@ -42,7 +47,7 @@
import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateInt32Source;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -56,14 +61,19 @@
import java.time.Duration;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
@RunWith(AndroidJUnit4.class)
public class Int32NodesTest {
- @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+ @Rule
+ public final MockitoRule mockito = MockitoJUnit.rule();
- @Mock private DynamicTypeValueReceiverWithPreUpdate<Integer> mMockValueReceiver;
+ @Mock
+ private DynamicTypeValueReceiverWithPreUpdate<Integer> mMockValueReceiver;
+
+ private static final AppDataKey<DynamicInt32> KEY_FOO = new AppDataKey<>("foo");
@Test
public void testFixedInt32Node() {
@@ -85,36 +95,36 @@
Duration duration = Duration.ofSeconds(123456);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_DAYS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_DAYS))
.isEqualTo(1);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_HOURS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_HOURS))
.isEqualTo(10);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
.isEqualTo(17);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
.isEqualTo(36);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
.isEqualTo(1);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
.isEqualTo(34);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
.isEqualTo(2057);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
.isEqualTo(123456);
}
@@ -125,36 +135,36 @@
Duration duration = Duration.ofSeconds(-123456);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_DAYS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_DAYS))
.isEqualTo(1);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_HOURS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_HOURS))
.isEqualTo(10);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
.isEqualTo(17);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
.isEqualTo(36);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
.isEqualTo(-1);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
.isEqualTo(-34);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
.isEqualTo(-2057);
assertThat(
- createGetDurationPartOpNodeAndGetPart(
- duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
+ createGetDurationPartOpNodeAndGetPart(
+ duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
.isEqualTo(-123456);
}
@@ -174,8 +184,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(65))
.build()));
@@ -195,8 +205,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(65))
.build()));
@@ -209,10 +219,10 @@
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(12))
.build()));
@@ -302,8 +312,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(
FixedInt32.newBuilder().setValue(value1).build())
.build()));
@@ -323,10 +333,10 @@
stateNode.init();
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(value2))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -337,10 +347,10 @@
int32Node.setVisibility(true);
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(value3))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -355,16 +365,22 @@
@Test
public void platformInt32Source_propagatesInvalidatedSignal() {
FakeSensorGateway fakeSensorGateway = new FakeSensorGateway();
+ StateStore stateStore = new StateStore(new ArrayMap<>());
+ stateStore.putAllPlatformProviders(
+ Collections.singletonMap(
+ PlatformHealthSources.HEART_RATE_BPM,
+ new SensorGatewaySingleDataProvider(
+ fakeSensorGateway, PlatformHealthSources.HEART_RATE_BPM)));
PlatformInt32Source platformSource =
PlatformInt32Source.newBuilder()
.setSourceType(
PlatformInt32SourceType
.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE)
.build();
- PlatformInt32SourceNode platformSourceNode =
- new PlatformInt32SourceNode(
+ LegacyPlatformInt32SourceNode platformSourceNode =
+ new LegacyPlatformInt32SourceNode(
+ stateStore,
platformSource,
- new SensorGatewayPlatformDataSource(Runnable::run, fakeSensorGateway),
mMockValueReceiver);
platformSourceNode.preInit();
@@ -381,28 +397,30 @@
final List<Consumer> registeredConsumers = new ArrayList<>();
@Override
- public void enableUpdates() {}
+ public void enableUpdates() {
+ }
@Override
- public void disableUpdates() {}
+ public void disableUpdates() {
+ }
@Override
public void registerSensorGatewayConsumer(
- @SensorDataType int requestedDataType, @NonNull Consumer consumer) {
+ @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer) {
registeredConsumers.add(consumer);
}
@Override
public void registerSensorGatewayConsumer(
- @SensorDataType int requestedDataType,
+ @NonNull PlatformDataKey<?> key,
@NonNull Executor executor,
@NonNull Consumer consumer) {
- registerSensorGatewayConsumer(requestedDataType, consumer);
+ registerSensorGatewayConsumer(key, consumer);
}
@Override
public void unregisterSensorGatewayConsumer(
- @SensorDataType int requestedDataType, @NonNull Consumer consumer) {
+ @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer) {
registeredConsumers.remove(consumer);
}
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
index 2f62ea9..4480847 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
@@ -38,11 +38,12 @@
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedBool;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -63,36 +64,38 @@
public class ParametrizedDynamicTypeEvaluatorTest {
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
public static ImmutableList<Object[]> params() {
+ AppDataKey<DynamicInt32> int32Source = new AppDataKey<>("state_int_15");
ParametrizedDynamicTypeEvaluatorTest.TestCase<?>[] testCases = {
test(constant("hello"), "hello"),
- test(DynamicString.fromState("state_hello_world"), "hello_world"),
+ test(DynamicString.from(new AppDataKey<>("state_hello_world")), "hello_world"),
test(DynamicInt32.constant(5).format(), "5"),
test(DynamicInt32.constant(10), 10),
- test(DynamicInt32.fromState("state_int_15"), 15),
- test(DynamicInt32.fromState("state_int_15").plus(DynamicInt32.constant(2)), 17),
- test(DynamicInt32.fromState("state_int_15").minus(DynamicInt32.constant(5)), 10),
- test(DynamicInt32.fromState("state_int_15").times(DynamicInt32.constant(2)), 30),
- test(DynamicInt32.fromState("state_int_15").div(DynamicInt32.constant(3)), 5),
- test(DynamicInt32.fromState("state_int_15").rem(DynamicInt32.constant(2)), 1),
- test(DynamicInt32.fromState("state_int_15").plus(2), 17),
- test(DynamicInt32.fromState("state_int_15").minus(5), 10),
- test(DynamicInt32.fromState("state_int_15").times(2), 30),
- test(DynamicInt32.fromState("state_int_15").div(3), 5),
- test(DynamicInt32.fromState("state_int_15").rem(2), 1),
- test(DynamicInt32.fromState("state_int_15").plus(2.5f), 17.5f),
- test(DynamicInt32.fromState("state_int_15").minus(5.5f), 9.5f),
- test(DynamicInt32.fromState("state_int_15").times(2.5f), 37.5f),
- test(DynamicInt32.fromState("state_int_15").div(2.0f), 7.5f),
- test(DynamicInt32.fromState("state_int_15").rem(4.5f), 1.5f),
- test(DynamicInt32.fromState("state_int_15").plus(DynamicFloat.constant(2.5f)), 17.5f),
- test(DynamicInt32.fromState("state_int_15").minus(DynamicFloat.constant(5.5f)), 9.5f),
- test(DynamicInt32.fromState("state_int_15").times(DynamicFloat.constant(2.5f)), 37.5f),
- test(DynamicInt32.fromState("state_int_15").div(DynamicFloat.constant(2.0f)), 7.5f),
- test(DynamicInt32.fromState("state_int_15").rem(DynamicFloat.constant(4.5f)), 1.5f),
+ test(DynamicInt32.from(int32Source), 15),
+ test(DynamicInt32.from(int32Source).plus(DynamicInt32.constant(2)), 17),
+ test(DynamicInt32.from(int32Source).minus(DynamicInt32.constant(5)), 10),
+ test(DynamicInt32.from(int32Source).times(DynamicInt32.constant(2)), 30),
+ test(DynamicInt32.from(int32Source).div(DynamicInt32.constant(3)), 5),
+ test(DynamicInt32.from(int32Source).rem(DynamicInt32.constant(2)), 1),
+ test(DynamicInt32.from(int32Source).plus(2), 17),
+ test(DynamicInt32.from(int32Source).minus(5), 10),
+ test(DynamicInt32.from(int32Source).times(2), 30),
+ test(DynamicInt32.from(int32Source).div(3), 5),
+ test(DynamicInt32.from(int32Source).rem(2), 1),
+ test(DynamicInt32.from(int32Source).plus(2.5f), 17.5f),
+ test(DynamicInt32.from(int32Source).minus(5.5f), 9.5f),
+ test(DynamicInt32.from(int32Source).times(2.5f), 37.5f),
+ test(DynamicInt32.from(int32Source).div(2.0f), 7.5f),
+ test(DynamicInt32.from(int32Source).rem(4.5f), 1.5f),
+ test(DynamicInt32.from(int32Source).plus(DynamicFloat.constant(2.5f)), 17.5f),
+ test(DynamicInt32.from(int32Source).minus(DynamicFloat.constant(5.5f)), 9.5f),
+ test(DynamicInt32.from(int32Source).times(DynamicFloat.constant(2.5f)), 37.5f),
+ test(DynamicInt32.from(int32Source).div(DynamicFloat.constant(2.0f)), 7.5f),
+ test(DynamicInt32.from(int32Source).rem(DynamicFloat.constant(4.5f)), 1.5f),
test(DynamicFloat.constant(5.0f), 5.0f),
testForInvalidValue(DynamicFloat.constant(Float.NaN)),
testForInvalidValue(DynamicFloat.constant(Float.NaN).plus(5.0f)),
- test(DynamicFloat.fromState("state_float_1.5"), 1.5f),
+ test(DynamicFloat.from(
+ new AppDataKey<>("state_float_1.5")), 1.5f),
test(DynamicFloat.constant(1234.567f).asInt(), 1234),
test(DynamicFloat.constant(0.967f).asInt(), 0),
test(DynamicFloat.constant(-1234.967f).asInt(), -1235),
@@ -146,9 +149,11 @@
test(DynamicBool.constant(true).or(DynamicBool.constant(false)), true),
test(DynamicBool.constant(false).or(DynamicBool.constant(true)), true),
test(DynamicBool.constant(false).or(DynamicBool.constant(false)), false),
- test(DynamicBool.fromState("state_bool_true"), true),
+ test(DynamicBool.from(
+ new AppDataKey<>("state_bool_true")), true),
test(DynamicBool.constant(false), false),
- test(DynamicBool.fromState("state_bool_false"), false),
+ test(DynamicBool.from(
+ new AppDataKey<>("state_bool_false")), false),
test(DynamicInt32.constant(5).eq(DynamicInt32.constant(5)), true),
test(DynamicInt32.constant(5).eq(DynamicInt32.constant(6)), false),
test(DynamicInt32.constant(5).ne(DynamicInt32.constant(5)), false),
@@ -204,7 +209,8 @@
.elseUse(constant("World")),
"World"),
test(
- DynamicString.fromState("state_hello_world")
+ DynamicString.from(
+ new AppDataKey<>("state_hello_world"))
.concat(DynamicString.constant("_test")),
"hello_world_test"),
test(
@@ -504,26 +510,26 @@
return DynamicDuration.withSecondsPrecision(Duration.ofSeconds(seconds));
}
- private static ImmutableMap<String, StateEntryValue> generateExampleState() {
+ private static ImmutableMap<AppDataKey<?>, DynamicDataValue> generateExampleState() {
return ImmutableMap.of(
- "state_hello_world",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicString>("state_hello_world"),
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("hello_world"))
.build(),
- "state_int_15",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicInt32>("state_int_15"),
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(15))
.build(),
- "state_float_1.5",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicFloat>("state_float_1.5"),
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(1.5f))
.build(),
- "state_bool_true",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBool>("state_bool_true"),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(true))
.build(),
- "state_bool_false",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBool>("state_bool_false"),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(false))
.build());
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
index d3a2bb4..3712441 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
@@ -16,6 +16,7 @@
package androidx.wear.protolayout.expression.pipeline;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -24,10 +25,17 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
+import android.util.ArrayMap;
+
+import androidx.annotation.NonNull;
+import androidx.collection.ArraySet;
import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.truth.Expect;
@@ -38,81 +46,208 @@
import org.mockito.InOrder;
import org.mockito.Mockito;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
@RunWith(AndroidJUnit4.class)
public class StateStoreTest {
@Rule public Expect mExpect = Expect.create();
+ private static final AppDataKey<DynamicString> KEY_FOO = new AppDataKey<>("foo");
+ private static final AppDataKey<DynamicString> KEY_BAZ = new AppDataKey<>("baz");
+
+ private static final PlatformDataKey<DynamicString> KEY_FOO_PLATFORM
+ = new PlatformDataKey<>("platform", "foo");
+ private static final PlatformDataKey<DynamicString> KEY_BAZ_PLATFORM
+ = new PlatformDataKey<>("platform","baz");
+
private final StateStore mStateStoreUnderTest =
new StateStore(
ImmutableMap.of(
- "foo", buildStateEntry("bar"),
- "baz", buildStateEntry("foobar")));
+ KEY_FOO, buildDynamicDataValue("bar"),
+ KEY_BAZ, buildDynamicDataValue("foobar")));
+
+ public StateStoreTest() {}
@Test
public void setBuilderApi() {
- mStateStoreUnderTest.setStateEntryValues(
- ImmutableMap.of("foo", StateEntryBuilders.StateEntryValue.fromString("baz")));
+ mStateStoreUnderTest.setAppStateEntryValues(
+ ImmutableMap.of(
+ KEY_FOO, DynamicDataBuilders.DynamicDataValue.fromString("baz")));
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
- .isEqualTo(buildStateEntry("baz"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+ .isEqualTo(buildDynamicDataValue("baz"));
+
+ // This should have been cleared...
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ)).isNull();
+ }
+
+ @Test
+ public void initState_largeNumberOfEntries_throws() {
+ Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> state = new HashMap<>();
+ for (int i = 0; i < StateStore.MAX_STATE_ENTRY_COUNT + 10; i++) {
+ state.put(
+ new AppDataKey<DynamicString>(Integer.toString(i)),
+ DynamicDataBuilders.DynamicDataValue.fromString("baz"));
+ }
+ assertThrows(IllegalStateException.class, () -> StateStore.create(state));
+ }
+
+ @Test
+ public void newState_largeNumberOfEntries_throws() {
+ Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> state = new HashMap<>();
+ for (int i = 0; i < StateStore.MAX_STATE_ENTRY_COUNT + 10; i++) {
+ state.put(
+ new AppDataKey<DynamicString>(Integer.toString(i)),
+ DynamicDataBuilders.DynamicDataValue.fromString("baz"));
+ }
+ assertThrows(
+ IllegalStateException.class,
+ () -> mStateStoreUnderTest.setAppStateEntryValues(state));
}
@Test
public void canReadInitialState() {
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
- .isEqualTo(buildStateEntry("bar"));
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("baz"))
- .isEqualTo(buildStateEntry("foobar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+ .isEqualTo(buildDynamicDataValue("bar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+ .isEqualTo(buildDynamicDataValue("foobar"));
}
@Test
public void unsetStateReturnsNull() {
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("AAAAAA")).isNull();
+ mExpect.that(
+ mStateStoreUnderTest.getDynamicDataValuesProto(new AppDataKey<>("AAAAAA"))
+ ).isNull();
}
@Test
public void canSetNewState() {
- mStateStoreUnderTest.setStateEntryValuesProto(
+ AppDataKey<DynamicString> keyNew = new AppDataKey<>("newKey");
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo", buildStateEntry("test"),
- "newKey", buildStateEntry("testNewKey")));
+ KEY_FOO, buildDynamicDataValue("test"),
+ keyNew, buildDynamicDataValue("testNewKey")));
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
- .isEqualTo(buildStateEntry("test"));
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("newKey"))
- .isEqualTo(buildStateEntry("testNewKey"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+ .isEqualTo(buildDynamicDataValue("test"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(keyNew))
+ .isEqualTo(buildDynamicDataValue("testNewKey"));
// This should have been cleared...
- mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("baz")).isNull();
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ)).isNull();
+ }
+
+ @Test
+ public void canUpdatePlatformData() {
+ mStateStoreUnderTest.updatePlatformDataEntryProto(
+ Map.of(KEY_FOO_PLATFORM, buildDynamicDataValue("valueFoo1")));
+
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+ .isEqualTo(buildDynamicDataValue("bar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+ .isEqualTo(buildDynamicDataValue("foobar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+ .isEqualTo(buildDynamicDataValue("valueFoo1"));
+
+ mStateStoreUnderTest.updatePlatformDataEntryProto(
+ Map.of(KEY_FOO_PLATFORM, buildDynamicDataValue("valueFoo2"),
+ KEY_BAZ_PLATFORM, buildDynamicDataValue("valueBaz")));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+ .isEqualTo(buildDynamicDataValue("valueFoo2"));
+
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+ .isEqualTo(buildDynamicDataValue("bar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+ .isEqualTo(buildDynamicDataValue("foobar"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+ .isEqualTo(buildDynamicDataValue("valueFoo2"));
+ mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ_PLATFORM))
+ .isEqualTo(buildDynamicDataValue("valueBaz"));
}
@Test
public void setStateFiresListeners() {
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb =
- buildStateUpdateCallbackMock();
- mStateStoreUnderTest.registerCallback("foo", cb);
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
+ mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
- mStateStoreUnderTest.setStateEntryValuesProto(
- ImmutableMap.of("foo", buildStateEntry("test")));
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
+ ImmutableMap.of(KEY_FOO, buildDynamicDataValue("test")));
verify(cb).onPreUpdate();
- verify(cb).onData(buildStateEntry("test"));
+ verify(cb).onData(buildDynamicDataValue("test"));
+ }
+
+ @Test
+ public void platformDataProvider_register_updateData_unregister() {
+ PlatformDataProviderUnderTest dataProvider = new PlatformDataProviderUnderTest();
+ Map<PlatformDataKey<?>, PlatformDataProvider> sourceKeyToDataProvider = new ArrayMap<>();
+ sourceKeyToDataProvider.put(KEY_FOO_PLATFORM, dataProvider);
+ sourceKeyToDataProvider.put(KEY_BAZ_PLATFORM, dataProvider);
+ mStateStoreUnderTest.putAllPlatformProviders(sourceKeyToDataProvider);
+
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo =
+ buildStateUpdateCallbackMock();
+ mStateStoreUnderTest.registerCallback(KEY_FOO_PLATFORM, cbFoo);
+ verify(cbFoo).onPreUpdate();
+ verify(cbFoo).onData(buildDynamicDataValue("fooValue"));
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbBaz =
+ buildStateUpdateCallbackMock();
+ mStateStoreUnderTest.registerCallback(KEY_BAZ_PLATFORM, cbBaz);
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo2 =
+ buildStateUpdateCallbackMock();
+ mStateStoreUnderTest.registerCallback(KEY_FOO_PLATFORM, cbFoo2);
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+ dataProvider.updateValues(
+ Map.of(KEY_FOO_PLATFORM,
+ DynamicDataBuilders.DynamicDataValue.fromString("newFooValue"),
+ KEY_BAZ_PLATFORM,
+ DynamicDataBuilders.DynamicDataValue.fromString("newBazValue")
+ ));
+ verify(cbFoo, times(2)).onPreUpdate();
+ verify(cbFoo2).onPreUpdate();
+ verify(cbBaz).onPreUpdate();
+ verify(cbFoo).onData(buildDynamicDataValue("newFooValue"));
+ verify(cbFoo2).onData(buildDynamicDataValue("newFooValue"));
+ verify(cbBaz).onData(buildDynamicDataValue("newBazValue"));
+
+ dataProvider.updateValues(
+ Map.of(
+ KEY_BAZ_PLATFORM,
+ DynamicDataBuilders.DynamicDataValue.fromString("updatedBazValue")
+ ));
+ verify(cbFoo, times(1)).onData(buildDynamicDataValue("newFooValue"));
+ verify(cbFoo2, times(1)).onData(buildDynamicDataValue("newFooValue"));
+ verify(cbBaz).onData(buildDynamicDataValue("newBazValue"));
+
+ mStateStoreUnderTest.unregisterCallback(KEY_FOO_PLATFORM, cbFoo);
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+ mStateStoreUnderTest.unregisterCallback(KEY_FOO_PLATFORM, cbFoo2);
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+ mStateStoreUnderTest.unregisterCallback(KEY_BAZ_PLATFORM, cbBaz);
+ mExpect.that(dataProvider.mRegisterCount).isEqualTo(0);
}
@Test
public void setStateFiresOnPreStateUpdateFirst() {
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb =
- buildStateUpdateCallbackMock();
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
InOrder inOrder = Mockito.inOrder(cb);
- mStateStoreUnderTest.registerCallback("foo", cb);
- mStateStoreUnderTest.registerCallback("baz", cb);
+ mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
+ mStateStoreUnderTest.registerCallback(KEY_BAZ, cb);
- mStateStoreUnderTest.setStateEntryValuesProto(
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo", buildStateEntry("testFoo"),
- "baz", buildStateEntry("testBaz")));
+ KEY_FOO, buildDynamicDataValue("testFoo"),
+ KEY_BAZ, buildDynamicDataValue("testBaz")));
inOrder.verify(cb, times(2)).onPreUpdate();
inOrder.verify(cb, times(2)).onData(any());
@@ -121,41 +256,44 @@
@Test
public void setStateOnlyFiresListenersForChangedData() {
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cbFoo =
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo =
buildStateUpdateCallbackMock();
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cbBaz =
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbBaz =
buildStateUpdateCallbackMock();
- mStateStoreUnderTest.registerCallback("foo", cbFoo);
- mStateStoreUnderTest.registerCallback("baz", cbBaz);
- mStateStoreUnderTest.setStateEntryValuesProto(
+ mStateStoreUnderTest.registerCallback(KEY_FOO, cbFoo);
+ mStateStoreUnderTest.registerCallback(KEY_BAZ, cbBaz);
+
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo", buildStateEntry("test"),
- "baz", buildStateEntry("foobar")));
+ KEY_FOO, buildDynamicDataValue("test"),
+ KEY_BAZ, buildDynamicDataValue("foobar")));
verify(cbFoo).onPreUpdate();
- verify(cbFoo).onData(buildStateEntry("test"));
+ verify(cbFoo).onData(buildDynamicDataValue("test"));
verify(cbBaz, never()).onPreUpdate();
- verify(cbBaz, never()).onData(buildStateEntry("test"));
+ verify(cbBaz, never()).onData(buildDynamicDataValue("test"));
}
@Test
public void removeStateFiresInvalidated() {
- mStateStoreUnderTest.setStateEntryValuesProto(
+ AppDataKey<DynamicString> keyInvalidated = new AppDataKey<>("invalidated");
+ AppDataKey<DynamicString> keyNotInvalidated = new AppDataKey<>("notInvalidated");
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
ImmutableMap.of(
- "invalidated",
- buildStateEntry("value"),
- "notInvalidated",
- buildStateEntry("value")));
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> invalidated =
+ keyInvalidated,
+ buildDynamicDataValue("value"),
+ keyNotInvalidated,
+ buildDynamicDataValue("value")));
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> invalidated =
buildStateUpdateCallbackMock();
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> notInvalidated =
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> notInvalidated =
buildStateUpdateCallbackMock();
- mStateStoreUnderTest.registerCallback("invalidated", invalidated);
- mStateStoreUnderTest.registerCallback("notInvalidated", notInvalidated);
+ mStateStoreUnderTest.registerCallback(keyInvalidated, invalidated);
+ mStateStoreUnderTest.registerCallback(keyNotInvalidated, notInvalidated);
- mStateStoreUnderTest.setStateEntryValuesProto(
- ImmutableMap.of("notInvalidated", buildStateEntry("value")));
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
+ ImmutableMap.of(keyNotInvalidated, buildDynamicDataValue("value")));
verify(invalidated).onPreUpdate();
verify(invalidated).onInvalidated();
@@ -166,33 +304,83 @@
@SuppressWarnings("unchecked")
@Test
public void canUnregisterListeners() {
- DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb =
- buildStateUpdateCallbackMock();
- mStateStoreUnderTest.registerCallback("foo", cb);
+ DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
+ mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
- mStateStoreUnderTest.setStateEntryValuesProto(
- ImmutableMap.of("foo", buildStateEntry("test")));
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
+ ImmutableMap.of(KEY_FOO, buildDynamicDataValue("test")));
reset(cb);
- mStateStoreUnderTest.unregisterCallback("foo", cb);
- mStateStoreUnderTest.setStateEntryValuesProto(
- ImmutableMap.of("foo", buildStateEntry("testAgain")));
+ mStateStoreUnderTest.unregisterCallback(KEY_FOO, cb);
+
+ mStateStoreUnderTest.setAppStateEntryValuesProto(
+ ImmutableMap.of(KEY_FOO, buildDynamicDataValue("testAgain")));
verifyNoInteractions(cb);
}
@SuppressWarnings("unchecked")
- private DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>
- buildStateUpdateCallbackMock() {
+ private DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> buildStateUpdateCallbackMock() {
// This needs an unchecked cast because of the generic; this method just centralizes the
// warning suppression.
return mock(DynamicTypeValueReceiverWithPreUpdate.class);
}
- private StateEntryValue buildStateEntry(String value) {
- return StateEntryValue.newBuilder()
+ private DynamicDataValue buildDynamicDataValue(String value) {
+ return DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue(value))
.build();
}
+
+ private class PlatformDataProviderUnderTest implements PlatformDataProvider {
+
+ private PlatformDataReceiver mRegisteredCallback = null;
+
+ private final Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue> mCurrentValue =
+ new ArrayMap<>();
+
+ private final Set<PlatformDataKey<?>> mSupportedKeys= new ArraySet<>();
+
+ int mRegisterCount = 0;
+
+ PlatformDataProviderUnderTest() {
+ mSupportedKeys.add(KEY_FOO_PLATFORM);
+ mSupportedKeys.add(KEY_BAZ_PLATFORM);
+ mCurrentValue.put(
+ KEY_FOO_PLATFORM,
+ DynamicDataBuilders.DynamicDataValue.fromString("fooValue")
+ );
+ mCurrentValue.put(
+ KEY_BAZ_PLATFORM,
+ DynamicDataBuilders.DynamicDataValue.fromString("bazValue")
+ );
+ }
+
+ public void updateValues(
+ @NonNull Map<PlatformDataKey<?> , DynamicDataBuilders.DynamicDataValue> newData) {
+ mCurrentValue.putAll(newData);
+ if (mRegisteredCallback != null) {
+ mRegisteredCallback.onData(mCurrentValue);
+ }
+ }
+
+ @Override
+ public void registerForData(
+ @NonNull Executor executor,
+ @NonNull PlatformDataReceiver callback) {
+ mRegisterCount++;
+ mRegisteredCallback = callback;
+ executor.execute(() -> callback.onData(mCurrentValue));
+ }
+
+ @Override
+ public void unregisterForData() {
+ if (mRegisteredCallback != null) {
+ mRegisteredCallback.onInvalidated(mSupportedKeys);
+ mRegisterCount--;
+ mRegisteredCallback = null;
+ }
+ }
+ }
}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
index 7b74e8ed..f9afae6 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
@@ -23,6 +23,8 @@
import android.icu.util.ULocale;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
import androidx.wear.protolayout.expression.pipeline.StringNodes.FixedStringNode;
import androidx.wear.protolayout.expression.pipeline.StringNodes.Int32FormatNode;
import androidx.wear.protolayout.expression.pipeline.StringNodes.StateStringNode;
@@ -30,7 +32,7 @@
import androidx.wear.protolayout.expression.proto.DynamicProto.Int32FormatOp;
import androidx.wear.protolayout.expression.proto.DynamicProto.StateStringSource;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import com.google.common.collect.ImmutableMap;
@@ -43,6 +45,7 @@
@RunWith(AndroidJUnit4.class)
public class StringNodesTest {
+ private static final AppDataKey<DynamicString> KEY_FOO = new AppDataKey<>("foo");
@Test
public void fixedStringNodeTest() {
List<String> results = new ArrayList<>();
@@ -106,8 +109,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("bar"))
.build()));
@@ -129,8 +132,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(
FixedString.newBuilder().setValue(string500chars))
.build()));
@@ -152,8 +155,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("bar"))
.build()));
@@ -166,10 +169,10 @@
results.clear();
- oss.setStateEntryValuesProto(
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("baz"))
.build()));
@@ -208,8 +211,8 @@
StateStore oss =
new StateStore(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("bar"))
.build()));
@@ -223,10 +226,11 @@
results.clear();
node.destroy();
- oss.setStateEntryValuesProto(
+
+ oss.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ KEY_FOO,
+ DynamicDataValue.newBuilder()
.setStringVal(FixedString.newBuilder().setValue("baz"))
.build()));
assertThat(results).isEmpty();
diff --git a/wear/protolayout/protolayout-expression/api/current.txt b/wear/protolayout/protolayout-expression/api/current.txt
index b4f26d0..7f2e9cb 100644
--- a/wear/protolayout/protolayout-expression/api/current.txt
+++ b/wear/protolayout/protolayout-expression/api/current.txt
@@ -78,6 +78,10 @@
method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
}
+ public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public AppDataKey(String);
+ }
+
public class ConditionScopes {
}
@@ -98,8 +102,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicColorByteArray();
}
@@ -138,8 +142,8 @@
public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicStringByteArray();
}
@@ -277,15 +281,31 @@
public static interface DynamicBuilders.DynamicType {
}
- public final class StateEntryBuilders {
+ public final class DynamicDataBuilders {
}
- public static interface StateEntryBuilders.StateEntryValue {
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
+ public static interface DynamicDataBuilders.DynamicDataValue {
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+ }
+
+ public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+ method public String getKey();
+ method public String getNamespace();
+ }
+
+ public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public PlatformDataKey(String, String);
+ }
+
+ public class PlatformHealthSources {
+ method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+ method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+ field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+ field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
}
public final class VersionBuilders {
diff --git a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
index adf05da..ace5549 100644
--- a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
@@ -78,6 +78,10 @@
method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
}
+ public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public AppDataKey(String);
+ }
+
public class ConditionScopes {
}
@@ -98,8 +102,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicColorByteArray();
}
@@ -138,8 +142,8 @@
public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicStringByteArray();
}
@@ -277,28 +281,39 @@
public static interface DynamicBuilders.DynamicType {
}
+ public final class DynamicDataBuilders {
+ }
+
+ public static interface DynamicDataBuilders.DynamicDataValue {
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+ }
+
+ public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+ method public String getKey();
+ method public String getNamespace();
+ }
+
@RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ExperimentalProtoLayoutExtensionApi {
}
- @androidx.wear.protolayout.expression.ProtoLayoutExperimental public class PlatformHealthSources {
- method @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
- method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 heartRateBpm();
+ public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public PlatformDataKey(String, String);
+ }
+
+ public class PlatformHealthSources {
+ method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+ method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+ field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+ field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
}
@RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ProtoLayoutExperimental {
}
- public final class StateEntryBuilders {
- }
-
- public static interface StateEntryBuilders.StateEntryValue {
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
- }
-
public final class VersionBuilders {
}
diff --git a/wear/protolayout/protolayout-expression/api/restricted_current.txt b/wear/protolayout/protolayout-expression/api/restricted_current.txt
index b4f26d0..7f2e9cb 100644
--- a/wear/protolayout/protolayout-expression/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression/api/restricted_current.txt
@@ -78,6 +78,10 @@
method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
}
+ public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public AppDataKey(String);
+ }
+
public class ConditionScopes {
}
@@ -98,8 +102,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicColorByteArray();
}
@@ -138,8 +142,8 @@
public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+ method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
- method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
method public default byte[] toDynamicStringByteArray();
}
@@ -277,15 +281,31 @@
public static interface DynamicBuilders.DynamicType {
}
- public final class StateEntryBuilders {
+ public final class DynamicDataBuilders {
}
- public static interface StateEntryBuilders.StateEntryValue {
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
- method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
+ public static interface DynamicDataBuilders.DynamicDataValue {
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+ method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+ }
+
+ public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+ method public String getKey();
+ method public String getNamespace();
+ }
+
+ public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+ ctor public PlatformDataKey(String, String);
+ }
+
+ public class PlatformHealthSources {
+ method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+ method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+ field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+ field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
}
public final class VersionBuilders {
diff --git a/wear/protolayout/protolayout-expression/build.gradle b/wear/protolayout/protolayout-expression/build.gradle
index c9777d4..f0bf70b 100644
--- a/wear/protolayout/protolayout-expression/build.gradle
+++ b/wear/protolayout/protolayout-expression/build.gradle
@@ -49,7 +49,7 @@
}
androidx {
- name = "ProtoLayout Dynamic Expression"
+ name = "ProtoLayout Expression"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "Create dynamic expressions (for late evaluation by a remote evaluator)."
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java
new file mode 100644
index 0000000..e350a5f
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Represent a {@link DynamicDataKey} that references app/tile pushed state data.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public final class AppDataKey<T extends DynamicBuilders.DynamicType> extends DynamicDataKey<T> {
+ @NonNull private static final String DEFAULT_NAMESPACE = "";
+
+ /**
+ * Create a {@link AppDataKey} with the specified key.
+ * @param key The key in the state to bind to.
+ */
+ public AppDataKey(@NonNull String key) {
+ super(DEFAULT_NAMESPACE, key);
+ }
+}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
index 9374277..162b840 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
@@ -36,7 +36,7 @@
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInstant;
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInt32;
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedString;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
import androidx.wear.protolayout.expression.proto.DynamicProto;
import androidx.wear.protolayout.protobuf.ExtensionRegistryLite;
import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException;
@@ -677,6 +677,16 @@
return mImpl.getSourceKey();
}
+ /**
+ * Gets the namespace for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public String getSourceNamespace() {
+ return mImpl.getSourceNamespace();
+ }
+
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
@@ -712,7 +722,12 @@
@Override
@NonNull
public String toString() {
- return "StateInt32Source{" + "sourceKey=" + getSourceKey() + "}";
+ return "StateInt32Source{"
+ + "sourceKey="
+ + getSourceKey()
+ + ", sourceNamespace="
+ + getSourceNamespace()
+ + "}";
}
/** Builder for {@link StateInt32Source}. */
@@ -735,6 +750,18 @@
return this;
}
+ /**
+ * Sets the name space for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+ mImpl.setSourceNamespace(sourceNamespace);
+ mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+ return this;
+ }
+
@Override
@NonNull
public StateInt32Source build() {
@@ -1507,12 +1534,14 @@
/**
* Creates a {@link DynamicInt32} that is bound to the value of an item of the State.
*
- * @param stateKey The key to a {@link StateEntryValue} with an int value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
*/
@NonNull
- static DynamicInt32 fromState(@NonNull String stateKey) {
- return new StateInt32Source.Builder().setSourceKey(stateKey).build();
+ static DynamicInt32 from(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
+ return new StateInt32Source.Builder()
+ .setSourceKey(dynamicDataKey.getKey())
+ .setSourceNamespace(dynamicDataKey.getNamespace())
+ .build();
}
/**
@@ -1548,12 +1577,13 @@
* time the state value changes, this {@link DynamicInt32} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with an int value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
*/
@NonNull
- static DynamicInt32 animate(@NonNull String stateKey) {
- return new AnimatableDynamicInt32.Builder().setInput(fromState(stateKey)).build();
+ static DynamicInt32 animate(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
+ return new AnimatableDynamicInt32.Builder()
+ .setInput(from(dynamicDataKey))
+ .build();
}
/**
@@ -1561,15 +1591,15 @@
* time the state value changes, this {@link DynamicInt32} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with an int value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value
* @param animationSpec The animation parameters.
*/
@NonNull
static DynamicInt32 animate(
- @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+ @NonNull DynamicDataKey<DynamicInt32> dynamicDataKey,
+ @NonNull AnimationSpec animationSpec) {
return new AnimatableDynamicInt32.Builder()
- .setInput(fromState(stateKey))
+ .setInput(from(dynamicDataKey))
.setAnimationSpec(animationSpec)
.build();
}
@@ -2643,6 +2673,17 @@
return mImpl.getSourceKey();
}
+ /**
+ * Gets the namespace for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public String getSourceNamespace() {
+ return mImpl.getSourceNamespace();
+ }
+
+
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
@@ -2678,7 +2719,11 @@
@Override
@NonNull
public String toString() {
- return "StateStringSource{" + "sourceKey=" + getSourceKey() + "}";
+ return "StateStringSource{"+ "sourceKey="
+ + getSourceKey()
+ + ", sourceNamespace="
+ + getSourceNamespace()
+ + "}";
}
/** Builder for {@link StateStringSource}. */
@@ -2701,6 +2746,18 @@
return this;
}
+ /**
+ * Sets the name space for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+ mImpl.setSourceNamespace(sourceNamespace);
+ mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+ return this;
+ }
+
@Override
@NonNull
public StateStringSource build() {
@@ -3258,12 +3315,14 @@
* Creates a {@link DynamicString} that is bound to the value of an item of the State. The
* resulted {@link DynamicString} is subject to being truncated if it's too long.
*
- * @param stateKey The key to a {@link StateEntryValue} with a string value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a string value.
*/
@NonNull
- static DynamicString fromState(@NonNull String stateKey) {
- return new StateStringSource.Builder().setSourceKey(stateKey).build();
+ static DynamicString from(@NonNull DynamicDataKey<DynamicString> dynamicDataKey) {
+ return new StateStringSource.Builder()
+ .setSourceKey(dynamicDataKey.getKey())
+ .setSourceNamespace(dynamicDataKey.getNamespace())
+ .build();
}
/**
@@ -3520,6 +3579,17 @@
return mImpl.getSourceKey();
}
+ /**
+ * Gets the namespace for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public String getSourceNamespace() {
+ return mImpl.getSourceNamespace();
+ }
+
+
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
@@ -3555,7 +3625,11 @@
@Override
@NonNull
public String toString() {
- return "StateFloatSource{" + "sourceKey=" + getSourceKey() + "}";
+ return "StateFloatSource{"+ "sourceKey="
+ + getSourceKey()
+ + ", sourceNamespace="
+ + getSourceNamespace()
+ + "}";
}
/** Builder for {@link StateFloatSource}. */
@@ -3578,6 +3652,18 @@
return this;
}
+ /**
+ * Sets the name space for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+ mImpl.setSourceNamespace(sourceNamespace);
+ mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+ return this;
+ }
+
@Override
@NonNull
public StateFloatSource build() {
@@ -4029,12 +4115,14 @@
/**
* Creates a {@link DynamicFloat} that is bound to the value of an item of the State.
*
- * @param stateKey The key to a {@link StateEntryValue} with a float value from the
- * provider's state.
+ * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
*/
@NonNull
- static DynamicFloat fromState(@NonNull String stateKey) {
- return new StateFloatSource.Builder().setSourceKey(stateKey).build();
+ static DynamicFloat from(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
+ return new StateFloatSource.Builder()
+ .setSourceKey(dynamicDataKey.getKey())
+ .setSourceNamespace(dynamicDataKey.getNamespace())
+ .build();
}
/**
@@ -4071,12 +4159,13 @@
* time the state value changes, this {@link DynamicFloat} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with a float value from the
- * providers state.
+ * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
*/
@NonNull
- static DynamicFloat animate(@NonNull String stateKey) {
- return new AnimatableDynamicFloat.Builder().setInput(fromState(stateKey)).build();
+ static DynamicFloat animate(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
+ return new AnimatableDynamicFloat.Builder()
+ .setInput(from(dynamicDataKey))
+ .build();
}
/**
@@ -4084,15 +4173,15 @@
* time the state value changes, this {@link DynamicFloat} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with a float value from the
- * providers state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a float value.
* @param animationSpec The animation parameters.
*/
@NonNull
static DynamicFloat animate(
- @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+ @NonNull DynamicDataKey<DynamicFloat> dynamicDataKey,
+ @NonNull AnimationSpec animationSpec) {
return new AnimatableDynamicFloat.Builder()
- .setInput(fromState(stateKey))
+ .setInput(from(dynamicDataKey))
.setAnimationSpec(animationSpec)
.build();
}
@@ -4935,6 +5024,17 @@
return mImpl.getSourceKey();
}
+ /**
+ * Gets the namespace for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public String getSourceNamespace() {
+ return mImpl.getSourceNamespace();
+ }
+
+
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
@@ -4970,7 +5070,12 @@
@Override
@NonNull
public String toString() {
- return "StateBoolSource{" + "sourceKey=" + getSourceKey() + "}";
+ return "StateBoolSource{"
+ + "sourceKey="
+ + getSourceKey()
+ + ", sourceNamespace="
+ + getSourceNamespace()
+ + "}";
}
/** Builder for {@link StateBoolSource}. */
@@ -4994,6 +5099,18 @@
return this;
}
+ /**
+ * Sets the name space for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+ mImpl.setSourceNamespace(sourceNamespace);
+ mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+ return this;
+ }
+
@Override
@NonNull
public StateBoolSource build() {
@@ -5579,12 +5696,14 @@
/**
* Creates a {@link DynamicBool} that is bound to the value of an item of the State.
*
- * @param stateKey The key to a {@link StateEntryValue} with a boolean value from the
- * provider's state.
+ * @param dynamicDataKey The key to a {@link DynamicDataValue} with a boolean value.
*/
@NonNull
- static DynamicBool fromState(@NonNull String stateKey) {
- return new StateBoolSource.Builder().setSourceKey(stateKey).build();
+ static DynamicBool from(@NonNull DynamicDataKey<DynamicBool> dynamicDataKey) {
+ return new StateBoolSource.Builder()
+ .setSourceKey(dynamicDataKey.getKey())
+ .setSourceNamespace(dynamicDataKey.getNamespace())
+ .build();
}
/**
@@ -5727,6 +5846,16 @@
return mImpl.getSourceKey();
}
+ /**
+ * Gets the namespace for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public String getSourceNamespace() {
+ return mImpl.getSourceNamespace();
+ }
+
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@Nullable
@@ -5762,7 +5891,12 @@
@Override
@NonNull
public String toString() {
- return "StateColorSource{" + "sourceKey=" + getSourceKey() + "}";
+ return "StateColorSource{"
+ + "sourceKey="
+ + getSourceKey()
+ + ", sourceNamespace="
+ + getSourceNamespace()
+ + "}";
}
/** Builder for {@link StateColorSource}. */
@@ -5785,6 +5919,18 @@
return this;
}
+ /**
+ * Sets the name space for the state key.
+ *
+ * @since 1.2
+ */
+ @NonNull
+ public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+ mImpl.setSourceNamespace(sourceNamespace);
+ mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+ return this;
+ }
+
@Override
@NonNull
public StateColorSource build() {
@@ -6283,12 +6429,14 @@
/**
* Creates a {@link DynamicColor} that is bound to the value of an item of the State.
*
- * @param stateKey The key to a {@link StateEntryValue} with a color value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
*/
@NonNull
- static DynamicColor fromState(@NonNull String stateKey) {
- return new StateColorSource.Builder().setSourceKey(stateKey).build();
+ static DynamicColor from(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
+ return new StateColorSource.Builder()
+ .setSourceKey(dynamicDataKey.getKey())
+ .setSourceNamespace(dynamicDataKey.getNamespace())
+ .build();
}
/**
@@ -6326,12 +6474,13 @@
* time the state value changes, this {@link DynamicColor} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with a color value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
*/
@NonNull
- static DynamicColor animate(@NonNull String stateKey) {
- return new AnimatableDynamicColor.Builder().setInput(fromState(stateKey)).build();
+ static DynamicColor animate(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
+ return new AnimatableDynamicColor.Builder()
+ .setInput(from(dynamicDataKey))
+ .build();
}
/**
@@ -6339,15 +6488,15 @@
* time the state value changes, this {@link DynamicColor} will animate from its current
* value to the new value (from the state).
*
- * @param stateKey The key to a {@link StateEntryValue} with a color value from the
- * provider's state.
+ * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
* @param animationSpec The animation parameters.
*/
@NonNull
static DynamicColor animate(
- @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+ @NonNull DynamicDataKey<DynamicColor> dynamicDataKey,
+ @NonNull AnimationSpec animationSpec) {
return new AnimatableDynamicColor.Builder()
- .setInput(fromState(stateKey))
+ .setInput(from(dynamicDataKey))
.setAnimationSpec(animationSpec)
.build();
}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
similarity index 71%
rename from wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java
rename to wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
index 304b9b8..7f4eddd 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
@@ -16,7 +16,6 @@
package androidx.wear.protolayout.expression;
-import android.annotation.SuppressLint;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -27,53 +26,53 @@
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedFloat;
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInt32;
import androidx.wear.protolayout.expression.FixedValueBuilders.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
-/** Builders for state entries of a provider. */
-public final class StateEntryBuilders {
- private StateEntryBuilders() {}
+/** Builders for dynamic data value of a provider. */
+public final class DynamicDataBuilders {
+ private DynamicDataBuilders() {}
/**
- * Interface defining a state entry value.
+ * Interface defining a dynamic data value.
*
* @since 1.2
*/
- public interface StateEntryValue {
+ public interface DynamicDataValue {
/**
* Get the protocol buffer representation of this object.
*
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- StateEntryProto.StateEntryValue toStateEntryValueProto();
+ DynamicDataProto.DynamicDataValue toDynamicDataValueProto();
- /** Creates a boolean {@link StateEntryValue}. */
+ /** Creates a boolean {@link DynamicDataValue}. */
@NonNull
- static StateEntryValue fromBool(boolean constant) {
+ static DynamicDataValue fromBool(boolean constant) {
return new FixedBool.Builder().setValue(constant).build();
}
- /** Creates a int {@link StateEntryValue}. */
+ /** Creates a int {@link DynamicDataValue}. */
@NonNull
- static StateEntryValue fromInt(int constant) {
+ static DynamicDataValue fromInt(int constant) {
return new FixedInt32.Builder().setValue(constant).build();
}
- /** Creates a float {@link StateEntryValue}. */
+ /** Creates a float {@link DynamicDataValue}. */
@NonNull
- static StateEntryValue fromFloat(float constant) {
+ static DynamicDataValue fromFloat(float constant) {
return new FixedFloat.Builder().setValue(constant).build();
}
- /** Creates a color {@link StateEntryValue}. */
+ /** Creates a color {@link DynamicDataValue}. */
@NonNull
- static StateEntryValue fromColor(@ColorInt int constant) {
+ static DynamicDataValue fromColor(@ColorInt int constant) {
return new FixedColor.Builder().setArgb(constant).build();
}
- /** Creates a string {@link StateEntryValue}. */
+ /** Creates a string {@link DynamicDataValue}. */
@NonNull
- static StateEntryValue fromString(@NonNull String constant) {
+ static DynamicDataValue fromString(@NonNull String constant) {
return new FixedString.Builder().setValue(constant).build();
}
@@ -85,7 +84,7 @@
@Nullable
Fingerprint getFingerprint();
- /** Builder to create {@link StateEntryValue} objects.
+ /** Builder to create {@link DynamicDataValue} objects.
*
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@@ -93,7 +92,7 @@
/** Builds an instance with values accumulated in this Builder. */
@NonNull
- StateEntryValue build();
+ DynamicDataValue build();
}
}
@@ -104,8 +103,8 @@
*/
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public static StateEntryValue stateEntryValueFromProto(
- @NonNull StateEntryProto.StateEntryValue proto) {
+ public static DynamicDataValue dynamicDataValueFromProto(
+ @NonNull DynamicDataProto.DynamicDataValue proto) {
if (proto.hasStringVal()) {
return FixedString.fromProto(proto.getStringVal());
}
@@ -121,6 +120,6 @@
if (proto.hasColorVal()) {
return FixedColor.fromProto(proto.getColorVal());
}
- throw new IllegalStateException("Proto was not a recognised instance of StateEntryValue");
+ throw new IllegalStateException("Proto was not a recognised instance of DynamicDataValue");
}
}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java
new file mode 100644
index 0000000..29c060d
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Represent a key that references a dynamic value source, such as state pushed by app/tile or
+ * real-time data from the platform.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public abstract class DynamicDataKey<T extends DynamicBuilders.DynamicType> {
+ @NonNull private final String mKey;
+ @NonNull private final String mNamespace;
+
+ /**
+ * Create a {@link DynamicDataKey} with the specified key in the given namespace.
+ * @param namespace The namespace of the key for the dynamic data source.
+ * @param key The key that references the dynamic data source.
+ */
+ DynamicDataKey(@NonNull String namespace, @NonNull String key) {
+ mKey = key;
+ mNamespace = namespace;
+ }
+
+ /**
+ * Gets the key that references the dynamic data source
+ */
+ @NonNull public String getKey() {
+ return mKey;
+ }
+
+ /**
+ * Gets the namespace of the key for the dynamic data source.
+ */
+ @NonNull public String getNamespace() {
+ return mNamespace;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (other == this) {
+ return true;
+ }
+
+ if (!(other instanceof DynamicDataKey)) {
+ return false;
+ }
+
+ DynamicDataKey<?> comp = (DynamicDataKey<?>) other;
+
+ return mKey.equals(comp.getKey()) && mNamespace.equals(comp.getNamespace());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mKey,mNamespace);
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return String.format("namespace = %s, key = %s", mNamespace, mKey);
+ }
+}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
index f4f2cb7..5d6d870 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
@@ -24,7 +24,7 @@
import androidx.annotation.RestrictTo.Scope;
import androidx.wear.protolayout.expression.proto.DynamicProto;
import androidx.wear.protolayout.expression.proto.FixedProto;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
/**
* Builders for fixed value primitive types that can be used in dynamic expressions and in for state
@@ -39,7 +39,7 @@
* @since 1.2
*/
static final class FixedInt32
- implements DynamicBuilders.DynamicInt32, StateEntryBuilders.StateEntryValue {
+ implements DynamicBuilders.DynamicInt32, DynamicDataBuilders.DynamicDataValue {
private final FixedProto.FixedInt32 mImpl;
@Nullable private final Fingerprint mFingerprint;
@@ -92,8 +92,8 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public StateEntryProto.StateEntryValue toStateEntryValueProto() {
- return StateEntryProto.StateEntryValue.newBuilder().setInt32Val(mImpl).build();
+ public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+ return DynamicDataProto.DynamicDataValue.newBuilder().setInt32Val(mImpl).build();
}
@Override
@@ -105,7 +105,7 @@
/** Builder for {@link FixedInt32}. */
public static final class Builder
implements DynamicBuilders.DynamicInt32.Builder,
- StateEntryBuilders.StateEntryValue.Builder {
+ DynamicDataBuilders.DynamicDataValue.Builder {
private final FixedProto.FixedInt32.Builder mImpl = FixedProto.FixedInt32.newBuilder();
private final Fingerprint mFingerprint = new Fingerprint(974881783);
@@ -137,7 +137,7 @@
* @since 1.2
*/
static final class FixedString
- implements DynamicBuilders.DynamicString, StateEntryBuilders.StateEntryValue {
+ implements DynamicBuilders.DynamicString, DynamicDataBuilders.DynamicDataValue {
private final FixedProto.FixedString mImpl;
@Nullable private final Fingerprint mFingerprint;
@@ -191,8 +191,8 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public StateEntryProto.StateEntryValue toStateEntryValueProto() {
- return StateEntryProto.StateEntryValue.newBuilder().setStringVal(mImpl).build();
+ public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+ return DynamicDataProto.DynamicDataValue.newBuilder().setStringVal(mImpl).build();
}
@Override
@@ -204,7 +204,7 @@
/** Builder for {@link FixedString}. */
public static final class Builder
implements DynamicBuilders.DynamicString.Builder,
- StateEntryBuilders.StateEntryValue.Builder {
+ DynamicDataBuilders.DynamicDataValue.Builder {
private final FixedProto.FixedString.Builder mImpl = FixedProto.FixedString.newBuilder();
private final Fingerprint mFingerprint = new Fingerprint(1963352072);
@@ -236,7 +236,7 @@
* @since 1.2
*/
static final class FixedFloat
- implements DynamicBuilders.DynamicFloat, StateEntryBuilders.StateEntryValue {
+ implements DynamicBuilders.DynamicFloat, DynamicDataBuilders.DynamicDataValue {
private final FixedProto.FixedFloat mImpl;
@Nullable private final Fingerprint mFingerprint;
@@ -290,8 +290,8 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public StateEntryProto.StateEntryValue toStateEntryValueProto() {
- return StateEntryProto.StateEntryValue.newBuilder().setFloatVal(mImpl).build();
+ public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+ return DynamicDataProto.DynamicDataValue.newBuilder().setFloatVal(mImpl).build();
}
@Override
@@ -303,7 +303,7 @@
/** Builder for {@link FixedFloat}. */
public static final class Builder
implements DynamicBuilders.DynamicFloat.Builder,
- StateEntryBuilders.StateEntryValue.Builder {
+ DynamicDataBuilders.DynamicDataValue.Builder {
private final FixedProto.FixedFloat.Builder mImpl = FixedProto.FixedFloat.newBuilder();
private final Fingerprint mFingerprint = new Fingerprint(-144724541);
@@ -338,7 +338,7 @@
* @since 1.2
*/
static final class FixedBool
- implements DynamicBuilders.DynamicBool, StateEntryBuilders.StateEntryValue {
+ implements DynamicBuilders.DynamicBool, DynamicDataBuilders.DynamicDataValue {
private final FixedProto.FixedBool mImpl;
@Nullable private final Fingerprint mFingerprint;
@@ -391,8 +391,8 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public StateEntryProto.StateEntryValue toStateEntryValueProto() {
- return StateEntryProto.StateEntryValue.newBuilder().setBoolVal(mImpl).build();
+ public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+ return DynamicDataProto.DynamicDataValue.newBuilder().setBoolVal(mImpl).build();
}
@Override
@@ -403,7 +403,8 @@
/** Builder for {@link FixedBool}. */
public static final class Builder
- implements DynamicBuilders.DynamicBool.Builder, StateEntryBuilders.StateEntryValue.Builder {
+ implements DynamicBuilders.DynamicBool.Builder,
+ DynamicDataBuilders.DynamicDataValue.Builder {
private final FixedProto.FixedBool.Builder mImpl = FixedProto.FixedBool.newBuilder();
private final Fingerprint mFingerprint = new Fingerprint(-665116398);
@@ -436,7 +437,7 @@
* @since 1.2
*/
static final class FixedColor
- implements DynamicBuilders.DynamicColor, StateEntryBuilders.StateEntryValue {
+ implements DynamicBuilders.DynamicColor, DynamicDataBuilders.DynamicDataValue {
private final FixedProto.FixedColor mImpl;
@Nullable private final Fingerprint mFingerprint;
@@ -490,8 +491,8 @@
@Override
@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
- public StateEntryProto.StateEntryValue toStateEntryValueProto() {
- return StateEntryProto.StateEntryValue.newBuilder().setColorVal(mImpl).build();
+ public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+ return DynamicDataProto.DynamicDataValue.newBuilder().setColorVal(mImpl).build();
}
@Override
@@ -503,7 +504,7 @@
/** Builder for {@link FixedColor}. */
public static final class Builder
implements DynamicBuilders.DynamicColor.Builder,
- StateEntryBuilders.StateEntryValue.Builder {
+ DynamicDataBuilders.DynamicDataValue.Builder {
private final FixedProto.FixedColor.Builder mImpl = FixedProto.FixedColor.newBuilder();
private final Fingerprint mFingerprint = new Fingerprint(-1895809356);
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java
new file mode 100644
index 0000000..24ed21e
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ * Represent a {@link DynamicDataKey} that references real-time data from the platform.
+ *
+ * <p> The [namespace, key] tuple creates the actual reference, so that a single key can refer to
+ * two different sources in two different namespaces.
+ *
+ * <p> The namespace must not be empty. Additionally, the "protolayout" namespace (and its
+ * lowercase and uppercase variations) are reserved for the default platform data sources and
+ * should not be used for any custom OEM data source. To choose the namespace that does not
+ * conflict with an existing one, use a unique prefix for your namespace, for example, company
+ * name or product name.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public final class PlatformDataKey<T extends DynamicBuilders.DynamicType> extends DynamicDataKey<T>
+{
+ @NonNull private static final String RESERVED_NAMESPACE = "protolayout";
+
+ /**
+ * Create a {@link PlatformDataKey} with the specified key in the given namespace.
+ *
+ * @param namespace The namespace of the key for the platform data source.
+ * @param key The key that references the platform data source.
+ */
+ public PlatformDataKey(@NonNull String namespace, @NonNull String key) {
+ super(namespace, key);
+ if (namespace.isEmpty()) {
+ throw new IllegalArgumentException("Custom data source namespace must not be empty.");
+ }
+
+ if (RESERVED_NAMESPACE.equalsIgnoreCase(namespace)) {
+ throw new IllegalArgumentException(String.format(
+ "Custom data source must not use the reserved namespace:%s",
+ RESERVED_NAMESPACE));
+ }
+ }
+
+ /**
+ * Create a {@link PlatformDataKey} with the specified key in the reserved namespace.
+ * This should only be used by protolayout library internally for default platform data sources.
+ *
+ * @param key The key that references the platform data source
+ */
+ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+ public PlatformDataKey(@NonNull String key) {
+ super(RESERVED_NAMESPACE, key);
+ }
+}
+
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
index 0974b70..8be1449 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
@@ -20,38 +20,57 @@
import static androidx.wear.protolayout.expression.DynamicBuilders.PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT;
import android.Manifest;
-import android.os.Build.VERSION_CODES;
import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
import androidx.annotation.RequiresPermission;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
import androidx.wear.protolayout.expression.DynamicBuilders.PlatformInt32Source;
/** Utility class provides utils to access health data. */
-@ProtoLayoutExperimental
public class PlatformHealthSources {
private PlatformHealthSources() {
}
- /** Creates a {@link DynamicInt32} which receives the current heat rate from the sensor. */
- @RequiresPermission(Manifest.permission.BODY_SENSORS)
- @ProtoLayoutExperimental
+ /**
+ * The data source key for heart rate bpm data from default platform health sources.
+ */
@NonNull
- public static DynamicInt32 heartRateBpm() {
+ @RequiresPermission(Manifest.permission.BODY_SENSORS)
+ public static final PlatformDataKey<DynamicFloat> HEART_RATE_BPM =
+ new PlatformDataKey<>("HeartRate");
+
+ /**
+ * The data source key for daily step count data from default platform health sources.
+ */
+ @NonNull
+ @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
+ public static final PlatformDataKey<DynamicInt32> DAILY_STEPS =
+ new PlatformDataKey<>("Daily Steps");
+
+ /**
+ * Creates a {@link DynamicInt32} which receives the current heat rate from the sensor.
+ *
+ * <p> This method provides backward compatibility and is preferred over using {@code
+ * HEART_RATE_BPM} directly.
+ */
+ @RequiresPermission(Manifest.permission.BODY_SENSORS)
+ @NonNull
+ public static DynamicFloat heartRateBpm() {
return new PlatformInt32Source.Builder()
.setSourceType(PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE)
- .build();
+ .build().asFloat();
}
/**
* Creates a {@link DynamicInt32} which receives the current daily steps from the sensor.
* This is the total step count over a day, where the previous day ends and a new day begins at
* 12:00 AM local time.
+ *
+ * <p> This method provides backward compatibility and is preferred over using {@code
+ * DAILY_STEPS} directly.
*/
- @RequiresApi(VERSION_CODES.Q)
@RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
- @ProtoLayoutExperimental
@NonNull
public static DynamicInt32 dailySteps() {
return new PlatformInt32Source.Builder()
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
index beb1207..c7263ec 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
@@ -51,7 +51,7 @@
@Test
public void stateEntryValueBool() {
- DynamicBool stateBool = DynamicBool.fromState(STATE_KEY);
+ DynamicBool stateBool = DynamicBool.from(new AppDataKey<>(STATE_KEY));
assertThat(stateBool.toDynamicBoolProto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
@@ -59,8 +59,8 @@
@Test
public void stateToString() {
- assertThat(DynamicBool.fromState("key").toString())
- .isEqualTo("StateBoolSource{sourceKey=key}");
+ assertThat(DynamicBool.from(new AppDataKey<>("key")).toString())
+ .isEqualTo("StateBoolSource{sourceKey=key, sourceNamespace=}");
}
@Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
index 9f03379..2751e61 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
@@ -58,7 +58,7 @@
@Test
public void stateEntryValueColor() {
- DynamicColor stateColor = DynamicColor.fromState(STATE_KEY);
+ DynamicColor stateColor = DynamicColor.from(new AppDataKey<>(STATE_KEY));
assertThat(stateColor.toDynamicColorProto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
@@ -66,8 +66,8 @@
@Test
public void stateToString() {
- assertThat(DynamicColor.fromState("key").toString())
- .isEqualTo("StateColorSource{sourceKey=key}");
+ assertThat(DynamicColor.from(new AppDataKey<>("key")).toString())
+ .isEqualTo("StateColorSource{sourceKey=key, sourceNamespace=}");
}
@Test
@@ -104,10 +104,11 @@
@Test
public void stateAnimatedColor() {
- DynamicColor stateColor = DynamicColor.fromState(STATE_KEY);
+ AppDataKey<DynamicColor> source = new AppDataKey<>(STATE_KEY);
+ DynamicColor stateColor = DynamicColor.from(source);
- DynamicColor animatedColor = DynamicColor.animate(STATE_KEY);
- DynamicColor animatedColorWithSpec = DynamicColor.animate(STATE_KEY, SPEC);
+ DynamicColor animatedColor = DynamicColor.animate(source);
+ DynamicColor animatedColorWithSpec = DynamicColor.animate(source, SPEC);
assertThat(animatedColor.toDynamicColorProto().getAnimatableDynamic().hasAnimationSpec())
.isFalse();
@@ -124,7 +125,7 @@
public void stateAnimatedToString() {
assertThat(
DynamicColor.animate(
- /* stateKey= */ "key",
+ /* stateKey= */ new AppDataKey<>("key"),
new AnimationSpec.Builder()
.setAnimationParameters(
new AnimationParameters.Builder().setDelayMillis(1).build())
@@ -132,7 +133,8 @@
.toString())
.isEqualTo(
"AnimatableDynamicColor{"
- + "input=StateColorSource{sourceKey=key}, animationSpec=AnimationSpec{"
+ + "input=StateColorSource{sourceKey=key, sourceNamespace=}, "
+ + "animationSpec=AnimationSpec{"
+ "animationParameters=AnimationParameters{durationMillis=0, easing=null, "
+ "delayMillis=1}, repeatable=null}}");
}
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java
new file mode 100644
index 0000000..47237c4
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+package androidx.wear.protolayout.expression;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DynamicDataValueTest {
+ @Test
+ public void boolDynamicDataValue() {
+ DynamicDataValue boolDynamicDataValue = DynamicDataValue.fromBool(true);
+
+ assertThat(boolDynamicDataValue.toDynamicDataValueProto().getBoolVal().getValue()).isTrue();
+ }
+
+ @Test
+ public void colorDynamicDataValue() {
+ DynamicDataValue colorDynamicDataValue = DynamicDataValue.fromColor(0xff00ff00);
+
+ assertThat(colorDynamicDataValue.toDynamicDataValueProto().getColorVal().getArgb())
+ .isEqualTo(0xff00ff00);
+ }
+
+ @Test
+ public void floatDynamicDataValue() {
+ DynamicDataValue floatDynamicDataValue = DynamicDataValue.fromFloat(42.42f);
+
+ assertThat(floatDynamicDataValue.toDynamicDataValueProto().getFloatVal().getValue())
+ .isWithin(0.0001f)
+ .of(42.42f);
+ }
+
+ @Test
+ public void intDynamicDataValue() {
+ DynamicDataValue intDynamicDataValue = DynamicDataValue.fromInt(42);
+
+ assertThat(intDynamicDataValue.toDynamicDataValueProto().getInt32Val().getValue())
+ .isEqualTo(42);
+ }
+
+ @Test
+ public void stringDynamicDataValue() {
+ DynamicDataValue stringDynamicDataValue = DynamicDataValue.fromString("constant-value");
+
+ assertThat(stringDynamicDataValue.toDynamicDataValueProto().getStringVal().getValue())
+ .isEqualTo("constant-value");
+ }
+}
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
index d00b7f3..3036fbed 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
@@ -67,7 +67,7 @@
@Test
public void stateEntryValueFloat() {
- DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
+ DynamicFloat stateFloat = DynamicFloat.from(new AppDataKey<>(STATE_KEY));
assertThat(stateFloat.toDynamicFloatProto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
@@ -75,8 +75,8 @@
@Test
public void stateToString() {
- assertThat(DynamicFloat.fromState("key").toString())
- .isEqualTo("StateFloatSource{sourceKey=key}");
+ assertThat(DynamicFloat.from(new AppDataKey<>("key")).toString())
+ .isEqualTo("StateFloatSource{sourceKey=key, sourceNamespace=}");
}
@Test
@@ -198,10 +198,10 @@
@Test
public void stateAnimatedFloat() {
- DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
-
- DynamicFloat animatedFloat = DynamicFloat.animate(STATE_KEY);
- DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(STATE_KEY, SPEC);
+ AppDataKey<DynamicFloat> source = new AppDataKey<>(STATE_KEY);
+ DynamicFloat stateFloat = DynamicFloat.from(source);
+ DynamicFloat animatedFloat = DynamicFloat.animate(source);
+ DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(source, SPEC);
assertThat(animatedFloat.toDynamicFloatProto().getAnimatableDynamic().hasAnimationSpec())
.isFalse();
@@ -221,7 +221,7 @@
public void stateAnimatedToString() {
assertThat(
DynamicFloat.animate(
- /* stateKey= */ "key",
+ new AppDataKey<>("key"),
new AnimationSpec.Builder()
.setAnimationParameters(
new AnimationParameters.Builder()
@@ -230,7 +230,8 @@
.build())
.toString())
.isEqualTo(
- "AnimatableDynamicFloat{input=StateFloatSource{sourceKey=key},"
+ "AnimatableDynamicFloat{"
+ + "input=StateFloatSource{sourceKey=key, sourceNamespace=},"
+ " animationSpec=AnimationSpec{animationParameters"
+ "=AnimationParameters{durationMillis=0,"
+ " easing=null, delayMillis=1}, repeatable=null}}");
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
index f87e5b5..a130199 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
@@ -48,7 +48,7 @@
@Test
public void stateEntryValueInt32() {
- DynamicInt32 stateInt32 = DynamicInt32.fromState(STATE_KEY);
+ DynamicInt32 stateInt32 = DynamicInt32.from(new AppDataKey<>(STATE_KEY));
assertThat(stateInt32.toDynamicInt32Proto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
@@ -56,8 +56,8 @@
@Test
public void stateToString() {
- assertThat(DynamicInt32.fromState("key").toString())
- .isEqualTo("StateInt32Source{sourceKey=key}");
+ assertThat(DynamicInt32.from(new AppDataKey<>("key")).toString())
+ .isEqualTo("StateInt32Source{sourceKey=key, sourceNamespace=}");
}
@Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
index b0f2be1..b33df22 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
@@ -46,7 +46,7 @@
@Test
public void stateEntryValueString() {
- DynamicString stateString = DynamicString.fromState(STATE_KEY);
+ DynamicString stateString = DynamicString.from(new AppDataKey<>(STATE_KEY));
assertThat(stateString.toDynamicStringProto().getStateSource().getSourceKey())
.isEqualTo(STATE_KEY);
@@ -54,8 +54,8 @@
@Test
public void stateToString() {
- assertThat(DynamicString.fromState("key").toString())
- .isEqualTo("StateStringSource{sourceKey=key}");
+ assertThat(DynamicString.from(new AppDataKey<>("key")).toString())
+ .isEqualTo("StateStringSource{sourceKey=key, sourceNamespace=}");
}
@Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java
deleted file mode 100644
index fae643d..0000000
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.
- */
-
-package androidx.wear.protolayout.expression;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public final class StateEntryValueTest {
- @Test
- public void boolStateEntryValue() {
- StateEntryValue boolStateEntryValue = StateEntryValue.fromBool(true);
-
- assertThat(boolStateEntryValue.toStateEntryValueProto().getBoolVal().getValue()).isTrue();
- }
-
- @Test
- public void colorStateEntryValue() {
- StateEntryValue colorStateEntryValue = StateEntryValue.fromColor(0xff00ff00);
-
- assertThat(colorStateEntryValue.toStateEntryValueProto().getColorVal().getArgb())
- .isEqualTo(0xff00ff00);
- }
-
- @Test
- public void floatStateEntryValue() {
- StateEntryValue floatStateEntryValue = StateEntryValue.fromFloat(42.42f);
-
- assertThat(floatStateEntryValue.toStateEntryValueProto().getFloatVal().getValue())
- .isWithin(0.0001f)
- .of(42.42f);
- }
-
- @Test
- public void intStateEntryValue() {
- StateEntryValue intStateEntryValue = StateEntryValue.fromInt(42);
-
- assertThat(intStateEntryValue.toStateEntryValueProto().getInt32Val().getValue()).isEqualTo(42);
- }
-
- @Test
- public void stringStateEntryValue() {
- StateEntryValue stringStateEntryValue = StateEntryValue.fromString("constant-value");
-
- assertThat(stringStateEntryValue.toStateEntryValueProto().getStringVal().getValue())
- .isEqualTo("constant-value");
- }
-}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/action.proto b/wear/protolayout/protolayout-proto/src/main/proto/action.proto
index 72e7e95..944843d 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/action.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/action.proto
@@ -4,7 +4,7 @@
package androidx.wear.protolayout.proto;
import "state.proto";
-import "state_entry.proto";
+import "dynamic_data.proto";
option java_package = "androidx.wear.protolayout.proto";
option java_outer_classname = "ActionProto";
@@ -54,11 +54,11 @@
// A launch action to send an intent to an Android activity.
message AndroidActivity {
- // The package name to send the intent to, for example, "com.google.weather".
+ // The package name to send the intent to, for example, "com.example.weather".
string package_name = 1;
// The fully qualified class name (including the package) to send the intent
- // to, for example, "com.google.weather.WeatherOverviewActivity".
+ // to, for example, "com.example.weather.WeatherOverviewActivity".
string class_name = 2;
// The extras to be included in the intent.
@@ -101,5 +101,5 @@
// The target key of the state item for this action.
string target_key = 1;
// The value to set the state item to, when this action is executed.
- androidx.wear.protolayout.expression.proto.StateEntryValue value = 2;
+ androidx.wear.protolayout.expression.proto.DynamicDataValue value = 2;
}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
index b0729ce..bbb26b9 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
@@ -75,6 +75,9 @@
message StateInt32Source {
// The key in the state to bind to.
string source_key = 1;
+
+ // The namespace for the state key.
+ string source_namespace = 2;
}
// A conditional operator which yields an integer depending on the boolean
@@ -214,6 +217,9 @@
message StateStringSource {
// The key in the state to bind to.
string source_key = 1;
+
+ // The namespace for the state key.
+ string source_namespace = 2;
}
// A conditional operator which yields an string depending on the boolean
@@ -299,6 +305,9 @@
message StateFloatSource {
// The key in the state to bind to.
string source_key = 1;
+
+ // The namespace for the state key.
+ string source_namespace = 2;
}
// An operation to convert a Int32 value in the dynamic data pipeline to a Float
@@ -373,6 +382,9 @@
message StateBoolSource {
// The key in the state to bind to.
string source_key = 1;
+
+ // The namespace for the state key.
+ string source_namespace = 2;
}
// The type of comparison used in ComparisonInt32Op and ComparisonFloatOp.
@@ -483,6 +495,9 @@
message StateColorSource {
// The key in the state to bind to.
string source_key = 1;
+
+ // The namespace for the state key.
+ string source_namespace = 2;
}
// A static interpolation node, between two fixed color values.
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto b/wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
similarity index 70%
rename from wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto
rename to wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
index 622043d..f373b86 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
@@ -1,4 +1,4 @@
-// State entries of a provider.
+// Dynamic data entries of a provider.
syntax = "proto3";
package androidx.wear.protolayout.expression.proto;
@@ -6,10 +6,10 @@
import "fixed.proto";
option java_package = "androidx.wear.protolayout.expression.proto";
-option java_outer_classname = "StateEntryProto";
+option java_outer_classname = "DynamicDataProto";
-// A state entry value.
-message StateEntryValue {
+// A dynamic data value.
+message DynamicDataValue {
oneof inner {
FixedString string_val = 1;
FixedInt32 int32_val = 2;
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
index db32f5c..e2d7a5c 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/layout.proto
@@ -48,7 +48,7 @@
FONT_VARIANT_BODY = 2;
// Placeholder for a custom font variant in the renderer.
- FONT_VARIANT_EXTENSION_1 = 3;
+ FONT_VARIANT_CUSTOM_1 = 3;
}
// An extensible FontVariant property.
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto b/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
index 4b4a012..010004ed 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/modifiers.proto
@@ -183,6 +183,9 @@
//
// Defaults to false (i.e. not hidden).
BoolProp hidden = 8;
+
+ // The optional identifier for the layout element.
+ string id = 9;
}
// The content transition of an element. Any update to the element or its
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/state.proto b/wear/protolayout/protolayout-proto/src/main/proto/state.proto
index 162077e..8929f1e 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/state.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/state.proto
@@ -3,7 +3,7 @@
package androidx.wear.protolayout.proto;
-import "state_entry.proto";
+import "dynamic_data.proto";
option java_package = "androidx.wear.protolayout.proto";
option java_outer_classname = "StateProto";
@@ -14,6 +14,6 @@
string last_clickable_id = 1;
// Any shared state between the provider and renderer.
- map<string, androidx.wear.protolayout.expression.proto.StateEntryValue>
+ map<string, androidx.wear.protolayout.expression.proto.DynamicDataValue>
id_to_value = 2;
}
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
index 208c686..3b0a666 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
@@ -40,6 +40,7 @@
import androidx.collection.ArrayMap;
import androidx.collection.ArraySet;
import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
import androidx.wear.protolayout.expression.pipeline.BoundDynamicType;
import androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest;
import androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator;
@@ -47,6 +48,7 @@
import androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver;
import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
import androidx.wear.protolayout.expression.pipeline.QuotaManager;
+import androidx.wear.protolayout.expression.pipeline.SensorGatewaySingleDataProvider;
import androidx.wear.protolayout.expression.pipeline.StateStore;
import androidx.wear.protolayout.expression.pipeline.TimeGatewayImpl;
import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
@@ -65,6 +67,7 @@
import androidx.wear.protolayout.renderer.dynamicdata.NodeInfo.ResolvedAvd;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -145,7 +148,16 @@
.setStateStore(stateStore);
evaluatorConfigBuilder.setDynamicTypesQuotaManager(dynamicNodeQuotaManager);
if (sensorGateway != null) {
- evaluatorConfigBuilder.setSensorGateway(sensorGateway);
+ evaluatorConfigBuilder.addPlatformDataProvider(
+ new SensorGatewaySingleDataProvider(
+ sensorGateway, PlatformHealthSources.HEART_RATE_BPM),
+ Collections.singleton(PlatformHealthSources.HEART_RATE_BPM)
+ );
+ evaluatorConfigBuilder.addPlatformDataProvider(
+ new SensorGatewaySingleDataProvider(
+ sensorGateway, PlatformHealthSources.DAILY_STEPS),
+ Collections.singleton(PlatformHealthSources.DAILY_STEPS)
+ );
}
if (enableAnimations) {
evaluatorConfigBuilder.setAnimationQuotaManager(animationQuotaManager);
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
index 9b7d7ac..12e7936 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
@@ -42,6 +42,8 @@
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
import androidx.wear.protolayout.expression.pipeline.QuotaManager;
import androidx.wear.protolayout.expression.pipeline.StateStore;
@@ -70,7 +72,7 @@
import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import androidx.wear.protolayout.proto.ColorProto.ColorProp;
import androidx.wear.protolayout.proto.DimensionProto.DegreesProp;
import androidx.wear.protolayout.proto.DimensionProto.DpProp;
@@ -168,7 +170,8 @@
}
@Test
- public void buildPipeline_dpProp_animatable_animationsDisabled_hasStaticValue_assignsEndVal() {
+ public void
+ buildPipeline_dpProp_animatable_animationsDisabled_hasStaticValue_assignsEndValue() {
List<Float> results = new ArrayList<>();
float endValue = 10.0f;
DynamicFloat dynamicFloat = animatableFixedFloat(5.0f, endValue);
@@ -183,7 +186,7 @@
@Test
public void
- buildPipeline_degreesProp_animatable_animationsDisabled_hasStaticValue_assignsEndVal() {
+ buildPipeline_degreesProp_animatable_animationsDisabled_hasStaticValue_assignsEndValue() {
List<Float> results = new ArrayList<>();
float endValue = 10.0f;
DynamicFloat dynamicFloat = animatableFixedFloat(5.0f, endValue);
@@ -217,7 +220,7 @@
@Test
public void
- buildPipeline_colorProp_animatable_animationsDisabled_noStaticValueSet_assignsEndVal() {
+ buildPipeline_colorProp_animatable_animationsDisabled_noStaticValueSet_assignsEndValue() {
List<Integer> results = new ArrayList<>();
DynamicColor dynamicColor = animatableFixedColor(0, 1);
ColorProp colorProp = ColorProp.newBuilder().setDynamicValue(dynamicColor).build();
@@ -1719,8 +1722,7 @@
Repeatable.newBuilder()
.setRepeatMode(
RepeatMode
- .REPEAT_MODE_REVERSE
- )
+ .REPEAT_MODE_REVERSE)
.setIterations(iterations)
.setForwardRepeatOverride(
alternateParameters)
@@ -1813,13 +1815,12 @@
ProtoLayoutDynamicDataPipeline pipeline =
enableAnimations
? new ProtoLayoutDynamicDataPipeline(
- /* sensorGateway= */ null,
+ /* sensorGateway= */ null,
mStateStore,
new FixedQuotaManagerImpl(MAX_VALUE),
new FixedQuotaManagerImpl(MAX_VALUE))
: new ProtoLayoutDynamicDataPipeline(
- /* sensorGateway= */ null,
- mStateStore);
+ /* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1842,7 +1843,7 @@
AddToListCallback<Float> receiver =
new AddToListCallback<>(results, /* invalidList= */ null);
ProtoLayoutDynamicDataPipeline pipeline =
- new ProtoLayoutDynamicDataPipeline( /* sensorGateway= */ null, mStateStore);
+ new ProtoLayoutDynamicDataPipeline(/* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1860,7 +1861,7 @@
AddToListCallback<Integer> receiver =
new AddToListCallback<>(results, /* invalidList= */ null);
ProtoLayoutDynamicDataPipeline pipeline =
- new ProtoLayoutDynamicDataPipeline( /* sensorGateway= */ null, mStateStore);
+ new ProtoLayoutDynamicDataPipeline(/* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1878,7 +1879,7 @@
AddToListCallback<Float> receiver =
new AddToListCallback<>(results, /* invalidList= */ null);
ProtoLayoutDynamicDataPipeline pipeline =
- new ProtoLayoutDynamicDataPipeline( /* sensorGateway= */ null, mStateStore);
+ new ProtoLayoutDynamicDataPipeline(/* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1896,7 +1897,7 @@
AddToListCallback<Float> receiver =
new AddToListCallback<>(results, /* invalidList= */ null);
ProtoLayoutDynamicDataPipeline pipeline =
- new ProtoLayoutDynamicDataPipeline( /* sensorGateway= */ null, mStateStore);
+ new ProtoLayoutDynamicDataPipeline(/* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1914,7 +1915,7 @@
AddToListCallback<Integer> receiver =
new AddToListCallback<>(results, /* invalidList= */ null);
ProtoLayoutDynamicDataPipeline pipeline =
- new ProtoLayoutDynamicDataPipeline( /* sensorGateway= */ null, mStateStore);
+ new ProtoLayoutDynamicDataPipeline(/* sensorGateway= */ null, mStateStore);
shadowOf(getMainLooper()).idle();
pipeline.setFullyVisible(true);
@@ -1927,20 +1928,20 @@
}
private void setFloatStateVal(String key, float val) {
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- key,
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBuilders.DynamicFloat>(key),
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(val))
.build()));
shadowOf(getMainLooper()).idle();
}
private void setBoolStateVal(String key, boolean val) {
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- key,
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBuilders.DynamicBool>(key),
+ DynamicDataValue.newBuilder()
.setBoolVal(FixedBool.newBuilder().setValue(val))
.build()));
shadowOf(getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
index 9e263bf..1eb0e31 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
@@ -75,6 +75,8 @@
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
import androidx.wear.protolayout.expression.pipeline.StateStore;
import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationParameters;
@@ -94,7 +96,7 @@
import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
import androidx.wear.protolayout.proto.ActionProto.Action;
import androidx.wear.protolayout.proto.ActionProto.AndroidActivity;
import androidx.wear.protolayout.proto.ActionProto.AndroidBooleanExtra;
@@ -415,38 +417,40 @@
assertThat(tv.isImportantForAccessibility()).isTrue();
assertThat(info.isFocusable()).isTrue();
- mStateStore.setStateEntryValuesProto(
+ AppDataKey<DynamicBuilders.DynamicString> keyContent = new AppDataKey<>("content");
+ AppDataKey<DynamicBuilders.DynamicString> keyState = new AppDataKey<>("state");
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "content",
- StateEntryValue.newBuilder()
+ keyContent,
+ DynamicDataValue.newBuilder()
.setStringVal(
FixedString.newBuilder()
.setValue(initialDynamicContentDescription))
.build(),
- "state",
- StateEntryValue.newBuilder()
+ keyState,
+ DynamicDataValue.newBuilder()
.setStringVal(
FixedString.newBuilder()
.setValue(initialDynamicStateDescription))
.build()));
info = AccessibilityNodeInfoCompat.wrap(tv.createAccessibilityNodeInfo());
- assertThat(mStateStore.getStateEntryValuesProto("content").getStringVal().getValue())
+ assertThat(mStateStore.getDynamicDataValuesProto(keyContent).getStringVal().getValue())
.isEqualTo(initialDynamicContentDescription);
assertThat(info.getContentDescription().toString())
.isEqualTo(initialDynamicContentDescription);
assertThat(info.getStateDescription().toString()).isEqualTo(initialDynamicStateDescription);
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "content",
- StateEntryValue.newBuilder()
+ keyContent,
+ DynamicDataValue.newBuilder()
.setStringVal(
FixedString.newBuilder()
.setValue(targetDynamicContentDescription))
.build(),
- "state",
- StateEntryValue.newBuilder()
+ keyState,
+ DynamicDataValue.newBuilder()
.setStringVal(
FixedString.newBuilder()
.setValue(targetDynamicStateDescription))
@@ -1675,10 +1679,10 @@
Drawable drawableAVDSeekable = imageAVDSeekable.getDrawable();
assertThat(drawableAVDSeekable).isInstanceOf(SeekableAnimatedVectorDrawable.class);
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "anim_val",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBuilders.DynamicFloat>("anim_val"),
+ DynamicDataValue.newBuilder()
.setFloatVal(FixedFloat.newBuilder().setValue(0.44f))
.build()));
shadowOf(getMainLooper()).idle();
@@ -2125,10 +2129,11 @@
@Test
public void inflate_arcLine_dynamicData_updatesArcLength() {
- mStateStore.setStateEntryValuesProto(
+ AppDataKey<DynamicBuilders.DynamicInt32> keyFoo = new AppDataKey<>("foo");
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(10))
.build()));
@@ -2173,10 +2178,10 @@
WearCurvedLineView line = (WearCurvedLineView) sizedContainer.getChildAt(0);
assertThat(line.getLineSweepAngleDegrees()).isEqualTo(10);
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setInt32Val(FixedInt32.newBuilder().setValue(20))
.build()));
@@ -2270,10 +2275,11 @@
@Test
public void inflate_text_dynamicColor_updatesColor() {
- mStateStore.setStateEntryValuesProto(
+ AppDataKey<DynamicBuilders.DynamicColor> keyFoo = new AppDataKey<>("foo");
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(0xFFFFFFFF))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -2301,10 +2307,10 @@
TextView tv = (TextView) rootLayout.getChildAt(0);
assertThat(tv.getCurrentTextColor()).isEqualTo(0xFFFFFFFF);
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "foo",
- StateEntryValue.newBuilder()
+ keyFoo,
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(0x11111111))
.build()));
@@ -2316,10 +2322,10 @@
// Must match a resource ID in buildResources
String protoResId = "android";
- mStateStore.setStateEntryValuesProto(
+ mStateStore.setAppStateEntryValuesProto(
ImmutableMap.of(
- "tint",
- StateEntryValue.newBuilder()
+ new AppDataKey<DynamicBuilders.DynamicColor>("tint"),
+ DynamicDataValue.newBuilder()
.setColorVal(FixedColor.newBuilder().setArgb(0xFFFFFFFF))
.build()));
shadowOf(Looper.getMainLooper()).idle();
@@ -4205,8 +4211,9 @@
private static FadeInTransition.Builder fadeIn(int delay) {
return FadeInTransition.newBuilder()
.setAnimationSpec(
- AnimationSpec.newBuilder().setAnimationParameters(
- AnimationParameters.newBuilder().setDelayMillis(delay)));
+ AnimationSpec.newBuilder()
+ .setAnimationParameters(
+ AnimationParameters.newBuilder().setDelayMillis(delay)));
}
private LayoutElement textFadeInSlideIn(String text) {
diff --git a/wear/protolayout/protolayout/api/current.txt b/wear/protolayout/protolayout/api/current.txt
index 506910e9..7b83100 100644
--- a/wear/protolayout/protolayout/api/current.txt
+++ b/wear/protolayout/protolayout/api/current.txt
@@ -117,15 +117,15 @@
}
public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
- method public String getTargetKey();
- method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+ method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+ method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
}
public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
ctor public ActionBuilders.SetStateAction.Builder();
method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
}
public final class ColorBuilders {
@@ -993,13 +993,13 @@
}
public static final class StateBuilders.State {
- method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+ method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
method public String getLastClickableId();
}
public static final class StateBuilders.State.Builder {
ctor public StateBuilders.State.Builder();
- method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
method public androidx.wear.protolayout.StateBuilders.State build();
}
diff --git a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
index ce4acaa..3c60bcf 100644
--- a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
@@ -117,15 +117,15 @@
}
public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
- method public String getTargetKey();
- method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+ method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+ method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
}
public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
ctor public ActionBuilders.SetStateAction.Builder();
method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
}
public final class ColorBuilders {
@@ -1211,13 +1211,13 @@
}
public static final class StateBuilders.State {
- method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+ method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
method public String getLastClickableId();
}
public static final class StateBuilders.State.Builder {
ctor public StateBuilders.State.Builder();
- method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
method public androidx.wear.protolayout.StateBuilders.State build();
}
diff --git a/wear/protolayout/protolayout/api/restricted_current.txt b/wear/protolayout/protolayout/api/restricted_current.txt
index 506910e9..7b83100 100644
--- a/wear/protolayout/protolayout/api/restricted_current.txt
+++ b/wear/protolayout/protolayout/api/restricted_current.txt
@@ -117,15 +117,15 @@
}
public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
- method public String getTargetKey();
- method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+ method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+ method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
}
public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
ctor public ActionBuilders.SetStateAction.Builder();
method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
- method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+ method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
}
public final class ColorBuilders {
@@ -993,13 +993,13 @@
}
public static final class StateBuilders.State {
- method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+ method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
method public String getLastClickableId();
}
public static final class StateBuilders.State.Builder {
ctor public StateBuilders.State.Builder();
- method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+ method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
method public androidx.wear.protolayout.StateBuilders.State build();
}
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
index b0706de..b0ef69b 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
@@ -26,9 +26,10 @@
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.wear.protolayout.StateBuilders.State;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
import androidx.wear.protolayout.expression.Fingerprint;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
import androidx.wear.protolayout.proto.ActionProto;
import java.util.Collections;
import java.util.HashMap;
@@ -923,8 +924,9 @@
* @since 1.2
*/
@NonNull
- public String getTargetKey() {
- return mImpl.getTargetKey();
+ public AppDataKey<?> getTargetKey() {
+
+ return new AppDataKey<>(mImpl.getTargetKey());
}
/**
@@ -933,9 +935,9 @@
* @since 1.2
*/
@Nullable
- public StateEntryValue getValue() {
+ public DynamicDataValue getValue() {
if (mImpl.hasValue()) {
- return StateEntryBuilders.stateEntryValueFromProto(mImpl.getValue());
+ return DynamicDataBuilders.dynamicDataValueFromProto(mImpl.getValue());
} else {
return null;
}
@@ -979,8 +981,8 @@
* @since 1.2
*/
@NonNull
- public Builder setTargetKey(@NonNull String targetKey) {
- mImpl.setTargetKey(targetKey);
+ public Builder setTargetKey(@NonNull AppDataKey<?> targetKey) {
+ mImpl.setTargetKey(targetKey.getKey());
mFingerprint.recordPropertyUpdate(1, targetKey.hashCode());
return this;
}
@@ -991,8 +993,8 @@
* @since 1.2
*/
@NonNull
- public Builder setValue(@NonNull StateEntryValue value) {
- mImpl.setValue(value.toStateEntryValueProto());
+ public Builder setValue(@NonNull DynamicDataValue value) {
+ mImpl.setValue(value.toDynamicDataValueProto());
mFingerprint.recordPropertyUpdate(
2, checkNotNull(value.getFingerprint()).aggregateValueAsInt());
return this;
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
index 8889ec0..a5a256b 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
@@ -23,10 +23,11 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
import androidx.wear.protolayout.expression.Fingerprint;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
import androidx.wear.protolayout.proto.StateProto;
import java.util.Collections;
import java.util.HashMap;
@@ -67,11 +68,13 @@
* @since 1.2
*/
@NonNull
- public Map<String, StateEntryValue> getIdToValueMapping() {
- Map<String, StateEntryValue> map = new HashMap<>();
- for (Entry<String, StateEntryProto.StateEntryValue> entry :
+ public Map<String, DynamicDataValue> getIdToValueMapping() {
+ Map<String, DynamicDataValue> map = new HashMap<>();
+ for (Entry<String, DynamicDataProto.DynamicDataValue> entry :
mImpl.getIdToValueMap().entrySet()) {
- map.put(entry.getKey(), StateEntryBuilders.stateEntryValueFromProto(entry.getValue()));
+ map.put(
+ entry.getKey(),
+ DynamicDataBuilders.dynamicDataValueFromProto(entry.getValue()));
}
return Collections.unmodifiableMap(map);
}
@@ -142,16 +145,27 @@
*/
@SuppressLint("MissingGetterMatchingBuilder")
@NonNull
- public Builder addIdToValueMapping(@NonNull String id, @NonNull StateEntryValue value) {
- mImpl.putIdToValue(id, value.toStateEntryValueProto());
+ public Builder addKeyToValueMapping(
+ @NonNull AppDataKey<?> sourceKey,
+ @NonNull DynamicDataValue value) {
+ mImpl.putIdToValue(sourceKey.getKey(), value.toDynamicDataValueProto());
mFingerprint.recordPropertyUpdate(
- id.hashCode(), checkNotNull(value.getFingerprint()).aggregateValueAsInt());
+ sourceKey.getKey().hashCode(),
+ checkNotNull(value.getFingerprint()).aggregateValueAsInt());
return this;
}
+ private static final int MAX_STATE_SIZE = 30;
+
/** Builds an instance from accumulated values. */
@NonNull
public State build() {
+ if (mImpl.getIdToValueMap().size() > MAX_STATE_SIZE) {
+ throw new IllegalStateException(
+ String.format(
+ "State size is too large: %d. Maximum " + "allowed state size is %d.",
+ mImpl.getIdToValueMap().size(), MAX_STATE_SIZE));
+ }
return new State(mImpl.build(), mFingerprint);
}
}
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
index 39aa11e..fa0d083 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
@@ -20,7 +20,9 @@
import android.content.ComponentName;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
import androidx.wear.protolayout.proto.ActionProto;
import org.junit.Test;
@@ -36,15 +38,15 @@
@Test
public void setStateAction() {
- String key = "key";
- StateEntryBuilders.StateEntryValue value = StateEntryBuilders.StateEntryValue.fromString(
- "value");
+ AppDataKey<DynamicBuilders.DynamicString> key = new AppDataKey<>("key");
+ DynamicDataBuilders.DynamicDataValue value =
+ DynamicDataBuilders.DynamicDataValue.fromString("value");
ActionBuilders.SetStateAction setStateAction = new ActionBuilders.SetStateAction.Builder()
.setTargetKey(key).setValue(value).build();
assertThat(setStateAction.getTargetKey()).isEqualTo(key);
- assertThat(setStateAction.getValue().toStateEntryValueProto()).isEqualTo(
- value.toStateEntryValueProto());
+ assertThat(setStateAction.getValue().toDynamicDataValueProto()).isEqualTo(
+ value.toDynamicDataValueProto());
}
@Test
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
index 078ae25..a37cb28 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
@@ -23,6 +23,7 @@
import android.graphics.Color;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.ColorProto;
import org.junit.Test;
@@ -34,13 +35,17 @@
private static final String STATE_KEY = "state-key";
private static final ColorBuilders.ColorProp COLOR =
new ColorBuilders.ColorProp.Builder(Color.RED)
- .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicColor.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
@SuppressWarnings("deprecation")
private static final ColorBuilders.ColorProp.Builder COLOR_BUILDER_WITHOUT_STATIC_VALUE =
new ColorBuilders.ColorProp.Builder()
- .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY));
+ .setDynamicValue(
+ DynamicBuilders.DynamicColor.from(
+ new AppDataKey<>(STATE_KEY)));
@Test
public void colorPropSupportsDynamicColor() {
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
index 81f3b67..cdee4a9 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertThrows;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.DimensionProto;
import org.junit.Test;
@@ -34,23 +35,31 @@
private static final String STATE_KEY = "state-key";
private static final DimensionBuilders.DpProp DP_PROP =
new DimensionBuilders.DpProp.Builder(3.14f)
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
@SuppressWarnings("deprecation")
private static final DimensionBuilders.DpProp.Builder DP_PROP_WITHOUT_STATIC_VALUE =
new DimensionBuilders.DpProp.Builder()
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY));
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)));
private static final DimensionBuilders.DegreesProp DEGREES_PROP =
new DimensionBuilders.DegreesProp.Builder(3.14f)
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
@SuppressWarnings("deprecation")
private static final DimensionBuilders.DegreesProp.Builder DEGREES_PROP_WITHOUT_STATIC_VALUE =
new DimensionBuilders.DegreesProp.Builder()
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY));
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)));
@Test
public void dpPropSupportsDynamicValue() {
@@ -113,7 +122,8 @@
public void wrappedMinSize_throwsWhenSetToDynamicValue() {
DimensionBuilders.DpProp minSizeDynamic =
new DimensionBuilders.DpProp.Builder(42)
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState("some-state"))
+ .setDynamicValue(DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>("some-state")))
.build();
assertThrows(
IllegalArgumentException.class,
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
index 3b6107e..691b328 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertThrows;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.DimensionProto;
import androidx.wear.protolayout.proto.LayoutElementProto;
import androidx.wear.protolayout.proto.TypesProto;
@@ -34,7 +35,9 @@
private static final String STATE_KEY = "state-key";
private static final DimensionBuilders.DegreesProp DEGREES_PROP =
new DimensionBuilders.DegreesProp.Builder(10)
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
private static final DimensionBuilders.AngularLayoutConstraint DEGREES_PROP_CONSTRAINT =
new DimensionBuilders.AngularLayoutConstraint.Builder(20)
@@ -42,7 +45,9 @@
.build();
private static final DimensionBuilders.DpProp DP_PROP =
new DimensionBuilders.DpProp.Builder(10)
- .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
private static final DimensionBuilders.HorizontalLayoutConstraint HORIZONTAL_LAYOUT_CONSTRAINT =
new DimensionBuilders.HorizontalLayoutConstraint.Builder(20)
@@ -54,7 +59,9 @@
.build();
private static final TypeBuilders.StringProp STRING_PROP =
new TypeBuilders.StringProp.Builder("string")
- .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicString.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
private static final TypeBuilders.StringLayoutConstraint STRING_LAYOUT_CONSTRAINT =
new TypeBuilders.StringLayoutConstraint.Builder("pattern")
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
index fec2fb2..8cb5f79 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
@@ -22,6 +22,7 @@
import android.graphics.Color;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.ModifiersProto;
import org.junit.Test;
@@ -33,7 +34,9 @@
private static final String STATE_KEY = "state-key";
private static final ColorBuilders.ColorProp COLOR =
new ColorBuilders.ColorProp.Builder(Color.RED)
- .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicColor.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
@Test
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
index 2b6348d..5f6c5d87 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
@@ -21,6 +21,7 @@
import static com.google.common.truth.Truth.assertThat;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.ResourceProto;
import org.junit.Test;
@@ -55,7 +56,9 @@
new ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder()
.setResourceId(RESOURCE_ID)
.setAnimatedImageFormat(FORMAT)
- .setProgress(DynamicBuilders.DynamicFloat.fromState(stateKey))
+ .setProgress(
+ DynamicBuilders.DynamicFloat.from(
+ new AppDataKey<>(stateKey)))
.build();
ResourceProto.AndroidSeekableAnimatedImageResourceByResId avdProto = avd.toProto();
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
index 3337f82..86d9ddb 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
@@ -18,7 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,20 +38,21 @@
@Test
public void additionalState() {
- StateEntryBuilders.StateEntryValue boolValue =
- StateEntryBuilders.StateEntryValue.fromBool(true);
- StateEntryBuilders.StateEntryValue stringValue =
- StateEntryBuilders.StateEntryValue.fromString("string");
+ DynamicDataBuilders.DynamicDataValue boolValue =
+ DynamicDataBuilders.DynamicDataValue.fromBool(true);
+ DynamicDataBuilders.DynamicDataValue stringValue =
+ DynamicDataBuilders.DynamicDataValue.fromString("string");
StateBuilders.State state = new StateBuilders.State.Builder()
- .addIdToValueMapping("boolValue", boolValue)
- .addIdToValueMapping("stringValue", stringValue)
+ .addKeyToValueMapping(
+ new AppDataKey<DynamicBool>("boolValue"), boolValue)
+ .addKeyToValueMapping(
+ new AppDataKey<DynamicString>("stringValue"), stringValue)
.build();
assertThat(state.getIdToValueMapping()).hasSize(2);
- assertThat(state.getIdToValueMapping().get("boolValue").toStateEntryValueProto()).isEqualTo(
- boolValue.toStateEntryValueProto());
- assertThat(
- state.getIdToValueMapping().get("stringValue").toStateEntryValueProto()).isEqualTo(
- stringValue.toStateEntryValueProto());
+ assertThat(state.getIdToValueMapping().get("boolValue").toDynamicDataValueProto())
+ .isEqualTo(boolValue.toDynamicDataValueProto());
+ assertThat(state.getIdToValueMapping().get("stringValue").toDynamicDataValueProto())
+ .isEqualTo(stringValue.toDynamicDataValueProto());
}
}
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
index 6230a66..7cdffd5 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
@@ -19,6 +19,7 @@
import static com.google.common.truth.Truth.assertThat;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +38,8 @@
@Test
public void onConditionTrigger() {
- DynamicBuilders.DynamicBool condition = DynamicBuilders.DynamicBool.fromState("state");
+ DynamicBuilders.DynamicBool condition =
+ DynamicBuilders.DynamicBool.from(new AppDataKey<>("state"));
TriggerBuilders.Trigger onConditionMetTrigger =
TriggerBuilders.createOnConditionMetTrigger(
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
index 4de0b0a..3245f32 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertThrows;
import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.proto.TypesProto;
import org.junit.Test;
@@ -29,13 +30,17 @@
private static final String STATE_KEY = "state-key";
private static final TypeBuilders.StringProp STRING_PROP =
new TypeBuilders.StringProp.Builder("string")
- .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY))
+ .setDynamicValue(
+ DynamicBuilders.DynamicString.from(
+ new AppDataKey<>(STATE_KEY)))
.build();
@SuppressWarnings("deprecation")
private static final TypeBuilders.StringProp.Builder STRING_PROP_BUILDER_WITHOUT_STATIC_VALUE =
new TypeBuilders.StringProp.Builder()
- .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY));
+ .setDynamicValue(
+ DynamicBuilders.DynamicString.from(
+ new AppDataKey<>(STATE_KEY)));
@Test
public void stringPropSupportsDynamicString() {
diff --git a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/DefaultTileClient.kt b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/DefaultTileClient.kt
index 4edda94..324056c 100644
--- a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/DefaultTileClient.kt
+++ b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/DefaultTileClient.kt
@@ -20,37 +20,37 @@
import android.content.Context
import androidx.annotation.VisibleForTesting
import androidx.concurrent.futures.ResolvableFuture
+import androidx.wear.protolayout.proto.ResourceProto
+import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException
import androidx.wear.tiles.EventBuilders
import androidx.wear.tiles.RequestBuilders
import androidx.wear.tiles.ResourcesCallback
import androidx.wear.tiles.ResourcesData
import androidx.wear.tiles.ResourcesRequestData
-import androidx.wear.tiles.TileCallback
-import androidx.wear.tiles.TileData
-import androidx.wear.tiles.TileRequestData
import androidx.wear.tiles.TileAddEventData
import androidx.wear.tiles.TileBuilders
+import androidx.wear.tiles.TileCallback
+import androidx.wear.tiles.TileData
import androidx.wear.tiles.TileEnterEventData
import androidx.wear.tiles.TileLeaveEventData
import androidx.wear.tiles.TileProvider
-import androidx.wear.tiles.TileService
import androidx.wear.tiles.TileRemoveEventData
+import androidx.wear.tiles.TileRequestData
+import androidx.wear.tiles.TileService
import androidx.wear.tiles.client.TileClient
-import androidx.wear.protolayout.proto.ResourceProto
import androidx.wear.tiles.proto.TileProto
-import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException
import com.google.common.util.concurrent.ListenableFuture
+import java.lang.IllegalArgumentException
+import java.util.concurrent.Executor
+import kotlin.coroutines.Continuation
+import kotlin.coroutines.resume
+import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
-import java.lang.IllegalArgumentException
-import java.util.concurrent.Executor
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.coroutines.resumeWithException
/**
* Implementation of [TileClient] which can connect to a `TileService` in either the local
diff --git a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/TilesConnectionBinder.kt b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/TilesConnectionBinder.kt
index cb797f6..c015756 100644
--- a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/TilesConnectionBinder.kt
+++ b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/connection/TilesConnectionBinder.kt
@@ -23,6 +23,8 @@
import android.os.IBinder
import androidx.wear.tiles.TileProvider
import androidx.wear.tiles.TileService
+import java.util.concurrent.TimeUnit.SECONDS
+import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
@@ -36,8 +38,6 @@
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
-import java.util.concurrent.TimeUnit.SECONDS
-import kotlin.coroutines.resume
/**
* Connection binder for Tiles. This will connect to a {@link TileProvider} (with a timeout), and
diff --git a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/renderer/TileRenderer.java b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/renderer/TileRenderer.java
index 184aa81..3fb2267 100644
--- a/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/renderer/TileRenderer.java
+++ b/wear/tiles/tiles-renderer/src/main/java/androidx/wear/tiles/renderer/TileRenderer.java
@@ -202,15 +202,18 @@
public View inflate(@NonNull ViewGroup parent) {
String errorMessage =
"This method only works with the deprecated constructors that accept Layout and"
- + " Resources.";
+ + " Resources.";
try {
// Waiting for the result from future for backwards compatibility.
return inflateLayout(
- checkNotNull(mLayout, errorMessage),
- checkNotNull(mResources, errorMessage),
- parent).get(10, TimeUnit.SECONDS);
- } catch (ExecutionException | InterruptedException | CancellationException |
- TimeoutException e) {
+ checkNotNull(mLayout, errorMessage),
+ checkNotNull(mResources, errorMessage),
+ parent)
+ .get(10, TimeUnit.SECONDS);
+ } catch (ExecutionException
+ | InterruptedException
+ | CancellationException
+ | TimeoutException e) {
// Wrap checked exceptions to avoid changing the method signature.
throw new RuntimeException("Rendering tile has not successfully finished.", e);
}
@@ -219,13 +222,12 @@
/**
* Inflates a Tile into {@code parent}.
*
- * @param layout The portion of the Tile to render.
+ * @param layout The portion of the Tile to render.
* @param resources The resources for the Tile.
- * @param parent The view to attach the tile into.
+ * @param parent The view to attach the tile into.
* @return The future with the first child that was inflated. This may be null if the Layout is
- * empty or the top-level LayoutElement has no inner set, or the top-level LayoutElement
- * contains an
- * unsupported inner type.
+ * empty or the top-level LayoutElement has no inner set, or the top-level LayoutElement
+ * contains an unsupported inner type.
*/
@NonNull
public ListenableFuture<View> inflateAsync(
@@ -241,7 +243,6 @@
@NonNull ResourceProto.Resources resources,
@NonNull ViewGroup parent) {
ListenableFuture<Void> result = mInstance.renderAndAttach(layout, resources, parent);
- return FluentFuture.from(result)
- .transform(ignored -> parent.getChildAt(0), mUiExecutor);
+ return FluentFuture.from(result).transform(ignored -> parent.getChildAt(0), mUiExecutor);
}
}
diff --git a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/checkers/TimelineCheckerTest.kt b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/checkers/TimelineCheckerTest.kt
index be1d8a2..4222ae5 100644
--- a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/checkers/TimelineCheckerTest.kt
+++ b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/checkers/TimelineCheckerTest.kt
@@ -18,6 +18,8 @@
import androidx.wear.tiles.TilesTestRunner
import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doReturn
@@ -25,8 +27,6 @@
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
-import org.junit.Test
-import org.junit.runner.RunWith
@RunWith(TilesTestRunner::class)
class TimelineCheckerTest {
diff --git a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/DefaultTileClientTest.kt b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/DefaultTileClientTest.kt
index 26f99dc..7e800c9 100644
--- a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/DefaultTileClientTest.kt
+++ b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/DefaultTileClientTest.kt
@@ -22,6 +22,7 @@
import android.os.Looper
import androidx.concurrent.futures.await
import androidx.test.core.app.ApplicationProvider
+import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException
import androidx.wear.tiles.RequestBuilders
import androidx.wear.tiles.ResourcesCallback
import androidx.wear.tiles.ResourcesData
@@ -37,13 +38,13 @@
import androidx.wear.tiles.TileRequestData
import androidx.wear.tiles.TilesTestRunner
import androidx.wear.tiles.proto.TileProto
-import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException
import com.google.common.truth.Truth.assertThat
+import java.lang.IllegalArgumentException
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
-import kotlinx.coroutines.Job
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.TestScope
@@ -56,7 +57,6 @@
import org.junit.runner.RunWith
import org.robolectric.Shadows
import org.robolectric.annotation.Config
-import java.lang.IllegalArgumentException
@Config(manifest = Config.NONE)
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalStdlibApi::class)
diff --git a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/TilesConnectionBinderTest.kt b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/TilesConnectionBinderTest.kt
index 613fa1b..64ae254 100644
--- a/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/TilesConnectionBinderTest.kt
+++ b/wear/tiles/tiles-renderer/src/test/java/androidx/wear/tiles/connection/TilesConnectionBinderTest.kt
@@ -32,11 +32,12 @@
import androidx.wear.tiles.TileRequestData
import androidx.wear.tiles.TilesTestRunner
import com.google.common.truth.Truth.assertThat
+import java.lang.IllegalStateException
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
-import kotlinx.coroutines.Job
import kotlinx.coroutines.test.TestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -49,7 +50,6 @@
import org.junit.runner.RunWith
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
-import java.lang.IllegalStateException
@Config(manifest = Config.NONE)
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/wear/tiles/tiles-testing/src/main/java/androidx/wear/tiles/testing/TestTileClient.kt b/wear/tiles/tiles-testing/src/main/java/androidx/wear/tiles/testing/TestTileClient.kt
index 5d5858d..9b36360 100644
--- a/wear/tiles/tiles-testing/src/main/java/androidx/wear/tiles/testing/TestTileClient.kt
+++ b/wear/tiles/tiles-testing/src/main/java/androidx/wear/tiles/testing/TestTileClient.kt
@@ -27,11 +27,11 @@
import androidx.wear.tiles.client.TileClient
import androidx.wear.tiles.connection.DefaultTileClient
import com.google.common.util.concurrent.ListenableFuture
+import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import org.robolectric.Shadows.shadowOf
import org.robolectric.android.controller.ServiceController
-import java.util.concurrent.Executor
/**
* [TileClient] for testing purposes. This will pass calls through to the given instance of
diff --git a/wear/tiles/tiles-testing/src/test/java/androidx/wear/tiles/testing/TestTileClientTest.kt b/wear/tiles/tiles-testing/src/test/java/androidx/wear/tiles/testing/TestTileClientTest.kt
index e437cc6..ed539b0 100644
--- a/wear/tiles/tiles-testing/src/test/java/androidx/wear/tiles/testing/TestTileClientTest.kt
+++ b/wear/tiles/tiles-testing/src/test/java/androidx/wear/tiles/testing/TestTileClientTest.kt
@@ -18,12 +18,12 @@
import android.os.Looper
import androidx.concurrent.futures.ResolvableFuture
+import androidx.wear.protolayout.ResourceBuilders
import androidx.wear.tiles.EventBuilders
import androidx.wear.tiles.RequestBuilders
import androidx.wear.tiles.TileBuilders
import androidx.wear.tiles.TileProvider
import androidx.wear.tiles.TileService
-import androidx.wear.protolayout.ResourceBuilders
import com.google.common.truth.Truth.assertThat
import com.google.common.util.concurrent.ListenableFuture
import org.junit.Before
diff --git a/wear/tiles/tiles-tooling/src/androidTest/java/androidx/wear/tiles/tooling/TileServiceViewAdapterTest.kt b/wear/tiles/tiles-tooling/src/androidTest/java/androidx/wear/tiles/tooling/TileServiceViewAdapterTest.kt
index 675e207..d197c38 100644
--- a/wear/tiles/tiles-tooling/src/androidTest/java/androidx/wear/tiles/tooling/TileServiceViewAdapterTest.kt
+++ b/wear/tiles/tiles-tooling/src/androidTest/java/androidx/wear/tiles/tooling/TileServiceViewAdapterTest.kt
@@ -16,11 +16,11 @@
package androidx.wear.tiles.tooling
-import androidx.wear.tiles.tooling.test.R
import android.app.Activity
import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView
+import androidx.wear.tiles.tooling.test.R
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
diff --git a/wear/tiles/tiles-tooling/src/test/java/androidx/wear/tiles/tooling/FindMethodTest.kt b/wear/tiles/tiles-tooling/src/test/java/androidx/wear/tiles/tooling/FindMethodTest.kt
index 05337da..e84bbc5 100644
--- a/wear/tiles/tiles-tooling/src/test/java/androidx/wear/tiles/tooling/FindMethodTest.kt
+++ b/wear/tiles/tiles-tooling/src/test/java/androidx/wear/tiles/tooling/FindMethodTest.kt
@@ -16,10 +16,9 @@
package androidx.wear.tiles.tooling
-import org.junit.Test
-
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
+import org.junit.Test
@Suppress("unused")
open class A {
diff --git a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
index 0f105f3..93ea260 100644
--- a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
+++ b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
@@ -22,9 +22,11 @@
import androidx.wear.protolayout.DeviceParametersBuilders;
import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters;
import androidx.wear.protolayout.StateBuilders.State;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.AppDataKey;
import androidx.wear.protolayout.expression.proto.FixedProto;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
import androidx.wear.protolayout.proto.DeviceParametersProto;
import androidx.wear.protolayout.proto.StateProto;
import androidx.wear.tiles.RequestBuilders.ResourcesRequest;
@@ -45,8 +47,9 @@
new TileRequest.Builder()
.setCurrentState(
new State.Builder()
- .addIdToValueMapping(
- "entry_id", StateEntryValue.fromInt(13))
+ .addKeyToValueMapping(
+ new AppDataKey<DynamicInt32>("entry_id"),
+ DynamicDataValue.fromInt(13))
.build())
.setDeviceConfiguration(
new DeviceParameters.Builder()
@@ -132,7 +135,7 @@
StateProto.State.newBuilder()
.putIdToValue(
"entry_id",
- StateEntryProto.StateEntryValue.newBuilder()
+ DynamicDataProto.DynamicDataValue.newBuilder()
.setInt32Val(
FixedProto.FixedInt32.newBuilder()
.setValue(13))
diff --git a/wear/watchface/watchface-client-guava/api/current.ignore b/wear/watchface/watchface-client-guava/api/current.ignore
new file mode 100644
index 0000000..91dda93
--- /dev/null
+++ b/wear/watchface/watchface-client-guava/api/current.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+ChangedThrows: androidx.wear.watchface.client.ListenableWatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.core.util.Consumer<java.lang.String>, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>):
+ Method androidx.wear.watchface.client.ListenableWatchFaceControlClient.getOrCreateInteractiveWatchFaceClient no longer throws exception android.os.RemoteException
+
+
+ParameterNameChange: androidx.wear.watchface.client.ListenableWatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.core.util.Consumer<java.lang.String>, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) parameter #7:
+ Attempted to remove parameter name from parameter arg8 in androidx.wear.watchface.client.ListenableWatchFaceControlClient.getOrCreateInteractiveWatchFaceClient
diff --git a/wear/watchface/watchface-client-guava/api/restricted_current.ignore b/wear/watchface/watchface-client-guava/api/restricted_current.ignore
new file mode 100644
index 0000000..91dda93
--- /dev/null
+++ b/wear/watchface/watchface-client-guava/api/restricted_current.ignore
@@ -0,0 +1,7 @@
+// Baseline format: 1.0
+ChangedThrows: androidx.wear.watchface.client.ListenableWatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.core.util.Consumer<java.lang.String>, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>):
+ Method androidx.wear.watchface.client.ListenableWatchFaceControlClient.getOrCreateInteractiveWatchFaceClient no longer throws exception android.os.RemoteException
+
+
+ParameterNameChange: androidx.wear.watchface.client.ListenableWatchFaceControlClient#getOrCreateInteractiveWatchFaceClient(String, androidx.wear.watchface.client.DeviceConfig, androidx.wear.watchface.client.WatchUiState, androidx.wear.watchface.style.UserStyleData, java.util.Map<java.lang.Integer,? extends androidx.wear.watchface.complications.data.ComplicationData>, java.util.concurrent.Executor, androidx.core.util.Consumer<java.lang.String>, kotlin.coroutines.Continuation<? super androidx.wear.watchface.client.InteractiveWatchFaceClient>) parameter #7:
+ Attempted to remove parameter name from parameter arg8 in androidx.wear.watchface.client.ListenableWatchFaceControlClient.getOrCreateInteractiveWatchFaceClient
diff --git a/wear/watchface/watchface-client-guava/build.gradle b/wear/watchface/watchface-client-guava/build.gradle
index 49dba28..45693e3 100644
--- a/wear/watchface/watchface-client-guava/build.gradle
+++ b/wear/watchface/watchface-client-guava/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "Android Wear Watchface Client Guava"
+ name = "Android Wear Watchface Client Guava Integration"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Guava wrappers for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.kt b/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.kt
index 8887171d..949c589 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.kt
@@ -1836,13 +1836,13 @@
*
* Returns this Builder to allow chaining.
*/
- fun setListEntryCollection(timelineEntries: Collection<ComplicationData>?) = apply {
- if (timelineEntries == null) {
+ fun setListEntryCollection(listEntries: Collection<ComplicationData>?) = apply {
+ if (listEntries == null) {
fields.remove(EXP_FIELD_LIST_ENTRIES)
} else {
fields.putParcelableArray(
EXP_FIELD_LIST_ENTRIES,
- timelineEntries
+ listEntries
.map { data ->
data.fields.putInt(EXP_FIELD_LIST_ENTRY_TYPE, data.type)
data.fields
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
index 94db677..ca001fa 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
@@ -18,18 +18,22 @@
import android.icu.util.ULocale
import android.support.wearable.complications.ComplicationData as WireComplicationData
-import android.support.wearable.complications.ComplicationData
+import android.support.wearable.complications.ComplicationData.Companion.TYPE_NO_DATA
import android.support.wearable.complications.ComplicationText as WireComplicationText
import androidx.annotation.MainThread
import androidx.annotation.RestrictTo
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
+import androidx.wear.protolayout.expression.PlatformDataKey
+import androidx.wear.protolayout.expression.PlatformHealthSources
import androidx.wear.protolayout.expression.pipeline.BoundDynamicType
import androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest
import androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator
import androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver
+import androidx.wear.protolayout.expression.pipeline.SensorGatewaySingleDataProvider
import androidx.wear.protolayout.expression.pipeline.StateStore
import androidx.wear.protolayout.expression.pipeline.TimeGateway
import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway
+import java.util.Collections
import java.util.concurrent.Executor
import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.CoroutineContext
@@ -41,22 +45,25 @@
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.emitAll
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.invoke
import kotlinx.coroutines.launch
/**
* Evaluates a [WireComplicationData] with
* [androidx.wear.protolayout.expression.DynamicBuilders.DynamicType] within its fields.
- *
- * Due to [WireComplicationData]'s shallow copy strategy the input is modified in-place.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class ComplicationDataExpressionEvaluator(
private val stateStore: StateStore? = StateStore(emptyMap()),
private val timeGateway: TimeGateway? = null,
+ // TODO(b/281664278): remove the SensorGateway usage, implement PlatformDataProvider instead.
private val sensorGateway: SensorGateway? = null,
private val keepExpression: Boolean = false,
) {
@@ -65,27 +72,101 @@
*
* The expression is evaluated _separately_ on each flow collection.
*/
- fun evaluate(unevaluatedData: WireComplicationData) =
- flow<WireComplicationData> {
- val state: MutableStateFlow<State> = unevaluatedData.buildState()
- state.value.use {
- val evaluatedData: Flow<WireComplicationData> =
- state
- .mapNotNull {
- when {
- // Emitting INVALID_DATA if there's an invalid receiver.
- it.invalidReceivers.isNotEmpty() -> INVALID_DATA
- // Emitting the data if all pending receivers are done and all
- // pre-updates are satisfied.
- it.pendingReceivers.isEmpty() -> it.data
- // Skipping states that are not ready for be emitted.
- else -> null
- }
- }
- .distinctUntilChanged()
- emitAll(evaluatedData)
+ fun evaluate(unevaluatedData: WireComplicationData): Flow<WireComplicationData> =
+ evaluateTopLevelFields(unevaluatedData)
+ // Combining with fields that are made of WireComplicationData.
+ .combineWithDataList(unevaluatedData.timelineEntries) { entries ->
+ // Timeline entries are set on the built WireComplicationData.
+ WireComplicationData.Builder(
+ this@combineWithDataList.build().apply { setTimelineEntryCollection(entries) }
+ )
}
+ .combineWithDataList(unevaluatedData.listEntries) { setListEntryCollection(it) }
+ // Must be last, as it overwrites INVALID_DATA.
+ .combineWithEvaluatedPlaceholder(unevaluatedData.placeholder)
+ .distinctUntilChanged()
+
+ /** Evaluates "local" fields, excluding fields of type WireComplicationData. */
+ private fun evaluateTopLevelFields(
+ unevaluatedData: WireComplicationData
+ ): Flow<WireComplicationData> = flow {
+ val state: MutableStateFlow<State> = unevaluatedData.buildState()
+ state.value.use {
+ val evaluatedData: Flow<WireComplicationData> =
+ state.mapNotNull {
+ when {
+ // Emitting INVALID_DATA if there's an invalid receiver.
+ it.invalidReceivers.isNotEmpty() -> INVALID_DATA
+ // Emitting the data if all pending receivers are done and all
+ // pre-updates are satisfied.
+ it.pendingReceivers.isEmpty() -> it.data
+ // Skipping states that are not ready for be emitted.
+ else -> null
+ }
+ }
+ emitAll(evaluatedData)
}
+ }
+
+ /**
+ * Combines the receiver with the evaluated version of the provided list.
+ *
+ * If the receiver [Flow] emits [INVALID_DATA] or the input list is null or empty, this does not
+ * mutate the flow and does not wait for the entries to finish evaluating.
+ *
+ * If even one [WireComplicationData] within the provided list is evaluated to [INVALID_DATA],
+ * the output [Flow] becomes [INVALID_DATA] (the receiver [Flow] is ignored).
+ */
+ private fun Flow<WireComplicationData>.combineWithDataList(
+ unevaluatedEntries: List<WireComplicationData>?,
+ setter:
+ WireComplicationData.Builder.(
+ List<WireComplicationData>
+ ) -> WireComplicationData.Builder,
+ ): Flow<WireComplicationData> {
+ if (unevaluatedEntries.isNullOrEmpty()) return this
+ val evaluatedEntriesFlow: Flow<List<WireComplicationData>> =
+ combine(unevaluatedEntries.map { evaluate(it) })
+
+ return this.combine(evaluatedEntriesFlow).map {
+ (data: WireComplicationData, evaluatedEntries: List<WireComplicationData>?) ->
+ // Not mutating if invalid.
+ if (data === INVALID_DATA) return@map data
+ // An entry is invalid, emitting invalid.
+ if (evaluatedEntries.any { it === INVALID_DATA }) return@map INVALID_DATA
+ // All is well, mutating the input.
+ return@map WireComplicationData.Builder(data).setter(evaluatedEntries).build()
+ }
+ }
+
+ /**
+ * Same as [combineWithDataList], but sets the evaluated placeholder ONLY when the receiver
+ * [Flow] emits [TYPE_NO_DATA], or [keepExpression] is true, otherwise clears it and does not
+ * wait for the placeholder to finish evaluating.
+ *
+ * If the placeholder is not required (per the above paragraph), this doesn't wait for it.
+ */
+ private fun Flow<WireComplicationData>.combineWithEvaluatedPlaceholder(
+ unevaluatedPlaceholder: WireComplicationData?
+ ): Flow<WireComplicationData> {
+ if (unevaluatedPlaceholder == null) return this
+ val evaluatedPlaceholderFlow: Flow<WireComplicationData> = evaluate(unevaluatedPlaceholder)
+
+ return this.combine(evaluatedPlaceholderFlow).map {
+ (data: WireComplicationData, evaluatedPlaceholder: WireComplicationData?) ->
+ if (!keepExpression && data.type != TYPE_NO_DATA) {
+ // Clearing the placeholder when data is not TYPE_NO_DATA (it was meant as an
+ // expression fallback).
+ return@map WireComplicationData.Builder(data).setPlaceholder(null).build()
+ }
+ // Placeholder required but invalid, emitting invalid.
+ if (evaluatedPlaceholder === INVALID_DATA) return@map INVALID_DATA
+ // All is well, mutating the input.
+ return@map WireComplicationData.Builder(data)
+ .setPlaceholder(evaluatedPlaceholder)
+ .build()
+ }
+ }
private suspend fun WireComplicationData.buildState() =
MutableStateFlow(State(this)).apply {
@@ -177,7 +258,7 @@
* [ComplicationEvaluationResultReceiver] that are evaluating it.
*/
private inner class State(
- val data: ComplicationData,
+ val data: WireComplicationData,
val pendingReceivers: Set<ComplicationEvaluationResultReceiver<out Any>> = setOf(),
val invalidReceivers: Set<ComplicationEvaluationResultReceiver<out Any>> = setOf(),
val completeReceivers: Set<ComplicationEvaluationResultReceiver<out Any>> = setOf(),
@@ -218,7 +299,22 @@
DynamicTypeEvaluator.Config.Builder()
.apply { stateStore?.let { setStateStore(it) } }
.apply { timeGateway?.let { setTimeGateway(it) } }
- .apply { sensorGateway?.let { setSensorGateway(it) } }
+ .apply { sensorGateway?.let {
+ addPlatformDataProvider(
+ SensorGatewaySingleDataProvider(
+ sensorGateway, PlatformHealthSources.HEART_RATE_BPM
+ ),
+ Collections.singleton(PlatformHealthSources.HEART_RATE_BPM)
+ as Set<PlatformDataKey<*>>
+ )
+ addPlatformDataProvider(
+ SensorGatewaySingleDataProvider(
+ sensorGateway, PlatformHealthSources.DAILY_STEPS
+ ),
+ Collections.singleton(PlatformHealthSources.DAILY_STEPS)
+ as Set<PlatformDataKey<*>>
+ )
+ } }
.build()
)
try {
@@ -317,3 +413,35 @@
runnable.run()
}
}
+
+/** Replacement of [kotlinx.coroutines.flow.combine], which doesn't seem to work. */
+internal fun <T> combine(flows: List<Flow<T>>): Flow<List<T>> = flow {
+ data class ValueExists(val value: T?, val exists: Boolean)
+ val latest = MutableStateFlow(List(flows.size) { ValueExists(null, false) })
+ @Suppress("UNCHECKED_CAST") // Flow<List<T?>> -> Flow<List<T>> safe after filtering exists.
+ emitAll(
+ flows
+ .mapIndexed { i, flow -> flow.map { i to it } } // List<Flow<Int, T>> (indexed flows)
+ .merge() // Flow<Int, T>
+ .map { (i, value) ->
+ // Updating latest and returning the current latest.
+ latest.updateAndGet {
+ val newLatest = it.toMutableList()
+ newLatest[i] = ValueExists(value, true)
+ newLatest
+ }
+ } // Flow<List<ValueExists>>
+ // Filtering emissions until we have all values.
+ .filter { values -> values.all { it.exists } }
+ // Flow<List<T>> + defensive copy.
+ .map { values -> values.map { it.value } } as Flow<List<T>>
+ )
+}
+
+/**
+ * Another replacement of [kotlinx.coroutines.flow.combine] which is similar to
+ * `combine(List<Flow<T>>)` but allows different types for each flow.
+ */
+@Suppress("UNCHECKED_CAST")
+internal fun <T1, T2> Flow<T1>.combine(other: Flow<T2>): Flow<Pair<T1, T2>> =
+ combine(listOf(this as Flow<*>, other as Flow<*>)).map { (a, b) -> (a as T1) to (b as T2) }
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Text.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Text.kt
index 9d2d48f..0bdbfb6 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Text.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Text.kt
@@ -22,8 +22,8 @@
import android.support.wearable.complications.ComplicationText as WireComplicationText
import android.support.wearable.complications.ComplicationText.TimeDifferenceBuilder as WireComplicationTextTimeDifferenceBuilder
import android.support.wearable.complications.ComplicationText.TimeFormatBuilder as WireComplicationTextTimeFormatBuilder
-import android.support.wearable.complications.TimeDependentText as WireTimeDependentText
import android.support.wearable.complications.TimeDependentText
+import android.support.wearable.complications.TimeDependentText as WireTimeDependentText
import android.support.wearable.complications.TimeDifferenceText
import android.text.style.ForegroundColorSpan
import android.text.style.LocaleSpan
diff --git a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
index c913c25..65d472b 100644
--- a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
+++ b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
@@ -17,12 +17,15 @@
package androidx.wear.watchface.complications.data
import android.support.wearable.complications.ComplicationData as WireComplicationData
+import android.support.wearable.complications.ComplicationData.Companion.TYPE_NO_DATA
+import android.support.wearable.complications.ComplicationData.Companion.TYPE_SHORT_TEXT
import android.support.wearable.complications.ComplicationText as WireComplicationText
import android.util.Log
+import androidx.wear.protolayout.expression.AppDataKey
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant
import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue
import androidx.wear.protolayout.expression.pipeline.StateStore
import androidx.wear.protolayout.expression.pipeline.TimeGateway
import androidx.wear.watchface.complications.data.ComplicationDataExpressionEvaluator.Companion.INVALID_DATA
@@ -58,10 +61,7 @@
@Test
fun evaluate_noExpression_returnsUnevaluated() = runBlocking {
- val data =
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
- .setRangedValue(10f)
- .build()
+ val data = WireComplicationData.Builder(TYPE_NO_DATA).setRangedValue(10f).build()
val evaluator = ComplicationDataExpressionEvaluator()
@@ -76,12 +76,12 @@
*/
enum class DataWithExpressionScenario(
val expressed: WireComplicationData,
- val states: List<Map<String, StateEntryValue>>,
+ val states: List<Map<AppDataKey<*>, DynamicDataValue>>,
val evaluated: List<WireComplicationData>,
) {
SET_IMMEDIATELY_WHEN_ALL_DATA_AVAILABLE(
expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValueExpression(DynamicFloat.constant(1f))
.setLongText(WireComplicationText(DynamicString.constant("Long Text")))
.setLongTitle(WireComplicationText(DynamicString.constant("Long Title")))
@@ -90,70 +90,123 @@
.setContentDescription(
WireComplicationText(DynamicString.constant("Description"))
)
- .build(),
+ .setPlaceholder(constantData("Placeholder"))
+ .setListEntryCollection(listOf(constantData("List")))
+ .build()
+ .also { it.setTimelineEntryCollection(listOf(constantData("Timeline"))) },
states = listOf(),
evaluated =
listOf(
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValue(1f)
.setLongText(WireComplicationText("Long Text"))
.setLongTitle(WireComplicationText("Long Title"))
.setShortText(WireComplicationText("Short Text"))
.setShortTitle(WireComplicationText("Short Title"))
.setContentDescription(WireComplicationText("Description"))
+ .setPlaceholder(evaluatedData("Placeholder"))
+ .setListEntryCollection(listOf(evaluatedData("List")))
.build()
+ .also { it.setTimelineEntryCollection(listOf(evaluatedData("Timeline"))) },
),
),
SET_ONLY_AFTER_ALL_FIELDS_EVALUATED(
expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
- .setRangedValueExpression(DynamicFloat.fromState("ranged_value"))
- .setLongText(WireComplicationText(DynamicString.fromState("long_text")))
- .setLongTitle(WireComplicationText(DynamicString.fromState("long_title")))
- .setShortText(WireComplicationText(DynamicString.fromState("short_text")))
- .setShortTitle(WireComplicationText(DynamicString.fromState("short_title")))
- .setContentDescription(
- WireComplicationText(DynamicString.fromState("description"))
+ WireComplicationData.Builder(TYPE_NO_DATA)
+ .setRangedValueExpression(DynamicFloat.from(AppDataKey("ranged_value")))
+ .setLongText(WireComplicationText(DynamicString.from(AppDataKey("long_text"))))
+ .setLongTitle(
+ WireComplicationText(DynamicString.from(AppDataKey("long_title")))
)
- .build(),
+ .setShortText(
+ WireComplicationText(DynamicString.from(AppDataKey("short_text")))
+ )
+ .setShortTitle(
+ WireComplicationText(DynamicString.from(AppDataKey("short_title")))
+ )
+ .setContentDescription(
+ WireComplicationText(DynamicString.from(AppDataKey("description")))
+ )
+ .setPlaceholder(stateData("placeholder"))
+ .setListEntryCollection(listOf(stateData("list")))
+ .build()
+ .also { it.setTimelineEntryCollection(listOf(stateData("timeline"))) },
states =
aggregate(
// Each map piles on top of the previous ones.
- mapOf("ranged_value" to StateEntryValue.fromFloat(1f)),
- mapOf("long_text" to StateEntryValue.fromString("Long Text")),
- mapOf("long_title" to StateEntryValue.fromString("Long Title")),
- mapOf("short_text" to StateEntryValue.fromString("Short Text")),
- mapOf("short_title" to StateEntryValue.fromString("Short Title")),
+ mapOf(
+ AppDataKey<DynamicFloat>("ranged_value") to DynamicDataValue.fromFloat(1f)
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("long_text") to
+ DynamicDataValue.fromString("Long Text")
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("long_title") to
+ DynamicDataValue.fromString("Long Title")
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("short_text") to
+ DynamicDataValue.fromString("Short Text")
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("short_title") to
+ DynamicDataValue.fromString("Short Title")
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("description") to
+ DynamicDataValue.fromString("Description")
+ ),
+ mapOf(
+ AppDataKey<DynamicString>("placeholder") to
+ DynamicDataValue.fromString("Placeholder")
+ ),
+ mapOf(AppDataKey<DynamicString>("list") to DynamicDataValue.fromString("List")),
+ mapOf(
+ AppDataKey<DynamicString>("timeline") to
+ DynamicDataValue.fromString("Timeline")
+ ),
// Only the last one will trigger an evaluated data.
- mapOf("description" to StateEntryValue.fromString("Description")),
),
evaluated =
listOf(
- INVALID_DATA, // Before state is available.
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ // Before any state is available.
+ INVALID_DATA,
+ // INVALID_DATA with placeholder, after it's available (and others aren't).
+ WireComplicationData.Builder(INVALID_DATA)
+ .setPlaceholder(evaluatedData("Placeholder"))
+ .build(),
+ // Evaluated data with after everything is available.
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValue(1f)
.setLongText(WireComplicationText("Long Text"))
.setLongTitle(WireComplicationText("Long Title"))
.setShortText(WireComplicationText("Short Text"))
.setShortTitle(WireComplicationText("Short Title"))
.setContentDescription(WireComplicationText("Description"))
+ // Not trimmed for TYPE_NO_DATA.
+ .setPlaceholder(evaluatedData("Placeholder"))
+ .setListEntryCollection(listOf(evaluatedData("List")))
.build()
+ .also { it.setTimelineEntryCollection(listOf(evaluatedData("Timeline"))) },
),
),
SET_TO_EVALUATED_IF_ALL_FIELDS_VALID(
expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_SHORT_TEXT)
- .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
- .setShortText(WireComplicationText(DynamicString.fromState("valid")))
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+ .setShortText(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
.build(),
states =
listOf(
- mapOf("valid" to StateEntryValue.fromString("Valid")),
+ mapOf(
+ AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+ ),
),
evaluated =
listOf(
INVALID_DATA, // Before state is available.
- WireComplicationData.Builder(WireComplicationData.TYPE_SHORT_TEXT)
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
.setShortTitle(WireComplicationText("Valid"))
.setShortText(WireComplicationText("Valid"))
.build(),
@@ -161,14 +214,16 @@
),
SET_TO_NO_DATA_IF_FIRST_STATE_IS_INVALID(
expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_SHORT_TEXT)
- .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
- .setShortText(WireComplicationText(DynamicString.fromState("invalid")))
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+ .setShortText(WireComplicationText(DynamicString.from(AppDataKey("invalid"))))
.build(),
states =
listOf(
mapOf(),
- mapOf("valid" to StateEntryValue.fromString("Valid")),
+ mapOf(
+ AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+ ),
),
evaluated =
listOf(
@@ -177,28 +232,61 @@
),
SET_TO_NO_DATA_IF_LAST_STATE_IS_INVALID(
expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_SHORT_TEXT)
- .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
- .setShortText(WireComplicationText(DynamicString.fromState("invalid")))
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+ .setShortText(WireComplicationText(DynamicString.from(AppDataKey("invalid"))))
.build(),
states =
listOf(
mapOf(
- "valid" to StateEntryValue.fromString("Valid"),
- "invalid" to StateEntryValue.fromString("Valid"),
+ AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid"),
+ AppDataKey<DynamicString>("invalid") to
+ DynamicDataValue.fromString("Valid"),
),
- mapOf("valid" to StateEntryValue.fromString("Valid")),
+ mapOf(
+ AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+ ),
),
evaluated =
listOf(
INVALID_DATA, // Before state is available.
- WireComplicationData.Builder(WireComplicationData.TYPE_SHORT_TEXT)
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
.setShortTitle(WireComplicationText("Valid"))
.setShortText(WireComplicationText("Valid"))
.build(),
INVALID_DATA, // After it was invalidated.
),
),
+ SET_TO_EVALUATED_WITHOUT_PLACEHOLDER_IF_NOT_NO_DATA(
+ expressed =
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .setPlaceholder(evaluatedData("Placeholder"))
+ .build(),
+ states = listOf(),
+ evaluated =
+ listOf(
+ // No placeholder.
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .build(),
+ )
+ ),
+ SET_TO_EVALUATED_WITHOUT_PLACEHOLDER_EVEN_IF_PLACEHOLDER_INVALID_IF_NOT_NO_DATA(
+ expressed =
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .setPlaceholder(stateData("placeholder"))
+ .build(),
+ states = listOf(), // placeholder state not set.
+ evaluated =
+ listOf(
+ // No placeholder.
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .build(),
+ )
+ ),
}
@Test
@@ -218,7 +306,7 @@
)
for (state in scenario.states) {
- stateStore.setStateEntryValues(state)
+ stateStore.setAppStateEntryValues(state)
}
expect
@@ -231,7 +319,7 @@
@Test
fun evaluate_cancelled_cleansUp() = runBlocking {
val expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValueExpression(
// Uses TimeGateway, which needs cleaning up.
DynamicInstant.withSecondsPrecision(Instant.EPOCH)
@@ -262,19 +350,22 @@
@Test
fun evaluate_keepExpression_doesNotTrimUnevaluatedExpression() = runBlocking {
val expressed =
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValueExpression(DynamicFloat.constant(1f))
.setLongText(WireComplicationText(DynamicString.constant("Long Text")))
.setLongTitle(WireComplicationText(DynamicString.constant("Long Title")))
.setShortText(WireComplicationText(DynamicString.constant("Short Text")))
.setShortTitle(WireComplicationText(DynamicString.constant("Short Title")))
.setContentDescription(WireComplicationText(DynamicString.constant("Description")))
+ .setPlaceholder(constantData("Placeholder"))
+ .setListEntryCollection(listOf(constantData("List")))
.build()
+ .also { it.setTimelineEntryCollection(listOf(constantData("Timeline"))) }
val evaluator = ComplicationDataExpressionEvaluator(keepExpression = true)
assertThat(evaluator.evaluate(expressed).firstOrNull())
.isEqualTo(
- WireComplicationData.Builder(WireComplicationData.TYPE_NO_DATA)
+ WireComplicationData.Builder(TYPE_NO_DATA)
.setRangedValue(1f)
.setRangedValueExpression(DynamicFloat.constant(1f))
.setLongText(
@@ -292,6 +383,29 @@
.setContentDescription(
WireComplicationText("Description", DynamicString.constant("Description"))
)
+ .setPlaceholder(evaluatedWithConstantData("Placeholder"))
+ .setListEntryCollection(listOf(evaluatedWithConstantData("List")))
+ .build()
+ .also {
+ it.setTimelineEntryCollection(listOf(evaluatedWithConstantData("Timeline")))
+ },
+ )
+ }
+
+ @Test
+ fun evaluate_keepExpressionNotNoData_doesNotTrimPlaceholder() = runBlocking {
+ val expressed =
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .setPlaceholder(evaluatedData("Placeholder"))
+ .build()
+ val evaluator = ComplicationDataExpressionEvaluator(keepExpression = true)
+
+ assertThat(evaluator.evaluate(expressed).firstOrNull())
+ .isEqualTo(
+ WireComplicationData.Builder(TYPE_SHORT_TEXT)
+ .setShortText(WireComplicationText("Text"))
+ .setPlaceholder(evaluatedData("Placeholder"))
.build()
)
}
@@ -300,5 +414,25 @@
/** Converts `[{a: A}, {b: B}, {c: C}]` to `[{a: A}, {a: A, b: B}, {a: A, b: B, c: C}]`. */
fun <K, V> aggregate(vararg maps: Map<K, V>): List<Map<K, V>> =
maps.fold(listOf()) { acc, map -> acc + ((acc.lastOrNull() ?: mapOf()) + map) }
+
+ fun constantData(value: String) =
+ WireComplicationData.Builder(TYPE_NO_DATA)
+ .setLongText(WireComplicationText(DynamicString.constant(value)))
+ .build()
+
+ fun stateData(value: String) =
+ WireComplicationData.Builder(TYPE_NO_DATA)
+ .setLongText(WireComplicationText(DynamicString.from(AppDataKey(value))))
+ .build()
+
+ fun evaluatedData(value: String) =
+ WireComplicationData.Builder(TYPE_NO_DATA)
+ .setLongText(WireComplicationText(value))
+ .build()
+
+ fun evaluatedWithConstantData(value: String) =
+ WireComplicationData.Builder(TYPE_NO_DATA)
+ .setLongText(WireComplicationText(value, DynamicString.constant(value)))
+ .build()
}
}
diff --git a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/TextTest.kt b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/TextTest.kt
index 2125d4f..bdb7c92 100644
--- a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/TextTest.kt
+++ b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/TextTest.kt
@@ -18,8 +18,8 @@
import android.content.Context
import android.icu.util.TimeZone
-import android.support.wearable.complications.ComplicationText as WireComplicationText
import android.support.wearable.complications.ComplicationText
+import android.support.wearable.complications.ComplicationText as WireComplicationText
import android.support.wearable.complications.ComplicationText.TimeDifferenceBuilder as WireTimeDifferenceBuilder
import android.support.wearable.complications.ComplicationText.TimeFormatBuilder as WireTimeFormatBuilder
import android.support.wearable.complications.TimeFormatText
diff --git a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
index 5342fd8..ecf03eb 100644
--- a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
+++ b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
@@ -29,7 +29,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Permission Dialog Samples"
+ name = "Wear Watchface Permission Dialog Samples"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains sample code for building Watchface Permission Dialogs"
diff --git a/wear/watchface/watchface-editor-guava/build.gradle b/wear/watchface/watchface-editor-guava/build.gradle
index c8cb24c..933c2fc 100644
--- a/wear/watchface/watchface-editor-guava/build.gradle
+++ b/wear/watchface/watchface-editor-guava/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android Wear Watchface Client Editor"
+ name = "Android Wear Watchface Editor Guava Integration"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Guava wrappers for the Androidx Wear Watchface Editor library"
diff --git a/wear/watchface/watchface-editor/samples/build.gradle b/wear/watchface/watchface-editor/samples/build.gradle
index 85c5449..4fa0e56 100644
--- a/wear/watchface/watchface-editor/samples/build.gradle
+++ b/wear/watchface/watchface-editor/samples/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "AndroidX Wear Editor Samples"
+ name = "Wear Editor Samples"
type = LibraryType.SAMPLES
inceptionYear = "2020"
description = "Contains sample code for the Androidx Wear Editor library"
diff --git a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
index 57efd34..0b32c3e 100644
--- a/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
+++ b/wear/watchface/watchface-editor/src/androidTest/java/androidx/wear/watchface/editor/EditorSessionGuavaTest.kt
@@ -57,6 +57,7 @@
import kotlinx.coroutines.CompletableDeferred
import org.junit.After
import org.junit.Assert
+import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
@@ -191,6 +192,7 @@
}
@Test
+ @Ignore("b/281083901")
public fun listenableOpenComplicationDataSourceChooser() {
ComplicationDataSourceChooserContract.useTestComplicationHelperActivity = true
val chosenComplicationDataSourceInfo =
diff --git a/wear/watchface/watchface-guava/build.gradle b/wear/watchface/watchface-guava/build.gradle
index 6571f63..c72486d 100644
--- a/wear/watchface/watchface-guava/build.gradle
+++ b/wear/watchface/watchface-guava/build.gradle
@@ -45,7 +45,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Guava"
+ name = "Android Wear Watchface Guava Integration"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "Guava wrappers for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-complications/build.gradle b/wear/watchface/watchface-samples-minimal-complications/build.gradle
index ce74910..eb6c3db 100644
--- a/wear/watchface/watchface-samples-minimal-complications/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-complications/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Minimal Complications Sample"
+ name = "Wear Watchface Minimal Complications Sample"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-instances/build.gradle b/wear/watchface/watchface-samples-minimal-instances/build.gradle
index 9fd911c..cefa848 100644
--- a/wear/watchface/watchface-samples-minimal-instances/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-instances/build.gradle
@@ -34,7 +34,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Minimal Style Sample"
+ name = "Wear Watchface Minimal Style Sample"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-style/build.gradle b/wear/watchface/watchface-samples-minimal-style/build.gradle
index 3931645..76d81e8 100644
--- a/wear/watchface/watchface-samples-minimal-style/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-style/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Minimal Style Sample"
+ name = "Wear Watchface Minimal Style Sample"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-style/old-api-test-service/build.gradle b/wear/watchface/watchface-style/old-api-test-service/build.gradle
index 6d668ff..905cc31 100644
--- a/wear/watchface/watchface-style/old-api-test-service/build.gradle
+++ b/wear/watchface/watchface-style/old-api-test-service/build.gradle
@@ -35,7 +35,7 @@
}
androidx {
- name = "AndroidX WatchFace Style Old Api Test Service"
+ name = "WatchFace Style Old Api Test Service"
type = LibraryType.SAMPLES
inceptionYear = "2022"
description = "Test service built with v1.0.0 of the API, used to check for binary AIDL compat"
diff --git a/wear/watchface/watchface-style/old-api-test-stub/build.gradle b/wear/watchface/watchface-style/old-api-test-stub/build.gradle
index ba36ffc..aa784be 100644
--- a/wear/watchface/watchface-style/old-api-test-stub/build.gradle
+++ b/wear/watchface/watchface-style/old-api-test-stub/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "AndroidX WatchFace Style Old Api Test Stub"
+ name = "WatchFace Style Old Api Test Stub"
type = LibraryType.INTERNAL_TEST_LIBRARY
inceptionYear = "2022"
description = "Test stub built with v1.0.0 of the API, used to check for binary AIDL compat"
diff --git a/wear/watchface/watchface/samples/app/build.gradle b/wear/watchface/watchface/samples/app/build.gradle
index 875f848..101b6ba 100644
--- a/wear/watchface/watchface/samples/app/build.gradle
+++ b/wear/watchface/watchface/samples/app/build.gradle
@@ -26,7 +26,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Samples app"
+ name = "Wear Watchface Samples app"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "APK for the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface/samples/build.gradle b/wear/watchface/watchface/samples/build.gradle
index 0e89628..f7b78e9 100644
--- a/wear/watchface/watchface/samples/build.gradle
+++ b/wear/watchface/watchface/samples/build.gradle
@@ -33,7 +33,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Samples"
+ name = "Wear Watchface Samples"
type = LibraryType.SAMPLES
inceptionYear = "2020"
description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface/samples/minimal/build.gradle b/wear/watchface/watchface/samples/minimal/build.gradle
index 38d5ed5..c8e5139 100644
--- a/wear/watchface/watchface/samples/minimal/build.gradle
+++ b/wear/watchface/watchface/samples/minimal/build.gradle
@@ -28,7 +28,7 @@
}
androidx {
- name = "AndroidX Wear Watchface Minimal Sample"
+ name = "Wear Watchface Minimal Sample"
type = LibraryType.SAMPLES
inceptionYear = "2021"
description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
index d8d78fc..53dddff 100644
--- a/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
+++ b/wear/watchface/watchface/src/androidTest/java/androidx/wear/watchface/test/WatchFaceServiceImageTest.kt
@@ -86,6 +86,7 @@
import org.junit.Assert.fail
import org.junit.Assume
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -378,6 +379,7 @@
@SuppressLint("NewApi")
@Test
+ @Ignore("b/274981990")
public fun testCommandTakeOpenGLScreenShot() {
val latch = CountDownLatch(1)
diff --git a/wear/wear-input-testing/build.gradle b/wear/wear-input-testing/build.gradle
index 6952126..d422e13 100644
--- a/wear/wear-input-testing/build.gradle
+++ b/wear/wear-input-testing/build.gradle
@@ -34,9 +34,9 @@
}
androidx {
- name = "Android Wear Support Input Testing Helpers"
+ name = "Android Wear Input Testing Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.WEAR_INPUT_TESTING
inceptionYear = "2020"
- description = "Android Wear Support Input Testing Helpers"
+ description = "Android Wear Support Input Testing Helpers"
}
diff --git a/wear/wear-input-testing/src/main/AndroidManifest.xml b/wear/wear-input-testing/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/wear/wear-input-testing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/wear/wear-input/build.gradle b/wear/wear-input/build.gradle
index 8301f64d..5b5c6d9 100644
--- a/wear/wear-input/build.gradle
+++ b/wear/wear-input/build.gradle
@@ -51,7 +51,7 @@
}
androidx {
- name = "Android Wear Support Input"
+ name = "Android Wear Input"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.WEAR_INPUT
inceptionYear = "2020"
diff --git a/wear/wear-input/src/main/AndroidManifest.xml b/wear/wear-input/src/main/AndroidManifest.xml
deleted file mode 100644
index 9cd4123..0000000
--- a/wear/wear-input/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2020 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 />
diff --git a/wear/wear-ongoing/build.gradle b/wear/wear-ongoing/build.gradle
index 8baebed..0985190 100644
--- a/wear/wear-ongoing/build.gradle
+++ b/wear/wear-ongoing/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android Wear Ongoing Activities"
+ name = "Android Wear Ongoing"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.WEAR_ONGOING
inceptionYear = "2021"
diff --git a/wear/wear-ongoing/src/main/AndroidManifest.xml b/wear/wear-ongoing/src/main/AndroidManifest.xml
deleted file mode 100644
index 9e46016..0000000
--- a/wear/wear-ongoing/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 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 />
-
diff --git a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityStatusTest.kt b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityStatusTest.kt
index 31c702f..ca17fe6 100644
--- a/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityStatusTest.kt
+++ b/wear/wear-ongoing/src/test/java/androidx/wear/ongoing/OngoingActivityStatusTest.kt
@@ -3,6 +3,7 @@
import android.content.Context
import android.os.Build
import androidx.test.core.app.ApplicationProvider
+import java.lang.IllegalStateException
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
@@ -10,7 +11,6 @@
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
-import java.lang.IllegalStateException
@RunWith(PatchedRobolectricTestRunner::class)
@DoNotInstrument
diff --git a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
index 2d0b389..1f175a9 100644
--- a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
+++ b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/authentication/RemoteAuthTest.kt
@@ -29,13 +29,13 @@
import androidx.test.core.app.ApplicationProvider
import androidx.wear.phone.interactions.WearPhoneInteractionsTestRunner
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Executor
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
import org.robolectric.Shadows
import org.robolectric.annotation.Config
import org.robolectric.annotation.internal.DoNotInstrument
-import java.util.concurrent.Executor
/** Unit tests for [RemoteAuthClient]. */
@RunWith(WearPhoneInteractionsTestRunner::class)
diff --git a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/notifications/BridgingManagerTest.kt b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/notifications/BridgingManagerTest.kt
index 7946e50..e49909c 100644
--- a/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/notifications/BridgingManagerTest.kt
+++ b/wear/wear-phone-interactions/src/test/java/androidx/wear/phone/interactions/notifications/BridgingManagerTest.kt
@@ -20,12 +20,12 @@
import android.content.pm.PackageManager
import androidx.wear.phone.interactions.WearPhoneInteractionsTestRunner
import com.google.common.truth.Truth.assertThat
+import java.util.Arrays
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
import org.robolectric.annotation.internal.DoNotInstrument
-import java.util.Arrays
/** Unit tests for [BridgingManager]. */
@RunWith(WearPhoneInteractionsTestRunner::class)
diff --git a/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt b/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
index b5c09d4..c043ba5 100644
--- a/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
+++ b/wear/wear-remote-interactions/src/test/java/androidx/wear/remote/interactions/RemoteActivityHelperTest.kt
@@ -30,13 +30,14 @@
import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.DEFAULT_PACKAGE
import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.RESULT_FAILED
import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.RESULT_OK
+import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.getRemoteIntentResultReceiver
import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.getTargetIntent
import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.getTargetNodeId
-import androidx.wear.remote.interactions.RemoteActivityHelper.Companion.getRemoteIntentResultReceiver
import com.google.android.gms.tasks.Tasks
import com.google.android.gms.wearable.Node
import com.google.android.gms.wearable.NodeClient
-import org.mockito.kotlin.mock
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
@@ -47,11 +48,10 @@
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito
+import org.mockito.kotlin.mock
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config
import org.robolectric.annotation.Implements
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.Executor
@RunWith(WearRemoteInteractionsTestRunner::class)
@Config(shadows = [RemoteActivityHelperTest.ActualResultReceiver::class])
diff --git a/wear/wear/build.gradle b/wear/wear/build.gradle
index 83bcb50..ea42582 100644
--- a/wear/wear/build.gradle
+++ b/wear/wear/build.gradle
@@ -62,7 +62,7 @@
}
androidx {
- name = "Android Wear Support UI"
+ name = "Android Wear"
publish = Publish.SNAPSHOT_AND_RELEASE
mavenVersion = LibraryVersions.WEAR
inceptionYear = "2016"
diff --git a/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java b/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
index 2e2720a..36e4a604 100644
--- a/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
+++ b/wear/wear/src/androidTest/java/androidx/wear/activity/ConfirmationActivityTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertTrue;
import android.widget.Button;
+import org.junit.Ignore;
import androidx.annotation.Nullable;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -56,6 +57,7 @@
new ActivityTestRule<>(ConfirmationActivityTestActivity.class, true, true);
@Test
+ @Ignore("b/272346886")
public void testConfirmationDialogShownForDefaultDuration() throws Throwable {
int testDuration = ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS;
// Check that the structure of the test is still valid
@@ -66,12 +68,14 @@
}
@Test
+ @Ignore("b/272346886")
public void testConfirmationDialogShownForLongerDuration() throws Throwable {
testConfirmationDialogShownForConfiguredDuration(
ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS * 2, "A message");
}
@Test
+ @Ignore("b/272346886")
public void testConfirmationDialogWithMissingMessage() throws Throwable {
testConfirmationDialogShownForConfiguredDuration(
ConfirmationActivity.DEFAULT_ANIMATION_DURATION_MILLIS * 2, /* message= */null);
diff --git a/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt b/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
index b03ecf3..0c16c1a 100644
--- a/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
+++ b/wear/wear/src/androidTest/java/androidx/wear/widget/ArcLayoutTest.kt
@@ -54,16 +54,17 @@
import androidx.wear.widget.ArcLayout.LayoutParams.VERTICAL_ALIGN_OUTER
import androidx.wear.widget.util.AsyncViewActions.waitForMatchingView
import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.CoreMatchers.any
import org.hamcrest.Matcher
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@RunWith(Parameterized::class)
@MediumTest
@@ -830,6 +831,7 @@
}
@Test(timeout = 5000)
+ @Ignore("b/280671279")
fun testBasicTouch() {
val context: Context = ApplicationProvider.getApplicationContext()
// This views are the same as the test testTouchEvents()
@@ -873,6 +875,7 @@
}
@Test(timeout = 10000)
+ @Ignore("b/280671279")
fun testMarginTouch() {
val views = createTwoArcsWithMargin()
testEventsFast("touch_fast_margin_screenshot", views)
diff --git a/wear/wear/src/androidTest/java/androidx/wear/widget/CurvedTextViewTest.kt b/wear/wear/src/androidTest/java/androidx/wear/widget/CurvedTextViewTest.kt
index 34cec3d..96c10c8 100644
--- a/wear/wear/src/androidTest/java/androidx/wear/widget/CurvedTextViewTest.kt
+++ b/wear/wear/src/androidTest/java/androidx/wear/widget/CurvedTextViewTest.kt
@@ -29,11 +29,11 @@
import androidx.test.filters.MediumTest
import androidx.test.screenshot.AndroidXScreenshotTestRule
import androidx.test.screenshot.assertAgainstGolden
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt b/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
index 0f24c5b..97204f0 100644
--- a/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
+++ b/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
@@ -47,6 +47,12 @@
* }
* ```
*
+ * If the observer is registered while the device is in ambient mode, the registered callback
+ * will immediately receive a call to
+ * [AmbientLifecycleObserver.AmbientLifecycleCallback.onEnterAmbient]. If the device is in active
+ * mode, the callbacks will be registered, and `onEnterAmbient` will be called when the device next
+ * enters ambient mode.
+ *
* @param activity The activity that this observer is being attached to.
* @param callbackExecutor The executor to run the provided callbacks on.
* @param callbacks An instance of [AmbientLifecycleObserver.AmbientLifecycleCallback], used to
diff --git a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
index 913e8b5..64b80a7 100644
--- a/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
+++ b/webkit/integration-tests/testapp/src/androidTest/java/com/example/androidx/webkit/ProcessGlobalConfigActivityTestAppTest.java
@@ -24,6 +24,7 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.webkit.WebViewFeature;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -42,6 +43,7 @@
new ActivityScenarioRule<>(ProcessGlobalConfigActivity.class);
@Test
+ @Ignore("b/280671406")
public void testSetDataDirectorySuffix() throws Throwable {
WebkitTestHelpers.assumeStartupFeature(
WebViewFeature.STARTUP_FEATURE_SET_DATA_DIRECTORY_SUFFIX,
diff --git a/webkit/webkit/build.gradle b/webkit/webkit/build.gradle
index 0cc7c77..446ce33 100644
--- a/webkit/webkit/build.gradle
+++ b/webkit/webkit/build.gradle
@@ -68,9 +68,9 @@
}
androidx {
- name = "WebView Support Library"
+ name = "WebKit"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2017"
- description = "The WebView Support Library is a static library you can add to your Android application in order to use android.webkit APIs that are not available for older platform versions."
+ description = "The WebKit Support Library is a static library you can add to your Android application in order to use android.webkit APIs that are not available for older platform versions."
additionalDeviceTestApkKeys.add("chrome")
}
diff --git a/webkit/webkit/src/main/AndroidManifest.xml b/webkit/webkit/src/main/AndroidManifest.xml
deleted file mode 100644
index 95c4426..0000000
--- a/webkit/webkit/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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 />
diff --git a/window/extensions/core/core/build.gradle b/window/extensions/core/core/build.gradle
index 9104d8c..5a895b0 100644
--- a/window/extensions/core/core/build.gradle
+++ b/window/extensions/core/core/build.gradle
@@ -45,7 +45,7 @@
}
androidx {
- name = "Jetpack WindowManager library Core Extensions"
+ name = "WindowManager Core Extensions"
type = LibraryType.PUBLISHED_LIBRARY
publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
inceptionYear = "2022"
diff --git a/window/extensions/extensions/build.gradle b/window/extensions/extensions/build.gradle
index 279cbba..4941b4f2 100644
--- a/window/extensions/extensions/build.gradle
+++ b/window/extensions/extensions/build.gradle
@@ -41,7 +41,7 @@
}
androidx {
- name = "Jetpack WindowManager library Extensions"
+ name = "WindowManager Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
inceptionYear = "2020"
diff --git a/window/extensions/extensions/src/main/AndroidManifest.xml b/window/extensions/extensions/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/window/extensions/extensions/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/window/sidecar/sidecar/build.gradle b/window/sidecar/sidecar/build.gradle
index 742646c..67a5ab4 100644
--- a/window/sidecar/sidecar/build.gradle
+++ b/window/sidecar/sidecar/build.gradle
@@ -27,7 +27,7 @@
}
androidx {
- name = "Jetpack WindowManager library Sidecar"
+ name = "WindowManager Sidecar"
publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
runApiTasks = new RunApiTasks.Yes("Need to track API surface but should never publish")
inceptionYear = "2020"
diff --git a/window/sidecar/sidecar/src/main/AndroidManifest.xml b/window/sidecar/sidecar/src/main/AndroidManifest.xml
deleted file mode 100644
index deac81d..0000000
--- a/window/sidecar/sidecar/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<!--
- Copyright 2020 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 />
diff --git a/window/window-core/build.gradle b/window/window-core/build.gradle
index e0e80a3..fbaefda 100644
--- a/window/window-core/build.gradle
+++ b/window/window-core/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "androidx.window:window-core"
+ name = "WindowManager Core"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2022"
description = "WindowManager Core Library."
diff --git a/window/window-demos/demo/build.gradle b/window/window-demos/demo/build.gradle
index 65adb00..cd3bcf4 100644
--- a/window/window-demos/demo/build.gradle
+++ b/window/window-demos/demo/build.gradle
@@ -82,7 +82,7 @@
}
androidx {
- name = "WM Jetpack Samples"
+ name = "WM Samples"
type = LibraryType.SAMPLES
inceptionYear = "2023"
description = "Samples for the WM Jetpack Library"
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/WindowMetricsActivity.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/WindowMetricsActivity.kt
index 4b0faa7..4bdc573 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/WindowMetricsActivity.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/WindowMetricsActivity.kt
@@ -20,8 +20,8 @@
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
-import androidx.window.layout.WindowMetricsCalculator
import androidx.window.demo.common.infolog.InfoLogAdapter
+import androidx.window.layout.WindowMetricsCalculator
class WindowMetricsActivity : AppCompatActivity() {
diff --git a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
index 7cfc7ee..a5fe754 100644
--- a/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
+++ b/window/window-demos/demo/src/main/java/androidx/window/demo/embedding/ExampleWindowInitializer.kt
@@ -34,8 +34,8 @@
import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.LEFT_TO_RIGHT
import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.RIGHT_TO_LEFT
import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.TOP_TO_BOTTOM
-import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EQUAL
+import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
import androidx.window.embedding.SplitAttributesCalculatorParams
import androidx.window.embedding.SplitController
import androidx.window.embedding.SplitController.SplitSupportStatus.Companion.SPLIT_AVAILABLE
diff --git a/window/window-java/build.gradle b/window/window-java/build.gradle
index ad4a7de..36a1f22 100644
--- a/window/window-java/build.gradle
+++ b/window/window-java/build.gradle
@@ -46,7 +46,7 @@
}
androidx {
- name = "WindowManager Java Support"
+ name = "WindowManager Java"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "WindowManager Java Support"
diff --git a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
index ccf2fc5..ccba465 100644
--- a/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
+++ b/window/window-java/src/androidTest/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
@@ -23,13 +23,13 @@
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.receiveAsFlow
import org.junit.Assert.assertTrue
import org.junit.Test
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Add a test for [WindowInfoTrackerCallbackAdapter] to verify adapted methods. Test converting
diff --git a/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
index c2f21fe..3ea0c05 100644
--- a/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
+++ b/window/window-java/src/main/java/androidx/window/java/area/WindowAreaControllerJavaAdapter.kt
@@ -18,18 +18,18 @@
import android.app.Activity
import androidx.core.util.Consumer
+import androidx.window.area.WindowAreaController
import androidx.window.area.WindowAreaSessionCallback
import androidx.window.area.WindowAreaStatus
-import androidx.window.area.WindowAreaController
import androidx.window.core.ExperimentalWindowApi
+import java.util.concurrent.Executor
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
-import java.util.concurrent.Executor
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
/**
* An adapted interface for [WindowAreaController] that provides the information and
diff --git a/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt b/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
index 35b10d3..1217182 100644
--- a/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
+++ b/window/window-java/src/main/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapter.kt
@@ -18,21 +18,21 @@
import android.app.Activity
import android.content.Context
+import android.inputmethodservice.InputMethodService
import androidx.annotation.UiContext
import androidx.core.util.Consumer
-import android.inputmethodservice.InputMethodService
import androidx.window.core.ExperimentalWindowApi
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
+import java.util.concurrent.Executor
+import java.util.concurrent.locks.ReentrantLock
+import kotlin.concurrent.withLock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
-import java.util.concurrent.Executor
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
/**
* An adapted interface for [WindowInfoTracker] that allows listening for events via a callback
diff --git a/window/window-java/src/test/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt b/window/window-java/src/test/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
index 639e073..f924a0f 100644
--- a/window/window-java/src/test/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
+++ b/window/window-java/src/test/java/androidx/window/java/layout/WindowInfoTrackerCallbackAdapterTest.kt
@@ -19,14 +19,14 @@
import androidx.core.util.Consumer
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.runBlocking
-import org.junit.Test
class WindowInfoTrackerCallbackAdapterTest {
diff --git a/window/window-rxjava2/build.gradle b/window/window-rxjava2/build.gradle
index 97a6430..f3d1277 100644
--- a/window/window-rxjava2/build.gradle
+++ b/window/window-rxjava2/build.gradle
@@ -50,7 +50,7 @@
}
androidx {
- name = "WindowManager RxJava 2"
+ name = "WindowManager RxJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
diff --git a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
index 7415e37..9c97bc5 100644
--- a/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava2/src/androidTest/java/androidx/window/rxjava2/layout/WindowInfoTrackerRxTest.kt
@@ -22,10 +22,10 @@
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import kotlinx.coroutines.flow.flowOf
import org.junit.Test
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Tests for the RxJava 2 adapters.
diff --git a/window/window-rxjava3/build.gradle b/window/window-rxjava3/build.gradle
index 2ab8d1a..e4962e8 100644
--- a/window/window-rxjava3/build.gradle
+++ b/window/window-rxjava3/build.gradle
@@ -49,7 +49,7 @@
}
androidx {
- name = "WindowManager RxJava 3 Support"
+ name = "WindowManager RxJava3"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2021"
description = "WindowManager RxJava 3 Support"
diff --git a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
index b32bfa0..07de2d7 100644
--- a/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
+++ b/window/window-rxjava3/src/androidTest/java/androidx/window/rxjava3/layout/WindowInfoTrackerRxTest.kt
@@ -22,10 +22,10 @@
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowInfoTracker
import androidx.window.layout.WindowLayoutInfo
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import kotlinx.coroutines.flow.flowOf
import org.junit.Test
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Test for the adapter functions that convert to [io.reactivex.rxjava3.core.Observable] or
diff --git a/window/window-testing/build.gradle b/window/window-testing/build.gradle
index 9ccb288..7996b4b 100644
--- a/window/window-testing/build.gradle
+++ b/window/window-testing/build.gradle
@@ -55,7 +55,7 @@
}
androidx {
- name = "WindowManager Test Library"
+ name = "WindowManager Testing Extensions"
type = LibraryType.PUBLISHED_TEST_LIBRARY
inceptionYear = "2021"
description = "WindowManager Test Library"
diff --git a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityEmbeddingRule.kt b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityEmbeddingRule.kt
index cd9fe23..70f2ba7 100644
--- a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityEmbeddingRule.kt
+++ b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityEmbeddingRule.kt
@@ -31,6 +31,9 @@
* A [TestRule] that will stub out the behavior of [ActivityEmbeddingController] and
* [RuleController] with a more simple one that will support testing independent of the current
* platform.
+ *
+ * By default [ActivityEmbeddingRule] has values as if the developer has not opted in to the
+ * ActivityEmbedding feature. There are no set rules, and each [Activity] is not embedded.
*/
class ActivityEmbeddingRule : TestRule {
diff --git a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
index 3bbca06..ef38d1a 100644
--- a/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
+++ b/window/window-testing/src/main/java/androidx/window/testing/embedding/ActivityStackTesting.kt
@@ -21,17 +21,15 @@
import androidx.window.embedding.ActivityStack
/**
- * Creates an [ActivityStack] instance for testing, which defaults to an [ActivityStack] with
- * cross-process activities.
- *
- * The [activitiesInProcess] can be passed from the activity obtained from
- * [androidx.test.core.app.ActivityScenario] or even mock Activities.
+ * Creates an [ActivityStack] instance for testing. The default values are an empty list for
+ * [activitiesInProcess] but a false value for [isEmpty]. This is the same as being embedded with
+ * an [Activity] from another process.
*
* @param activitiesInProcess The [Activity] list with the same process of the host task with
- * empty list as the default value
+ * empty list as the default value.
* @param isEmpty Indicates whether this `ActivityStack` contains any [Activity] regardless of the
- * process with `false` as the default value
- * @return An [ActivityStack] instance for testing
+ * process with `false` as the default value.
+ * @return An [ActivityStack] instance for testing.
*/
@Suppress("FunctionName")
@JvmName("createTestActivityStack")
diff --git a/window/window-testing/src/main/java/androidx/window/testing/layout/DisplayFeatureTesting.kt b/window/window-testing/src/main/java/androidx/window/testing/layout/DisplayFeatureTesting.kt
index 2a065cb..ee66c4f 100644
--- a/window/window-testing/src/main/java/androidx/window/testing/layout/DisplayFeatureTesting.kt
+++ b/window/window-testing/src/main/java/androidx/window/testing/layout/DisplayFeatureTesting.kt
@@ -42,10 +42,10 @@
* always cover the window in one dimension and that determines the other coordinates.
*
* @param activity that will house the [FoldingFeature].
- * @param center the center of the fold complementary to the orientation. For a [HORIZONTAL] fold,
- * this is the y-axis and for a [VERTICAL] fold this is the x-axis.
- * @param size the smaller dimension of the fold. The larger dimension always covers the entire
- * window.
+ * @param center the center of the fold complementary to the orientation in px. For a
+ * [HORIZONTAL] fold, this is the y-axis and for a [VERTICAL] fold this is the x-axis.
+ * @param size the smaller dimension of the fold in px. The larger dimension always covers the
+ * entire window.
* @param state [State] of the fold. The default value is [HALF_OPENED]
* @param orientation [Orientation] of the fold. The default value is [HORIZONTAL]
* @return [FoldingFeature] that is splitting if the width is not 0 and runs parallel to the
@@ -84,10 +84,10 @@
* always cover the window in one dimension and that determines the other coordinates.
*
* @param windowBounds that will contain the [FoldingFeature].
- * @param center the center of the fold complementary to the orientation. For a [HORIZONTAL] fold,
- * this is the y-axis and for a [VERTICAL] fold this is the x-axis.
- * @param size the smaller dimension of the fold. The larger dimension always covers the entire
- * window.
+ * @param center the center of the fold complementary to the orientation in px. For a
+ * [HORIZONTAL] fold, this is the y-axis and for a [VERTICAL] fold this is the x-axis.
+ * @param size the smaller dimension of the fold in px. The larger dimension always covers the
+ * entire window.
* @param state [State] of the fold. The default value is [HALF_OPENED]
* @param orientation [Orientation] of the fold. The default value is [HORIZONTAL]
* @return [FoldingFeature] that is splitting if the width is not 0 and runs parallel to the
diff --git a/window/window-testing/src/test/java/androidx/window/testing/embedding/SplitAttributesCalculatorParamsTestingTest.kt b/window/window-testing/src/test/java/androidx/window/testing/embedding/SplitAttributesCalculatorParamsTestingTest.kt
index f8e8ce2..66dc2e8 100644
--- a/window/window-testing/src/test/java/androidx/window/testing/embedding/SplitAttributesCalculatorParamsTestingTest.kt
+++ b/window/window-testing/src/test/java/androidx/window/testing/embedding/SplitAttributesCalculatorParamsTestingTest.kt
@@ -16,7 +16,6 @@
package androidx.window.testing.embedding
-import androidx.window.testing.layout.FoldingFeature as testFoldingFeature
import android.content.res.Configuration
import android.graphics.Rect
import androidx.window.core.ExperimentalWindowApi
@@ -27,6 +26,7 @@
import androidx.window.layout.FoldingFeature
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.WindowMetrics
+import androidx.window.testing.layout.FoldingFeature as testFoldingFeature
import androidx.window.testing.layout.TestWindowLayoutInfo
import java.util.Collections
import org.junit.Assert.assertEquals
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 4e4170e..402be78 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -85,7 +85,7 @@
}
androidx {
- name = "Jetpack WindowManager Library"
+ name = "WindowManager"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "WindowManager Jetpack library. Currently only provides additional " +
diff --git a/window/window/samples/build.gradle b/window/window/samples/build.gradle
index e44e0ac..7db715c 100644
--- a/window/window/samples/build.gradle
+++ b/window/window/samples/build.gradle
@@ -36,7 +36,7 @@
}
androidx {
- name = "Jetpack WindowManager Library Samples"
+ name = "WindowManager Samples"
type = LibraryType.SAMPLES
inceptionYear = "2022"
description = "Code samples for WindowManager Jetpack library."
diff --git a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
index e796c8f..963966d 100644
--- a/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/area/WindowAreaControllerImplTest.kt
@@ -24,19 +24,19 @@
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.window.TestActivity
import androidx.window.TestConsumer
+import androidx.window.WindowTestUtils.Companion.assumeAtLeastVendorApiLevel
import androidx.window.core.ExperimentalWindowApi
import androidx.window.extensions.area.WindowAreaComponent
import androidx.window.extensions.core.util.function.Consumer
-import androidx.window.WindowTestUtils.Companion.assumeAtLeastVendorApiLevel
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
-import org.junit.Rule
-import org.junit.Test
import kotlin.test.assertFailsWith
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import org.junit.Rule
+import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class, ExperimentalWindowApi::class)
class WindowAreaControllerImplTest {
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
index ec34298..d927096 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/ActivityFilterTest.kt
@@ -20,12 +20,12 @@
import android.content.ComponentName
import android.content.Intent
import com.google.common.truth.Truth.assertWithMessage
-import org.mockito.kotlin.doReturn
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/**
* Integration test for [ActivityFilter] to test construction from [ComponentName].
diff --git a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
index 9d0aaba..6d76005 100644
--- a/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/embedding/EmbeddingAdapterTest.kt
@@ -16,9 +16,6 @@
package androidx.window.embedding
-import androidx.window.extensions.embedding.ActivityStack as OEMActivityStack
-import androidx.window.extensions.embedding.SplitAttributes as OEMSplitAttributes
-import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
import android.app.Activity
import androidx.window.WindowTestUtils
import androidx.window.core.ExtensionsUtil
@@ -26,13 +23,16 @@
import androidx.window.embedding.SplitAttributes.SplitType
import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.embedding.ActivityStack as OEMActivityStack
+import androidx.window.extensions.embedding.SplitAttributes as OEMSplitAttributes
import androidx.window.extensions.embedding.SplitAttributes.LayoutDirection.TOP_TO_BOTTOM
import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.whenever
+import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
/** Tests for [EmbeddingAdapter] */
class EmbeddingAdapterTest {
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
index ff28be7..67f29671 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackendTest.kt
@@ -16,10 +16,6 @@
package androidx.window.layout.adapter.extensions
-import androidx.window.extensions.core.util.function.Consumer as OEMConsumer
-import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
-import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
-import java.util.function.Consumer as JavaConsumer
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
@@ -37,19 +33,16 @@
import androidx.window.core.ConsumerAdapter
import androidx.window.core.ExtensionsUtil
import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.core.util.function.Consumer as OEMConsumer
+import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
import androidx.window.extensions.layout.FoldingFeature.STATE_FLAT
import androidx.window.extensions.layout.FoldingFeature.TYPE_HINGE
import androidx.window.extensions.layout.WindowLayoutComponent
+import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.WindowMetricsCalculatorCompat
import androidx.window.layout.adapter.extensions.ExtensionsWindowLayoutInfoAdapter.translate
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
+import java.util.function.Consumer as JavaConsumer
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
@@ -58,6 +51,13 @@
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
class ExtensionWindowLayoutInfoBackendTest {
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapterTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapterTest.kt
index 376cf74..02f89fe 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapterTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapterTest.kt
@@ -16,8 +16,6 @@
package androidx.window.layout.adapter.extensions
-import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
-import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import android.graphics.Rect
import android.os.Build
import androidx.annotation.RequiresApi
@@ -25,8 +23,10 @@
import androidx.window.TestActivity
import androidx.window.WindowTestUtils
import androidx.window.core.Bounds
+import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
import androidx.window.extensions.layout.FoldingFeature.STATE_HALF_OPENED
import androidx.window.extensions.layout.FoldingFeature.TYPE_HINGE
+import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.layout.HardwareFoldingFeature
import androidx.window.layout.HardwareFoldingFeature.Type.Companion.HINGE
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
index 8d3873e..8a36b00 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatDeviceTest.kt
@@ -28,19 +28,13 @@
import androidx.window.core.VerificationMode.QUIET
import androidx.window.core.Version
import androidx.window.layout.HardwareFoldingFeature
-import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.layout.HardwareFoldingFeature.Type
import androidx.window.layout.HardwareFoldingFeature.Type.Companion.FOLD
import androidx.window.layout.HardwareFoldingFeature.Type.Companion.HINGE
import androidx.window.layout.WindowLayoutInfo
+import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.sidecar.SidecarDisplayFeature
import androidx.window.sidecar.SidecarWindowLayoutInfo
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argThat
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
@@ -51,6 +45,12 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
/**
* Tests for [SidecarCompat] implementation of [ExtensionInterfaceCompat] that are
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
index 305c4f8..e8e0ff1 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarCompatTest.kt
@@ -31,7 +31,6 @@
import androidx.window.WindowTestBase
import androidx.window.core.Bounds
import androidx.window.layout.FoldingFeature
-import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.layout.FoldingFeature.State.Companion.FLAT
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.layout.HardwareFoldingFeature
@@ -39,11 +38,18 @@
import androidx.window.layout.TestFoldingFeatureUtil.invalidFoldBounds
import androidx.window.layout.TestFoldingFeatureUtil.validFoldBound
import androidx.window.layout.WindowLayoutInfo
+import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.sidecar.SidecarDeviceState
import androidx.window.sidecar.SidecarDisplayFeature
import androidx.window.sidecar.SidecarInterface
import androidx.window.sidecar.SidecarInterface.SidecarCallback
import androidx.window.sidecar.SidecarWindowLayoutInfo
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.argumentCaptor
@@ -57,12 +63,6 @@
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyZeroInteractions
import org.mockito.kotlin.whenever
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNotNull
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
/**
* Tests for [SidecarCompat] implementation of [ExtensionInterfaceCompat]. This class
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
index 46ae397..283faac 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendIntegrationTest.kt
@@ -37,11 +37,7 @@
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.WindowMetricsCalculator
import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argThat
-import org.mockito.kotlin.atLeastOnce
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
+import java.util.HashSet
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Assume
@@ -50,7 +46,11 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
-import java.util.HashSet
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
/** Tests for the extension implementation on the device. */
@LargeTest
diff --git a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
index 434cc92..43daf25 100644
--- a/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
+++ b/window/window/src/androidTest/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendTest.kt
@@ -30,10 +30,6 @@
import androidx.window.layout.HardwareFoldingFeature.Type.Companion.HINGE
import androidx.window.layout.WindowLayoutInfo
import com.google.common.util.concurrent.MoreExecutors
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
@@ -41,6 +37,10 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
/** Tests for [SidecarWindowBackend] class. */
@LargeTest
diff --git a/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
index d56eccb..de0971a 100644
--- a/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
+++ b/window/window/src/main/java/androidx/window/area/EmptyWindowAreaControllerImpl.kt
@@ -18,9 +18,9 @@
import android.app.Activity
import androidx.window.core.ExperimentalWindowApi
+import java.util.concurrent.Executor
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
-import java.util.concurrent.Executor
/**
* Empty Implementation for devices that do not
diff --git a/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt b/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
index 6dd98b7..3340a8b 100644
--- a/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
+++ b/window/window/src/main/java/androidx/window/embedding/EmbeddingAdapter.kt
@@ -16,23 +16,12 @@
package androidx.window.embedding
-import android.util.Pair as AndroidPair
-import androidx.window.extensions.embedding.ActivityRule as OEMActivityRule
-import androidx.window.extensions.embedding.ActivityRule.Builder as ActivityRuleBuilder
-import androidx.window.extensions.embedding.EmbeddingRule as OEMEmbeddingRule
-import androidx.window.extensions.embedding.SplitAttributes as OEMSplitAttributes
-import androidx.window.extensions.embedding.SplitAttributes.SplitType as OEMSplitType
-import androidx.window.extensions.embedding.SplitAttributesCalculatorParams as OEMSplitAttributesCalculatorParams
-import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
-import androidx.window.extensions.embedding.SplitPairRule as OEMSplitPairRule
-import androidx.window.extensions.embedding.SplitPairRule.Builder as SplitPairRuleBuilder
-import androidx.window.extensions.embedding.SplitPlaceholderRule as OEMSplitPlaceholderRule
-import androidx.window.extensions.embedding.SplitPlaceholderRule.Builder as SplitPlaceholderRuleBuilder
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.util.LayoutDirection
+import android.util.Pair as AndroidPair
import android.view.WindowMetrics
import androidx.window.core.ExperimentalWindowApi
import androidx.window.core.ExtensionsUtil
@@ -43,17 +32,28 @@
import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.RIGHT_TO_LEFT
import androidx.window.embedding.SplitAttributes.LayoutDirection.Companion.TOP_TO_BOTTOM
import androidx.window.embedding.SplitAttributes.SplitType
-import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EQUAL
import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_EXPAND
+import androidx.window.embedding.SplitAttributes.SplitType.Companion.SPLIT_TYPE_HINGE
import androidx.window.embedding.SplitAttributes.SplitType.Companion.ratio
import androidx.window.extensions.WindowExtensions
import androidx.window.extensions.core.util.function.Function
import androidx.window.extensions.core.util.function.Predicate
+import androidx.window.extensions.embedding.ActivityRule as OEMActivityRule
+import androidx.window.extensions.embedding.ActivityRule.Builder as ActivityRuleBuilder
+import androidx.window.extensions.embedding.EmbeddingRule as OEMEmbeddingRule
+import androidx.window.extensions.embedding.SplitAttributes as OEMSplitAttributes
+import androidx.window.extensions.embedding.SplitAttributes.SplitType as OEMSplitType
import androidx.window.extensions.embedding.SplitAttributes.SplitType.RatioSplitType
+import androidx.window.extensions.embedding.SplitAttributesCalculatorParams as OEMSplitAttributesCalculatorParams
+import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
+import androidx.window.extensions.embedding.SplitPairRule as OEMSplitPairRule
+import androidx.window.extensions.embedding.SplitPairRule.Builder as SplitPairRuleBuilder
import androidx.window.extensions.embedding.SplitPairRule.FINISH_ADJACENT
import androidx.window.extensions.embedding.SplitPairRule.FINISH_ALWAYS
import androidx.window.extensions.embedding.SplitPairRule.FINISH_NEVER
+import androidx.window.extensions.embedding.SplitPlaceholderRule as OEMSplitPlaceholderRule
+import androidx.window.extensions.embedding.SplitPlaceholderRule.Builder as SplitPlaceholderRuleBuilder
import androidx.window.layout.WindowMetricsCalculator
import androidx.window.layout.adapter.extensions.ExtensionsWindowLayoutInfoAdapter
import kotlin.Pair
diff --git a/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt b/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
index 6a1248c..d54b21a 100644
--- a/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
+++ b/window/window/src/main/java/androidx/window/embedding/EmbeddingCompat.kt
@@ -16,7 +16,6 @@
package androidx.window.embedding
-import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
import android.app.Activity
import android.content.Context
import android.util.Log
@@ -31,6 +30,7 @@
import androidx.window.extensions.WindowExtensionsProvider
import androidx.window.extensions.core.util.function.Consumer
import androidx.window.extensions.embedding.ActivityEmbeddingComponent
+import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
import java.lang.reflect.Proxy
/**
diff --git a/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt b/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt
index 92965c3..be35e2a 100644
--- a/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt
+++ b/window/window/src/main/java/androidx/window/embedding/SafeActivityEmbeddingComponentProvider.kt
@@ -18,6 +18,7 @@
import android.app.Activity
import androidx.annotation.VisibleForTesting
+import androidx.window.SafeWindowExtensionsProvider
import androidx.window.core.ConsumerAdapter
import androidx.window.core.ExtensionsUtil
import androidx.window.extensions.WindowExtensions
@@ -27,7 +28,6 @@
import androidx.window.reflection.ReflectionUtils.doesReturn
import androidx.window.reflection.ReflectionUtils.isPublic
import androidx.window.reflection.ReflectionUtils.validateReflection
-import androidx.window.SafeWindowExtensionsProvider
import androidx.window.reflection.WindowExtensionsConstants.ACTIVITY_EMBEDDING_COMPONENT_CLASS
/**
diff --git a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
index b9dcbef..047a14c 100644
--- a/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
+++ b/window/window/src/main/java/androidx/window/layout/SafeWindowLayoutComponentProvider.kt
@@ -20,6 +20,7 @@
import android.content.Context
import android.graphics.Rect
import androidx.annotation.VisibleForTesting
+import androidx.window.SafeWindowExtensionsProvider
import androidx.window.core.ConsumerAdapter
import androidx.window.core.ExtensionsUtil
import androidx.window.extensions.WindowExtensions
@@ -29,7 +30,6 @@
import androidx.window.reflection.ReflectionUtils.doesReturn
import androidx.window.reflection.ReflectionUtils.isPublic
import androidx.window.reflection.ReflectionUtils.validateReflection
-import androidx.window.SafeWindowExtensionsProvider
import androidx.window.reflection.WindowExtensionsConstants.FOLDING_FEATURE_CLASS
import androidx.window.reflection.WindowExtensionsConstants.JAVA_CONSUMER
import androidx.window.reflection.WindowExtensionsConstants.WINDOW_CONSUMER
diff --git a/window/window/src/main/java/androidx/window/layout/WindowMetricsCalculator.kt b/window/window/src/main/java/androidx/window/layout/WindowMetricsCalculator.kt
index 8d8151e..94dd455 100644
--- a/window/window/src/main/java/androidx/window/layout/WindowMetricsCalculator.kt
+++ b/window/window/src/main/java/androidx/window/layout/WindowMetricsCalculator.kt
@@ -16,12 +16,12 @@
package androidx.window.layout
-import android.view.WindowMetrics as AndroidWindowMetrics
import android.app.Activity
import android.content.Context
import android.inputmethodservice.InputMethodService
import android.os.Build
import android.view.Display
+import android.view.WindowMetrics as AndroidWindowMetrics
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.annotation.UiContext
diff --git a/window/window/src/main/java/androidx/window/layout/adapter/WindowBackend.kt b/window/window/src/main/java/androidx/window/layout/adapter/WindowBackend.kt
index 3524cb1..efb74a0 100644
--- a/window/window/src/main/java/androidx/window/layout/adapter/WindowBackend.kt
+++ b/window/window/src/main/java/androidx/window/layout/adapter/WindowBackend.kt
@@ -17,10 +17,10 @@
import android.app.Activity
import android.content.Context
+import androidx.annotation.UiContext
import androidx.core.util.Consumer
import androidx.window.layout.WindowLayoutInfo
import java.util.concurrent.Executor
-import androidx.annotation.UiContext
/**
* Backing interface for [androidx.window.layout.WindowInfoTracker] instances that serve as the
diff --git a/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackend.kt b/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackend.kt
index 64e60f8..9de412a 100644
--- a/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackend.kt
+++ b/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionWindowLayoutInfoBackend.kt
@@ -16,8 +16,6 @@
package androidx.window.layout.adapter.extensions
-import androidx.window.extensions.core.util.function.Consumer as OEMConsumer
-import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import android.app.Activity
import android.content.Context
import androidx.annotation.GuardedBy
@@ -27,7 +25,9 @@
import androidx.window.core.ConsumerAdapter
import androidx.window.core.ExtensionsUtil
import androidx.window.extensions.WindowExtensions
+import androidx.window.extensions.core.util.function.Consumer as OEMConsumer
import androidx.window.extensions.layout.WindowLayoutComponent
+import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.adapter.WindowBackend
import androidx.window.layout.adapter.extensions.ExtensionsWindowLayoutInfoAdapter.translate
diff --git a/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapter.kt b/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapter.kt
index ed9f74d..5f4a31b 100644
--- a/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapter.kt
+++ b/window/window/src/main/java/androidx/window/layout/adapter/extensions/ExtensionsWindowLayoutInfoAdapter.kt
@@ -16,13 +16,13 @@
package androidx.window.layout.adapter.extensions
-import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
-import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import android.app.Activity
import android.content.Context
import android.os.Build
import androidx.annotation.UiContext
import androidx.window.core.Bounds
+import androidx.window.extensions.layout.FoldingFeature as OEMFoldingFeature
+import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo
import androidx.window.layout.FoldingFeature
import androidx.window.layout.FoldingFeature.State.Companion.FLAT
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
diff --git a/window/window/src/test/java/androidx/window/core/ConsumerAdapterTest.kt b/window/window/src/test/java/androidx/window/core/ConsumerAdapterTest.kt
index cc18d1e..22dd2b4 100644
--- a/window/window/src/test/java/androidx/window/core/ConsumerAdapterTest.kt
+++ b/window/window/src/test/java/androidx/window/core/ConsumerAdapterTest.kt
@@ -20,11 +20,11 @@
import android.app.Activity
import android.content.Context
import android.os.Build
-import org.mockito.kotlin.mock
import java.util.function.Consumer
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
+import org.mockito.kotlin.mock
/**
* Tests for [ConsumerAdapter] ensuring that the reflection calls work as expected.
diff --git a/window/window/src/test/java/androidx/window/core/SpecificationComputerTest.kt b/window/window/src/test/java/androidx/window/core/SpecificationComputerTest.kt
index a527f04..848f97a 100644
--- a/window/window/src/test/java/androidx/window/core/SpecificationComputerTest.kt
+++ b/window/window/src/test/java/androidx/window/core/SpecificationComputerTest.kt
@@ -20,15 +20,15 @@
import androidx.window.core.VerificationMode.LOG
import androidx.window.core.VerificationMode.QUIET
import androidx.window.core.VerificationMode.STRICT
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.mockito.ArgumentMatchers.contains
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
/**
* Tests [SpecificationComputer] to verify the following behaviors.
diff --git a/window/window/src/test/java/androidx/window/embedding/EmbeddingCompatTest.kt b/window/window/src/test/java/androidx/window/embedding/EmbeddingCompatTest.kt
index aa9e3f1..029aa99 100644
--- a/window/window/src/test/java/androidx/window/embedding/EmbeddingCompatTest.kt
+++ b/window/window/src/test/java/androidx/window/embedding/EmbeddingCompatTest.kt
@@ -16,8 +16,6 @@
package androidx.window.embedding
-import java.util.function.Consumer as JavaConsumer
-import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
import android.app.Activity
import androidx.window.core.ConsumerAdapter
import androidx.window.core.ExtensionsUtil
@@ -25,6 +23,8 @@
import androidx.window.extensions.WindowExtensions.VENDOR_API_LEVEL_2
import androidx.window.extensions.core.util.function.Consumer
import androidx.window.extensions.embedding.ActivityEmbeddingComponent
+import androidx.window.extensions.embedding.SplitInfo as OEMSplitInfo
+import java.util.function.Consumer as JavaConsumer
import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
diff --git a/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarCompatUnitTest.kt b/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarCompatUnitTest.kt
index 6af845c..b7dddc4 100644
--- a/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarCompatUnitTest.kt
+++ b/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarCompatUnitTest.kt
@@ -25,15 +25,18 @@
import android.view.Window
import android.view.WindowManager
import androidx.window.TestWindow
-import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.layout.TestFoldingFeatureUtil.invalidFoldBounds
import androidx.window.layout.TestFoldingFeatureUtil.validFoldBound
import androidx.window.layout.WindowLayoutInfo
+import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.sidecar.SidecarDeviceState
import androidx.window.sidecar.SidecarDisplayFeature
import androidx.window.sidecar.SidecarInterface
import androidx.window.sidecar.SidecarInterface.SidecarCallback
import androidx.window.sidecar.SidecarWindowLayoutInfo
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
@@ -42,9 +45,6 @@
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
-import org.junit.Assert.assertEquals
-import org.junit.Before
-import org.junit.Test
/**
* Unit tests for [SidecarCompat] that run on the JVM.
diff --git a/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendUnitTest.kt b/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendUnitTest.kt
index f286aa1..dc01b98 100644
--- a/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendUnitTest.kt
+++ b/window/window/src/test/java/androidx/window/layout/adapter/sidecar/SidecarWindowBackendUnitTest.kt
@@ -20,16 +20,16 @@
import androidx.core.util.Consumer
import androidx.window.layout.WindowLayoutInfo
import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
-import org.mockito.kotlin.any
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.times
-import org.mockito.kotlin.verify
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
/**
* Unit tests for [SidecarWindowBackend] that run on the JVM.
diff --git a/window/window/src/testUtil/java/androidx/window/layout/adapter/sidecar/SwitchOnUnregisterExtensionInterfaceCompat.kt b/window/window/src/testUtil/java/androidx/window/layout/adapter/sidecar/SwitchOnUnregisterExtensionInterfaceCompat.kt
index 1af0445..d902e75 100644
--- a/window/window/src/testUtil/java/androidx/window/layout/adapter/sidecar/SwitchOnUnregisterExtensionInterfaceCompat.kt
+++ b/window/window/src/testUtil/java/androidx/window/layout/adapter/sidecar/SwitchOnUnregisterExtensionInterfaceCompat.kt
@@ -20,13 +20,13 @@
import androidx.annotation.GuardedBy
import androidx.window.core.Bounds
import androidx.window.layout.FoldingFeature
-import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import androidx.window.layout.FoldingFeature.State
import androidx.window.layout.FoldingFeature.State.Companion.FLAT
import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED
import androidx.window.layout.HardwareFoldingFeature
import androidx.window.layout.HardwareFoldingFeature.Type.Companion.HINGE
import androidx.window.layout.WindowLayoutInfo
+import androidx.window.layout.adapter.sidecar.ExtensionInterfaceCompat.ExtensionCallbackInterface
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
diff --git a/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RemoteService.kt b/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RemoteService.kt
index 98a2ffd..b1a8714 100644
--- a/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RemoteService.kt
+++ b/work/integration-tests/testapp/src/main/java/androidx/work/integration/testapp/RemoteService.kt
@@ -31,11 +31,11 @@
import androidx.work.WorkQuery
import androidx.work.await
import androidx.work.multiprocess.RemoteWorkManager
+import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
-import java.util.concurrent.TimeUnit
class RemoteService : LifecycleService() {
diff --git a/work/work-benchmark/build.gradle b/work/work-benchmark/build.gradle
index d4a2c31..cd0c8a6 100644
--- a/work/work-benchmark/build.gradle
+++ b/work/work-benchmark/build.gradle
@@ -38,7 +38,7 @@
}
androidx {
- name = "Android WorkManager Benchmarks"
+ name = "WorkManager Benchmarks"
publish = Publish.NONE
inceptionYear = "2019"
description = "Android WorkManager Benchmark Library"
diff --git a/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt b/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt
index 84bf03b..9f3beef 100644
--- a/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt
+++ b/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/DispatchingExecutor.kt
@@ -16,12 +16,12 @@
package androidx.work.benchmark
+import java.util.concurrent.Executor
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import java.util.concurrent.Executor
/**
* An [Executor] where we can await termination of all commands.
diff --git a/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/MarshallingBenchmark.kt b/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/MarshallingBenchmark.kt
index e174f59..d362916 100644
--- a/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/MarshallingBenchmark.kt
+++ b/work/work-benchmark/src/androidTest/java/androidx/work/benchmark/MarshallingBenchmark.kt
@@ -31,11 +31,11 @@
import androidx.work.multiprocess.parcelable.ParcelConverters
import androidx.work.multiprocess.parcelable.ParcelableConstraints
import androidx.work.multiprocess.parcelable.ParcelableWorkRequest
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/work/work-benchmark/src/main/AndroidManifest.xml b/work/work-benchmark/src/main/AndroidManifest.xml
deleted file mode 100644
index 4d64e1c..0000000
--- a/work/work-benchmark/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<!--
- ~ Copyright (C) 2019 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 />
diff --git a/work/work-gcm/build.gradle b/work/work-gcm/build.gradle
index 562422b0..98a4351 100644
--- a/work/work-gcm/build.gradle
+++ b/work/work-gcm/build.gradle
@@ -47,7 +47,7 @@
}
androidx {
- name = "Android WorkManager GCMNetworkManager Support"
+ name = "WorkManager GCM Integration"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2019"
description = "Android WorkManager GCMNetworkManager Support"
diff --git a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
index 639d5b1..da05ab5 100644
--- a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
+++ b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/GcmTaskConverterTest.kt
@@ -23,19 +23,20 @@
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
+import androidx.work.SystemClock
import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.background.gcm.GcmTaskConverter.EXECUTION_WINDOW_SIZE_IN_SECONDS
import com.google.android.gms.gcm.Task
+import java.util.concurrent.TimeUnit
+import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.greaterThan
import org.hamcrest.Matchers.lessThanOrEqualTo
import org.junit.Assert.assertEquals
-import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.spy
-import java.util.concurrent.TimeUnit
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
@SmallTest
@@ -45,7 +46,7 @@
@Before
fun setUp() {
- mTaskConverter = spy(GcmTaskConverter())
+ mTaskConverter = spy(GcmTaskConverter(SystemClock()))
}
@Test
diff --git a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
index 7e14f39..b3b56f5 100644
--- a/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
+++ b/work/work-gcm/src/androidTest/java/androidx/work/impl/background/gcm/WorkManagerGcmDispatcherTest.kt
@@ -26,27 +26,27 @@
import androidx.work.Configuration
import androidx.work.OneTimeWorkRequest
import androidx.work.impl.TestWorkManagerImpl
-import androidx.work.impl.model.WorkGenerationalId
import androidx.work.impl.WorkManagerImpl
+import androidx.work.impl.model.WorkGenerationalId
import androidx.work.impl.utils.SerialExecutorImpl
import androidx.work.impl.utils.SynchronousExecutor
import androidx.work.impl.utils.WorkTimer
import androidx.work.impl.utils.taskexecutor.SerialExecutor
import com.google.android.gms.gcm.GcmNetworkManager
import com.google.android.gms.gcm.TaskParams
+import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.eq
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
@MediumTest
diff --git a/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmScheduler.java b/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmScheduler.java
index f8ffaba..71f595e 100644
--- a/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmScheduler.java
+++ b/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmScheduler.java
@@ -19,6 +19,7 @@
import android.content.Context;
import androidx.annotation.NonNull;
+import androidx.work.Clock;
import androidx.work.Logger;
import androidx.work.impl.Scheduler;
import androidx.work.impl.model.WorkSpec;
@@ -38,14 +39,14 @@
private final GcmNetworkManager mNetworkManager;
private final GcmTaskConverter mTaskConverter;
- public GcmScheduler(@NonNull Context context) {
+ public GcmScheduler(@NonNull Context context, @NonNull Clock clock) {
boolean isPlayServicesAvailable = GoogleApiAvailability.getInstance()
.isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
if (!isPlayServicesAvailable) {
throw new IllegalStateException("Google Play Services not available");
}
mNetworkManager = GcmNetworkManager.getInstance(context);
- mTaskConverter = new GcmTaskConverter();
+ mTaskConverter = new GcmTaskConverter(clock);
}
@Override
diff --git a/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmTaskConverter.java b/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmTaskConverter.java
index 6dec44e..fb6e1ae 100644
--- a/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmTaskConverter.java
+++ b/work/work-gcm/src/main/java/androidx/work/impl/background/gcm/GcmTaskConverter.java
@@ -27,6 +27,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
+import androidx.work.Clock;
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.impl.model.WorkSpec;
@@ -40,7 +41,6 @@
* Converts a {@link androidx.work.impl.model.WorkSpec} to a {@link Task}.
*/
public class GcmTaskConverter {
-
/**
* This is referring to the size of the execution window in seconds. {@link GcmNetworkManager}
* requires that we specify a window of time relative to {@code now} where a {@link Task}
@@ -53,6 +53,11 @@
public static final long EXECUTION_WINDOW_SIZE_IN_SECONDS = 5L;
static final String EXTRA_WORK_GENERATION = "androidx.work.impl.background.gcm.GENERATION";
+ private final Clock mClock;
+
+ public GcmTaskConverter(@NonNull Clock clock) {
+ mClock = clock;
+ }
OneoffTask convert(@NonNull WorkSpec workSpec) {
Bundle extras = new Bundle();
@@ -81,7 +86,7 @@
*/
@VisibleForTesting
public long now() {
- return System.currentTimeMillis();
+ return mClock.currentTimeMillis();
}
private static Task.Builder applyConstraints(
diff --git a/work/work-inspection/build.gradle b/work/work-inspection/build.gradle
index 5385c55..5cfd833 100644
--- a/work/work-inspection/build.gradle
+++ b/work/work-inspection/build.gradle
@@ -42,7 +42,7 @@
}
androidx {
- name = "Android WorkManager Inspector"
+ name = "WorkManager Inspector"
type = LibraryType.IDE_PLUGIN
inceptionYear = "2020"
description = "The implementation of WorkManager Inspector."
diff --git a/work/work-inspection/src/androidTest/java/androidx/work/inspection/DispatchingExecutor.kt b/work/work-inspection/src/androidTest/java/androidx/work/inspection/DispatchingExecutor.kt
index 772f31f..68643032 100644
--- a/work/work-inspection/src/androidTest/java/androidx/work/inspection/DispatchingExecutor.kt
+++ b/work/work-inspection/src/androidTest/java/androidx/work/inspection/DispatchingExecutor.kt
@@ -16,12 +16,12 @@
package androidx.work.inspection
+import java.util.concurrent.Executor
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import java.util.concurrent.Executor
/**
* An [Executor] where we can await termination of all commands.
diff --git a/work/work-inspection/src/androidTest/java/androidx/work/inspection/worker/IdleWorker.kt b/work/work-inspection/src/androidTest/java/androidx/work/inspection/worker/IdleWorker.kt
index e5e63e7..c4ba239 100644
--- a/work/work-inspection/src/androidTest/java/androidx/work/inspection/worker/IdleWorker.kt
+++ b/work/work-inspection/src/androidTest/java/androidx/work/inspection/worker/IdleWorker.kt
@@ -19,9 +19,9 @@
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
+import kotlin.time.Duration
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
-import kotlin.time.Duration
class IdleWorker(
context: Context,
diff --git a/work/work-lint/build.gradle b/work/work-lint/build.gradle
index 083e406..fb59083 100644
--- a/work/work-lint/build.gradle
+++ b/work/work-lint/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android WorkManager Runtime Lint Checks"
+ name = "WorkManager Runtime Lint Checks"
type = LibraryType.LINT
inceptionYear = "2019"
description = "Android WorkManager Runtime Lint Checks"
diff --git a/work/work-lint/src/main/java/androidx/work/lint/IdleBatteryChargingConstraintsDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/IdleBatteryChargingConstraintsDetector.kt
index a0f5d40..975a5a8 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/IdleBatteryChargingConstraintsDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/IdleBatteryChargingConstraintsDetector.kt
@@ -28,6 +28,7 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UBlockExpression
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UQualifiedReferenceExpression
@@ -35,7 +36,6 @@
import org.jetbrains.uast.getParentOfType
import org.jetbrains.uast.toUElement
import org.jetbrains.uast.visitor.AbstractUastVisitor
-import java.util.EnumSet
/**
* Warns when a developer uses both idle + battery charging constraints in WorkManager.
diff --git a/work/work-lint/src/main/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetector.kt
index a4c7cf6..6404e126cc 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/InvalidPeriodicWorkRequestIntervalDetector.kt
@@ -27,11 +27,11 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import java.util.concurrent.TimeUnit
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.uast.UCallExpression
-import java.util.EnumSet
-import java.util.concurrent.TimeUnit
/**
* Ensures a valid interval duration for a `PeriodicWorkRequest`.
diff --git a/work/work-lint/src/main/java/androidx/work/lint/RxWorkerSetProgressDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/RxWorkerSetProgressDetector.kt
index 41a6ac4..f2c1f5d 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/RxWorkerSetProgressDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/RxWorkerSetProgressDetector.kt
@@ -28,8 +28,8 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UCallExpression
import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
class RxWorkerSetProgressDetector : Detector(), SourceCodeScanner {
companion object {
diff --git a/work/work-lint/src/main/java/androidx/work/lint/SpecifyForegroundServiceTypeIssueDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/SpecifyForegroundServiceTypeIssueDetector.kt
index 0d6e67d..c4f30bf 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/SpecifyForegroundServiceTypeIssueDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/SpecifyForegroundServiceTypeIssueDetector.kt
@@ -31,9 +31,9 @@
import com.android.tools.lint.detector.api.XmlContext
import com.android.tools.lint.detector.api.XmlScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.w3c.dom.Element
-import java.util.EnumSet
/**
* Detects usage of `ForegroundInfo` with the `foregroundServiceType` and ensure that the service
diff --git a/work/work-lint/src/main/java/androidx/work/lint/SpecifyJobSchedulerIdRangeIssueDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/SpecifyJobSchedulerIdRangeIssueDetector.kt
index e3245f8..5d1a66d 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/SpecifyJobSchedulerIdRangeIssueDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/SpecifyJobSchedulerIdRangeIssueDetector.kt
@@ -29,9 +29,9 @@
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UClass
-import java.util.EnumSet
class SpecifyJobSchedulerIdRangeIssueDetector : Detector(), SourceCodeScanner {
companion object {
diff --git a/work/work-lint/src/main/java/androidx/work/lint/WorkerHasPublicModifierDetector.kt b/work/work-lint/src/main/java/androidx/work/lint/WorkerHasPublicModifierDetector.kt
index a5730e6..b3c794b7 100644
--- a/work/work-lint/src/main/java/androidx/work/lint/WorkerHasPublicModifierDetector.kt
+++ b/work/work-lint/src/main/java/androidx/work/lint/WorkerHasPublicModifierDetector.kt
@@ -30,9 +30,9 @@
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.intellij.lang.jvm.JvmModifier
import com.intellij.psi.PsiMethod
+import java.util.EnumSet
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UClass
-import java.util.EnumSet
class WorkerHasPublicModifierDetector : Detector(), SourceCodeScanner {
companion object {
diff --git a/work/work-multiprocess/build.gradle b/work/work-multiprocess/build.gradle
index 7b7697d..94c4112 100644
--- a/work/work-multiprocess/build.gradle
+++ b/work/work-multiprocess/build.gradle
@@ -49,7 +49,7 @@
}
androidx {
- name = "Android WorkManager Multiprocess Implementation"
+ name = "WorkManager Multiprocess"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android WorkManager runtime library"
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ListenableWorkerImplClientTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ListenableWorkerImplClientTest.kt
index 65381d0..4f225a8 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ListenableWorkerImplClientTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ListenableWorkerImplClientTest.kt
@@ -28,6 +28,7 @@
import androidx.work.impl.utils.SerialExecutorImpl
import androidx.work.impl.utils.futures.SettableFuture
import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import java.util.concurrent.Executor
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
@@ -37,11 +38,10 @@
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
public class ListenableWorkerImplClientTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkContinuationImplTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkContinuationImplTest.kt
index d0d6eee..4e96412 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkContinuationImplTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkContinuationImplTest.kt
@@ -36,14 +36,14 @@
import androidx.work.multiprocess.parcelable.ParcelConverters.marshall
import androidx.work.multiprocess.parcelable.ParcelConverters.unmarshall
import androidx.work.multiprocess.parcelable.ParcelableWorkContinuationImpl
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.spy
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
public class ParcelableWorkContinuationImplTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkInfoTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkInfoTest.kt
index 0be0967..96a5676 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkInfoTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkInfoTest.kt
@@ -24,10 +24,10 @@
import androidx.work.multiprocess.parcelable.ParcelConverters
import androidx.work.multiprocess.parcelable.ParcelableWorkInfo
import androidx.work.multiprocess.parcelable.ParcelableWorkInfos
+import java.util.UUID
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.UUID
@RunWith(AndroidJUnit4::class)
public class ParcelableWorkInfoTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkQueryTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkQueryTest.kt
index 64a7a50..679f860 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkQueryTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkQueryTest.kt
@@ -23,10 +23,10 @@
import androidx.work.WorkQuery
import androidx.work.multiprocess.parcelable.ParcelConverters
import androidx.work.multiprocess.parcelable.ParcelableWorkQuery
+import java.util.UUID
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.UUID
@RunWith(AndroidJUnit4::class)
public class ParcelableWorkQueryTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkRequestConvertersTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkRequestConvertersTest.kt
index ea7ed12..ba9e090 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkRequestConvertersTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/ParcelableWorkRequestConvertersTest.kt
@@ -30,10 +30,10 @@
import androidx.work.multiprocess.parcelable.ParcelConverters
import androidx.work.multiprocess.parcelable.ParcelableWorkRequest
import androidx.work.multiprocess.parcelable.ParcelableWorkRequests
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
public class ParcelableWorkRequestConvertersTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteCoroutineWorkerTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteCoroutineWorkerTest.kt
index e28fc49..3b1c18b 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteCoroutineWorkerTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteCoroutineWorkerTest.kt
@@ -34,13 +34,13 @@
import androidx.work.impl.foreground.ForegroundProcessor
import androidx.work.impl.utils.SerialExecutorImpl
import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
public class RemoteCoroutineWorkerTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
index 5efb197..5871f12 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteListenableWorkerTest.kt
@@ -39,14 +39,14 @@
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import androidx.work.multiprocess.RemoteListenableWorker.ARGUMENT_CLASS_NAME
import androidx.work.multiprocess.RemoteListenableWorker.ARGUMENT_PACKAGE_NAME
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
public class RemoteListenableWorkerTest {
diff --git a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteWorkManagerClientTest.kt b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteWorkManagerClientTest.kt
index 7e1329e..e5d60a2 100644
--- a/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteWorkManagerClientTest.kt
+++ b/work/work-multiprocess/src/androidTest/java/androidx/work/multiprocess/RemoteWorkManagerClientTest.kt
@@ -27,6 +27,7 @@
import androidx.work.impl.utils.SerialExecutorImpl
import androidx.work.impl.utils.futures.SettableFuture
import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import java.util.concurrent.Executor
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
@@ -35,14 +36,13 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyString
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
-import java.util.concurrent.Executor
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
public class RemoteWorkManagerClientTest {
diff --git a/work/work-runtime-ktx/build.gradle b/work/work-runtime-ktx/build.gradle
index f45007c..34051b4 100644
--- a/work/work-runtime-ktx/build.gradle
+++ b/work/work-runtime-ktx/build.gradle
@@ -40,7 +40,7 @@
}
androidx {
- name = "Android WorkManager Kotlin Extensions"
+ name = "WorkManager Kotlin Extensions"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android WorkManager Kotlin Extensions"
diff --git a/work/work-runtime-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt b/work/work-runtime-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
index a37928b..34e716c 100644
--- a/work/work-runtime-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
+++ b/work/work-runtime-ktx/src/androidTest/java/androidx/work/CoroutineWorkerTest.kt
@@ -30,10 +30,12 @@
import androidx.work.impl.utils.futures.SettableFuture
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import androidx.work.workers.ProgressUpdatingWorker
+import java.util.UUID
+import java.util.concurrent.Executor
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.nullValue
import org.hamcrest.MatcherAssert.assertThat
import org.junit.After
@@ -46,8 +48,6 @@
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/work/work-runtime-ktx/src/androidTest/java/androidx/work/ListenableFutureTest.kt b/work/work-runtime-ktx/src/androidTest/java/androidx/work/ListenableFutureTest.kt
index 61b8b36..7cf491c 100644
--- a/work/work-runtime-ktx/src/androidTest/java/androidx/work/ListenableFutureTest.kt
+++ b/work/work-runtime-ktx/src/androidTest/java/androidx/work/ListenableFutureTest.kt
@@ -25,8 +25,8 @@
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.instanceOf
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Ignore
import org.junit.Test
diff --git a/work/work-runtime-ktx/src/androidTest/java/androidx/work/PeriodicWorkRequestTest.kt b/work/work-runtime-ktx/src/androidTest/java/androidx/work/PeriodicWorkRequestTest.kt
index f406101..c20e521 100644
--- a/work/work-runtime-ktx/src/androidTest/java/androidx/work/PeriodicWorkRequestTest.kt
+++ b/work/work-runtime-ktx/src/androidTest/java/androidx/work/PeriodicWorkRequestTest.kt
@@ -20,11 +20,11 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.work.workers.TestWorker
+import java.time.Duration
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
-import java.time.Duration
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/work/work-runtime-ktx/src/main/java/androidx/work/ListenableFuture.kt b/work/work-runtime-ktx/src/main/java/androidx/work/ListenableFuture.kt
index 3b825b5..f0edd3f 100644
--- a/work/work-runtime-ktx/src/main/java/androidx/work/ListenableFuture.kt
+++ b/work/work-runtime-ktx/src/main/java/androidx/work/ListenableFuture.kt
@@ -21,12 +21,12 @@
import androidx.annotation.RestrictTo
import androidx.work.impl.utils.futures.SettableFuture
import com.google.common.util.concurrent.ListenableFuture
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.suspendCancellableCoroutine
import java.util.concurrent.CancellationException
import java.util.concurrent.ExecutionException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.suspendCancellableCoroutine
/**
* Awaits for the completion of the [ListenableFuture] without blocking a thread.
diff --git a/work/work-runtime/api/current.txt b/work/work-runtime/api/current.txt
index 2b6df42d..42fc6a2 100644
--- a/work/work-runtime/api/current.txt
+++ b/work/work-runtime/api/current.txt
@@ -336,7 +336,7 @@
}
public final class WorkInfo {
- ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long earliestPossibleRuntimeMillis);
+ ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long nextScheduleTimeMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints);
@@ -346,10 +346,10 @@
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags);
method public androidx.work.Constraints getConstraints();
- method public long getEarliestPossibleRuntimeMillis();
method public int getGeneration();
method public java.util.UUID getId();
method public long getInitialDelayMillis();
+ method public long getNextScheduleTimeMillis();
method public androidx.work.Data getOutputData();
method public androidx.work.WorkInfo.PeriodicityInfo? getPeriodicityInfo();
method public androidx.work.Data getProgress();
@@ -357,10 +357,10 @@
method public androidx.work.WorkInfo.State getState();
method public java.util.Set<java.lang.String> getTags();
property public final androidx.work.Constraints constraints;
- property public final long earliestPossibleRuntimeMillis;
property public final int generation;
property public final java.util.UUID id;
property public final long initialDelayMillis;
+ property public final long nextScheduleTimeMillis;
property public final androidx.work.Data outputData;
property public final androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo;
property public final androidx.work.Data progress;
diff --git a/work/work-runtime/api/public_plus_experimental_current.txt b/work/work-runtime/api/public_plus_experimental_current.txt
index 2b6df42d..42fc6a2 100644
--- a/work/work-runtime/api/public_plus_experimental_current.txt
+++ b/work/work-runtime/api/public_plus_experimental_current.txt
@@ -336,7 +336,7 @@
}
public final class WorkInfo {
- ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long earliestPossibleRuntimeMillis);
+ ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long nextScheduleTimeMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints);
@@ -346,10 +346,10 @@
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags);
method public androidx.work.Constraints getConstraints();
- method public long getEarliestPossibleRuntimeMillis();
method public int getGeneration();
method public java.util.UUID getId();
method public long getInitialDelayMillis();
+ method public long getNextScheduleTimeMillis();
method public androidx.work.Data getOutputData();
method public androidx.work.WorkInfo.PeriodicityInfo? getPeriodicityInfo();
method public androidx.work.Data getProgress();
@@ -357,10 +357,10 @@
method public androidx.work.WorkInfo.State getState();
method public java.util.Set<java.lang.String> getTags();
property public final androidx.work.Constraints constraints;
- property public final long earliestPossibleRuntimeMillis;
property public final int generation;
property public final java.util.UUID id;
property public final long initialDelayMillis;
+ property public final long nextScheduleTimeMillis;
property public final androidx.work.Data outputData;
property public final androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo;
property public final androidx.work.Data progress;
diff --git a/work/work-runtime/api/restricted_current.txt b/work/work-runtime/api/restricted_current.txt
index 2b6df42d..42fc6a2 100644
--- a/work/work-runtime/api/restricted_current.txt
+++ b/work/work-runtime/api/restricted_current.txt
@@ -336,7 +336,7 @@
}
public final class WorkInfo {
- ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long earliestPossibleRuntimeMillis);
+ ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo, optional long nextScheduleTimeMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis, optional androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints, optional long initialDelayMillis);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData, optional androidx.work.Data progress, optional int runAttemptCount, optional int generation, optional androidx.work.Constraints constraints);
@@ -346,10 +346,10 @@
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags, optional androidx.work.Data outputData);
ctor public WorkInfo(java.util.UUID id, androidx.work.WorkInfo.State state, java.util.Set<java.lang.String> tags);
method public androidx.work.Constraints getConstraints();
- method public long getEarliestPossibleRuntimeMillis();
method public int getGeneration();
method public java.util.UUID getId();
method public long getInitialDelayMillis();
+ method public long getNextScheduleTimeMillis();
method public androidx.work.Data getOutputData();
method public androidx.work.WorkInfo.PeriodicityInfo? getPeriodicityInfo();
method public androidx.work.Data getProgress();
@@ -357,10 +357,10 @@
method public androidx.work.WorkInfo.State getState();
method public java.util.Set<java.lang.String> getTags();
property public final androidx.work.Constraints constraints;
- property public final long earliestPossibleRuntimeMillis;
property public final int generation;
property public final java.util.UUID id;
property public final long initialDelayMillis;
+ property public final long nextScheduleTimeMillis;
property public final androidx.work.Data outputData;
property public final androidx.work.WorkInfo.PeriodicityInfo? periodicityInfo;
property public final androidx.work.Data progress;
diff --git a/work/work-runtime/build.gradle b/work/work-runtime/build.gradle
index 5e8d67b..ff562a1 100644
--- a/work/work-runtime/build.gradle
+++ b/work/work-runtime/build.gradle
@@ -96,7 +96,7 @@
}
androidx {
- name = "Android WorkManager Runtime"
+ name = "WorkManager Runtime"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android WorkManager runtime library"
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
index b89ef48..07cb922 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/DelegatingWorkerFactoryTest.kt
@@ -24,6 +24,7 @@
import androidx.work.impl.utils.taskexecutor.WorkManagerTaskExecutor
import androidx.work.worker.FailureWorker
import androidx.work.worker.TestWorker
+import java.util.UUID
import org.hamcrest.CoreMatchers.instanceOf
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
@@ -31,7 +32,6 @@
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
-import java.util.UUID
@RunWith(AndroidJUnit4::class)
@SmallTest
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/RawWorkInfoDaoTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/RawWorkInfoDaoTest.kt
index a7d4179..d7a6146 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/RawWorkInfoDaoTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/RawWorkInfoDaoTest.kt
@@ -22,8 +22,8 @@
import androidx.work.worker.RetryWorker
import androidx.work.worker.TestWorker
import org.hamcrest.CoreMatchers.`is`
-import org.hamcrest.Matchers.containsInAnyOrder
import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.containsInAnyOrder
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/SchedulersTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/SchedulersTest.kt
index aa90135..92f289e 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/SchedulersTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/SchedulersTest.kt
@@ -24,8 +24,8 @@
import androidx.work.impl.Scheduler
import androidx.work.impl.StartStopTokens
import androidx.work.impl.WorkDatabase
-import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.WorkLauncherImpl
+import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.background.greedy.GreedyScheduler
import androidx.work.impl.constraints.trackers.Trackers
import androidx.work.impl.model.WorkSpec
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkDatabasePathHelperTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkDatabasePathHelperTest.kt
index b02375a..9b8dd501 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkDatabasePathHelperTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkDatabasePathHelperTest.kt
@@ -27,13 +27,13 @@
import androidx.work.impl.WorkDatabase
import androidx.work.impl.WorkDatabasePathHelper
import androidx.work.impl.WorkDatabaseVersions.VERSION_9
+import java.io.File
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-import java.io.File
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
index d13e1f3..cbae3d9 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkForegroundRunnableTest.kt
@@ -30,8 +30,10 @@
import androidx.work.impl.utils.taskexecutor.InstantWorkTaskExecutor
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import androidx.work.worker.TestWorker
-import org.hamcrest.CoreMatchers.`is`
+import java.util.UUID
+import java.util.concurrent.Executor
import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert.fail
import org.junit.Before
@@ -42,8 +44,6 @@
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(AndroidJUnit4::class)
public class WorkForegroundRunnableTest : DatabaseTest() {
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt
index 4a49ecd..6543a12 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkRequestTest.kt
@@ -19,10 +19,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.work.worker.TestWorker
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class WorkRequestTest {
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
index b150905..8421dc5 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/WorkUpdateTest.kt
@@ -29,8 +29,8 @@
import androidx.work.WorkManager.UpdateResult.NOT_APPLIED
import androidx.work.impl.Processor
import androidx.work.impl.WorkDatabase
-import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.WorkLauncherImpl
+import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.background.greedy.GreedyScheduler
import androidx.work.impl.constraints.trackers.Trackers
import androidx.work.impl.testutils.TestConstraintTracker
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
index 0528bf1..6845d6c 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
@@ -1308,7 +1308,7 @@
@Test
@SmallTest
- public void testGetWorkInfoById_earliestPossibleRunTime_notEnqueued()
+ public void testGetWorkInfoById_nextScheduleTime_notEnqueued()
throws ExecutionException, InterruptedException {
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).build();
work.getWorkSpec().state = RUNNING;
@@ -1318,12 +1318,12 @@
WorkInfo info = mWorkManagerImpl.getWorkInfoById(work.getId()).get();
assertThat(info.getState(), equalTo(RUNNING));
- assertThat(info.getEarliestPossibleRuntimeMillis(), equalTo(Long.MAX_VALUE));
+ assertThat(info.getNextScheduleTimeMillis(), equalTo(Long.MAX_VALUE));
}
@Test
@SmallTest
- public void testGetWorkInfoById_earliestPossibleRunTime_enqueued()
+ public void testGetWorkInfoById_nextScheduleTime_enqueued()
throws ExecutionException, InterruptedException {
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).build();
work.getWorkSpec().lastEnqueueTime = 1000L;
@@ -1332,14 +1332,14 @@
WorkInfo info = mWorkManagerImpl.getWorkInfoById(work.getId()).get();
assertThat(info.getState(), equalTo(ENQUEUED));
- assertThat(info.getEarliestPossibleRuntimeMillis(),
+ assertThat(info.getNextScheduleTimeMillis(),
equalTo(1000L));
}
@Test
@SmallTest
@SdkSuppress(minSdkVersion = 26)
- public void testGetWorkInfoById_earliestPossibleRunTime_onetime_initialDelay()
+ public void testGetWorkInfoById_nextScheduleTime_onetime_initialDelay()
throws ExecutionException, InterruptedException {
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class).setInitialDelay(
Duration.ofMillis(2000)).build();
@@ -1349,14 +1349,14 @@
WorkInfo info = mWorkManagerImpl.getWorkInfoById(work.getId()).get();
assertThat(info.getState(), equalTo(ENQUEUED));
- assertThat(info.getEarliestPossibleRuntimeMillis(),
+ assertThat(info.getNextScheduleTimeMillis(),
equalTo(3000L));
}
@Test
@SmallTest
@SdkSuppress(minSdkVersion = 26)
- public void testGetWorkInfoById_earliestPossibleRunTime_periodic_period()
+ public void testGetWorkInfoById_nextScheduleTime_periodic_period()
throws ExecutionException, InterruptedException {
Duration period = Duration.ofMinutes(15);
Duration initialDelay = Duration.ofMillis(2000);
@@ -1374,7 +1374,7 @@
WorkInfo info = mWorkManagerImpl.getWorkInfoById(work0.getId()).get();
assertThat(info.getState(), equalTo(ENQUEUED));
- assertThat(info.getEarliestPossibleRuntimeMillis(),
+ assertThat(info.getNextScheduleTimeMillis(),
equalTo(lastEnqueueTime.plus(period).toMillis()));
assertThat(info.getInitialDelayMillis(), equalTo(initialDelay.toMillis()));
}
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/greedy/DelayedWorkTrackerTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/greedy/DelayedWorkTrackerTest.kt
index ffce534..3906259 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/greedy/DelayedWorkTrackerTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/greedy/DelayedWorkTrackerTest.kt
@@ -20,7 +20,9 @@
import androidx.test.filters.MediumTest
import androidx.work.OneTimeWorkRequest
import androidx.work.RunnableScheduler
+import androidx.work.SystemClock
import androidx.work.worker.TestWorker
+import java.util.concurrent.TimeUnit
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -28,7 +30,6 @@
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
class DelayedWorkTrackerTest {
@@ -40,7 +41,7 @@
fun setUp() {
mScheduler = mock(GreedyScheduler::class.java)
mRunnableScheduler = mock(RunnableScheduler::class.java)
- mDelayedWorkTracker = DelayedWorkTracker(mScheduler, mRunnableScheduler)
+ mDelayedWorkTracker = DelayedWorkTracker(mScheduler, mRunnableScheduler, SystemClock())
}
@Test
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
index 2b97041..d000c32 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobInfoConverterTest.java
@@ -44,6 +44,7 @@
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
+import androidx.work.SystemClock;
import androidx.work.WorkManagerTest;
import androidx.work.impl.WorkManagerImpl;
import androidx.work.impl.model.WorkSpec;
@@ -70,7 +71,7 @@
@Before
public void setUp() {
mConverter = new SystemJobInfoConverter(
- ApplicationProvider.getApplicationContext());
+ ApplicationProvider.getApplicationContext(), new SystemClock());
}
@Test
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobSchedulerTest.java b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobSchedulerTest.java
index 305ccf2..164b411 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobSchedulerTest.java
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/background/systemjob/SystemJobSchedulerTest.java
@@ -126,7 +126,7 @@
workDatabase,
configuration,
mJobScheduler,
- new SystemJobInfoConverter(context)));
+ new SystemJobInfoConverter(context, configuration.getClock())));
doNothing().when(mSystemJobScheduler).scheduleInternal(any(WorkSpec.class), anyInt());
}
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/SerialExecutorTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/SerialExecutorTest.kt
index c723d90..814e22f 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/SerialExecutorTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/SerialExecutorTest.kt
@@ -18,14 +18,14 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executors
+import java.util.concurrent.TimeUnit
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.greaterThanOrEqualTo
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
@RunWith(AndroidJUnit4::class)
@LargeTest
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
index b9373a0..d7e25ac 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkForegroundUpdaterTest.kt
@@ -32,15 +32,15 @@
import androidx.work.impl.utils.taskexecutor.InstantWorkTaskExecutor
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import androidx.work.worker.TestWorker
+import java.util.UUID
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyString
import org.mockito.Mockito.mock
-import java.util.UUID
+import org.mockito.Mockito.`when`
@RunWith(AndroidJUnit4::class)
diff --git a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
index da29a44..eaf7b7b 100644
--- a/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
+++ b/work/work-runtime/src/androidTest/java/androidx/work/impl/utils/WorkProgressUpdaterTest.kt
@@ -26,13 +26,13 @@
import androidx.work.impl.model.WorkSpecDao
import androidx.work.impl.utils.taskexecutor.InstantWorkTaskExecutor
import androidx.work.impl.utils.taskexecutor.TaskExecutor
+import java.util.UUID
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito
import org.mockito.Mockito.`when`
-import java.util.UUID
@RunWith(AndroidJUnit4::class)
// Mockito tries to class load android.os.CancellationSignal which is only available on API >= 16
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkInfo.kt b/work/work-runtime/src/main/java/androidx/work/WorkInfo.kt
index 67c79d0..943e845 100644
--- a/work/work-runtime/src/main/java/androidx/work/WorkInfo.kt
+++ b/work/work-runtime/src/main/java/androidx/work/WorkInfo.kt
@@ -104,7 +104,7 @@
* Even if this value is set, the work may not be registered with the system scheduler if
* there are limited scheduling slots or other factors.
*/
- val earliestPossibleRuntimeMillis: Long = Long.MAX_VALUE,
+ val nextScheduleTimeMillis: Long = Long.MAX_VALUE,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -118,7 +118,7 @@
if (constraints != workInfo.constraints) return false
if (initialDelayMillis != workInfo.initialDelayMillis) return false
if (periodicityInfo != workInfo.periodicityInfo) return false
- if (earliestPossibleRuntimeMillis != workInfo.earliestPossibleRuntimeMillis) return false
+ if (nextScheduleTimeMillis != workInfo.nextScheduleTimeMillis) return false
return if (tags != workInfo.tags) false else progress == workInfo.progress
}
@@ -133,7 +133,7 @@
result = 31 * result + constraints.hashCode()
result = 31 * result + initialDelayMillis.hashCode()
result = 31 * result + periodicityInfo.hashCode()
- result = 31 * result + earliestPossibleRuntimeMillis.hashCode()
+ result = 31 * result + nextScheduleTimeMillis.hashCode()
return result
}
@@ -143,7 +143,7 @@
"runAttemptCount=$runAttemptCount, generation=$generation, " +
"constraints=$constraints}, initialDelayMillis=$initialDelayMillis, " +
"periodicityInfo=$periodicityInfo, " +
- "earliestPossibleRunTimeMillis=$earliestPossibleRuntimeMillis")
+ "nextScheduleTimeMillis=$nextScheduleTimeMillis")
}
/**
diff --git a/work/work-runtime/src/main/java/androidx/work/WorkRequest.kt b/work/work-runtime/src/main/java/androidx/work/WorkRequest.kt
index 60dd8fe..8232cf1a8 100644
--- a/work/work-runtime/src/main/java/androidx/work/WorkRequest.kt
+++ b/work/work-runtime/src/main/java/androidx/work/WorkRequest.kt
@@ -20,8 +20,8 @@
import androidx.annotation.RequiresApi
import androidx.annotation.RestrictTo
import androidx.annotation.VisibleForTesting
-import androidx.work.impl.utils.toMillisCompat
import androidx.work.impl.model.WorkSpec
+import androidx.work.impl.utils.toMillisCompat
import java.time.Duration
import java.util.UUID
import java.util.concurrent.TimeUnit
@@ -224,7 +224,7 @@
* Sets an initial delay for the [WorkRequest].
*
* @param duration The length of the delay
- * @return The current [Builder] *
+ * @return The current [Builder]
* @throws IllegalArgumentException if the given initial delay will push the execution time
* past `Long.MAX_VALUE` and cause an overflow
*/
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/Schedulers.java b/work/work-runtime/src/main/java/androidx/work/impl/Schedulers.java
index 6a1ed29..b0786fe 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/Schedulers.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/Schedulers.java
@@ -26,6 +26,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
+import androidx.work.Clock;
import androidx.work.Configuration;
import androidx.work.Logger;
import androidx.work.impl.background.systemalarm.SystemAlarmScheduler;
@@ -100,13 +101,13 @@
List<WorkSpec> contentUriWorkSpecs = null;
if (Build.VERSION.SDK_INT >= CONTENT_URI_TRIGGER_API_LEVEL) {
contentUriWorkSpecs = workSpecDao.getEligibleWorkForSchedulingWithContentUris();
- markScheduled(workSpecDao, contentUriWorkSpecs);
+ markScheduled(workSpecDao, configuration.getClock(), contentUriWorkSpecs);
}
// Enqueued workSpecs when scheduling limits are applicable.
eligibleWorkSpecsForLimitedSlots = workSpecDao.getEligibleWorkForScheduling(
configuration.getMaxSchedulerLimit());
- markScheduled(workSpecDao, eligibleWorkSpecsForLimitedSlots);
+ markScheduled(workSpecDao, configuration.getClock(), eligibleWorkSpecsForLimitedSlots);
if (contentUriWorkSpecs != null) {
eligibleWorkSpecsForLimitedSlots.addAll(contentUriWorkSpecs);
}
@@ -157,7 +158,7 @@
setComponentEnabled(context, SystemJobService.class, true);
Logger.get().debug(TAG, "Created SystemJobScheduler and enabled SystemJobService");
} else {
- scheduler = tryCreateGcmBasedScheduler(context);
+ scheduler = tryCreateGcmBasedScheduler(context, configuration.getClock());
if (scheduler == null) {
scheduler = new SystemAlarmScheduler(context);
setComponentEnabled(context, SystemAlarmService.class, true);
@@ -168,11 +169,12 @@
}
@Nullable
- private static Scheduler tryCreateGcmBasedScheduler(@NonNull Context context) {
+ private static Scheduler tryCreateGcmBasedScheduler(@NonNull Context context, Clock clock) {
try {
Class<?> klass = Class.forName(GCM_SCHEDULER);
Scheduler scheduler =
- (Scheduler) klass.getConstructor(Context.class).newInstance(context);
+ (Scheduler) klass.getConstructor(Context.class, Clock.class)
+ .newInstance(context, clock);
Logger.get().debug(TAG, "Created " + GCM_SCHEDULER);
return scheduler;
} catch (Throwable throwable) {
@@ -184,9 +186,9 @@
private Schedulers() {
}
- private static void markScheduled(WorkSpecDao dao, List<WorkSpec> workSpecs) {
+ private static void markScheduled(WorkSpecDao dao, Clock clock, List<WorkSpec> workSpecs) {
if (workSpecs.size() > 0) {
- long now = System.currentTimeMillis();
+ long now = clock.currentTimeMillis();
// Mark all the WorkSpecs as scheduled.
// Calls to Scheduler#schedule() could potentially result in more schedules
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/DelayedWorkTracker.java b/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/DelayedWorkTracker.java
index 01e484a..3ae8711 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/DelayedWorkTracker.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/DelayedWorkTracker.java
@@ -18,6 +18,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
+import androidx.work.Clock;
import androidx.work.Logger;
import androidx.work.RunnableScheduler;
import androidx.work.impl.model.WorkSpec;
@@ -43,14 +44,17 @@
final GreedyScheduler mGreedyScheduler;
private final RunnableScheduler mRunnableScheduler;
+ private final Clock mClock;
private final Map<String, Runnable> mRunnables;
public DelayedWorkTracker(
@NonNull GreedyScheduler scheduler,
- @NonNull RunnableScheduler runnableScheduler) {
+ @NonNull RunnableScheduler runnableScheduler,
+ @NonNull Clock clock) {
mGreedyScheduler = scheduler;
mRunnableScheduler = runnableScheduler;
+ mClock = clock;
mRunnables = new HashMap<>();
}
@@ -77,7 +81,7 @@
};
mRunnables.put(workSpec.id, runnable);
- long now = System.currentTimeMillis();
+ long now = mClock.currentTimeMillis();
long delay = nextRunTime - now;
mRunnableScheduler.scheduleWithDelay(delay, runnable);
}
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java b/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
index b7e8767..bb48033 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/greedy/GreedyScheduler.java
@@ -93,7 +93,8 @@
) {
mContext = context;
mWorkConstraintsTracker = new WorkConstraintsTrackerImpl(trackers, this);
- mDelayedWorkTracker = new DelayedWorkTracker(this, configuration.getRunnableScheduler());
+ mDelayedWorkTracker = new DelayedWorkTracker(
+ this, configuration.getRunnableScheduler(), configuration.getClock());
mConfiguration = configuration;
mProcessor = processor;
mWorkLauncher = workLauncher;
@@ -152,7 +153,7 @@
}
long throttled = throttleIfNeeded(workSpec);
long nextRunTime = max(workSpec.calculateNextRunTime(), throttled);
- long now = System.currentTimeMillis();
+ long now = mConfiguration.getClock().currentTimeMillis();
if (workSpec.state == WorkInfo.State.ENQUEUED) {
if (now < nextRunTime) {
// Future work
@@ -290,7 +291,7 @@
AttemptData firstRunAttempt = mFirstRunAttempts.get(id);
if (firstRunAttempt == null) {
firstRunAttempt = new AttemptData(workSpec.runAttemptCount,
- System.currentTimeMillis());
+ mConfiguration.getClock().currentTimeMillis());
mFirstRunAttempts.put(id, firstRunAttempt);
}
return firstRunAttempt.mTimeStamp
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java
index ade9938..1e73418 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/CommandHandler.java
@@ -24,6 +24,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.annotation.WorkerThread;
+import androidx.work.Clock;
import androidx.work.Logger;
import androidx.work.impl.ExecutionListener;
import androidx.work.impl.StartStopToken;
@@ -128,10 +129,13 @@
private final Context mContext;
private final Map<WorkGenerationalId, DelayMetCommandHandler> mPendingDelayMet;
private final Object mLock;
+ private final Clock mClock;
private final StartStopTokens mStartStopTokens;
- CommandHandler(@NonNull Context context, @NonNull StartStopTokens startStopTokens) {
+ CommandHandler(@NonNull Context context, Clock clock,
+ @NonNull StartStopTokens startStopTokens) {
mContext = context;
+ mClock = clock;
mStartStopTokens = startStopTokens;
mPendingDelayMet = new HashMap<>();
mLock = new Object();
@@ -332,7 +336,7 @@
// Constraints changed command handler is synchronous. No cleanup
// is necessary.
ConstraintsCommandHandler changedCommandHandler =
- new ConstraintsCommandHandler(mContext, startId, dispatcher);
+ new ConstraintsCommandHandler(mContext, mClock, startId, dispatcher);
changedCommandHandler.handleConstraintsChanged();
}
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/ConstraintsCommandHandler.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/ConstraintsCommandHandler.java
index ad3361b..4bd3fbf 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/ConstraintsCommandHandler.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/ConstraintsCommandHandler.java
@@ -24,6 +24,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.WorkerThread;
+import androidx.work.Clock;
import androidx.work.Logger;
import androidx.work.impl.constraints.WorkConstraintsTrackerImpl;
import androidx.work.impl.constraints.trackers.Trackers;
@@ -35,7 +36,6 @@
/**
* This is a command handler which handles the constraints changed event.
* Typically this happens for WorkSpec's for which we have pending alarms.
- *
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class ConstraintsCommandHandler {
@@ -43,16 +43,18 @@
private static final String TAG = Logger.tagWithPrefix("ConstraintsCmdHandler");
private final Context mContext;
+ private final Clock mClock;
private final int mStartId;
private final SystemAlarmDispatcher mDispatcher;
private final WorkConstraintsTrackerImpl mWorkConstraintsTracker;
ConstraintsCommandHandler(
@NonNull Context context,
+ Clock clock,
int startId,
@NonNull SystemAlarmDispatcher dispatcher) {
-
mContext = context;
+ mClock = clock;
mStartId = startId;
mDispatcher = dispatcher;
Trackers trackers = mDispatcher.getWorkManager().getTrackers();
@@ -74,7 +76,7 @@
List<WorkSpec> eligibleWorkSpecs = new ArrayList<>(candidates.size());
// Filter candidates should have already been scheduled.
- long now = System.currentTimeMillis();
+ long now = mClock.currentTimeMillis();
for (WorkSpec workSpec : candidates) {
String workSpecId = workSpec.id;
long triggerAt = workSpec.calculateNextRunTime();
@@ -87,7 +89,8 @@
for (WorkSpec workSpec : eligibleWorkSpecs) {
String workSpecId = workSpec.id;
Intent intent = CommandHandler.createDelayMetIntent(mContext, generationalId(workSpec));
- Logger.get().debug(TAG, "Creating a delay_met command for workSpec with id (" + workSpecId + ")");
+ Logger.get().debug(TAG,
+ "Creating a delay_met command for workSpec with id (" + workSpecId + ")");
mDispatcher.getTaskExecutor().getMainThreadExecutor().execute(
new SystemAlarmDispatcher.AddRunnable(mDispatcher, intent, mStartId));
}
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcher.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcher.java
index c92310b..d6a5ef4 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcher.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemalarm/SystemAlarmDispatcher.java
@@ -90,8 +90,9 @@
) {
mContext = context.getApplicationContext();
mStartStopTokens = new StartStopTokens();
- mCommandHandler = new CommandHandler(mContext, mStartStopTokens);
mWorkManager = workManager != null ? workManager : WorkManagerImpl.getInstance(context);
+ mCommandHandler = new CommandHandler(
+ mContext, mWorkManager.getConfiguration().getClock(), mStartStopTokens);
mWorkTimer = new WorkTimer(mWorkManager.getConfiguration().getRunnableScheduler());
mProcessor = processor != null ? processor : mWorkManager.getProcessor();
mTaskExecutor = mWorkManager.getWorkTaskExecutor();
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
index 61a24d5..f292f3f 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobInfoConverter.java
@@ -29,6 +29,7 @@
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.work.BackoffPolicy;
+import androidx.work.Clock;
import androidx.work.Constraints;
import androidx.work.Logger;
import androidx.work.NetworkType;
@@ -50,8 +51,10 @@
static final String EXTRA_WORK_SPEC_GENERATION = "EXTRA_WORK_SPEC_GENERATION";
private final ComponentName mWorkServiceComponent;
+ private final Clock mClock;
- SystemJobInfoConverter(@NonNull Context context) {
+ SystemJobInfoConverter(@NonNull Context context, Clock clock) {
+ mClock = clock;
Context appContext = context.getApplicationContext();
mWorkServiceComponent = new ComponentName(appContext, SystemJobService.class);
}
@@ -86,7 +89,7 @@
}
long nextRunTime = workSpec.calculateNextRunTime();
- long now = System.currentTimeMillis();
+ long now = mClock.currentTimeMillis();
long offset = Math.max(nextRunTime - now, 0);
if (Build.VERSION.SDK_INT <= 28) {
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java
index af76cf1..fc679669 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/background/systemjob/SystemJobScheduler.java
@@ -78,7 +78,7 @@
workDatabase,
configuration,
(JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE),
- new SystemJobInfoConverter(context)
+ new SystemJobInfoConverter(context, configuration.getClock())
);
}
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/constraints/trackers/BatteryNotLowTracker.kt b/work/work-runtime/src/main/java/androidx/work/impl/constraints/trackers/BatteryNotLowTracker.kt
index da13e81..c1b592f 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/constraints/trackers/BatteryNotLowTracker.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/constraints/trackers/BatteryNotLowTracker.kt
@@ -16,8 +16,8 @@
package androidx.work.impl.constraints.trackers
import android.content.Context
-import android.content.IntentFilter
import android.content.Intent
+import android.content.IntentFilter
import android.os.BatteryManager
import androidx.annotation.RestrictTo
import androidx.work.Logger
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/utils/CancelWorkRunnable.java b/work/work-runtime/src/main/java/androidx/work/impl/utils/CancelWorkRunnable.java
index 03158ae..71e3ec8 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/utils/CancelWorkRunnable.java
+++ b/work/work-runtime/src/main/java/androidx/work/impl/utils/CancelWorkRunnable.java
@@ -222,7 +222,9 @@
}
// Update the last cancelled time in Preference.
new PreferenceUtils(workManagerImpl.getWorkDatabase())
- .setLastCancelAllTimeMillis(System.currentTimeMillis());
+ .setLastCancelAllTimeMillis(
+ workManagerImpl.getConfiguration().getClock()
+ .currentTimeMillis());
workDatabase.setTransactionSuccessful();
} finally {
workDatabase.endTransaction();
diff --git a/work/work-runtime/src/main/java/androidx/work/impl/workers/DiagnosticsWorker.kt b/work/work-runtime/src/main/java/androidx/work/impl/workers/DiagnosticsWorker.kt
index 2781cdf..b8bc4e6 100644
--- a/work/work-runtime/src/main/java/androidx/work/impl/workers/DiagnosticsWorker.kt
+++ b/work/work-runtime/src/main/java/androidx/work/impl/workers/DiagnosticsWorker.kt
@@ -22,11 +22,11 @@
import androidx.work.WorkerParameters
import androidx.work.impl.Scheduler
import androidx.work.impl.WorkManagerImpl
-import androidx.work.impl.model.generationalId
import androidx.work.impl.model.SystemIdInfoDao
import androidx.work.impl.model.WorkNameDao
import androidx.work.impl.model.WorkSpec
import androidx.work.impl.model.WorkTagDao
+import androidx.work.impl.model.generationalId
import java.util.concurrent.TimeUnit
internal class DiagnosticsWorker(context: Context, parameters: WorkerParameters) :
@@ -38,7 +38,8 @@
val workNameDao = database.workNameDao()
val workTagDao = database.workTagDao()
val systemIdInfoDao = database.systemIdInfoDao()
- val startAt = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)
+ val startAt =
+ workManager.configuration.clock.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)
val completed = workSpecDao.getRecentlyCompletedWork(startAt)
val running = workSpecDao.getRunningWork()
val enqueued = workSpecDao.getAllEligibleWorkSpecsForScheduling(
diff --git a/work/work-rxjava2/build.gradle b/work/work-rxjava2/build.gradle
index e8e0e7e..9779ab9 100644
--- a/work/work-rxjava2/build.gradle
+++ b/work/work-rxjava2/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android WorkManager RxJava2 Support"
+ name = "WorkManager RxJava2"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android WorkManager RxJava2 interoperatibility library"
diff --git a/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt b/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
index 892795f..e2713c2 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/RxForegroundInfoTest.kt
@@ -23,12 +23,12 @@
import androidx.work.impl.utils.futures.SettableFuture
import com.google.common.truth.Truth.assertThat
import io.reactivex.Single
+import java.util.UUID
+import java.util.concurrent.Executor
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(JUnit4::class)
class RxForegroundInfoTest {
diff --git a/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt b/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
index 5bb80f0..6e04386 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/RxWorkerTest.kt
@@ -22,6 +22,10 @@
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
+import java.util.UUID
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
@@ -29,10 +33,6 @@
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executor
-import java.util.concurrent.TimeUnit
@RunWith(JUnit4::class)
class RxWorkerTest {
diff --git a/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt b/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
index f8e2c28..8579353 100644
--- a/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
+++ b/work/work-rxjava2/src/test/java/androidx/work/SetCompletableProgressTest.kt
@@ -20,14 +20,14 @@
import androidx.work.ListenableWorker.Result
import androidx.work.impl.utils.SynchronousExecutor
import androidx.work.impl.utils.futures.SettableFuture
+import java.util.UUID
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(JUnit4::class)
class SetCompletableProgressTest {
diff --git a/work/work-rxjava3/build.gradle b/work/work-rxjava3/build.gradle
index a725099..c6e82b9 100644
--- a/work/work-rxjava3/build.gradle
+++ b/work/work-rxjava3/build.gradle
@@ -32,7 +32,7 @@
}
androidx {
- name = "Android WorkManager RxJava3 Support"
+ name = "WorkManager RxJava3"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2020"
description = "Android WorkManager RxJava3 interoperatibility library"
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
index 89c230b..131e8a8 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxForegroundInfoTest.kt
@@ -29,12 +29,12 @@
import androidx.work.impl.utils.futures.SettableFuture
import com.google.common.truth.Truth.assertThat
import io.reactivex.rxjava3.core.Single
+import java.util.UUID
+import java.util.concurrent.Executor
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(JUnit4::class)
class RxForegroundInfoTest {
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
index 2f7d422..13d4305 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/RxWorkerTest.kt
@@ -28,6 +28,10 @@
import androidx.work.impl.utils.taskexecutor.TaskExecutor
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
+import java.util.UUID
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Assert
@@ -35,10 +39,6 @@
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Executor
-import java.util.concurrent.TimeUnit
@RunWith(JUnit4::class)
class RxWorkerTest {
diff --git a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
index ee837b8..24e8155 100644
--- a/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
+++ b/work/work-rxjava3/src/test/java/androidx/work/rxjava3/SetCompletableProgressTest.kt
@@ -25,14 +25,14 @@
import androidx.work.WorkerParameters
import androidx.work.impl.utils.SynchronousExecutor
import androidx.work.impl.utils.futures.SettableFuture
+import java.util.UUID
+import java.util.concurrent.Executor
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.Mockito.mock
-import java.util.UUID
-import java.util.concurrent.Executor
@RunWith(JUnit4::class)
class SetCompletableProgressTest {
diff --git a/work/work-testing/build.gradle b/work/work-testing/build.gradle
index 45e33ef..52a3ba4 100644
--- a/work/work-testing/build.gradle
+++ b/work/work-testing/build.gradle
@@ -44,7 +44,7 @@
}
androidx {
- name = "Android WorkManager Testing"
+ name = "WorkManager Testing"
publish = Publish.SNAPSHOT_AND_RELEASE
inceptionYear = "2018"
description = "Android WorkManager testing library"
diff --git a/work/work-testing/src/androidTest/java/androidx/work/testing/CustomClockTest.kt b/work/work-testing/src/androidTest/java/androidx/work/testing/CustomClockTest.kt
index 101c334..002e439 100644
--- a/work/work-testing/src/androidTest/java/androidx/work/testing/CustomClockTest.kt
+++ b/work/work-testing/src/androidTest/java/androidx/work/testing/CustomClockTest.kt
@@ -60,7 +60,7 @@
@Test
@SdkSuppress(minSdkVersion = 26)
@Throws(InterruptedException::class, ExecutionException::class)
- fun testScheduledTime_relativeToTestClock() {
+ fun testScheduleTime_relativeToTestClock() {
testClock.timeMillis = Duration.ofDays(100).toMillis()
val initialDelay = Duration.ofHours(1)
@@ -72,7 +72,7 @@
workManagerImpl.enqueue(listOf(request)).result.get()
val status = workManagerImpl.getWorkInfoById(request.id).get()
- assertThat(status.earliestPossibleRuntimeMillis)
+ assertThat(status.nextScheduleTimeMillis)
.isEqualTo(testClock.timeMillis + initialDelay.toMillis())
}
}
diff --git a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
index 2e44ffd..ca861ee 100644
--- a/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
+++ b/work/work-testing/src/androidTest/java/androidx/work/testing/TestSchedulerTest.java
@@ -44,6 +44,7 @@
import androidx.work.testing.workers.TestWorker;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -77,6 +78,7 @@
CountingTestWorker.COUNT.set(0);
}
+ @Ignore // b/281720148
@Test
public void testWorker_shouldSucceedSynchronously()
throws InterruptedException, ExecutionException {
diff --git a/work/work-testing/src/androidTest/java/androidx/work/testing/TestWorkerBuilderTest.kt b/work/work-testing/src/androidTest/java/androidx/work/testing/TestWorkerBuilderTest.kt
index 077765c..7548ecb 100644
--- a/work/work-testing/src/androidTest/java/androidx/work/testing/TestWorkerBuilderTest.kt
+++ b/work/work-testing/src/androidTest/java/androidx/work/testing/TestWorkerBuilderTest.kt
@@ -30,9 +30,14 @@
import androidx.work.await
import androidx.work.testing.workers.TestListenableWorker
import androidx.work.testing.workers.TestWorker
+import java.util.UUID
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.Executor
+import java.util.concurrent.Executors
+import kotlin.jvm.Throws
import kotlinx.coroutines.runBlocking
-import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.hasItems
+import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.containsInAnyOrder
import org.hamcrest.Matchers.notNullValue
@@ -44,11 +49,6 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
-import java.util.UUID
-import java.util.concurrent.ExecutionException
-import java.util.concurrent.Executor
-import java.util.concurrent.Executors
-import kotlin.jvm.Throws
@RunWith(AndroidJUnit4::class)
class TestWorkerBuilderTest {
diff --git a/work/work-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.kt b/work/work-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.kt
index aa1ba31..851f31e 100644
--- a/work/work-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.kt
+++ b/work/work-testing/src/main/java/androidx/work/testing/TestWorkManagerImpl.kt
@@ -17,7 +17,6 @@
package androidx.work.testing
import android.content.Context
-
import androidx.work.Configuration
import androidx.work.impl.Processor
import androidx.work.impl.Scheduler