[go: nahoru, domu]

Merge "Migrated update_tracing_perfetto.sh code to Python" into androidx-main
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index dd1dd37..a6fafc74 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -73,11 +73,12 @@
   }
 
   public abstract class OnBackPressedCallback {
-    ctor public OnBackPressedCallback(boolean);
+    ctor public OnBackPressedCallback(boolean isEnabled);
     method @MainThread public abstract void handleOnBackPressed();
     method @MainThread public final boolean isEnabled();
     method @MainThread public final void remove();
     method @MainThread public final void setEnabled(boolean);
+    property @MainThread public final boolean isEnabled;
   }
 
   public final class OnBackPressedDispatcher {
@@ -141,8 +142,8 @@
     field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
   }
 
-  public interface ActivityResultCallback<O> {
-    method public void onActivityResult(O!);
+  public fun interface ActivityResultCallback<O> {
+    method public void onActivityResult(O? result);
   }
 
   public interface ActivityResultCaller {
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index dd1dd37..a6fafc74 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -73,11 +73,12 @@
   }
 
   public abstract class OnBackPressedCallback {
-    ctor public OnBackPressedCallback(boolean);
+    ctor public OnBackPressedCallback(boolean isEnabled);
     method @MainThread public abstract void handleOnBackPressed();
     method @MainThread public final boolean isEnabled();
     method @MainThread public final void remove();
     method @MainThread public final void setEnabled(boolean);
+    property @MainThread public final boolean isEnabled;
   }
 
   public final class OnBackPressedDispatcher {
@@ -141,8 +142,8 @@
     field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
   }
 
-  public interface ActivityResultCallback<O> {
-    method public void onActivityResult(O!);
+  public fun interface ActivityResultCallback<O> {
+    method public void onActivityResult(O? result);
   }
 
   public interface ActivityResultCaller {
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 64662e2..cf252d3 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -72,11 +72,12 @@
   }
 
   public abstract class OnBackPressedCallback {
-    ctor public OnBackPressedCallback(boolean);
+    ctor public OnBackPressedCallback(boolean isEnabled);
     method @MainThread public abstract void handleOnBackPressed();
     method @MainThread public final boolean isEnabled();
     method @MainThread public final void remove();
     method @MainThread public final void setEnabled(boolean);
+    property @MainThread public final boolean isEnabled;
   }
 
   public final class OnBackPressedDispatcher {
@@ -140,8 +141,8 @@
     field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
   }
 
-  public interface ActivityResultCallback<O> {
-    method public void onActivityResult(O!);
+  public fun interface ActivityResultCallback<O> {
+    method public void onActivityResult(O? result);
   }
 
   public interface ActivityResultCaller {
diff --git a/activity/activity/src/androidTest/java/androidx/activity/result/ActivityResultRegistryTest.kt b/activity/activity/src/androidTest/java/androidx/activity/result/ActivityResultRegistryTest.kt
index dad575f..a6af035 100644
--- a/activity/activity/src/androidTest/java/androidx/activity/result/ActivityResultRegistryTest.kt
+++ b/activity/activity/src/androidTest/java/androidx/activity/result/ActivityResultRegistryTest.kt
@@ -59,12 +59,10 @@
 
         // register for the result
         val activityResult = registry.register(
-            "test", lifecycleOwner,
-            TakePicturePreview(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {
+            resultReturned = true
+        }
 
         // move the state to started
         lifecycleOwner.currentState = Lifecycle.State.STARTED
@@ -82,8 +80,8 @@
         // register for the result
         val activityResult = registry.register(
             "test", lifecycleOwner,
-            TakePicturePreview(), ActivityResultCallback {}
-        )
+            TakePicturePreview()
+        ) {}
 
         // saved the state of the registry
         val state = Bundle()
@@ -101,11 +99,10 @@
         var resultReturned = false
         // re-register for the result that should have been saved
         registry.register(
-            "test", lifecycleOwner, TakePicturePreview(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {
+            resultReturned = true
+        }
 
         lifecycleOwner.currentState = Lifecycle.State.STARTED
 
@@ -119,9 +116,8 @@
         try {
             // register for the result
             registry.register(
-                "test", lifecycleOwner,
-                TakePicturePreview(), ActivityResultCallback {}
-            )
+                "test", lifecycleOwner, TakePicturePreview()
+            ) {}
             fail("Registering for activity result after Lifecycle ON_CREATE should fail")
         } catch (e: IllegalStateException) {
             assertThat(e).hasMessageThat().contains(
@@ -138,9 +134,8 @@
 
         // register for the result
         val activityResult = registry.register(
-            "test", lifecycleOwner,
-            TakePicturePreview(), ActivityResultCallback {}
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {}
 
         // saved the state of the registry
         val state = Bundle()
@@ -155,11 +150,10 @@
         var resultReturned = false
         // re-register for the result that should have been saved
         registry.register(
-            "test", lifecycleOwner, TakePicturePreview(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {
+            resultReturned = true
+        }
 
         // launch the result
         activityResult.launch(null)
@@ -200,10 +194,9 @@
         var resultReturned = false
         val activityResult = dispatchResultRegistry.register(
             "test", lifecycleOwner, TakePicture(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+        ) {
+            resultReturned = true
+        }
 
         // launch the result
         activityResult.launch(null)
@@ -244,10 +237,9 @@
         var resultReturned = false
         val activityResult = dispatchResultRegistry.register(
             "test", lifecycleOwner, TakePicturePreview(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+        ) {
+            resultReturned = true
+        }
 
         // launch the result
         activityResult.launch(null)
@@ -276,9 +268,8 @@
 
         // register for the result
         val activityResult = registry.register(
-            "test", lifecycleOwner,
-            TakePicturePreview(), ActivityResultCallback {}
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {}
 
         // saved the state of the registry
         val state = Bundle()
@@ -296,11 +287,10 @@
         var resultReturned = false
         // re-register for the result that should have been saved
         registry.register(
-            "test", lifecycleOwner, TakePicturePreview(),
-            ActivityResultCallback {
-                resultReturned = true
-            }
-        )
+            "test", lifecycleOwner, TakePicturePreview()
+        ) {
+            resultReturned = true
+        }
 
         // move to CREATED and make sure the callback is not fired
         lifecycleOwner.currentState = Lifecycle.State.CREATED
diff --git a/activity/activity/src/main/java/androidx/activity/Cancellable.java b/activity/activity/src/main/java/androidx/activity/Cancellable.kt
similarity index 90%
rename from activity/activity/src/main/java/androidx/activity/Cancellable.java
rename to activity/activity/src/main/java/androidx/activity/Cancellable.kt
index a5cb90a..33af37c 100644
--- a/activity/activity/src/main/java/androidx/activity/Cancellable.java
+++ b/activity/activity/src/main/java/androidx/activity/Cancellable.kt
@@ -13,17 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package androidx.activity;
+package androidx.activity
 
 /**
  * Token representing a cancellable operation.
  */
-interface Cancellable {
-
+internal interface Cancellable {
     /**
      * Cancel the subscription. This call should be idempotent, making it safe to
      * call multiple times.
      */
-    void cancel();
-}
+    fun cancel()
+}
\ No newline at end of file
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java
deleted file mode 100644
index afa44f3..0000000
--- a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.java
+++ /dev/null
@@ -1,122 +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.
- */
-
-package androidx.activity;
-
-import androidx.annotation.MainThread;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.OptIn;
-import androidx.core.os.BuildCompat;
-import androidx.core.util.Consumer;
-import androidx.lifecycle.LifecycleOwner;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Class for handling {@link OnBackPressedDispatcher#onBackPressed()} callbacks without
- * strongly coupling that implementation to a subclass of {@link ComponentActivity}.
- * <p>
- * This class maintains its own {@link #isEnabled() enabled state}. Only when this callback
- * is enabled will it receive callbacks to {@link #handleOnBackPressed()}.
- * <p>
- * Note that the enabled state is an additional layer on top of the
- * {@link androidx.lifecycle.LifecycleOwner} passed to
- * {@link OnBackPressedDispatcher#addCallback(LifecycleOwner, OnBackPressedCallback)}
- * which controls when the callback is added and removed to the dispatcher.
- * <p>
- * By calling {@link #remove()}, this callback will be removed from any
- * {@link OnBackPressedDispatcher} it has been added to. It is strongly recommended
- * to instead disable this callback to handle temporary changes in state.
- *
- * @see ComponentActivity#getOnBackPressedDispatcher()
- */
-public abstract class OnBackPressedCallback {
-
-    private boolean mEnabled;
-    private CopyOnWriteArrayList<Cancellable> mCancellables = new CopyOnWriteArrayList<>();
-    private Consumer<Boolean> mEnabledConsumer;
-
-    /**
-     * Create a {@link OnBackPressedCallback}.
-     *
-     * @param enabled The default enabled state for this callback.
-     * @see #setEnabled(boolean)
-     */
-    public OnBackPressedCallback(boolean enabled) {
-        mEnabled = enabled;
-    }
-
-    /**
-     * Set the enabled state of the callback. Only when this callback
-     * is enabled will it receive callbacks to {@link #handleOnBackPressed()}.
-     * <p>
-     * Note that the enabled state is an additional layer on top of the
-     * {@link androidx.lifecycle.LifecycleOwner} passed to
-     * {@link OnBackPressedDispatcher#addCallback(LifecycleOwner, OnBackPressedCallback)}
-     * which controls when the callback is added and removed to the dispatcher.
-     *
-     * @param enabled whether the callback should be considered enabled
-     */
-    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
-    @MainThread
-    public final void setEnabled(boolean enabled) {
-        mEnabled = enabled;
-        if (mEnabledConsumer != null) {
-            mEnabledConsumer.accept(mEnabled);
-        }
-    }
-
-    /**
-     * Checks whether this callback should be considered enabled. Only when this callback
-     * is enabled will it receive callbacks to {@link #handleOnBackPressed()}.
-     *
-     * @return Whether this callback should be considered enabled.
-     */
-    @MainThread
-    public final boolean isEnabled() {
-        return mEnabled;
-    }
-
-    /**
-     * Removes this callback from any {@link OnBackPressedDispatcher} it is currently
-     * added to.
-     */
-    @MainThread
-    public final void remove() {
-        for (Cancellable cancellable: mCancellables) {
-            cancellable.cancel();
-        }
-    }
-
-    /**
-     * Callback for handling the {@link OnBackPressedDispatcher#onBackPressed()} event.
-     */
-    @MainThread
-    public abstract void handleOnBackPressed();
-
-    void addCancellable(@NonNull Cancellable cancellable) {
-        mCancellables.add(cancellable);
-    }
-
-    void removeCancellable(@NonNull Cancellable cancellable) {
-        mCancellables.remove(cancellable);
-    }
-
-    void setIsEnabledConsumer(@Nullable Consumer<Boolean> isEnabled) {
-        mEnabledConsumer = isEnabled;
-    }
-}
diff --git a/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt
new file mode 100644
index 0000000..67efa4b
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/OnBackPressedCallback.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+package androidx.activity
+
+import androidx.annotation.MainThread
+import androidx.annotation.OptIn
+import androidx.core.os.BuildCompat
+import androidx.core.util.Consumer
+import java.util.concurrent.CopyOnWriteArrayList
+
+/**
+ * Class for handling [OnBackPressedDispatcher.onBackPressed] callbacks without
+ * strongly coupling that implementation to a subclass of [ComponentActivity].
+ *
+ * This class maintains its own [enabled state][isEnabled]. Only when this callback
+ * is enabled will it receive callbacks to [handleOnBackPressed].
+ *
+ * Note that the enabled state is an additional layer on top of the
+ * [androidx.lifecycle.LifecycleOwner] passed to
+ * [OnBackPressedDispatcher.addCallback]
+ * which controls when the callback is added and removed to the dispatcher.
+ *
+ * By calling [remove], this callback will be removed from any
+ * [OnBackPressedDispatcher] it has been added to. It is strongly recommended
+ * to instead disable this callback to handle temporary changes in state.
+ *
+ * @param isEnabled The default enabled state for this callback.
+ *
+ * @see ComponentActivity.getOnBackPressedDispatcher
+ */
+abstract class OnBackPressedCallback(isEnabled: Boolean) {
+    /**
+     * The enabled state of the callback. Only when this callback
+     * is enabled will it receive callbacks to [handleOnBackPressed].
+     *
+     * Note that the enabled state is an additional layer on top of the
+     * [androidx.lifecycle.LifecycleOwner] passed to
+     * [OnBackPressedDispatcher.addCallback]
+     * which controls when the callback is added and removed to the dispatcher.
+     */
+    @get:MainThread
+    @set:MainThread
+    @set:OptIn(markerClass = [BuildCompat.PrereleaseSdkCheck::class])
+    var isEnabled: Boolean = isEnabled
+        set(value) {
+            field = value
+            if (enabledConsumer != null) {
+                enabledConsumer!!.accept(field)
+            }
+        }
+
+    private val cancellables = CopyOnWriteArrayList<Cancellable>()
+    private var enabledConsumer: Consumer<Boolean>? = null
+
+    /**
+     * Removes this callback from any [OnBackPressedDispatcher] it is currently
+     * added to.
+     */
+    @MainThread
+    fun remove() = cancellables.forEach { it.cancel() }
+
+    /**
+     * Callback for handling the [OnBackPressedDispatcher.onBackPressed] event.
+     */
+    @MainThread
+    abstract fun handleOnBackPressed()
+
+    @JvmName("addCancellable")
+    internal fun addCancellable(cancellable: Cancellable) {
+        cancellables.add(cancellable)
+    }
+
+    @JvmName("removeCancellable")
+    internal fun removeCancellable(cancellable: Cancellable) {
+        cancellables.remove(cancellable)
+    }
+
+    @JvmName("setIsEnabledConsumer")
+    internal fun setIsEnabledConsumer(isEnabled: Consumer<Boolean>?) {
+        enabledConsumer = isEnabled
+    }
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.kt
similarity index 66%
rename from activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java
rename to activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.kt
index fde2497..1c500f4 100644
--- a/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.kt
@@ -13,23 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.activity.result
 
-
-package androidx.activity.result;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
+import android.app.Activity
 
 /**
- * A type-safe callback to be called when an {@link Activity#onActivityResult activity result}
+ * A type-safe callback to be called when an [activity result][Activity.onActivityResult]
  * is available.
- *
- * @param <O> result type
  */
-public interface ActivityResultCallback<O> {
-
+fun interface ActivityResultCallback<O> {
     /**
      * Called when result is available
      */
-    void onActivityResult(@SuppressLint("UnknownNullness") O result);
+    fun onActivityResult(result: O)
 }
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index c188aea..afb0b80 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -25,7 +25,7 @@
     implementation("androidx.collection:collection:1.0.0")
     api("androidx.cursoradapter:cursoradapter:1.0.0")
     api("androidx.activity:activity:1.6.0")
-    api("androidx.fragment:fragment:1.3.6")
+    api("androidx.fragment:fragment:1.5.4")
     api(project(":appcompat:appcompat-resources"))
     api("androidx.drawerlayout:drawerlayout:1.0.0")
     implementation("androidx.lifecycle:lifecycle-runtime:2.5.1")
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt
new file mode 100644
index 0000000..73d01c3
--- /dev/null
+++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/PerfettoTraceTest.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.benchmark
+
+import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
+import androidx.benchmark.perfetto.PerfettoHelper
+import androidx.benchmark.perfetto.PerfettoTrace
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import kotlin.test.assertFailsWith
+import kotlin.test.assertNotNull
+import kotlin.test.fail
+import org.junit.Assume.assumeTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalPerfettoCaptureApi::class)
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = 21)
+class PerfettoTraceTest {
+    @Test
+    fun record_basic() {
+        assumeTrue(PerfettoHelper.isAbiSupported())
+        var perfettoTrace: PerfettoTrace? = null
+        PerfettoTrace.record(
+            fileLabel = "testTrace",
+            traceCallback = { trace ->
+                perfettoTrace = trace
+            }
+        ) {
+            // noop
+        }
+        assertNotNull(perfettoTrace)
+        assert(perfettoTrace!!.path.matches(Regex(".*/testTrace_[0-9-]+.perfetto-trace"))) {
+            "$perfettoTrace didn't match!"
+        }
+    }
+    @Test
+    fun record_reentrant() {
+        assumeTrue(PerfettoHelper.isAbiSupported())
+        var perfettoTrace: PerfettoTrace? = null
+        PerfettoTrace.record(
+            fileLabel = "outer",
+            traceCallback = { trace ->
+                perfettoTrace = trace
+            }
+        ) {
+            // tracing while tracing should fail
+            assertFailsWith<IllegalStateException> {
+                PerfettoTrace.record(
+                    fileLabel = "inner",
+                    traceCallback = { _ ->
+                        fail("inner trace should not complete / record")
+                    }
+                ) {
+                    // noop
+                }
+            }
+        }
+        assertNotNull(perfettoTrace)
+    }
+}
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 58a1723..198ab7a 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
@@ -39,6 +39,17 @@
         }
     }
 
+    companion object {
+        val inUseLock = Object()
+
+        /**
+         * Prevents re-entrance of perfetto trace capture, as it doesn't handle this correctly
+         *
+         * (Single file output location, process cleanup, etc.)
+         */
+        var inUse = false
+    }
+
     @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
     private fun start(
         appTagPackages: List<String>,
@@ -63,23 +74,6 @@
     }
 
     @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
-    private fun stop(benchmarkName: String, iteration: Int?): String {
-        val traceName: String
-        val reportKey: String
-        if (iteration != null) {
-            val iterString = iteration.toString().padStart(3, '0')
-            traceName = "${benchmarkName}_iter${iterString}_${dateToFileName()}.perfetto-trace"
-            reportKey = "perfetto_trace_$iterString"
-        } else {
-            traceName = "${benchmarkName}_${dateToFileName()}.perfetto-trace"
-            reportKey = "perfetto_trace"
-        }
-        return Outputs.writeFile(fileName = traceName, reportKey = reportKey) {
-            capture!!.stop(it.absolutePath)
-        }
-    }
-
-    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
     private fun stop(traceLabel: String): String {
         return Outputs.writeFile(
             fileName = "${traceLabel}_${dateToFileName()}.perfetto-trace",
@@ -102,6 +96,17 @@
             return null
         }
 
+        synchronized(inUseLock) {
+            if (inUse) {
+                throw IllegalStateException(
+                    "Reentrant Perfetto Tracing is not supported." +
+                        " This means you cannot use more than one of" +
+                        " BenchmarkRule/MacrobenchmarkRule/PerfettoTraceRule/PerfettoTrace.record" +
+                        " together."
+                )
+            }
+            inUse = true
+        }
         // Prior to Android 11 (R), a shell property must be set to enable perfetto tracing, see
         // https://perfetto.dev/docs/quickstart/android-tracing#starting-the-tracing-services
         val propOverride = if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
@@ -122,6 +127,9 @@
             return path
         } finally {
             propOverride?.resetIfOverridden()
+            synchronized(inUseLock) {
+                inUse = false
+            }
         }
     }
 }
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoHelper.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoHelper.kt
index 4d149d2..3e74e58 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoHelper.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoHelper.kt
@@ -375,11 +375,8 @@
 
         fun isAbiSupported(): Boolean {
             Log.d(LOG_TAG, "Supported ABIs: ${Build.SUPPORTED_ABIS.joinToString()}")
-            // Cuttlefish is x86 but claims support for x86_64
-            return !Build.MODEL.contains("Cuttlefish") && ( // b/204892353
-                Build.SUPPORTED_64_BIT_ABIS.any { SUPPORTED_64_ABIS.contains(it) } ||
-                    Build.SUPPORTED_32_BIT_ABIS.any { SUPPORTED_32_ABIS.contains(it) }
-                )
+            return Build.SUPPORTED_64_BIT_ABIS.any { SUPPORTED_64_ABIS.contains(it) } ||
+                Build.SUPPORTED_32_BIT_ABIS.any { SUPPORTED_32_ABIS.contains(it) }
         }
 
         @get:TestOnly
@@ -399,6 +396,8 @@
                     // supported by a device. That is why we need to search from most specific to
                     // least specific. For e.g. emulators claim to support aarch64, when in reality
                     // they can only support x86 or x86_64.
+                    // Note: Cuttlefish is x86 but claims support for x86_64
+                    Build.MODEL.contains("Cuttlefish") -> "x86" // TODO(204892353): handle properly
                     Build.SUPPORTED_64_BIT_ABIS.any { it.startsWith("x86_64") } -> "x86_64"
                     Build.SUPPORTED_32_BIT_ABIS.any { it.startsWith("x86") } -> "x86"
                     Build.SUPPORTED_64_BIT_ABIS.any { it.startsWith("arm64") } -> "aarch64"
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 33bdde3..98ed9d8 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
@@ -35,6 +35,15 @@
         /**
          * Record a Perfetto System Trace for the specified [block].
          *
+         * ```
+         * PerfettoTrace.record("myTrace") {
+         *     // 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
diff --git a/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkPlugin.kt b/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkPlugin.kt
index e98a49b..a016541 100644
--- a/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkPlugin.kt
+++ b/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkPlugin.kt
@@ -20,6 +20,8 @@
 import java.util.concurrent.atomic.AtomicBoolean
 import org.gradle.api.Plugin
 import org.gradle.api.Project
+import org.gradle.api.file.Directory
+import org.gradle.api.provider.Provider
 import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
 import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
@@ -109,15 +111,47 @@
             it.xcResultPath.set(runDarwinBenchmarks.flatMap { task ->
                 task.xcResultPath
             })
+            val resultFileName = "${extension.xcodeProjectName.get()}-benchmark-result.json"
             it.outputFile.set(
                 project.layout.buildDirectory.file(
-                    "${extension.xcodeProjectName.get()}-benchmark-result.json"
+                    resultFileName
                 )
             )
+            val provider = project.benchmarksDistributionDirectory(extension)
+            val resultFile = provider.map { directory ->
+                directory.file(resultFileName)
+            }
+            it.distFile.set(resultFile)
+        }
+    }
+
+    private fun Project.benchmarksDistributionDirectory(
+        extension: DarwinBenchmarkPluginExtension
+    ): Provider<Directory> {
+        val distProvider = project.distributionDirectory()
+        val benchmarksDirProvider = distProvider.flatMap { distDir ->
+            extension.xcodeProjectName.map { projectName ->
+                val projectPath = project.path.replace(":", "/")
+                val benchmarksDirectory = File(distDir, DARWIN_BENCHMARKS_DIR)
+                File(benchmarksDirectory, "$projectPath/$projectName")
+            }
+        }
+        return project.layout.dir(benchmarksDirProvider)
+    }
+
+    private fun Project.distributionDirectory(): Provider<File> {
+        // We want to write metrics to library metrics specific location
+        // Context: b/257326666
+        return providers.environmentVariable(DIST_DIR).map { value ->
+            File(value, LIBRARY_METRICS)
         }
     }
 
     private companion object {
+        // Environment variables
+        const val DIST_DIR = "DIST_DIR"
+        const val LIBRARY_METRICS = "librarymetrics"
+        const val DARWIN_BENCHMARKS_DIR = "darwinBenchmarks"
         // Gradle Properties
         const val XCODEGEN_DOWNLOAD_URI = "androidx.benchmark.darwin.xcodeGenDownloadUri"
 
diff --git a/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkResultsTask.kt b/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkResultsTask.kt
index b95352d..7d4136d 100644
--- a/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkResultsTask.kt
+++ b/benchmark/benchmark-darwin-gradle-plugin/src/main/kotlin/androidx/benchmark/darwin/gradle/DarwinBenchmarkResultsTask.kt
@@ -27,6 +27,7 @@
 import org.gradle.api.file.RegularFileProperty
 import org.gradle.api.tasks.CacheableTask
 import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.Optional
 import org.gradle.api.tasks.OutputFile
 import org.gradle.api.tasks.PathSensitive
 import org.gradle.api.tasks.PathSensitivity
@@ -44,6 +45,10 @@
     @get:OutputFile
     abstract val outputFile: RegularFileProperty
 
+    @get:OutputFile
+    @get:Optional
+    abstract val distFile: RegularFileProperty
+
     @TaskAction
     fun benchmarkResults() {
         val xcResultFile = xcResultPath.get().asFile
@@ -68,5 +73,10 @@
             .toJson(metrics)
 
         outputFile.get().asFile.writeText(output)
+
+        // Add output to the DIST_DIR when specified
+        if (distFile.isPresent) {
+            distFile.get().asFile.writeText(output)
+        }
     }
 }
diff --git a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/PerfettoTraceRule.kt b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/PerfettoTraceRule.kt
index a39994d..aa35558 100644
--- a/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/PerfettoTraceRule.kt
+++ b/benchmark/benchmark-junit4/src/main/java/androidx/benchmark/junit4/PerfettoTraceRule.kt
@@ -29,6 +29,17 @@
 /**
  * Add this rule to record a Perfetto trace for each test on Android Lollipop (API 21)+ devices.
  *
+ * ```
+ * @RunWith(AndroidJUnit4::class)
+ * class PerfettoOverheadBenchmark {
+ *     // traces all tests in file
+ *     @get:Rule
+ *     val perfettoRule = PerfettoTraceRule()
+ *
+ *     @Test
+ *     fun test() {}
+ * }
+ * ```
  * Captured traces can be observed through any of:
  * * Android Studio trace linking under `Benchmark` in test output tab
  * * The optional `traceCallback` parameter
@@ -44,6 +55,9 @@
  * ```
  * > adb pull /storage/emulated/0/Android/data/mypackage.test/files/PerfettoCaptureTest.trace
  * ```
+ *
+ * Reentrant Perfetto trace capture is not supported, so this API may not be combined with
+ * `BenchmarkRule`, `MacrobenchmarkRule`, or `PerfettoTrace.record`.
  */
 @ExperimentalPerfettoCaptureApi
 class PerfettoTraceRule(
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 080c259..7b09cb7 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
@@ -44,7 +44,7 @@
  *
  *     @Test
  *     fun startup() = baselineProfileRule.collectBaselineProfile(
- *         packageName = "com.example.app"
+ *         packageName = "com.example.my.application.id"
  *     ) {
  *         pressHome()
  *         // This block defines the app's critical user journey. Here we are
@@ -78,10 +78,12 @@
     }
 
     /**
-     * Collects baseline profiles for a critical user journey.
-     * @param packageName Package name of the app for which profiles are to be generated.
+     * Collects baseline profiles for a set of interactions with the application
+     * @param packageName ApplicationId / Application manifest package name of the app for
+     *   which profiles are generated.
      * @param packageFilters List of package names to use as a filter for the generated profiles.
-     *  By default no filters are applied. Note that this works only when the code is not obfuscated.
+     *  By default no filters are applied. Note that this works only when the code is not
+     *  obfuscated.
      * @param [profileBlock] defines the critical user journey.
      */
     @JvmOverloads
diff --git a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/MacrobenchmarkRule.kt b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/MacrobenchmarkRule.kt
index f14b0bd9..d8a01b7 100644
--- a/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/MacrobenchmarkRule.kt
+++ b/benchmark/benchmark-macro-junit4/src/main/java/androidx/benchmark/macro/junit4/MacrobenchmarkRule.kt
@@ -40,7 +40,7 @@
  *
  *     @Test
  *     fun startup() = benchmarkRule.measureRepeated(
- *         packageName = "mypackage.myapp",
+ *         packageName = "com.example.my.application.id"
  *         metrics = listOf(StartupTimingMetric()),
  *         iterations = 5,
  *         startupMode = StartupMode.COLD,
@@ -70,13 +70,14 @@
      *     compile(compilationMode)
      *     repeat(iterations) {
      *         setupBlock()
-     *         captureTrace {
+     *         captureTraceAndMetrics {
      *             measureBlock()
      *         }
      *     }
      * ```
      *
-     * @param packageName Package name of the app being measured.
+     * @param packageName ApplicationId / Application manifest package name of the app for
+     *   which profiles are generated.
      * @param metrics List of metrics to measure.
      * @param compilationMode Mode of compilation used before capturing measurement, such as
      * [CompilationMode.Partial], defaults to [CompilationMode.DEFAULT].
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 1db82176..de94880 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
@@ -17,6 +17,7 @@
 package androidx.benchmark.macro
 
 import androidx.annotation.RequiresApi
+import androidx.benchmark.DeviceInfo
 import androidx.benchmark.perfetto.PerfettoHelper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -29,12 +30,19 @@
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
 import kotlin.test.assertTrue
+import org.junit.Assume.assumeFalse
+import org.junit.Before
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 @OptIn(ExperimentalMacrobenchmarkApi::class)
 class MacrobenchmarkTest {
 
+    @Before
+    fun setUp() {
+        assumeFalse(DeviceInfo.isEmulator)
+    }
+
     @Test
     fun macrobenchmarkWithStartupMode_emptyMetricList() {
         val exception = assertFailsWith<IllegalArgumentException> {
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 b3561e8..4deb295 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
@@ -20,6 +20,7 @@
 import android.content.Intent
 import android.os.Build
 import androidx.annotation.RequiresApi
+import androidx.benchmark.DeviceInfo
 import androidx.benchmark.Outputs
 import androidx.benchmark.macro.perfetto.PerfettoTraceProcessor
 import androidx.benchmark.perfetto.PerfettoCaptureWrapper
@@ -37,6 +38,7 @@
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
+import org.junit.Assume.assumeFalse
 import org.junit.Assume.assumeTrue
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -182,12 +184,14 @@
     @LargeTest
     @Test
     fun startupInAppNav_immediate() {
+        assumeFalse(DeviceInfo.isEmulator) // TODO(b/255754739): address failures on Cuttlefish
         validateStartup_fullyDrawn(delayMs = 0, useInAppNav = true)
     }
 
     @LargeTest
     @Test
     fun startupInAppNav_fullyDrawn() {
+        assumeFalse(DeviceInfo.isEmulator) // TODO(b/255754739): address failures on Cuttlefish
         validateStartup_fullyDrawn(delayMs = 100, useInAppNav = true)
     }
 
diff --git a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
index db37987..296d682 100644
--- a/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
+++ b/benchmark/benchmark-macro/src/main/java/androidx/benchmark/macro/MacrobenchmarkScope.kt
@@ -36,7 +36,7 @@
  */
 public class MacrobenchmarkScope(
     /**
-     * Package name of the app being tested.
+     * ApplicationId / Package name of the app being tested.
      */
     val packageName: String,
     /**
diff --git a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoOverheadBenchmark.kt b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoOverheadBenchmark.kt
index cc8012b..449e495 100644
--- a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoOverheadBenchmark.kt
+++ b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoOverheadBenchmark.kt
@@ -17,11 +17,10 @@
 package androidx.benchmark.benchmark
 
 import androidx.benchmark.junit4.BenchmarkRule
-import androidx.benchmark.junit4.PerfettoTraceRule
 import androidx.benchmark.junit4.measureRepeated
-import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
+import androidx.test.platform.app.InstrumentationRegistry
 import androidx.tracing.Trace
 import androidx.tracing.trace
 import org.junit.Rule
@@ -31,12 +30,11 @@
 @LargeTest
 @RunWith(AndroidJUnit4::class)
 class PerfettoOverheadBenchmark {
-    @get:Rule
-    val benchmarkRule = BenchmarkRule()
+    private val targetPackage =
+        InstrumentationRegistry.getInstrumentation().targetContext.packageName
 
-    @OptIn(ExperimentalPerfettoCaptureApi::class)
     @get:Rule
-    val mPerfettoTraceRule = PerfettoTraceRule()
+    val benchmarkRule = BenchmarkRule(packages = listOf(targetPackage))
 
     /**
      * Empty baseline, no tracing. Expect similar results to [TrivialJavaBenchmark.nothing].
diff --git a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoSdkOverheadBenchmark.kt b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoSdkOverheadBenchmark.kt
index 18de45a..0da127f 100644
--- a/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoSdkOverheadBenchmark.kt
+++ b/benchmark/benchmark/src/androidTest/java/androidx/benchmark/benchmark/PerfettoSdkOverheadBenchmark.kt
@@ -18,9 +18,7 @@
 
 import android.os.Build
 import androidx.benchmark.junit4.BenchmarkRule
-import androidx.benchmark.junit4.PerfettoTraceRule
 import androidx.benchmark.junit4.measureRepeated
-import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
 import androidx.benchmark.perfetto.PerfettoCapture
 import androidx.benchmark.perfetto.PerfettoHelper.Companion.isAbiSupported
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -50,10 +48,6 @@
     @get:Rule
     val benchmarkRule = BenchmarkRule(packages = listOf(targetPackage))
 
-    @OptIn(ExperimentalPerfettoCaptureApi::class)
-    @get:Rule
-    val mPerfettoTraceRule = PerfettoTraceRule()
-
     private val testData = Array(50_000) { UUID.randomUUID().toString() }
 
     @Before
diff --git a/biometric/biometric/src/main/res/values-da/strings.xml b/biometric/biometric/src/main/res/values-da/strings.xml
index 41fe471..b08401b 100644
--- a/biometric/biometric/src/main/res/values-da/strings.xml
+++ b/biometric/biometric/src/main/res/values-da/strings.xml
@@ -17,11 +17,11 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="fingerprint_dialog_touch_sensor" msgid="1072308044213194243">"Sæt finger på fingeraftrykslæser"</string>
+    <string name="fingerprint_dialog_touch_sensor" msgid="1072308044213194243">"Sæt finger på fingeraftrykssensor"</string>
     <string name="fingerprint_not_recognized" msgid="3873359464293253009">"Ikke genkendt"</string>
     <string name="fingerprint_error_hw_not_available" msgid="8216738333501875566">"Hardwaren til fingeraftryk er ikke tilgængelig."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7520712796891883488">"Der er ikke registreret nogen fingeraftryk."</string>
-    <string name="fingerprint_error_hw_not_present" msgid="6306988885793029438">"Denne enhed har ingen fingeraftrykslæser"</string>
+    <string name="fingerprint_error_hw_not_present" msgid="6306988885793029438">"Denne enhed har ingen fingeraftrykssensor"</string>
     <string name="fingerprint_error_user_canceled" msgid="7627716295344353987">"Fingeraftrykshandlingen blev annulleret af brugeren."</string>
     <string name="fingerprint_error_lockout" msgid="7291787166416782245">"Der var for mange forsøg Prøv igen senere."</string>
     <string name="default_error_msg" msgid="4776854077120974966">"Ukendt fejl"</string>
diff --git a/browser/browser/api/current.txt b/browser/browser/api/current.txt
index f084924..0598270 100644
--- a/browser/browser/api/current.txt
+++ b/browser/browser/api/current.txt
@@ -73,7 +73,7 @@
     ctor public CustomTabsCallback();
     method public void extraCallback(String, android.os.Bundle?);
     method public android.os.Bundle? extraCallbackWithResult(String, android.os.Bundle?);
-    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
+    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, @Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
     method public void onMessageChannelReady(android.os.Bundle?);
     method public void onNavigationEvent(int, android.os.Bundle?);
     method public void onPostMessage(String, android.os.Bundle?);
@@ -118,7 +118,7 @@
     field public static final int COLOR_SCHEME_LIGHT = 1; // 0x1
     field public static final int COLOR_SCHEME_SYSTEM = 0; // 0x0
     field public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
-    field public static final String EXTRA_ACTIVITY_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_RESIZE_BEHAVIOR";
+    field public static final String EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_HEIGHT_RESIZE_BEHAVIOR";
     field public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
     field public static final String EXTRA_CLOSE_BUTTON_POSITION = "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION";
     field public static final String EXTRA_COLOR_SCHEME = "androidx.browser.customtabs.extra.COLOR_SCHEME";
diff --git a/browser/browser/api/public_plus_experimental_current.txt b/browser/browser/api/public_plus_experimental_current.txt
index f084924..0598270 100644
--- a/browser/browser/api/public_plus_experimental_current.txt
+++ b/browser/browser/api/public_plus_experimental_current.txt
@@ -73,7 +73,7 @@
     ctor public CustomTabsCallback();
     method public void extraCallback(String, android.os.Bundle?);
     method public android.os.Bundle? extraCallbackWithResult(String, android.os.Bundle?);
-    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
+    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, @Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
     method public void onMessageChannelReady(android.os.Bundle?);
     method public void onNavigationEvent(int, android.os.Bundle?);
     method public void onPostMessage(String, android.os.Bundle?);
@@ -118,7 +118,7 @@
     field public static final int COLOR_SCHEME_LIGHT = 1; // 0x1
     field public static final int COLOR_SCHEME_SYSTEM = 0; // 0x0
     field public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
-    field public static final String EXTRA_ACTIVITY_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_RESIZE_BEHAVIOR";
+    field public static final String EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_HEIGHT_RESIZE_BEHAVIOR";
     field public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
     field public static final String EXTRA_CLOSE_BUTTON_POSITION = "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION";
     field public static final String EXTRA_COLOR_SCHEME = "androidx.browser.customtabs.extra.COLOR_SCHEME";
diff --git a/browser/browser/api/restricted_current.txt b/browser/browser/api/restricted_current.txt
index 09759da..de4bb0c 100644
--- a/browser/browser/api/restricted_current.txt
+++ b/browser/browser/api/restricted_current.txt
@@ -84,7 +84,7 @@
     ctor public CustomTabsCallback();
     method public void extraCallback(String, android.os.Bundle?);
     method public android.os.Bundle? extraCallbackWithResult(String, android.os.Bundle?);
-    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
+    method public void onActivityResized(@Dimension(unit=androidx.annotation.Dimension.PX) int, @Dimension(unit=androidx.annotation.Dimension.PX) int, android.os.Bundle);
     method public void onMessageChannelReady(android.os.Bundle?);
     method public void onNavigationEvent(int, android.os.Bundle?);
     method public void onPostMessage(String, android.os.Bundle?);
@@ -129,7 +129,7 @@
     field public static final int COLOR_SCHEME_LIGHT = 1; // 0x1
     field public static final int COLOR_SCHEME_SYSTEM = 0; // 0x0
     field public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
-    field public static final String EXTRA_ACTIVITY_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_RESIZE_BEHAVIOR";
+    field public static final String EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR = "androidx.browser.customtabs.extra.ACTIVITY_HEIGHT_RESIZE_BEHAVIOR";
     field public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
     field public static final String EXTRA_CLOSE_BUTTON_POSITION = "androidx.browser.customtabs.extra.CLOSE_BUTTON_POSITION";
     field public static final String EXTRA_COLOR_SCHEME = "androidx.browser.customtabs.extra.COLOR_SCHEME";
diff --git a/browser/browser/src/androidTest/java/androidx/browser/customtabs/CustomTabsCallbackTest.java b/browser/browser/src/androidTest/java/androidx/browser/customtabs/CustomTabsCallbackTest.java
index 2caee24..6df7e8b 100644
--- a/browser/browser/src/androidTest/java/androidx/browser/customtabs/CustomTabsCallbackTest.java
+++ b/browser/browser/src/androidTest/java/androidx/browser/customtabs/CustomTabsCallbackTest.java
@@ -45,7 +45,7 @@
 
     @Test
     public void testOnActivityResized() throws Throwable {
-        mToken.getCallback().onActivityResized(75239, new Bundle());
+        mToken.getCallback().onActivityResized(75239, 1200, new Bundle());
         assertTrue(mCallback.hasActivityBeenResized());
     }
 }
diff --git a/browser/browser/src/androidTest/java/androidx/browser/customtabs/TestCustomTabsCallback.java b/browser/browser/src/androidTest/java/androidx/browser/customtabs/TestCustomTabsCallback.java
index 3363e0f..9293212 100644
--- a/browser/browser/src/androidTest/java/androidx/browser/customtabs/TestCustomTabsCallback.java
+++ b/browser/browser/src/androidTest/java/androidx/browser/customtabs/TestCustomTabsCallback.java
@@ -70,8 +70,8 @@
         }
 
         @Override
-        public void onActivityResized(int size, Bundle extras) throws RemoteException {
-            TestCustomTabsCallback.this.onActivityResized(size, extras);
+        public void onActivityResized(int height, int width, Bundle extras) throws RemoteException {
+            TestCustomTabsCallback.this.onActivityResized(height, width, extras);
         }
     };
 
@@ -104,7 +104,7 @@
     }
 
     @Override
-    public void onActivityResized(int size, Bundle extras) {
+    public void onActivityResized(int height, int width, @NonNull Bundle extras) {
         mOnResizedReceived = true;
     }
 
diff --git a/browser/browser/src/main/aidl/android/support/customtabs/ICustomTabsCallback.aidl b/browser/browser/src/main/aidl/android/support/customtabs/ICustomTabsCallback.aidl
index 38bb3e1..951e8ee 100644
--- a/browser/browser/src/main/aidl/android/support/customtabs/ICustomTabsCallback.aidl
+++ b/browser/browser/src/main/aidl/android/support/customtabs/ICustomTabsCallback.aidl
@@ -29,5 +29,5 @@
     void onPostMessage(String message, in Bundle extras) = 4;
     void onRelationshipValidationResult(int relation, in Uri origin, boolean result, in Bundle extras) = 5;
     Bundle extraCallbackWithResult(String callbackName, in Bundle args) = 6;
-    void onActivityResized(int size, in Bundle extras) = 7;
+    void onActivityResized(int height, int width, in Bundle extras) = 7;
 }
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsCallback.java b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsCallback.java
index 3ac0a3c..a111f89 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsCallback.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsCallback.java
@@ -161,12 +161,12 @@
             boolean result, @Nullable Bundle extras) {}
 
     /**
-     * Called when the tab is resized in its height. This is applicable when users resize a tab
-     * launched with {@link CustomTabsIntent#ACTIVITY_HEIGHT_ADJUSTABLE} for the {@link
-     * CustomTabsIntent#ActivityResizeBehavior}.
+     * Called when the tab is resized.
      *
-     * @param size The updated height in px.
+     * @param height The updated height in px.
+     * @param width The updated width in px.
      * @param extras Reserved for future use.
      */
-    public void onActivityResized(@Dimension(unit = PX) int size, @NonNull Bundle extras) {}
+    public void onActivityResized(@Dimension(unit = PX) int height,
+            @Dimension(unit = PX) int width, @NonNull Bundle extras) {}
 }
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
index e45d218..36d1393 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsClient.java
@@ -398,13 +398,14 @@
             }
 
             @Override
-            public void onActivityResized(final int size, final @Nullable Bundle extras)
+            public void onActivityResized(final int height, final int width,
+                    final @Nullable Bundle extras)
                     throws RemoteException {
                 if (callback == null) return;
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
-                        callback.onActivityResized(size, extras);
+                        callback.onActivityResized(height, width, extras);
                     }
                 });
             }
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java
index 9792aff..53c77a0 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsIntent.java
@@ -357,24 +357,24 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef({ACTIVITY_HEIGHT_DEFAULT, ACTIVITY_HEIGHT_ADJUSTABLE, ACTIVITY_HEIGHT_FIXED})
     @Retention(RetentionPolicy.SOURCE)
-    public @interface ActivityResizeBehavior {
+    public @interface ActivityHeightResizeBehavior {
     }
 
     /**
-     * Applies the default resize behavior for the Custom Tab Activity when it behaves as a
+     * Applies the default height resize behavior for the Custom Tab Activity when it behaves as a
      * bottom sheet.
      */
     public static final int ACTIVITY_HEIGHT_DEFAULT = 0;
 
     /**
-     * The Custom Tab Activity, when it behaves as a bottom sheet, can be manually resized by the
-     * user.
+     * The Custom Tab Activity, when it behaves as a bottom sheet, can have its height manually
+     * resized by the user.
      */
     public static final int ACTIVITY_HEIGHT_ADJUSTABLE = 1;
 
     /**
-     * The Custom Tab Activity, when it behaves as a bottom sheet, cannot be manually resized by
-     * the user.
+     * The Custom Tab Activity, when it behaves as a bottom sheet, cannot have its height manually
+     * resized by the user.
      */
     public static final int ACTIVITY_HEIGHT_FIXED = 2;
 
@@ -385,12 +385,12 @@
 
     /**
      * Extra that, if set in combination with
-     * {@link CustomTabsIntent#EXTRA_INITIAL_ACTIVITY_HEIGHT_PX}, defines the resize behavior of
-     * the Custom Tab Activity when it behaves as a bottom sheet.
+     * {@link CustomTabsIntent#EXTRA_INITIAL_ACTIVITY_HEIGHT_PX}, defines the height resize
+     * behavior of the Custom Tab Activity when it behaves as a bottom sheet.
      * Default is {@link CustomTabsIntent#ACTIVITY_HEIGHT_DEFAULT}.
      */
-    public static final String EXTRA_ACTIVITY_RESIZE_BEHAVIOR =
-            "androidx.browser.customtabs.extra.ACTIVITY_RESIZE_BEHAVIOR";
+    public static final String EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR =
+            "androidx.browser.customtabs.extra.ACTIVITY_HEIGHT_RESIZE_BEHAVIOR";
 
     /**
      * Extra that sets the toolbar's top corner radii in dp. This will only have
@@ -980,27 +980,28 @@
          * The Custom Tab will behave as a bottom sheet.
          *
          * @param initialHeightPx The Custom Tab Activity's initial height in pixels.
-         * @param activityResizeBehavior Desired height behavior.
+         * @param activityHeightResizeBehavior Desired height behavior.
          * @see CustomTabsIntent#EXTRA_INITIAL_ACTIVITY_HEIGHT_PX
-         * @see CustomTabsIntent#EXTRA_ACTIVITY_RESIZE_BEHAVIOR
+         * @see CustomTabsIntent#EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR
          * @see CustomTabsIntent#ACTIVITY_HEIGHT_DEFAULT
          * @see CustomTabsIntent#ACTIVITY_HEIGHT_ADJUSTABLE
          * @see CustomTabsIntent#ACTIVITY_HEIGHT_FIXED
          */
         @NonNull
         public Builder setInitialActivityHeightPx(@Dimension(unit = PX) int initialHeightPx,
-                @ActivityResizeBehavior int activityResizeBehavior) {
+                @ActivityHeightResizeBehavior int activityHeightResizeBehavior) {
             if (initialHeightPx <= 0) {
                 throw new IllegalArgumentException("Invalid value for the initialHeightPx "
                         + "argument");
             }
-            if (activityResizeBehavior < 0 || activityResizeBehavior > ACTIVITY_HEIGHT_MAX) {
-                throw new IllegalArgumentException("Invalid value for the activityResizeBehavior "
-                        + "argument");
+            if (activityHeightResizeBehavior < 0
+                    || activityHeightResizeBehavior > ACTIVITY_HEIGHT_MAX) {
+                throw new IllegalArgumentException(
+                        "Invalid value for the activityHeightResizeBehavior argument");
             }
 
             mIntent.putExtra(EXTRA_INITIAL_ACTIVITY_HEIGHT_PX, initialHeightPx);
-            mIntent.putExtra(EXTRA_ACTIVITY_RESIZE_BEHAVIOR, activityResizeBehavior);
+            mIntent.putExtra(EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR, activityHeightResizeBehavior);
             return this;
         }
 
@@ -1184,14 +1185,14 @@
      * @param intent Intent to retrieve the resize behavior from.
      * @return The resize behavior. If {@link CustomTabsIntent#EXTRA_INITIAL_ACTIVITY_HEIGHT_PX}
      *         is not set as part of the same intent, the value has no effect.
-     * @see CustomTabsIntent#EXTRA_ACTIVITY_RESIZE_BEHAVIOR
+     * @see CustomTabsIntent#EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR
      * @see CustomTabsIntent#ACTIVITY_HEIGHT_DEFAULT
      * @see CustomTabsIntent#ACTIVITY_HEIGHT_ADJUSTABLE
      * @see CustomTabsIntent#ACTIVITY_HEIGHT_FIXED
      */
-    @ActivityResizeBehavior
+    @ActivityHeightResizeBehavior
     public static int getActivityResizeBehavior(@NonNull Intent intent) {
-        return intent.getIntExtra(EXTRA_ACTIVITY_RESIZE_BEHAVIOR,
+        return intent.getIntExtra(EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR,
                 CustomTabsIntent.ACTIVITY_HEIGHT_DEFAULT);
     }
 
diff --git a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
index e495fc9..435e242 100644
--- a/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
+++ b/browser/browser/src/main/java/androidx/browser/customtabs/CustomTabsSessionToken.java
@@ -74,7 +74,7 @@
                 Uri requestedOrigin, boolean result, Bundle extras) {}
 
         @Override
-        public void onActivityResized(int size, Bundle extras) {}
+        public void onActivityResized(int height, int width, Bundle extras) {}
 
         @Override
         public IBinder asBinder() {
@@ -191,9 +191,9 @@
 
             @SuppressWarnings("NullAway")  // TODO: b/142938599
             @Override
-            public void onActivityResized(int size, @NonNull Bundle extras) {
+            public void onActivityResized(int height, int width, @NonNull Bundle extras) {
                 try {
-                    mCallbackBinder.onActivityResized(size, extras);
+                    mCallbackBinder.onActivityResized(height, width, extras);
                 } catch (RemoteException e) {
                     Log.e(TAG, "RemoteException during ICustomTabsCallback transaction");
                 }
diff --git a/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java b/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
index 18e3aa6..1bba7b6 100644
--- a/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
+++ b/browser/browser/src/test/java/androidx/browser/customtabs/CustomTabsIntentTest.java
@@ -157,7 +157,7 @@
     }
 
     @Test
-    public void testActivityInitialFixedResizeBehavior() {
+    public void testActivityInitialFixedHeightResizeBehavior() {
         int heightFixedResizeBehavior = CustomTabsIntent.ACTIVITY_HEIGHT_FIXED;
         int initialActivityHeight = 200;
 
@@ -166,9 +166,10 @@
                 .build()
                 .intent;
 
-        assertEquals("The value of EXTRA_ACTIVITY_FIXED_HEIGHT should be ACTIVITY_HEIGHT_FIXED.",
+        assertEquals("The value of EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR should be "
+                        + "ACTIVITY_HEIGHT_FIXED.",
                 heightFixedResizeBehavior,
-                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_RESIZE_BEHAVIOR,
+                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR,
                         CustomTabsIntent.ACTIVITY_HEIGHT_DEFAULT));
         assertEquals("The height should be the same as the one that was set.",
                 initialActivityHeight,
@@ -182,7 +183,7 @@
     }
 
     @Test
-    public void testActivityInitialAdjustableResizeBehavior() {
+    public void testActivityInitialAdjustableHeightResizeBehavior() {
         int heightAdjustableResizeBehavior = CustomTabsIntent.ACTIVITY_HEIGHT_ADJUSTABLE;
         int initialActivityHeight = 200;
 
@@ -191,10 +192,10 @@
                 .build()
                 .intent;
 
-        assertEquals("The value of EXTRA_ACTIVITY_FIXED_HEIGHT should be "
+        assertEquals("The value of EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR should be "
                         + "ACTIVITY_HEIGHT_ADJUSTABLE.",
                 heightAdjustableResizeBehavior,
-                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_RESIZE_BEHAVIOR,
+                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR,
                         CustomTabsIntent.ACTIVITY_HEIGHT_DEFAULT));
         assertEquals("The height should be the same as the one that was set.",
                 initialActivityHeight,
@@ -220,10 +221,10 @@
         assertEquals("The height should be the same as the one that was set.",
                 initialActivityHeight,
                 intent.getIntExtra(CustomTabsIntent.EXTRA_INITIAL_ACTIVITY_HEIGHT_PX, 0));
-        assertEquals("The value of EXTRA_ACTIVITY_RESIZE_BEHAVIOR should be "
+        assertEquals("The value of EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR should be "
                         + "ACTIVITY_HEIGHT_DEFAULT.",
                 defaultResizeBehavior,
-                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_RESIZE_BEHAVIOR,
+                intent.getIntExtra(CustomTabsIntent.EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR,
                         CustomTabsIntent.ACTIVITY_HEIGHT_FIXED));
         assertEquals("The height returned by the getter should be the same.",
                 initialActivityHeight,
@@ -242,8 +243,8 @@
 
         assertFalse("The EXTRA_INITIAL_ACTIVITY_HEIGHT_PX should not be set.",
                 intent.hasExtra(CustomTabsIntent.EXTRA_INITIAL_ACTIVITY_HEIGHT_PX));
-        assertFalse("The EXTRA_ACTIVITY_RESIZE_BEHAVIOR should not be set.",
-                intent.hasExtra(CustomTabsIntent.EXTRA_ACTIVITY_RESIZE_BEHAVIOR));
+        assertFalse("The EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR should not be set.",
+                intent.hasExtra(CustomTabsIntent.EXTRA_ACTIVITY_HEIGHT_RESIZE_BEHAVIOR));
         assertEquals("The getter should return the default value.",
                 defaultInitialActivityHeight,
                 CustomTabsIntent.getInitialActivityHeightPx(intent));
diff --git a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt b/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
index 5ad9a67..653ae96 100644
--- a/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
+++ b/buildSrc-tests/project-subsets/src/test/kotlin/androidx/build/ProjectSubsetsTest.kt
@@ -88,9 +88,13 @@
         if (outDir == null || outDir == "") {
             outDir = File(projectDir, "../../out").normalize().toString()
         }
+        // --dependency-verification=off is set because we don't have to do validation of
+        // dependencies during these tests, it is already handled by the main build.
+        // Having it validate here breaks in androidx-studio-integration case where we
+        // might get new dependencies from AGP that are missinng signatures.
         GradleRunner.create()
             .withProjectDir(projectDir)
-            .withArguments("-Pandroidx.projects=$name", "tasks")
+            .withArguments("-Pandroidx.projects=$name", "tasks", "--dependency-verification=off")
             .withTestKitDir(File(outDir, ".gradle-testkit"))
             .build(); // fails the test if the build fails
     }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
index bc95bb6e..9a796c7e 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/MavenUploadHelper.kt
@@ -36,7 +36,6 @@
 import org.gradle.api.GradleException
 import org.gradle.api.Project
 import org.gradle.api.XmlProvider
-import org.gradle.api.attributes.DocsType
 import org.gradle.api.component.ComponentWithVariants
 import org.gradle.api.component.SoftwareComponent
 import org.gradle.api.component.SoftwareComponentFactory
@@ -383,10 +382,7 @@
 ) {
     val targetConfigurations = mutableSetOf<Configuration>()
     configurations.configureEach {
-        if (
-            it.attributes.getAttribute(DocsType.DOCS_TYPE_ATTRIBUTE)?.name == DocsType.SOURCES &&
-            it.name in names
-        ) {
+        if (it.name in names) {
             targetConfigurations.add(it)
             if (targetConfigurations.size == names.size) {
                 action(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
index a4a255a..597648d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/dependencyTracker/AffectedModuleDetector.kt
@@ -623,6 +623,15 @@
                 ":compose:material:material:icons:generator",
                 ":compose:material:material-icons-extended"
             ),
+            // Link glance-appwidget macrobenchmark and its target.
+            setOf(
+                ":glance:glance-appwidget:integration-tests:macrobenchmark",
+                ":glance:glance-appwidget:integration-tests:macrobenchmark-target"
+            ),
+            setOf(
+                ":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark",
+                ":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark-target"
+            )
         )
 
         val IGNORED_PATHS = setOf(
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraUseCaseAdapter.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraUseCaseAdapter.kt
index 8aec946..db29d61 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraUseCaseAdapter.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/adapter/CameraUseCaseAdapter.kt
@@ -17,16 +17,13 @@
 package androidx.camera.camera2.pipe.integration.adapter
 
 import android.content.Context
-import android.graphics.Point
 import android.hardware.camera2.CameraCaptureSession.CaptureCallback
 import android.hardware.camera2.CameraDevice
-import android.hardware.display.DisplayManager
-import android.util.Size
-import android.view.Display
 import androidx.annotation.RequiresApi
 import androidx.camera.camera2.pipe.core.Log.debug
 import androidx.camera.camera2.pipe.core.Log.info
 import androidx.camera.camera2.pipe.integration.impl.Camera2ImplConfig
+import androidx.camera.camera2.pipe.integration.impl.DisplayInfoManager
 import androidx.camera.camera2.pipe.integration.impl.SESSION_PHYSICAL_CAMERA_ID_OPTION
 import androidx.camera.camera2.pipe.integration.interop.ExperimentalCamera2Interop
 import androidx.camera.core.impl.CameraCaptureCallback
@@ -48,17 +45,7 @@
 @Suppress("DEPRECATION")
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 class CameraUseCaseAdapter(context: Context) : UseCaseConfigFactory {
-    private val MAX_PREVIEW_SIZE = Size(1920, 1080)
-
-    private val displayManager: DisplayManager by lazy {
-        context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
-    }
-    private val defaultDisplay: Display by lazy {
-        getMaxSizeDisplay()
-    }
-    private val previewSize: Size by lazy {
-        calculatePreviewSize()
-    }
+    private val displayInfoManager by lazy { DisplayInfoManager(context) }
 
     init {
         if (context === context.applicationContext) {
@@ -132,56 +119,17 @@
         if (captureType == UseCaseConfigFactory.CaptureType.PREVIEW) {
             mutableConfig.insertOption(
                 ImageOutputConfig.OPTION_MAX_RESOLUTION,
-                previewSize
+                displayInfoManager.previewSize
             )
         }
 
         mutableConfig.insertOption(
             ImageOutputConfig.OPTION_TARGET_ROTATION,
-            defaultDisplay.rotation
+            displayInfoManager.defaultDisplay.rotation
         )
         return OptionsBundle.from(mutableConfig)
     }
 
-    private fun getMaxSizeDisplay(): Display {
-        val displays = displayManager.displays
-        var maxDisplay: Display? = null
-        var maxDisplaySize = -1
-        for (display: Display in displays) {
-            val displaySize = Point()
-            // TODO(b/230400472): Use WindowManager#getCurrentWindowMetrics(). Display#getRealSize()
-            //  is deprecated since API level 31.
-            display.getRealSize(displaySize)
-            if (displaySize.x * displaySize.y > maxDisplaySize) {
-                maxDisplaySize = displaySize.x * displaySize.y
-                maxDisplay = display
-            }
-        }
-        return checkNotNull(maxDisplay) { "No displays found from ${displayManager.displays}!" }
-    }
-
-    /**
-     * Calculates the device's screen resolution, or MAX_PREVIEW_SIZE, whichever is smaller.
-     */
-    private fun calculatePreviewSize(): Size {
-        val displaySize = Point()
-        val display: Display = defaultDisplay
-        display.getRealSize(displaySize)
-        var displayViewSize: Size
-        displayViewSize = if (displaySize.x > displaySize.y) {
-            Size(displaySize.x, displaySize.y)
-        } else {
-            Size(displaySize.y, displaySize.x)
-        }
-        if (displayViewSize.width * displayViewSize.height
-            > MAX_PREVIEW_SIZE.width * MAX_PREVIEW_SIZE.height
-        ) {
-            displayViewSize = MAX_PREVIEW_SIZE
-        }
-        // TODO(b/230402463): Migrate extra cropping quirk from CameraX.
-        return displayViewSize
-    }
-
     object DefaultCaptureOptionsUnpacker : CaptureConfig.OptionUnpacker {
         @OptIn(ExperimentalCamera2Interop::class)
         override fun unpack(config: UseCaseConfig<*>, builder: CaptureConfig.Builder) {
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManager.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManager.kt
new file mode 100644
index 0000000..1babffd
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManager.kt
@@ -0,0 +1,92 @@
+/*
+ * 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.camera.camera2.pipe.integration.impl
+
+import android.content.Context
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.util.Size
+import android.view.Display
+import androidx.annotation.RequiresApi
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Suppress("DEPRECATION") // getRealSize
+@Singleton
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+class DisplayInfoManager @Inject constructor(context: Context) {
+    private val MAX_PREVIEW_SIZE = Size(1920, 1080)
+
+    private val displayManager: DisplayManager by lazy {
+        context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+    }
+
+    // TODO(b/198257203): Fetch latest display information for devices where display size is not
+    //  guaranteed to be fixed. (e.g. foldable devices or devices with multiple displays)
+
+    val defaultDisplay: Display by lazy {
+        getMaxSizeDisplay()
+    }
+
+    val previewSize: Size by lazy {
+        calculatePreviewSize()
+    }
+
+    private fun getMaxSizeDisplay(): Display {
+        val displays = displayManager.displays
+        var maxDisplay: Display? = null
+        var maxDisplaySize = -1
+
+        // TODO(b/211945950, b/255170076): Handle STATE_OFF displays.
+
+        for (display: Display in displays) {
+            val displaySize = Point()
+            // TODO(b/230400472): Use WindowManager#getCurrentWindowMetrics(). Display#getRealSize()
+            //  is deprecated since API level 31.
+            display.getRealSize(displaySize)
+            if (displaySize.x * displaySize.y > maxDisplaySize) {
+                maxDisplaySize = displaySize.x * displaySize.y
+                maxDisplay = display
+            }
+        }
+        return checkNotNull(maxDisplay) { "No displays found from ${displayManager.displays}!" }
+    }
+
+    /**
+     * Calculates the device's screen resolution, or MAX_PREVIEW_SIZE, whichever is smaller.
+     */
+    private fun calculatePreviewSize(): Size {
+        val displaySize = Point()
+        val display: Display = defaultDisplay
+        // TODO(b/230400472): Use WindowManager#getCurrentWindowMetrics(). Display#getRealSize()
+        //  is deprecated since API level 31.
+        display.getRealSize(displaySize)
+        var displayViewSize: Size
+        displayViewSize = if (displaySize.x > displaySize.y) {
+            Size(displaySize.x, displaySize.y)
+        } else {
+            Size(displaySize.y, displaySize.x)
+        }
+        if (displayViewSize.width * displayViewSize.height
+            > MAX_PREVIEW_SIZE.width * MAX_PREVIEW_SIZE.height
+        ) {
+            displayViewSize = MAX_PREVIEW_SIZE
+        }
+        // TODO(b/230402463): Migrate extra cropping quirk from CameraX.
+        return displayViewSize
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
index 0f8323fa..684eb88 100644
--- a/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
+++ b/camera/camera-camera2-pipe-integration/src/main/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeating.kt
@@ -43,6 +43,7 @@
 import androidx.camera.core.impl.UseCaseConfig.OPTION_SESSION_CONFIG_UNPACKER
 import androidx.camera.core.impl.UseCaseConfigFactory
 import androidx.camera.core.impl.utils.executor.CameraXExecutors
+import kotlin.math.min
 
 private val DEFAULT_PREVIEW_SIZE = Size(0, 0)
 
@@ -55,9 +56,10 @@
 class MeteringRepeating(
     private val cameraProperties: CameraProperties,
     config: MeteringRepeatingConfig,
+    private val displayInfoManager: DisplayInfoManager
 ) : UseCase(config) {
 
-    private val meteringSurfaceSize = cameraProperties.getMinimumPreviewSize()
+    private val meteringSurfaceSize = getProperPreviewSize()
 
     private val deferrableSurfaceLock = Any()
 
@@ -65,9 +67,10 @@
     private var deferrableSurface: DeferrableSurface? = null
 
     override fun getDefaultConfig(applyDefaultConfig: Boolean, factory: UseCaseConfigFactory) =
-        Builder(cameraProperties).useCaseConfig
+        Builder(cameraProperties, displayInfoManager).useCaseConfig
 
-    override fun getUseCaseConfigBuilder(config: Config) = Builder(cameraProperties)
+    override fun getUseCaseConfigBuilder(config: Config) =
+        Builder(cameraProperties, displayInfoManager)
 
     override fun onSuggestedResolutionUpdated(suggestedResolution: Size): Size {
         updateSessionConfig(createPipeline().build())
@@ -120,28 +123,57 @@
             }
     }
 
-    private fun CameraProperties.getMinimumPreviewSize(): Size {
-        val map = metadata[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP]
-        if (map == null) {
+    private fun CameraProperties.getOutputSizes(): Array<Size>? {
+        val map = metadata[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP] ?: run {
             error { "Can not retrieve SCALER_STREAM_CONFIGURATION_MAP." }
-            return DEFAULT_PREVIEW_SIZE
+            return null
         }
 
-        val outputSizes = if (Build.VERSION.SDK_INT < 23) {
+        return if (Build.VERSION.SDK_INT < 23) {
             // ImageFormat.PRIVATE is only public after Android level 23. Therefore, use
             // SurfaceTexture.class to get the supported output sizes before Android level 23.
             map.getOutputSizes(SurfaceTexture::class.java)
         } else {
             map.getOutputSizes(ImageFormat.PRIVATE)
         }
+    }
+
+    private fun getProperPreviewSize(): Size {
+        val outputSizes = cameraProperties.getOutputSizes()
 
         if (outputSizes == null) {
             error { "Can not get output size list." }
             return DEFAULT_PREVIEW_SIZE
         }
 
-        check(outputSizes.isNotEmpty()) { "Output sizes empty" }
-        return outputSizes.minWithOrNull { size1, size2 -> size1.area().compareTo(size2.area()) }!!
+        if (outputSizes.isEmpty()) {
+            error { "Output sizes empty" }
+            return DEFAULT_PREVIEW_SIZE
+        }
+
+        // TODO(b/256805716): get supported output sizes handling quirks.
+
+        outputSizes.sortBy { size -> size.width.toLong() * size.height.toLong() }
+
+        // Find maximum supported resolution that is <= min(VGA, display resolution)
+        // Using minimum supported size could cause some issue on certain devices.
+        val previewSize = displayInfoManager.previewSize
+        val maxSizeProduct =
+            min(640L * 480L, previewSize.width.toLong() * previewSize.height.toLong())
+
+        var previousSize: Size? = null
+        for (outputSize in outputSizes) {
+            val product = outputSize.width.toLong() * outputSize.height.toLong()
+            if (product == maxSizeProduct) {
+                return outputSize
+            } else if (product > maxSizeProduct) {
+                return previousSize ?: break // fallback to minimum size.
+            }
+            previousSize = outputSize
+        }
+
+        // If not found, return the minimum size.
+        return outputSizes[0]
     }
 
     class MeteringRepeatingConfig : UseCaseConfig<MeteringRepeating>, ImageInputConfig {
@@ -157,7 +189,10 @@
         override fun getInputFormat() = ImageFormatConstants.INTERNAL_DEFINED_IMAGE_FORMAT_PRIVATE
     }
 
-    class Builder(private val cameraProperties: CameraProperties) :
+    class Builder(
+        private val cameraProperties: CameraProperties,
+        private val displayInfoManager: DisplayInfoManager
+    ) :
         UseCaseConfig.Builder<MeteringRepeating, MeteringRepeatingConfig, Builder> {
 
         override fun getMutableConfig() = MutableOptionsBundle.create()
@@ -185,7 +220,7 @@
         override fun setZslDisabled(disabled: Boolean) = this
 
         override fun build(): MeteringRepeating {
-            return MeteringRepeating(cameraProperties, useCaseConfig)
+            return MeteringRepeating(cameraProperties, useCaseConfig, displayInfoManager)
         }
     }
 }
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 cdef936..537adf9 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
@@ -66,7 +66,8 @@
     @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") // Java version required for Dagger
     private val controls: java.util.Set<UseCaseCameraControl>,
     private val camera2CameraControl: Camera2CameraControl,
-    cameraProperties: CameraProperties
+    cameraProperties: CameraProperties,
+    displayInfoManager: DisplayInfoManager
 ) {
     private val lock = Any()
 
@@ -76,7 +77,12 @@
     @GuardedBy("lock")
     private val activeUseCases = mutableSetOf<UseCase>()
 
-    private val meteringRepeating by lazy { MeteringRepeating.Builder(cameraProperties).build() }
+    private val meteringRepeating by lazy {
+        MeteringRepeating.Builder(
+            cameraProperties,
+            displayInfoManager
+        ).build()
+    }
 
     @Volatile
     private var _activeComponent: UseCaseCameraComponent? = null
@@ -285,4 +291,4 @@
     private fun <T> Collection<T>.only(predicate: (T) -> Boolean): Boolean {
         return isNotEmpty() && all(predicate)
     }
-}
\ No newline at end of file
+}
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManagerTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManagerTest.kt
new file mode 100644
index 0000000..f550d39
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/DisplayInfoManagerTest.kt
@@ -0,0 +1,98 @@
+/*
+ * 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.camera.camera2.pipe.integration.impl
+
+import android.content.Context
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.util.Size
+import androidx.test.core.app.ApplicationProvider
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.internal.DoNotInstrument
+import org.robolectric.shadows.ShadowDisplayManager
+
+@Suppress("DEPRECATION") // getRealSize
+@RunWith(RobolectricTestRunner::class)
+@DoNotInstrument
+class DisplayInfoManagerTest {
+    private val displayInfoManager = DisplayInfoManager(ApplicationProvider.getApplicationContext())
+
+    private fun addDisplay(width: Int, height: Int) {
+        ShadowDisplayManager.addDisplay(String.format("w%ddp-h%ddp", width, height))
+    }
+
+    @Test
+    fun defaultDisplayIsDeviceDisplay_whenOneDisplay() {
+        // Arrange
+        val displayManager = (ApplicationProvider.getApplicationContext() as Context)
+            .getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
+        val currentDisplaySize = Point()
+        displayManager.displays[0].getRealSize(currentDisplaySize)
+
+        // Act
+        val size = Point()
+        displayInfoManager.defaultDisplay.getRealSize(size)
+
+        // Assert
+        assertEquals(currentDisplaySize, size)
+    }
+
+    @Test
+    fun defaultDisplayIsMaxSizeDisplay_whenMultipleDisplay() {
+        // Arrange
+        addDisplay(2000, 3000)
+        addDisplay(480, 640)
+
+        // Act
+        val size = Point()
+        displayInfoManager.defaultDisplay.getRealSize(size)
+
+        // Assert
+        assertEquals(Point(2000, 3000), size)
+    }
+
+    @Test(expected = IllegalStateException::class)
+    fun throwsCorrectExceptionForDefaultDisplay_whenNoDisplay() {
+        // Arrange
+        ShadowDisplayManager.removeDisplay(0)
+
+        // Act
+        val size = Point()
+        displayInfoManager.defaultDisplay.getRealSize(size)
+    }
+
+    @Test
+    fun previewSizeIsProperSize_whenDisplaySmallerThan1080P() {
+        // Arrange
+        addDisplay(480, 640)
+
+        // Act & Assert
+        assertEquals(Size(640, 480), displayInfoManager.previewSize)
+    }
+
+    @Test
+    fun previewSizeIsMaxPreviewSize_whenDisplayLargerThan1080P() {
+        // Arrange
+        addDisplay(2000, 3000)
+
+        // Act & Assert
+        assertEquals(Size(1920, 1080), displayInfoManager.previewSize)
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeatingTest.kt b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeatingTest.kt
new file mode 100644
index 0000000..f40a4cf
--- /dev/null
+++ b/camera/camera-camera2-pipe-integration/src/test/java/androidx/camera/camera2/pipe/integration/impl/MeteringRepeatingTest.kt
@@ -0,0 +1,141 @@
+/*
+ * 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.camera.camera2.pipe.integration.impl
+
+import android.hardware.camera2.CameraCharacteristics
+import android.os.Build
+import android.util.Size
+import androidx.camera.camera2.pipe.integration.adapter.RobolectricCameraPipeTestRunner
+import androidx.camera.camera2.pipe.integration.testing.FakeCameraProperties
+import androidx.camera.camera2.pipe.testing.FakeCameraMetadata
+import androidx.test.core.app.ApplicationProvider
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.annotation.Config
+import org.robolectric.annotation.internal.DoNotInstrument
+import org.robolectric.shadows.ShadowDisplayManager
+import org.robolectric.shadows.StreamConfigurationMapBuilder
+
+@RunWith(RobolectricCameraPipeTestRunner::class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+class MeteringRepeatingTest {
+    companion object {
+        val dummyZeroSize = Size(0, 0)
+
+        val dummySizeListWithout640x480 = listOf(
+            Size(4160, 3120),
+            Size(1920, 1080),
+            Size(1280, 720),
+            Size(320, 240),
+            Size(240, 144),
+        )
+
+        val dummySizeListWith640x480 = listOf(
+            Size(4160, 3120),
+            Size(1920, 1080),
+            Size(1280, 720),
+            Size(640, 480),
+            Size(320, 240),
+        )
+
+        val dummySizeListWithoutSmaller = listOf(
+            Size(4160, 3120),
+            Size(1920, 1080),
+            Size(1280, 720)
+        )
+
+        val dummySizeListSmallerThan640x480 = listOf(
+            Size(320, 480),
+            Size(320, 240),
+            Size(240, 144),
+        )
+
+        fun getFakeMetadata(sizeList: List<Size>): FakeCameraMetadata {
+            val shuffledList = sizeList.shuffled()
+
+            val builder = StreamConfigurationMapBuilder.newBuilder()
+            for (size in shuffledList) {
+                builder.addOutputSize(size)
+            }
+
+            return FakeCameraMetadata(
+                mapOf(
+                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP to builder.build(),
+                )
+            )
+        }
+    }
+
+    private lateinit var meteringRepeating: MeteringRepeating
+
+    private fun addDisplay(width: Int, height: Int) {
+        ShadowDisplayManager.addDisplay(String.format("w%ddp-h%ddp", width, height))
+    }
+
+    private fun getMeteringRepeatingAndInitDisplay(outputSizeList: List<Size>): MeteringRepeating {
+        for (size in outputSizeList) {
+            addDisplay(size.width, size.height)
+        }
+
+        return MeteringRepeating.Builder(
+            FakeCameraProperties(
+                getFakeMetadata(
+                    outputSizeList
+                )
+            ),
+            DisplayInfoManager(ApplicationProvider.getApplicationContext())
+        ).build()
+    }
+
+    @Test
+    fun attachedSurfaceResolutionIsLargestLessThan640x480_when640x480NotPresentInOutputSizes() {
+        meteringRepeating = getMeteringRepeatingAndInitDisplay(dummySizeListWithout640x480)
+
+        meteringRepeating.updateSuggestedResolution(dummyZeroSize)
+
+        assertEquals(Size(320, 240), meteringRepeating.attachedSurfaceResolution)
+    }
+
+    @Test
+    fun attachedSurfaceResolutionIs640x480_when640x480PresentInOutputSizes() {
+        meteringRepeating = getMeteringRepeatingAndInitDisplay(dummySizeListWith640x480)
+
+        meteringRepeating.updateSuggestedResolution(dummyZeroSize)
+
+        assertEquals(Size(640, 480), meteringRepeating.attachedSurfaceResolution)
+    }
+
+    @Test
+    fun attachedSurfaceResolutionFallsBackToMinimum_whenAllOutputSizesLargerThan640x480() {
+        meteringRepeating = getMeteringRepeatingAndInitDisplay(dummySizeListWithoutSmaller)
+
+        meteringRepeating.updateSuggestedResolution(dummyZeroSize)
+
+        assertEquals(Size(1280, 720), meteringRepeating.attachedSurfaceResolution)
+    }
+
+    @Test
+    fun attachedSurfaceResolutionIsLargestWithinPreviewSize_whenAllOutputSizesLessThan640x480() {
+        meteringRepeating = getMeteringRepeatingAndInitDisplay(dummySizeListSmallerThan640x480)
+
+        meteringRepeating.updateSuggestedResolution(dummyZeroSize)
+
+        assertEquals(Size(320, 480), meteringRepeating.attachedSurfaceResolution)
+    }
+}
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 865ad2c..13ef7aa 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
@@ -27,6 +27,7 @@
 import androidx.camera.camera2.pipe.integration.testing.FakeUseCaseCameraComponentBuilder
 import androidx.camera.core.ImageCapture
 import androidx.camera.core.Preview
+import androidx.test.core.app.ApplicationProvider
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -183,6 +184,7 @@
             FakeCamera2CameraControlCompat(),
             useCaseThreads,
             ComboRequestListener()
-        )
+        ),
+        displayInfoManager = DisplayInfoManager(ApplicationProvider.getApplicationContext())
     )
 }
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
index c9816f5..dd26326 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/imagecapture/RequestWithCallback.java
@@ -144,6 +144,10 @@
     @MainThread
     void abortAndSendErrorToApp(@NonNull ImageCaptureException imageCaptureException) {
         checkMainThread();
+        if (mCompleteFuture.isDone()) {
+            // The app has already received a callback. No need to abort.
+            return;
+        }
         abort();
         onFailure(imageCaptureException);
     }
@@ -151,6 +155,10 @@
     @MainThread
     void abortSilentlyAndRetry() {
         checkMainThread();
+        if (mCompleteFuture.isDone()) {
+            // The app has already received a callback. No need to abort.
+            return;
+        }
         abort();
         mRetryControl.retryRequest(mTakePictureRequest);
     }
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/RequestWithCallbackTest.kt b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/RequestWithCallbackTest.kt
index f0b794e..acdc78e 100644
--- a/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/RequestWithCallbackTest.kt
+++ b/camera/camera-core/src/test/java/androidx/camera/core/imagecapture/RequestWithCallbackTest.kt
@@ -91,6 +91,37 @@
     }
 
     @Test
+    fun abortAndRetryAfterSuccess_abortIsNoOp() {
+        // Arrange.
+        val request = FakeTakePictureRequest(FakeTakePictureRequest.Type.IN_MEMORY)
+        val callback = RequestWithCallback(request, retryControl)
+
+        // Act: deliver result then abort
+        callback.onImageCaptured()
+        callback.onFinalResult(imageResult)
+        callback.abortSilentlyAndRetry()
+        shadowOf(getMainLooper()).idle()
+
+        // Assert: retry is not queued.
+        assertThat(retryControl.retriedRequest).isNull()
+    }
+
+    @Test
+    fun abortAndFailAfterFail_abortIsNoOp() {
+        // Arrange.
+        val request = FakeTakePictureRequest(FakeTakePictureRequest.Type.IN_MEMORY)
+        val callback = RequestWithCallback(request, retryControl)
+
+        // Fail request then abort
+        callback.onCaptureFailure(otherError)
+        callback.abortAndSendErrorToApp(abortError)
+        shadowOf(getMainLooper()).idle()
+
+        // Assert:
+        assertThat(request.exceptionReceived).isEqualTo(otherError)
+    }
+
+    @Test
     fun abortRequestThenSendOtherErrors_receiveAbortError() {
         // Arrange.
         val request = FakeTakePictureRequest(FakeTakePictureRequest.Type.IN_MEMORY)
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/Recording.java b/camera/camera-video/src/main/java/androidx/camera/video/Recording.java
index 9002f39..c4c874b 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/Recording.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/Recording.java
@@ -16,8 +16,11 @@
 
 package androidx.camera.video;
 
+import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
+import androidx.annotation.RestrictTo;
 import androidx.camera.core.impl.utils.CloseGuardHelper;
 import androidx.core.util.Consumer;
 import androidx.core.util.Preconditions;
@@ -46,7 +49,7 @@
 public final class Recording implements AutoCloseable {
 
     // Indicates the recording has been explicitly stopped by users.
-    private final AtomicBoolean mIsStopped = new AtomicBoolean(false);
+    private final AtomicBoolean mIsClosed = new AtomicBoolean(false);
     private final Recorder mRecorder;
     private final long mRecordingId;
     private final OutputOptions mOutputOptions;
@@ -59,7 +62,7 @@
         mOutputOptions = options;
 
         if (finalizedOnCreation) {
-            mIsStopped.set(true);
+            mIsClosed.set(true);
         } else {
             mCloseGuard.open("stop");
         }
@@ -119,7 +122,7 @@
      * {@link #close()} or {@link #stop()}.
      */
     public void pause() {
-        if (mIsStopped.get()) {
+        if (mIsClosed.get()) {
             throw new IllegalStateException("The recording has been stopped.");
         }
         mRecorder.pause(this);
@@ -138,43 +141,44 @@
      * {@link #close()} or {@link #stop()}.
      */
     public void resume() {
-        if (mIsStopped.get()) {
+        if (mIsClosed.get()) {
             throw new IllegalStateException("The recording has been stopped.");
         }
         mRecorder.resume(this);
     }
 
     /**
-     * Stops the recording.
+     * Stops the recording, as if calling {@link #close()}.
      *
-     * <p>Once stopped, all methods for controlling the state of this recording besides
-     * {@code stop()} or {@link #close()} will throw an {@link IllegalStateException}.
-     *
-     * <p>Once an active recording has been stopped, the next recording can be started with
-     * {@link PendingRecording#start(Executor, Consumer)}.
-     *
-     * <p>This method is idempotent; if the recording has already been stopped or has been
-     * finalized internally, calling {@code stop()} is a no-op.
+     * <p>This method is equivalent to calling {@link #close()}.
      */
     public void stop() {
-        mCloseGuard.close();
-        if (mIsStopped.getAndSet(true)) {
-            return;
-        }
-        mRecorder.stop(this);
+        close();
     }
 
     /**
-     * Close this recording, as if calling {@link #stop()}.
+     * Close this recording.
+     *
+     * <p>Once {@link #stop()} or {@code close()} called, all methods for controlling the state of
+     * this recording besides {@link #stop()} or {@code close()} will throw an
+     * {@link IllegalStateException}.
+     *
+     * <p>Once an active recording has been closed, the next recording can be started with
+     * {@link PendingRecording#start(Executor, Consumer)}.
+     *
+     * <p>This method is idempotent; if the recording has already been closed or has been
+     * finalized internally, calling {@link #stop()} or {@code close()} is a no-op.
      *
      * <p>This method is invoked automatically on active recording instances managed by the {@code
      * try-with-resources} statement.
-     *
-     * <p>This method is equivalent to calling {@link #stop()}.
      */
     @Override
     public void close() {
-        stop();
+        mCloseGuard.close();
+        if (mIsClosed.getAndSet(true)) {
+            return;
+        }
+        mRecorder.stop(this);
     }
 
     @Override
@@ -192,4 +196,21 @@
     long getRecordingId() {
         return mRecordingId;
     }
+
+    /**
+     * Returns whether the recording is closed.
+     *
+     * <p>The returned value does not reflect the state of the recording; it only reflects
+     * whether {@link #stop()} or {@link #close()} was called on this object.
+     *
+     * <p>The state of the recording should be checked from the listener passed to
+     * {@link PendingRecording#start(Executor, Consumer)}. Once the active recording is
+     * stopped, a {@link VideoRecordEvent.Finalize} event will be sent to the listener.
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    public boolean isClosed() {
+        return mIsClosed.get();
+    }
 }
diff --git a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/camera2extensions/Camera2ExtensionsImageCaptureStressTest.kt b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/camera2extensions/Camera2ExtensionsImageCaptureStressTest.kt
new file mode 100644
index 0000000..f9d8b9d
--- /dev/null
+++ b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/camera2extensions/Camera2ExtensionsImageCaptureStressTest.kt
@@ -0,0 +1,136 @@
+/*
+ * 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.camera.integration.extensions.camera2extensions
+
+import android.content.Context
+import android.hardware.camera2.CameraDevice
+import android.hardware.camera2.CameraExtensionSession
+import android.hardware.camera2.CameraManager
+import android.hardware.camera2.params.OutputConfiguration
+import android.media.ImageReader
+import android.view.Surface
+import androidx.camera.camera2.Camera2Config
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil.assumeCameraExtensionSupported
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil.createCaptureImageReader
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil.openCameraDevice
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil.openExtensionSession
+import androidx.camera.integration.extensions.util.Camera2ExtensionsTestUtil.takePicture
+import androidx.camera.integration.extensions.util.assertImageIsValid
+import androidx.camera.integration.extensions.utils.CameraIdExtensionModePair
+import androidx.camera.testing.CameraUtil
+import androidx.camera.testing.StressTestRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.filters.LargeTest
+import androidx.test.filters.SdkSuppress
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.ClassRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/**
+ * Stress test to verify that the camera can successfully capture images for all supported
+ * extension modes for each cameras ID.
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@SdkSuppress(minSdkVersion = 31)
+class Camera2ExtensionsImageCaptureStressTest(private val config: CameraIdExtensionModePair) {
+    @get:Rule
+    val useCamera =
+        CameraUtil.grantCameraPermissionAndPreTest(
+            CameraUtil.PreTestCameraIdList(Camera2Config.defaultConfig())
+        )
+
+    companion object {
+        @ClassRule
+        @JvmField val stressTest = StressTestRule()
+
+        @Parameterized.Parameters(name = "config = {0}")
+        @JvmStatic
+        fun parameters() = Camera2ExtensionsTestUtil.getAllCameraIdExtensionModeCombinations()
+    }
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+    private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
+
+    private lateinit var cameraDevice: CameraDevice
+    private lateinit var imageReader: ImageReader
+    private lateinit var captureSurface: Surface
+    private lateinit var extensionSession: CameraExtensionSession
+
+    @Before
+    fun setUp(): Unit = runBlocking {
+        assumeTrue(Camera2ExtensionsTestUtil.isTargetDeviceExcludedForExtensionsTest())
+
+        val (cameraId, extensionMode) = config
+
+        val extensionsCharacteristics = cameraManager.getCameraExtensionCharacteristics(cameraId)
+        assumeCameraExtensionSupported(extensionMode, extensionsCharacteristics)
+
+        cameraDevice = openCameraDevice(cameraManager, cameraId)
+        imageReader = createCaptureImageReader(extensionsCharacteristics, extensionMode)
+        captureSurface = imageReader.surface
+        val outputConfigurationCapture = OutputConfiguration(captureSurface)
+        extensionSession = openExtensionSession(
+            cameraDevice,
+            extensionMode,
+            listOf(outputConfigurationCapture)
+        )
+        assertThat(extensionSession).isNotNull()
+    }
+
+    @After
+    fun tearDown() {
+        if (::extensionSession.isInitialized) {
+            extensionSession.close()
+        }
+
+        if (::cameraDevice.isInitialized) {
+            cameraDevice.close()
+        }
+
+        if (::imageReader.isInitialized) {
+            imageReader.close()
+        }
+
+        if (::captureSurface.isInitialized) {
+            captureSurface.release()
+        }
+    }
+
+    @Test
+    fun captureImage(): Unit = runBlocking {
+        repeat(Camera2ExtensionsTestUtil.getStressTestRepeatingCount()) {
+            val image = takePicture(cameraDevice, extensionSession, imageReader)
+            assertThat(image).isNotNull()
+
+            image?.let {
+                assertThat(it.timestamp).isGreaterThan(0)
+                assertImageIsValid(it, imageReader.width, imageReader.height)
+            }
+
+            image!!.close()
+        }
+    }
+}
\ No newline at end of file
diff --git a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/Camera2ExtensionsTestUtil.kt b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/Camera2ExtensionsTestUtil.kt
index 18051b9..429f3c8 100644
--- a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/Camera2ExtensionsTestUtil.kt
+++ b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/Camera2ExtensionsTestUtil.kt
@@ -22,6 +22,7 @@
 import android.hardware.camera2.CameraAccessException
 import android.hardware.camera2.CameraCharacteristics
 import android.hardware.camera2.CameraDevice
+import android.hardware.camera2.CameraExtensionCharacteristics
 import android.hardware.camera2.CameraExtensionSession
 import android.hardware.camera2.CameraManager
 import android.hardware.camera2.CaptureRequest
@@ -88,15 +89,7 @@
         verifyOutput: Boolean = false
     ) {
         val extensionsCharacteristics = cameraManager.getCameraExtensionCharacteristics(cameraId)
-        assumeTrue(extensionsCharacteristics.supportedExtensions.contains(extensionMode))
-        assumeTrue(
-            extensionsCharacteristics
-                .getExtensionSupportedSizes(extensionMode, SurfaceTexture::class.java).isNotEmpty()
-        )
-        assumeTrue(
-            extensionsCharacteristics
-                .getExtensionSupportedSizes(extensionMode, ImageFormat.JPEG).isNotEmpty()
-        )
+        assumeCameraExtensionSupported(extensionMode, extensionsCharacteristics)
 
         // Preview surface
         val previewSize = extensionsCharacteristics
@@ -119,11 +112,7 @@
         val previewSurface = Surface(surfaceTextureHolder.surfaceTexture)
 
         // Still capture surface
-        val captureSize = extensionsCharacteristics
-            .getExtensionSupportedSizes(extensionMode, ImageFormat.JPEG)
-            .maxBy { it.width * it.height }
-        val imageReader = ImageReader
-            .newInstance(captureSize.width, captureSize.height, ImageFormat.JPEG, 2)
+        val imageReader = createCaptureImageReader(extensionsCharacteristics, extensionMode)
         val captureSurface = imageReader.surface
 
         val cameraDevice = openCameraDevice(cameraManager, cameraId)
@@ -197,9 +186,39 @@
     }
 
     /**
+     * Check if the device supports the [extensionMode] and other extension specific characteristics
+     * required for testing. Halt the test if any criteria is not satisfied.
+     */
+    fun assumeCameraExtensionSupported(
+        extensionMode: Int,
+        extensionsCharacteristics: CameraExtensionCharacteristics
+    ) {
+        assumeTrue(extensionsCharacteristics.supportedExtensions.contains(extensionMode))
+        assumeTrue(
+            extensionsCharacteristics
+                .getExtensionSupportedSizes(extensionMode, SurfaceTexture::class.java).isNotEmpty()
+        )
+        assumeTrue(
+            extensionsCharacteristics
+                .getExtensionSupportedSizes(extensionMode, ImageFormat.JPEG).isNotEmpty()
+        )
+    }
+
+    fun createCaptureImageReader(
+        extensionsCharacteristics: CameraExtensionCharacteristics,
+        extensionMode: Int
+    ): ImageReader {
+        val captureSize = extensionsCharacteristics
+            .getExtensionSupportedSizes(extensionMode, ImageFormat.JPEG)
+            .maxBy { it.width * it.height }
+        return ImageReader
+            .newInstance(captureSize.width, captureSize.height, ImageFormat.JPEG, 2)
+    }
+
+    /**
      * Open the camera device and return the [CameraDevice] instance.
      */
-    private suspend fun openCameraDevice(
+    suspend fun openCameraDevice(
         cameraManager: CameraManager,
         cameraId: String
     ): CameraDevice {
@@ -228,7 +247,7 @@
     /**
      * Open the [CameraExtensionSession] and return the instance.
      */
-    private suspend fun openExtensionSession(
+    suspend fun openExtensionSession(
         cameraDevice: CameraDevice,
         extensionMode: Int,
         outputConfigs: List<OutputConfiguration>
@@ -256,7 +275,11 @@
         return deferred.await()
     }
 
-    private suspend fun takePicture(
+    /**
+     * Take a picture with the provided [session] and output the contents to the [imageReader]. The
+     * latest image written to the [imageReader] is returned.
+     */
+    suspend fun takePicture(
         cameraDevice: CameraDevice,
         session: CameraExtensionSession,
         imageReader: ImageReader
diff --git a/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/ImageCaptureTestUtil.kt b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/ImageCaptureTestUtil.kt
new file mode 100644
index 0000000..1875421
--- /dev/null
+++ b/camera/integration-tests/extensionstestapp/src/androidTest/java/androidx/camera/integration/extensions/util/ImageCaptureTestUtil.kt
@@ -0,0 +1,61 @@
+/*
+ * 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.camera.integration.extensions.util
+
+import android.graphics.BitmapFactory
+import android.graphics.ImageFormat
+import android.media.Image
+import com.google.common.truth.Truth.assertThat
+import junit.framework.TestCase.assertNotNull
+import junit.framework.TestCase.assertTrue
+
+/**
+ * Validate the image can be correctly decoded from a jpeg format to a bitmap.
+ */
+fun assertImageIsValid(image: Image, width: Int, height: Int) {
+    assertThat(image.width).isEqualTo(width)
+    assertThat(image.height).isEqualTo(height)
+    assertThat(image.format).isEqualTo(ImageFormat.JPEG)
+
+    val data = imageData(image)
+    assertTrue("Invalid image data", data.isNotEmpty())
+
+    val bmpOptions = BitmapFactory.Options().apply {
+        inJustDecodeBounds = true
+    }
+
+    BitmapFactory.decodeByteArray(data, 0, data.size, bmpOptions)
+
+    assertThat(width).isEqualTo(bmpOptions.outWidth)
+    assertThat(height).isEqualTo(bmpOptions.outHeight)
+
+    val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
+    assertNotNull("Decoding jpeg failed", bitmap)
+}
+
+private fun imageData(image: Image): ByteArray {
+    val planes = image.planes
+    assertTrue("Fail to get image planes", planes != null && planes.isNotEmpty())
+
+    val buffer = planes[0].buffer
+    assertNotNull("Fail to get jpeg ByteBuffer", buffer)
+
+    val data = ByteArray(buffer.remaining())
+    buffer.get(data)
+    buffer.rewind()
+    return data
+}
\ No newline at end of file
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-af/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-af/strings.xml
index 6f6ad1c..d269c76 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-af/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-af/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Taaklimiet is bereik\nAs jy voortgaan, sal die program verplig word om te stop"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Taak se stap %1$d van %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klik om aan te beweeg"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Besoek asseblief die verskillende template en maak seker die motor is in rymodus"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstrasie van wisselknoppie"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Wissel toets"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Dinamiese veranderinge word toegelaat"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Opdaterings toegelaat vir terughandelinge."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Wisseltoets is geaktiveer"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Wisseltoets is gedeaktiveer"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Sekondêre handeling en versieringdemonstrasie"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Sekondêrehandelingtoets"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Net die sekondêre handeling kan gekies word"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Versieringtoets"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekondêre handelinge en versiering"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Die ry kan ook gekies word"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Sekondêre handeling is gekies"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Primêre handeling vir ry is gekies"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstrasies oor diverse template"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Stal demonstrasies uit"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstrasie van templaatuitlegte"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demonstrasieskerm vir stemtoegang"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Gebruikerinteraksies"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Versoek demonstrasies van toestemmings"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Appoorvloei-bekragtiger"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Toets asseblief die volgende template terwyl jy"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"die voertuig van parkeer- na bestuurstaat toe verander"</string>
     <string name="perm_group" msgid="3834918337351876270">"Toestemminggroep"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Toestemminggroep vir uitstalprogram"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Toegang tot fyn ligging"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-am/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-am/strings.xml
index 364cd95..70ff493 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-am/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-am/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"የተግባር ገደብ ላይ ደርሷል\nወደፊት መሄድ መተግበሪያውን በኃይል ያስቆማል"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"የተግባር እርምጃ %1$d ከ%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ወደፊት ለመሄድ ጠቅ ያድርጉ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"እባክዎ የተለያዩ የቅንብር ደንቦችን ይጎብኙ እና መኪናው የማሽከርከር ሁነታ ላይ እንደሆነ ያረጋግጡ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"የቀያይር አዝራር ቅንጭብ ማሳያ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ሙከራን ቀያይር"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ተጨባጭ ለውጦች ተፈቅደዋል"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ዝማኔዎች በዳራ ክወናዎች ላይ ይፈቀዳሉ።"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"የመቀያየር ሙከራ ነቅቷል"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"የመቀያየር ሙከራ ተሰናክሏል"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ሁለተኛ እርምጃ እና የማስዋቢያ ቅንጭብ ማሳያ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"የሁለተኛ እርምጃ ሙከራ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"መመረጥ የሚችለው ሁለተኛው እርምጃ ብቻ ነው"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"የማስዋቢያ ሙከራ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ሁለተኛ እርምጃዎች እና ማስዋብ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"እንዲሁም ረድፉ መመረጥ ይችላል"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ሁለተኛ እርምጃ ተመርጧል"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"የረድፍ አንደኛ እርምጃ ተመርጧል"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"የተለያዩ ቅንብር ደንቦች ቅንጭብ ማሳያዎች"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"የመሳያ ቅንጭብ ማሳያ"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"የቅንብር ደንብ አቀማመጥ ቅንጭብ ማሳያዎች"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"የድምጽ መዳረሻ ቅንጭብ ማሳያ ማያ ገጽ"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"የተጠቃሚ መስተጋብሮች"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"የቅንጭብ ማሳያ ፈቃዶችን ይጠይቁ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"የመተግበሪያ ትርፍ አረጋጋጭ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"በሚቀይሩበት ጊዜ እባክዎ የሚከተሉትን የቅንብር ደንቦች ይሞክሩ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ተሽከርካሪው ከመቆም ወደ የማሽከርከር ሁኔታ"</string>
     <string name="perm_group" msgid="3834918337351876270">"የፈቃድ ቡድን"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ለማሳያ መተግበሪያ የፈቃድ ቡድን"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"የትክክለኛ አካባቢ መዳረሻ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ar/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ar/strings.xml
index 576646c..afb470f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ar/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ar/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"تم الوصول إلى حد المهمّة.\nسيؤدي التقدم إلى فرض إيقاف التطبيق."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"‏خطوة المهمة: %1$d من %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"انقر للتقدم إلى الأمام."</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"يُرجى الانتقال إلى النماذج المختلفة والتأكّد من أنّ السيارة في وضع القيادة."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"عرض توضيحي لزر الإيقاف/التفعيل"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"إيقاف/تفعيل الاختبار"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"يُسمَح بتغيير الحالة."</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"التحديثات المسموح بها على العمليات التي تتم بالخلفية"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"تم تفعيل زر إيقاف/تفعيل الاختبار."</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"تم إيقاف زر إيقاف/تفعيل الاختبار."</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"عرض توضيحي للإجراء الثانوي والتصميم"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"إجراء ثانوي تجريبي"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"يمكن اختيار الإجراء الثانوي فقط."</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"تصميم تجريبي"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"الإجراءات الثانوية والتصميم"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"يمكن أيضًا اختيار الصف."</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"تم اختيار إجراء ثانوي للصف."</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"تم اختيار إجراء أساسي للصف."</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"إصدارات تجريبية لنموذج ميزات متنوّعة"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"عرض الإصدارات التجريبية"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"عروض توضيحية لتنسيقات النماذج"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"شاشة العرض التوضيحي للاستخدام عبر الصوت"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"تفاعلات المستخدمين"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"عروض توضيحية لطلب الأذونات"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"أداة السماح بالتجاوز"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"يُرجى تجربة النماذج التالية أثناء تغيير"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"حالة المركبة من \"مركونة\" إلى \"القيادة\""</string>
     <string name="perm_group" msgid="3834918337351876270">"مجموعة أذونات"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"مجموعة أذونات لتطبيق العرض"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"الوصول إلى الموقع الدقيق"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-as/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-as/strings.xml
index 5e1c2d3..7e4e8da 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-as/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-as/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"কাৰ্যৰ সীমাত উপনীত হৈছে\nআগবাঢ়ি গ’লে এপ্‌টো বলপূৰ্বকভাৱে বন্ধ কৰা হ’ব"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"কাৰ্যৰ পদক্ষেপ %2$d টাৰ %1$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"আগবাঢ়ি যাবলৈ ক্লিক কৰক"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"অনুগ্ৰহ কৰি বিভিন্ন টেমপ্লে’টসমূহ চাওক আৰু গাড়ীখন ড্ৰাইভিং ম’ডত থকাটো নিশ্চিত কৰক"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ট’গল বুটামৰ ডেম’"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"পৰীক্ষা ট’গল কৰক"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ষ্টে’টফুল সলনি কৰাৰ অনুমতি আছে"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"নেপথ্যৰ কাৰ্যত আপডে’টৰ অনুমতি আছে।"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"পৰীক্ষা ট’গল কৰাৰ সুবিধা সক্ষম কৰা হৈছে"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"পৰীক্ষা ট’গল কৰাৰ সুবিধা অক্ষম কৰা হৈছে"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"গৌণ কাৰ্য আৰু সজোৱা কাৰ্যৰ ডেম’"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"গৌণ কাৰ্যৰ পৰীক্ষা"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"কেৱল গৌণ কাৰ্যটোও বাছনি কৰিব পৰা যায়"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"সজোৱা কাৰ্য"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"গৌণ কাৰ্য আৰু সজোৱা কাৰ্য"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"শাৰীটোও বাছনি কৰিব পৰা যায়"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"গৌণ কাৰ্য বাছনি কৰা হৈছে"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"শাৰীৰ প্ৰাথমিক কাৰ্য বাছনি কৰা হৈছে"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"সানমিহলি টেম্পলে’টৰ ডেম’"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ডেম’ দেখুৱাওক"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"টেমপ্লে’ট লে’আউটৰ ডেম’"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"কণ্ঠধ্বনিৰে এক্সেছ কৰাৰ ডেম’ৰ স্ক্ৰীন"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ব্যৱহাৰকাৰীৰ ভাব-বিনিময়"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"অনুমতিৰ অনুৰোধৰ ডেম’"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"এপ্লিকেশ্বন অভাৰফ্ল’ৰ মান্যতা প্ৰদানকাৰী"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"অনুগ্ৰহ কৰি, সলনি কৰাৰ সময়ত তলত দিয়া টেমপ্লে’টসমূহ পৰীক্ষা কৰি চাওক"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ৰখাই থোৱা অৱস্থাৰ পৰা চলাই থকা অৱস্থালৈ বাহনখন"</string>
     <string name="perm_group" msgid="3834918337351876270">"অনুমতিৰ গোট"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase এপক দিয়া অনুমতিৰ গোট"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"সঠিক অৱস্থানৰ এক্সেছ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-az/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-az/strings.xml
index f7eab61..de50258 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-az/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-az/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Tapşırıq limitinə çatdınız\nİrəli getmək tətbiqi məcburi dayandıracaq"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Tapşırıq mərhələsi %1$d/%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"İrəli keçmək üçün klikləyin"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Müxtəlif şablonları ziyarət edin və avtomobilin sürücülük rejimində olduğuna əmin olun"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Keçirmə Düyməsi Demosu"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Keçirmə testi"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Status dəyişikliyinə icazə verilir"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Geri əməliyyatlar üzrə güncəlləmələrə icazə verilir."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Keçirmə Testi Aktivdir"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Keçirmə Testi Deaktivdir"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"İkinci Dərəcəli Əməliyyat və Dekorasiya Demosu"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"İkinci Dərəcəli Əməliyyat Testi"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Yalnız ikinci dərəcəli əməliyyat seçilə bilər"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekorasiya Testi"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"İkinci Dərəcəli Əməliyyatlar və Dekorasiya"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Sıra da seçilə bilər"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"İkinci Dərəcəli Əməliyyat seçilib"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Sıra üzrə əsas əməliyyat seçilib"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Digər Şablon Demoları"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Vitrin Demoları"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Şablon Düzən Demoları"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Səsli Giriş Demo Ekranı"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"İstifadəçi əlaqələri"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"İcazə Demosu Tələb edin"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Tətbiq Aşma Doğrulayıcısı"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Avtomobili park vəziyyətindən sürmə vəziyyətinə"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"dəyişdirərkən aşağıdakı şablonları sınayın"</string>
     <string name="perm_group" msgid="3834918337351876270">"İcazə Qrupu"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Xəbərlər Vitrini Tətbiqi üçün İcazə Qrupu"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Dəqiq Məkana Giriş"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-b+sr+Latn/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-b+sr+Latn/strings.xml
index 21b1418..b6e3dac 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-b+sr+Latn/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-b+sr+Latn/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Dostignuto je ograničenje zadataka\nAko nastavite, aplikacija će se prinudno zaustaviti"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d. korak zadatka od %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknite da biste išli napred"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Posetite različite šablone i uverite se da je automobil u režimu vožnje"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstracija dugmeta za uključivanje/isključivanje"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Uključi/isključi test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Promene stanja su dozvoljene"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Ažuriranja su dozvoljena za operacije u pozadini."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test uključivanja/isključivanja je omogućen"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test uključivanja/isključivanja je onemogućen"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demonstracija sekundarne radnje i dekoracije"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test sekundarne radnje"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Može da se izabere samo sekundarna radnja"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test dekoracije"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundarne radnje i dekoracija"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Može da se izabere i red"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Sekundarna radnja je izabrana"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Primarna radnja reda je izabrana"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstracije različitih šablona"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demonstracije prikazivanja"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstracije izgleda šablona"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ekran demonstracije pristupa glasu"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Korisničke interakcije"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demonstracije zahteva za dozvole"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validator prekoračenja aplikacije"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testirajte sledeće šablone tokom punjenja"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"status vozila iz parkiranog u vožnja"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupa dozvola"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupa dozvola za isticanje aplikacije"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Pristup preciznoj lokaciji"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-be/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-be/strings.xml
index 2deca03..eb81f87 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-be/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-be/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Дасягнута максімальная колькасць задач\nДалейшы рух прывядзе да прымусовага спынення праграмы"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Крок задачы %1$d з %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Націсніце, каб рухацца далей"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Праглядзіце розныя шаблоны і пераканайцеся, што аўтамабіль знаходзіцца ў рэжыме \"За рулём\""</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Дэманстрацыя кнопкі пераключэння"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Праверка пераключэння"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Дазволена змяняць стан"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Абнаўленні дазволены для аперацый вяртання."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Праверка пераключэння ўключана"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Праверка пераключэння адключана"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Дэмаверсія другаснага дзеяння і аздаблення"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Тэст другаснага дзеяння"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Можна выбраць толькі другаснае дзеянне"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Тэст элементаў аздаблення"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Другасныя дзеянні і аздабленне"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Таксама можна выбраць радок"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Выбрана другаснае дзеянне"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Выбрана галоўнае дзеянне для радка"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Дэманстрацыі розных шаблонаў"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Дэманстрацыі выбранага"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Дэманстрацыі макета шаблона"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Экран дэманстрацыі Галасавога доступу"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Узаемадзеянне з карыстальнікамі"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Запытаць дэманстрацыі дазволаў"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Сродак праверкі дадатковага меню праграмы"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Пры змяненні пратэсціруйце наступныя шаблоны"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"змяненне стану аўтамабіля з \"Прыпаркаваны\" на \"За рулём\""</string>
     <string name="perm_group" msgid="3834918337351876270">"Група дазволаў"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Група дазволаў для праграмы \"Выбранае\""</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Доступ да дакладнага месцазнаходжання"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-bg/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-bg/strings.xml
index 2aad28d..f278d69 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-bg/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-bg/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Ограничението за задачи е достигнато\nАко продължите, приложението ще бъде спряно принудително"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Стъпка %1$d от %2$d в задачата"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Кликнете, за да продължите напред"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Отворете отделните шаблони, докато автомобилът е в режим за шофиране"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Демонстрация на бутон за превключване"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Тест с превключвател"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Промените на състоянието са разрешени"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Актуализациите са разрешени за операции за връщане назад."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Тестът с превключвател е активиран"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Тестът с превключвател е деактивиран"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Демонстрация на алтернативно действие и декоративен елемент"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Тестване на алтернативно действие"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Само алтернативното действие може да бъде избрано"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Тестване на декоративен елемент"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Алтернативни действия и декоративни елементи"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Редът може също да бъде избран"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Избрано е алтернативното действие"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Избрано е основното действие за реда"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Демонстрации на разни шаблони"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Демонстрации на Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Демонстрации на оформления за шаблон"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Екран за демонстрация на Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Потребителски взаимодействия"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Демонстрации за заявяване на разрешения"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Проверка при препълване за приложението"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Тествайте следните шаблони, докато превключвате между"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"режим за паркиране и шофиране"</string>
     <string name="perm_group" msgid="3834918337351876270">"Група разрешения"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Група разрешения за приложението „На фокус“"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Достъп до точното местоположение"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-bn/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-bn/strings.xml
index 541d5e3..282632f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-bn/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-bn/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"টাস্কের সীমা পেরিয়ে গেছে\nআরও এগোলে, অ্যাপকে জোর করে বন্ধ করা হবে"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"টাস্কের %2$d ধাপের %1$d নম্বর ধাপ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"এগিয়ে যাওয়ার জন্য ক্লিক করুন"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"বিভিন্ন টেমপ্লেট দেখুন ও নিশ্চিত করুন যে গাড়িটি \'ড্রাইভিং\' মোডে আছে"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"টগল বোতাম সংক্রান্ত ডেমো"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"টগল টেস্ট"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"স্টেটফুল পরিবর্তন করার অনুমতি দেওয়া হয়েছে"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"পিছনের পৃষ্ঠাতে গিয়ে পরিবর্তন করা যাবে।"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"টগল টেস্ট চালু করা হয়েছে"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"টগল টেস্ট বন্ধ করা হয়েছে"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"সেকেন্ডারি অ্যাকশন ও ডেকরেশন ডেমো"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"সেকেন্ডারি অ্যাকশন টেস্ট"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"শুধুমাত্র সেকেন্ডারি অ্যাকশন বেছে নেওয়া যেতে পারে"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ডেকরেশন টেস্ট"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"সেকেন্ডারি অ্যাকশন ও ডেকরেশন"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"সারিও বেছে নেওয়া যেতে পারে"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"সেকেন্ডারি অ্যাকশন বেছে নেওয়া হয়েছে"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"সারির প্রাইমারি অ্যাকশন বেছে নেওয়া হয়েছে"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"অন্যান্য টেমপ্লেটের ডেমো"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ডেমো শোকেস করুন"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"টেমপ্লেট লেআউট সংক্রান্ত ডেমো"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"\'ভয়েস অ্যাক্সেস\' অ্যাপের ডেমো স্ক্রিন"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ব্যবহারকারীর ইন্টার‍্যাকশন"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"অনুমতি সংক্রান্ত ডেমোর জন্য অনুরোধ জানানো"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"অ্যাপ্লিকেশন ওভারফ্লো ভ্যালিডেটর"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"পরিবর্তন করার সময় নিম্নলিখিত টেমপ্লেট পরীক্ষা করুন"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"গাড়ি পার্ক করা থেকে ড্রাইভিং অবস্থা"</string>
     <string name="perm_group" msgid="3834918337351876270">"অনুমতি সংক্রান্ত গ্রুপ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase অ্যাপের জন্য অনুমতি সংক্রান্ত গ্রুপ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"সুনির্দিষ্ট লোকেশনে অ্যাক্সেস"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-bs/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-bs/strings.xml
index f92b5a5..e2b505e 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-bs/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-bs/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Dostignuto je ograničenje za zadatak\nAko nastavite, prisilno ćete zaustaviti aplikaciju"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Korak zadatka: %1$d od %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknite da idete naprijed"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Posjetite različite šablone i pobrinite se da automobil bude u načinu rada za vožnju"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo verzija dugmeta za uključivanje/isključivanje"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Testiranje uključivanja/isključivanja"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Dozvoljene su izmjene koje zavise od statusa"</string>
@@ -307,14 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Dozvoljena su ažuriranja u vezi s radnjama navigiranja prema nazad."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Testiranje uključivanja/isključivanja je omogućeno"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Testiranje uključivanja/isključivanja je onemogućeno"</string>
-    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Pokazna verzija sekundarne radnje i dekoracije"</string>
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Sekundarna radnja i demo verzija dekoracije"</string>
     <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test sekundarne radnje"</string>
-    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Može se odabrati samo sekundarna radnja"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Moguće je odabrati samo sekundarnu radnju"</string>
     <string name="decoration_test_title" msgid="8450127046762442244">"Test dekoracije"</string>
     <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundarne radnje i dekoracija"</string>
-    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Može se odabrati i redak"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Moguće je odabrati i red"</string>
     <string name="secondary_action_toast" msgid="5076434693504006565">"Odabrana je sekundarna radnja"</string>
-    <string name="row_primary_action_toast" msgid="756516694751965204">"Odabran je redak primarne radnje"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Odabrana je primarna radnja reda"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demo verzije raznih šablona"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demo verzije predstavljanja"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo verzije rasporeda predloška"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ekran demo verzije Pristupa glasom"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Korisničke interakcije"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Zatraži demo verzije odobrenja"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Alat za provjeru preklopnog menija aplikacije"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testirajte sljedeće šablone tokom promjene"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"vozilo iz stanja parkiranosti u stanje vožnje"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupa odobrenja"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupa odobrenja za aplikaciju Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Pristup preciznoj lokaciji"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ca/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ca/strings.xml
index db8e8fa..e51c494 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ca/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ca/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"S\'ha arribat al límit de tasques\nEn continuar es forçarà l\'aturada de l\'aplicació"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Pas de la tasca %1$d de %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Fes clic per anar endavant"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Visita les diferents plantilles i comprova que el cotxe sigui en mode de conducció"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demostració d\'un botó de commutació"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test de commutació"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Es permeten canvis amb estat"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Es permeten actualitzacions a les operacions d\'anar enrere."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Prova de commutació activada"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Prova de commutació desactivada"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demostració de l\'acció secundària i la decoració"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Prova de l\'acció secundària"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Només es pot seleccionar l\'acció secundària"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Prova de decoració"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Accions secundàries i decoració"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"La fila també es pot seleccionar"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"S\'ha seleccionat l\'acció secundària"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"S\'ha seleccionat l\'acció principal de la fila"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demostracions de plantilles diverses"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demostracions de Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demostracions de dissenys de plantilles"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Pantalla de demostració de Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interaccions dels usuaris"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demostracions de sol·licitud de permisos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador del menú addicional de l\'aplicació"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Prova les següents plantilles mentre canvies"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"el vehicle de l\'estat aparcat a mode de conducció"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grup de permisos"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grup de permisos de l\'aplicació Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Accés a la ubicació precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-cs/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-cs/strings.xml
index ba7bab0..5f4d0ad 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-cs/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-cs/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Byl dosažen limit úkolů\nPokračováním vynutíte ukončení aplikace"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Krok úkolu %1$d z %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknutím přejdete vpřed"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Navštivte různé šablony a ujistěte se, že je auto v režimu jízdy"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Ukázka přepínače"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test přepínače"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Sledované změny jsou povoleny"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"U zpětných operací jsou povoleny aktualizace."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test přepínače je povolen"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test přepínače byl zakázán"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Ukázka sekundární akce a dekorace"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test sekundární akce"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Lze vybrat pouze sekundární akci"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Zkouška dekorace"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundární akce a dekorace"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Řádek lze také vybrat"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Je vybrána sekundární akce"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Je vybrána primární akce řádku"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Ukázky různých šablon"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Ukázky Výběru"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Ukázky šablon rozvržení"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ukázka obrazovky pro ovládání hlasem"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interakce uživatelů"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Ukázky žádostí o oprávnění"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validátor přetečení aplikace"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Vyzkoušejte následující šablony při přechodu"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"auta ze zaparkovaného do jedoucího stavu"</string>
     <string name="perm_group" msgid="3834918337351876270">"Skupina oprávnění"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Skupina oprávnění pro vystavenou aplikaci"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Přístup k přesné poloze"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-da/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-da/strings.xml
index 03958d9..5039e9d 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-da/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-da/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Grænsen for opgaver blev nået\nHvis du fortsætter, tvinges appen til at standse"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Opgavetrin %1$d af %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klik for at gå videre"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Gå til de forskellige skabeloner, og tjek, at bilen er i køretilstand"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo for kontakt"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Slå test til/fra"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Tilstandsfulde ændringer er tilladt"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demoskærm for Stemmeadgang"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Brugerinteraktioner"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Anmod om tilladelsesdemoer"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validator for overløb af apps"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Test følgende skabeloner, mens du skifter"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"bilens tilstand fra Parkeret til Kører"</string>
     <string name="perm_group" msgid="3834918337351876270">"Tilladelsesgruppe"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Tilladelsesgruppe for Showcase-appen"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Adgang til nøjagtig lokation"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-de/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-de/strings.xml
index e3c79af..0ea9b40 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-de/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-de/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Aufgabenlimit erreicht\nDurch Fortfahren wird das Beenden der App erzwungen"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Aufgabe: Schritt %1$d von %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klicken, um fortzufahren"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Bitte rufe die verschiedenen Vorlagen auf und achte darauf, dass sich das Auto im Fahrmodus befindet"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo der Ein-/Aus-Schaltfläche"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test der Ein-/Aus-Schaltfläche"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Zustandsorientierte Änderungen sind erlaubt"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Updates beim Zurückgehen erlaubt."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test der Ein-/Aus-Schaltfläche aktiviert"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test der Ein-/Aus-Schaltfläche deaktiviert"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo der sekundären Aktion und der Dekoration"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test für sekundäre Aktion"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Nur die sekundäre Aktion kann ausgewählt werden"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekorationstest"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundäre Aktionen und Dekoration"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Auch diese Zeile kann ausgewählt werden"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Sekundäre Aktion ist ausgewählt"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Zeile mit der primären Aktion ist ausgewählt"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demos der verschiedenen Vorlagen"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demos anzeigen"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo der Layoutvorlagen"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Bildschirm für Voice Access-Demo"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Nutzerinteraktionen"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demos zur Berechtigungsanfrage"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Anwendungs-Overflow-Validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Bitte teste die folgenden Vorlagen, wenn du"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"das Fahrzeug vom Park- in den Fahrmodus umschaltest"</string>
     <string name="perm_group" msgid="3834918337351876270">"Berechtigungsgruppe"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Berechtigungsgruppe für die Showcase App"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Zugriff auf genauen Standort"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-el/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-el/strings.xml
index 5213362..13c3309 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-el/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-el/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Συμπληρώθηκε το όριο εργασιών\nΜε μετάβαση προς τα εμπρός, θα γίνει αναγκαστική διακοπή της εφαρμογής."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Βήμα εργασίας %1$d από %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Κάντε κλικ για μετάβαση εμπρός"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Επισκεφτείτε διαφορετικά πρότυπα και διασφαλίστε ότι το αυτοκίνητό σας είναι σε λειτουργία οδήγησης"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Επίδειξη κουμπιού εναλλαγής"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Εναλλαγή δοκιμής"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Επιτρέπονται οι αλλαγές με επίβλεψη κατάστασης"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Οθόνη επίδειξης Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Αλληλεπιδράσεις χρήστη"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Αίτημα για επιδείξεις αδειών"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Επικύρωση υπερχείλισης εφαρμογής"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Δοκιμάστε τα παρακάτω πρότυπα κατά την αλλαγή"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"της κατάστασης του αυτοκινήτου από στάθμευση σε οδήγηση"</string>
     <string name="perm_group" msgid="3834918337351876270">"Ομάδα αδειών"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Ομάδα αδειών για την εφαρμογή Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Πρόσβαση στην Ακριβή τοποθεσία"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-en-rAU/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-en-rAU/strings.xml
index d2a35fd..7d3d9cb 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-en-rAU/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-en-rAU/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Task limit reached\nGoing forward will force stop the app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Task step %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Click to go forward"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Please visit the different templates and ensure that the car is in driving mode"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Toggle button demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Toggle test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stateful changes are allowed"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access demo screen"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"User interactions"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Request permissions demos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Application overflow validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Please test the following templates while changing"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"the vehicle from parked to driving state"</string>
     <string name="perm_group" msgid="3834918337351876270">"Permission group"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Permission group for Showcase app"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Access to fine location"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-en-rCA/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-en-rCA/strings.xml
index d2a35fd..7d3d9cb 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-en-rCA/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-en-rCA/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Task limit reached\nGoing forward will force stop the app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Task step %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Click to go forward"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Please visit the different templates and ensure that the car is in driving mode"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Toggle button demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Toggle test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stateful changes are allowed"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access demo screen"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"User interactions"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Request permissions demos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Application overflow validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Please test the following templates while changing"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"the vehicle from parked to driving state"</string>
     <string name="perm_group" msgid="3834918337351876270">"Permission group"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Permission group for Showcase app"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Access to fine location"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-en-rGB/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-en-rGB/strings.xml
index d2a35fd..7d3d9cb 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-en-rGB/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-en-rGB/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Task limit reached\nGoing forward will force stop the app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Task step %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Click to go forward"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Please visit the different templates and ensure that the car is in driving mode"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Toggle button demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Toggle test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stateful changes are allowed"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access demo screen"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"User interactions"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Request permissions demos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Application overflow validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Please test the following templates while changing"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"the vehicle from parked to driving state"</string>
     <string name="perm_group" msgid="3834918337351876270">"Permission group"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Permission group for Showcase app"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Access to fine location"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-en-rIN/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-en-rIN/strings.xml
index d2a35fd..7d3d9cb 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-en-rIN/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-en-rIN/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Task limit reached\nGoing forward will force stop the app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Task step %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Click to go forward"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Please visit the different templates and ensure that the car is in driving mode"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Toggle button demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Toggle test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stateful changes are allowed"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access demo screen"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"User interactions"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Request permissions demos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Application overflow validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Please test the following templates while changing"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"the vehicle from parked to driving state"</string>
     <string name="perm_group" msgid="3834918337351876270">"Permission group"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Permission group for Showcase app"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Access to fine location"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-es-rUS/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-es-rUS/strings.xml
index 1e8bca3..dabdb75 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-es-rUS/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-es-rUS/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Se alcanzó el límite de tareas\nSi avanzas, se forzará la detención de la app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Paso %1$d de %2$d de la tarea"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Haz clic para avanzar"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Visita las diferentes plantillas y asegúrate de que el automóvil esté en modo de conducción"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demostración de botón de activación"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Prueba el botón de activación"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Se permiten los cambios con estado"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Se permiten las actualizaciones en las operaciones de retroceso."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Prueba del botón de activación habilitada"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Prueba del botón de activación desactivada"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demostración de una acción secundaria y decoración"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Prueba de la acción secundaria"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Sólo puede seleccionarse la acción secundaria"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Prueba de decoración"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Acciones secundarias y decoraciones"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"También se puede seleccionar la fila"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Se seleccionó una acción secundaria"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Se seleccionó una acción de fila principal"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demostraciones de plantillas varias"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demostraciones de Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demostración de plantilla de diseño"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Pantalla de demostración de Acceso por voz"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interacciones del usuario"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demostración de solicitudes de permisos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador de exceso de aplicaciones"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Prueba las siguientes plantillas mientras cambias"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"el vehículo del estado de estacionamiento al de conducción"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo de permisos"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo de permisos para la app de Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acceso a la ubicación precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-es/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-es/strings.xml
index 3db6907..1d82de7 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-es/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-es/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Se ha alcanzado el límite de tareas\nSi continuas, se forzará la detención de la aplicación"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Paso %1$d de %2$d de la tarea"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Haz clic para continuar"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Consulta las diferentes plantillas y comprueba que el coche esté en modo de conducción"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo de botón activar/desactivar"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Prueba del interruptor"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Se permiten cambios de estado"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Actualizaciones permitidas al ir atrás."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Prueba del interruptor habilitada"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Prueba del interruptor inhabilitada"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo sobre acción secundaria y decoración"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Prueba de acción secundaria"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Solo se puede seleccionar la acción secundaria"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Prueba de decoración"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Acciones secundarias y decoración"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"También se puede seleccionar la fila"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Se ha seleccionado la acción secundaria"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Se ha seleccionado la acción principal de la fila"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Otras demos de plantillas"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demos de Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demos de diseño de plantillas"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Pantalla de la demo de Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interacciones de usuarios"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demos de solicitud de permisos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador de desbordamiento de aplicaciones"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Prueba las siguientes plantillas mientras se hace el cambio"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"el vehículo del estado de estacionamiento al de conducción"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo de permisos"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo de permisos de la aplicación Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acceso a la ubicación precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-et/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-et/strings.xml
index 40d2630..9d508d5 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-et/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-et/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Ülesannete piirang on saavutatud\nJätkamisel rakendus sundsuletakse"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Ülesande toiming %1$d %2$d-st"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klõpsake edasiliikumiseks"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Vaadake eri mallid üle ja veenduge, et auto oleks sõidurežiimis"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Lülitusnupu demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Testi lüliti"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Olekulised muudatused on lubatud"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Värskendused on tagasiminekutoimingute korral lubatud."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Lülititest on lubatud"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Lülititest on keelatud"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Teisese toimingu ja dekoratsiooni demo"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Teisese toimingu test"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Valida saab ainult teisese toimingu"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekoratsiooni test"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Teisesed toimingud ja dekoratsioon"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Rea saab samuti valida"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Valitud on teisene toiming"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Valitud on rea peamine toiming"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Mitmesuguste mallide demod"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Esiletõstmise demod"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Malli paigutuse demod"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Accessi demo kuva"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Kasutaja interaktsioonid"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Lubade taotlemise demod"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Rakenduse ületäite kinnitaja"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testige järgmisi malle, kui lülitate"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"sõidukit pargitud olekust sõitmise olekusse"</string>
     <string name="perm_group" msgid="3834918337351876270">"Lubade grupp"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase\'i rakenduse lubade grupp"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Juurdepääs täpsele asukohale"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-eu/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-eu/strings.xml
index 447e227..eda6e05 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-eu/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-eu/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Zereginen mugara iritsi zara\nAurrera eginez gero, aplikazioa gelditzera behartuko duzu"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Zereginaren %1$d/%2$d urratsa"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Aurrera egiteko, sakatu hau"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Ikusi txantiloiak eta ziurtatu ibilgailua gidatze moduan dagoela"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Etengailuaren demo-bertsioa"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Etengailuaren proba"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Aldaketa egoeradunak egin daitezke"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Atzeko planoko eragiketak eguneratu egin daitezke."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Gaitu da etengailuaren proba"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Desgaitu da etengailuaren proba"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Bigarren mailako ekintzaren eta apainketaren demo-bertsioa"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Bigarren mailako ekintzaren proba"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Bigarren mailako ekintza soilik hauta daiteke"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Apainketaren proba"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Bigarren mailako ekintzak eta apainketa"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Errenkada ere hauta daiteke"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Bigarren mailako ekintza hautatuta dago"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Errenkadari dagokion ekintza nagusia hautatuta dago"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Bestelako txantiloien demo-bertsioak"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Erakutsi demo-bertsioak"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Txantiloi-diseinuen demo-bertsioak"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ahots bidezko sarbidearen demo-bertsioaren pantaila"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Erabiltzailearen interakzioak"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Baimen-eskaeren demo-bertsioak"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Aplikazio-luzapenen baliozkotzailea"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Egin txantiloi hauen probak"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ibilgailua \"aparkatuta\" egoeratik \"gidatzen\" egoerara aldatu bitartean"</string>
     <string name="perm_group" msgid="3834918337351876270">"Baimenen taldea"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase aplikazioaren baimenen taldea"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Kokapen zehatzerako sarbidea"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-fa/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-fa/strings.xml
index 4dbd909..1cd0cda 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-fa/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-fa/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"به حد مجاز تکلیف رسیدید\nاگر ادامه دهید، برنامه به‌اجبار متوقف خواهد شد"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"‏مرحله %1$d از %2$d تکلیف"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"برای ادامه دادن، کلیک کنید"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"لطفاً از الگوهای مختلف بازدید کنید و مطمئن شوید خودرو در حالت رانندگی باشد"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"نسخه نمونه دکمه مبدل"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"امتحان کردن تغییر وضعیت"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"تغییرات حالت‌مند مجاز است"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"به‌روزرسانی در عملیات‌های برگشتی مجاز است."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"آزمایش تغییر وضعیت فعال شد"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"آزمایش تغییر وضعیت غیرفعال شد"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"نمونه آرایه‌گری و کنش فرعی"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"آزمایش کنش فرعی"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"فقط کنش فرعی را می‌توان انتخاب کرد"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"آزمایش آرایه‌گری"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"کنش‌های فرعی و آرایه‌گری"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ردیف را هم می‌توان انتخاب کرد"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"کنش فرعی انتخاب شده است"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"کنش اصلی ردیف انتخاب شده است"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"الگوهای متفرقه نمونه"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"نمایش نمونه‌ها"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"نسخه‌های نمونه طرح‌بندی الگو"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"صفحه نمونه دسترسی صوتی"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"تعاملات کاربران"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"درخواست اجازه برای نسخه‌های نمونه"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"اعتبارسنج سرریز برنامه"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"لطفاً درحین تغییر دادن، الگوهای زیر را آزمایش کنید"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"وسیله نقلیه از حالت پارک به حالت رانندگی"</string>
     <string name="perm_group" msgid="3834918337351876270">"گروه اجازه"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"گروه اجازه برنامه «ویترین»"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"دسترسی به مکان دقیق"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-fi/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-fi/strings.xml
index 622bd9e..f5de8d0 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-fi/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-fi/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Tehtäväraja saavutettu\nEteneminen pakottaa sovelluksen sulkeutumaan"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Tehtävän vaihe %1$d/%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Siirry eteenpäin klikkaamalla"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Tarkista eri mallit ja varmista, että auto on ajotilassa"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Päälle/pois-painikkeen esittely"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Vaihtotesti"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Tilattomat muutokset ovat sallittuja"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Päivitykset sallittu siirryttäessä edelliseen näkymään."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Vaihtotesti käytössä"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Vaihtotesti pois käytöstä"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Toissijainen toiminto ja kuvio ‑demo"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Toissijaisen toiminnon testi"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Voit valita vain toissijaisen toiminnon"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Kuviotesti"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Toissijaiset toiminnot ja kuvio"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Voit valita myös rivin"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Toissijainen toiminto on valittu"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Rivin ensisijainen toiminto on valittu"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Sekalaisten mallien esittelyt"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase-esittelyt"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Malliasettelujen esittelyt"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Accessin esittelynäyttö"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Käyttäjän toiminta"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Pyydä lupien esittelyjä"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Sovelluksen ylivuodon tarkistustyökalu"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testaa seuraavat mallit vaihtaessasi"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"pysäköidystä autosta ajettuun autoon"</string>
     <string name="perm_group" msgid="3834918337351876270">"Luparyhmä"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Esittely-sovelluksen luparyhmä"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Pääsy tarkkaan sijaintiin"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-fr-rCA/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-fr-rCA/strings.xml
index a215254..1f27a42 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-fr-rCA/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-fr-rCA/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Limite de la tâche atteinte\nAller de l\'avant forcera l\'arrêt de l\'application"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Étape %1$d de %2$d de la tâche"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Cliquez pour avancer"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Veuillez consulter les différents modèles et vous assurer que la voiture est en mode Voiture"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Démo du commutateur"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Essai du commutateur"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Les changements à état sont autorisés"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Mises à jour autorisées lors des opérations de retour."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Essai du commutateur activé"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Essai du commutateur désactivé"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Démo d\'action secondaire et de décoration"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test d\'action secondaire"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Seule l\'action secondaire peut être sélectionnée"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test de décoration"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Actions secondaires et décoration"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Cette ligne peut également être sélectionnée"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"L\'action secondaire est sélectionnée"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"L\'action primaire de la ligne est sélectionnée"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Démos de divers modèles"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Présenter les démos"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Démos de mise en page du modèle"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Écran d\'autorisation à l\'accès vocal"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interactions avec l\'utilisateur"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demande d\'autorisation pour les démos."</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Outil de validation de menu à développer d\'application"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Veuillez tester les modèles suivants lorsque vous basculez"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"l\'état du véhicule stationné à celui de conduite"</string>
     <string name="perm_group" msgid="3834918337351876270">"Groupe d\'autorisations"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Groupe d\'autorisations pour l\'application Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Accès à la localisation précise"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-fr/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-fr/strings.xml
index b38ddf4..917226e 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-fr/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-fr/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Limite de tâche atteinte\nContinuer forcera l\'arrêt de l\'appli"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Étape %1$d sur %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Cliquer pour continuer"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Veuillez consulter les différents modèles et vous assurer que le véhicule est en mode Voiture."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Démo du bouton d\'activation"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Activer/Désactiver le test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Les modifications avec état sont autorisées"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Mises à jour autorisées sur les opérations de retour."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test d\'activation/de désactivation activé"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test d\'activation/de désactivation désactivé"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Démo de l\'action secondaire et de la décoration"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test de l\'action secondaire"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Seule l\'action secondaire peut être sélectionnée"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test de la décoration"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Actions secondaires et décoration"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"La ligne peut également être sélectionnée"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"L\'action secondaire est sélectionnée"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"L\'action principale de la ligne est sélectionnée"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Démos de divers modèles"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Présenter les démos"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Démos de mise en page du modèle"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Écran de démo Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interactions des utilisateurs"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Démos de demandes d\'autorisation"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Programme de validation du menu de développement de l\'appli"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Veuillez tester les modèles suivant lorsque vous faites passer"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"l\'état du véhicule de garé à en mouvement"</string>
     <string name="perm_group" msgid="3834918337351876270">"Groupe d\'autorisations"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Groupe d\'autorisations pour l\'appli Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Accès à la position précise"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-gl/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-gl/strings.xml
index 7610451..f8d344e 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-gl/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-gl/strings.xml
@@ -307,22 +307,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Permítense actualizacións ao ir á pantalla anterior."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Activouse a proba do interruptor"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Desactivouse a proba do interruptor"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Acción secundaria e demostración de decoración"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Proba da acción secundaria"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Só se pode seleccionar a acción secundaria"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Proba de decoración"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Accións secundarias e decoración"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Tamén se pode seleccionar a fila"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Seleccionouse a acción secundaria"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Seleccionouse a acción principal da fila"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Outras demostracións de modelos"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demostracións de Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demostracións de deseños de modelo"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-gu/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-gu/strings.xml
index c64878f..fc2bc84 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-gu/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-gu/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"કાર્યની મર્યાદાએ પહોંચી ગયા\nઆગળ વધવાથી ઍપ ફરજિયાત બંધ થઈ જશે"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$dમાંથી %1$d કાર્ય માટેનું પગલું"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"આગળ વધવા માટે ક્લિક કરો"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"કૃપા કરીને વિભિન્ન નમૂનાઓની મુલાકાત લો અને ખાતરી કરો કે કાર ડ્રાઇવિંગ મોડમાં છે"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ટૉગલ બટનનો ડેમો"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"પરીક્ષણ ટૉગલ કરો"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"સ્ટેટસમાં થતા ફેરફારનો મંજૂરી છે"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"અગાઉના કાર્યો પર અપડેટ કરવાની મંજૂરી છે."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"ટૉગલનું પરીક્ષણ ચાલુ કર્યું"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"ટૉગલનું પરીક્ષણ બંધ કર્યું"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ગૌણ ઍક્શન અને ડેકોરેશન ડેમો"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ગૌણ ઍક્શન પરીક્ષણ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"માત્ર ગૌણ ઍક્શન પસંદ કરી શકાય છે"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ડેકોરેશન પરીક્ષણ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ગૌણ ઍક્શન અને ડેકોરેશન"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"પંક્તિ પણ પસંદ કરી શકાય છે"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ગૌણ ઍક્શન પસંદ કરી"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"પ્રાથમિક ઍક્શન પંક્તિ પસંદ કરી"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"વિવિધ નમૂનાઓના ડેમો"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ડેમો બતાવો"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"નમૂનાના લેઆઉટનો ડેમો"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Accessના ડેમોની સ્ક્રીન"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"વપરાશકર્તાની ક્રિયાપ્રતિક્રિયાઓ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"પરવાનગીઓના ડેમોની વિનંતી કરો"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ઍપ્લિકેશન ઓવરફ્લો વૅલિડેટર"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"વાહનને પાર્ક કરેલામાંથી ડ્રાઇવિંગ સ્થિતિમાં બદલતી વખતે"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"કૃપા કરીને નીચે આપેલા નમૂનાનું પરીક્ષણ કરો"</string>
     <string name="perm_group" msgid="3834918337351876270">"પરવાનગીનું ગ્રૂપ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase ઍપ માટે પરવાનગીનું ગ્રૂપ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"સચોટ લોકેશનનો ઍક્સેસ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-hi/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-hi/strings.xml
index 3d7f0af..44b1b65 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-hi/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-hi/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"टास्क की सीमा पूरी हुई\nआगे जाने पर, ऐप्लिकेशन को ज़बरदस्ती रोक दिया जाएगा"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"टास्क के %2$d चरणों में से %1$d चरण"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"आगे जाने के लिए क्लिक करें"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"कृपया अलग-अलग टेंप्लेट पर जाकर, यह पक्का करें कि कार ड्राइविंग मोड में है"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"टॉगल बटन का डेमो"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"टॉगल टेस्ट"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"स्टेटफ़ुल बदलाव करने की अनुमति है"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"पिछले पेज पर जाकर बदलाव किए जा सकते हैं."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"टॉगल टेस्ट चालू किया गया"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"टॉगल टेस्ट बंद किया गया"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"सेकंडरी ऐक्शन और डेकोरेशन का डेमो"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"सेकंडरी ऐक्शन टेस्ट"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"सिर्फ़ सेकंडरी ऐक्शन को चुना जा सकता है"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"डेकोरेशन टेस्ट"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"सेकंडरी ऐक्शन और डेकोरेशन"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"पंक्ति को भी चुना जा सकता है"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"सेकंडरी ऐक्शन चुना गया"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"पंक्ति से जुड़ा प्राइमरी ऐक्शन चुना गया"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"दूसरे टेंप्लेट के डेमो"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"डेमो दिखाएं"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"टेंप्लेट लेआउट के डेमो"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access के डेमो की स्क्रीन"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"यूज़र इंटरैक्शन"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"अनुमतियों के अनुरोध का डेमो"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ऐप्लिकेशन ओवरफ़्लो वैलिडेटर"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"कार की स्थिति को पार्क से ड्राइविंग में बदलते समय"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"दिए गए टेंप्लेट आज़माएं"</string>
     <string name="perm_group" msgid="3834918337351876270">"अनुमतियों का ग्रुप"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase ऐप्लिकेशन को दी गई अनुमतियों का ग्रुप"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"जगह की सटीक जानकारी का ऐक्सेस"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-hr/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-hr/strings.xml
index 7b12f9d..dbe9520 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-hr/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-hr/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Dosegnuto ograničenje zadatka\nAko nastavite, aplikacija će se prisilno zaustaviti"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Korak zadatka: %1$d od %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknite da biste nastavili"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Posjetite različite predloške i potvrdite da je automobil u načinu za vožnju"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Pokazna verzija prekidača"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Prebaci test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Dopuštene su promjene u praćenju stanja"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Pokazna verzija zaslona za Glasovni pristup"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Korisničke interakcije"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Zatraži pokazne verzije dopuštenja"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validator prelijevanja aplikacije"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testirajte sljedeće predloške tijekom promjene"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"stanja vozila iz parkiranog u vožnju"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupa dopuštenja"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupa dopuštenja za aplikaciju Odabir urednika"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Pristup preciznoj lokaciji"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-hu/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-hu/strings.xml
index cd2c9c8..919d60a 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-hu/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-hu/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Feladatkorlát elérve\nA továbblépés az app bezárását kényszeríti"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$d/%1$d. lépés a feladatban"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kattintson a továbblépéshez"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Keresse fel a különböző sablonokat, és ellenőrizze, hogy az autó vezetési módban van-e"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Váltógomb bemutatója"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Kapcsolóteszt"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Az állapotmegőrző módosítások engedélyezettek"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Frissítések engedélyezve a visszalépési műveleteknél."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Kapcsolóteszt engedélyezve"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Kapcsolóteszt letiltva"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Másodlagos művelet és dekorációs demó"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Másodlagos művelet tesztelése"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Csak a másodlagos művelet választható ki"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekoráció tesztelése"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Másodlagos műveletek és dekorációk"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"A sor is kiválasztható"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Másodlagos művelet kiválasztva"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Sor elsődleges művelete kiválasztva"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Egyéb sablonok – demók"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Kirakat – demók"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Sablonelrendezések bemutatói"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Hangalapú hozzáférés képernyő – demó"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Felhasználói interakciók"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Engedélyek kérése – demók"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"További alkalmazáselemeket tartalmazó menü ellenőrzője"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Tesztelje a következő sablonokat, miközben"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"a járművel parkolásból vezetés állapotba vált"</string>
     <string name="perm_group" msgid="3834918337351876270">"Engedélycsoport"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Engedélycsoport a bemutató alkalmazáshoz"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Pontos helymeghatározáshoz való hozzáférés"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-hy/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-hy/strings.xml
index 3c3fc70..375942e 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-hy/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-hy/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Առաջադրանքների սահմանաչափը սպառված է։\nԵթե շարունակեք, հավելվածի աշխատանքը կկանգնեցվի։"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Առաջադրանքի քայլ %1$d՝ %2$d-ից"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Սեղմեք՝ առաջ անցնելու համար"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Դիտեք տարբեր ձևանմուշներ և համոզվեք, որ մեքենան վարելու ռեժիմում է"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Փոխանջատիչի դեմո"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Միացնել/անջատել ստուգումը"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Կարգավիճակի փոփոխությունները թույլատրված են"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Թարմացումները թույլատրված են՝ ֆոնային ռեժիմում գործողություններ կատարելու համար։"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Փոխանջատիչի փորձարկումը միացված է"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Փոխանջատիչի փորձարկումն անջատված է"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Երկրորդական գործողության և ձևավորման դեմո"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Երկրորդական գործողության թեստ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Կարելի է ընտրել միայն երկրորդական գործողությունը"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Ձևավորման թեստ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Երկրորդական գործողություններ և ձևավորում"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Շարքը ևս կարելի է ընտրել"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Ընտրված է շարքի երկրորդական գործողությունը"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Ընտրված է շարքի գլխավոր գործողությունը"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Այլ ձևանմուշների դեմոներ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Ցուցադրել դեմոները"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Ձևանմուշի դասավորության դեմոներ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access-ի դեմոյի էկրան"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Օգտատիրոջ փոխազդումներ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Թույլտվության հարցումների դեմոներ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Հավելվածի լրացուցիչ ընտրացանկի ստուգում"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Փորձարկեք հետևյալ ձևանմուշները, երբ փոխում եք"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"մեքենայի ռեժիմը կայանվածից վարելու ռեժիմի"</string>
     <string name="perm_group" msgid="3834918337351876270">"Թույլտվությունների խումբ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase հավելվածի թույլտվությունների խումբ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Ճշգրիտ տեղադրության հասանելիություն"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-in/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-in/strings.xml
index c5708cf..4735ecd 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-in/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-in/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Batas tugas tercapai\nJika dilanjutkan, aplikasi akan dipaksa berhenti"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Langkah tugas %1$d dari %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klik untuk melanjutkan"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Buka template lain dan pastikan mobil dalam mode mengemudi"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo Tombol"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Pengujian tombol"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Perubahan stateful diizinkan"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Update diizinkan di halaman sebelumnya."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Pengujian Tombol Diaktifkan"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Pengujian Tombol Dinonaktifkan"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo Tindakan Sekunder dan Dekorasi"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Pengujian Tindakan Sekunder"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Hanya tindakan sekunder yang dapat dipilih"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Pengujian Dekorasi"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Tindakan Sekunder dan Dekorasi"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Baris juga dapat dipilih"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Tindakan Sekunder dipilih"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Tindakan utama baris dipilih"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demo Template Lain-Lain"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demo Berita Pilihan"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo Tata Letak Template"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Layar Demo Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interaksi Pengguna"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demo Permintaan Izin"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validator Overflow Aplikasi"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Uji template berikut saat mengubah"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"status kendaraan dari parkir ke mengemudi"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grup Izin"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grup Izin untuk Aplikasi Etalase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Akses ke Lokasi Terperinci"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-is/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-is/strings.xml
index e81894d..5ffd5fb 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-is/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-is/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Verkefnismörkum náð\nEf haldið er áfram verður lokun forrits þvinguð"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Verkefnisskref %1$d af %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Smelltu til að halda áfram"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Opnaðu mismunandi sniðmát og gakktu úr skugga um að bíllinn sé í akstursstillingu"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Sýnishorn hnapps til að slökkva og kveikja"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Velja/afvelja prófun"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Breytingar á stöðu eru leyfðar"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Uppfærslur leyfðar á fyrri aðgerðum."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Kveikt á rofaprófun"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Slökkt á rofaprófun"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Aukaaðgerð og prufuskreyting"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Prufa aukaaðgerðar"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Aðeins er hægt að velja aukaaðgerð"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Prufuskreyting"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Aukaaðgerðir og skreyting"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Einnig er hægt að velja línuna"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Aukaaðgerð er valin"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Aðalaðgerð línu er valin"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Sýnishorn ýmissa sniðmáta"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Prufuútgáfur Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Sýnishorn sniðmátsuppsetningar"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Prufuskjár fyrir raddskipanir"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Aðgerðir notenda"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Sýnishorn heimildabeiðna"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Notkunarprófun á yfirflæði forrits"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Prófaðu eftirfarandi sniðmát á meðan skipt er á milli þess að hafa"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ökutækið kyrrstætt eða akandi"</string>
     <string name="perm_group" msgid="3834918337351876270">"Heimildahópur"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Heimildahópur fyrir Showcase forritið"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Aðgangur að nákvæmri staðsetningu"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-it/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-it/strings.xml
index 09c13bf..c3a7bdf 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-it/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-it/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Limite attività raggiunto\nSe prosegui forzerai l\'interruzione dell\'app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Passaggio attività %1$d di %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Fai clic per proseguire"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Controlla i diversi modelli e assicurati che l\'auto sia in modalità Auto"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo Pulsante di attivazione/disattivazione"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test attivazione/disattivazione"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Sono consentite modifiche stateful"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Aggiornamenti consentiti per le operazioni in background."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test di attivazione/disattivazione abilitato"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test di attivazione/disattivazione disabilitato"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo su azione secondaria e decorazione"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test azione secondaria"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Solo l\'azione secondaria può essere selezionata"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test decorazione"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Azioni secondarie e decorazione"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Anche la riga può essere selezionata"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"È stata selezionata l\'azione secondaria"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"È stata selezionata l\'azione principale della riga"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demo modelli vari"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demo Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo Layout modello"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Schermata demo Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interazioni dell\'utente"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demo su come richiedere le autorizzazioni"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Strumento di convalida del menu Extra dell\'applicazione"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testa i seguenti modelli mentre lo stato"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"del veicolo passa da \"Parcheggiato\" a \"Alla guida\""</string>
     <string name="perm_group" msgid="3834918337351876270">"Gruppo di autorizzazioni"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Gruppo di autorizzazioni relativo all\'app Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Accesso alla posizione precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-iw/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-iw/strings.xml
index 7fc4821..f5bc7e7 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-iw/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-iw/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"הגעת להגבלת המשימות\nהמשך יוביל לסגירה ידנית של האפליקציה"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"‏שלב %1$d מתוך %2$d במשימה"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"יש ללחוץ כדי להמשיך"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"יש לבדוק את התבניות השונות ולוודא שהמכונית במצב נהיגה"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"הדגמה של מתג להחלפת מצב"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"בדיקה של החלפת המצב"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"מותר לערוך שינויי מצב"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"‏מסך ההדגמה של אפליקציית Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"אינטראקציות של משתמשים"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"הדגמה של בקשת הרשאות"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"כלי התיקוף לגבי גלישה באפליקציה"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"יש לבדוק את התבניות הבאות במהלך שינוי"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"מצב הרכב מ\'חניה\' ל\'נהיגה\'"</string>
     <string name="perm_group" msgid="3834918337351876270">"קבוצת הרשאות"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"‏קבוצת הרשאות לאפליקציית Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"גישה למיקום המדויק"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ja/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ja/strings.xml
index 772f3a6..e697085 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ja/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ja/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"タスクの上限に達しました\n続行するとアプリが強制停止されます"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"タスクのステップ %1$d / %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"クリックして続行"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"別のテンプレートにアクセスして自動車が運転モードであることを確認してください"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"切り替えボタンのデモ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"切り替えのテスト"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ステートフルな変更が許可されています"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"アップデートにより「戻る」操作ができるようになりました。"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"切り替えのテスト有効"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"切り替えのテスト無効"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"セカンダリ アクションとデコレーションのデモ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"セカンダリ アクション テスト"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"セカンダリ アクションのみ選択できます"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"デコレーション テスト"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"セカンダリ アクションとデコレーション"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"行も選択できます"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"セカンダリ アクションを選択しました"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"行のプライマリ アクションを選択しました"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"その他のテンプレートのデモ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"デモを表示"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"テンプレート レイアウトのデモ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access のデモ画面"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ユーザー操作"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"権限リクエストのデモ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"アプリ オーバーフロー バリデータ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"変更を行う際に以下のテンプレートをテストしてください"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"車両の状態が駐車中から運転状態に変わりました"</string>
     <string name="perm_group" msgid="3834918337351876270">"権限グループ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ショーケース アプリの権限グループ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"精細な位置情報へのアクセス"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ka/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ka/strings.xml
index 0db9ab0..3a78f70 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ka/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ka/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"მიღწეულია ამოცანების ლიმიტი\nგაგრძელება გამოიწვევს აპის ძალით შეჩერებას"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"ამოცანის ეტაპი: %1$d/%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"დააწკაპუნეთ გასაგრძელებლად"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"გთხოვთ, ეწვიოთ სხვადასხვა შაბლონებს, რათა დარწმუნდეთ, რომ მანქანა საავტომობილო რეჟიმშია"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"გადართვა ღილაკის დემო"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"გადამრთველის ტესტი"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"სტატუსის ცვლილებები ნებადართულია"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"განახლებებმა დაუშვა უკან დაბრუნება."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"გადამრთველის ტესტი ჩართულია"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"გადამრთველის ტესტი გათიშულია"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"მეორადი მოქმედების და დეკორაციის დემო"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"მეორადი მოქმედების ტესტი"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"შესაძლებელია მხოლოდ მეორადი მოქმედების არჩევა"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"დეკორაციის ტესტი"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"მეორადი მოქმედებები და დეკორაცია"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ასევე შეიძლება მწკრივის არჩევა"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"არჩეულია მეორადი მოქმედება"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"არჩეულია მწკრივის პირველადი მოქმედება"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"სხვადასხვა შაბლონური დემოები"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"დემოების ჩვენება"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"შაბლონის განლაგების დემო"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"ხმის წვდომის დემო ეკრანი"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"მომხმარებლის ინტერაქციები"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"მოითხოვეთ ნებართვების დემო"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"აპლიკაციების გადატვირთვის ვალიდატორი"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"გთხოვთ, შეამოწმოთ შემდეგი შაბლონები ცვლილებისას"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ავტომობილი პარკირებულიდან მართვის მდგომარეობამდე"</string>
     <string name="perm_group" msgid="3834918337351876270">"ნებართვის ჯგუფი"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ნებართვის ჯგუფი Showcase აპისთვის"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"წვდომა კარგ მდებარეობაზე"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-kk/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-kk/strings.xml
index fbec90e..fe5649b 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-kk/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-kk/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Тапсырма өз шегіне жетті.\nІлгері жүрсеңіз, қолданба күштеп тоқтатылады."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d/%2$d тапсырма қадамы"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Ілгері жүру үшін басыңыз."</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Әртүрлі үлгілерді қарап, автокөліктің жүргізу режимінде тұрғанына көз жеткізіңіз."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Ауыстыру түймесі (демо нұсқасы)"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Ауыстырғыш сынағы"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Күй бақыланатын өзгерістерге рұқсат берілген."</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"\"Артқа\" операциясында өзгертуге рұқсат етілген"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Ауыстырғыш сынағы қосылған."</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Ауыстырғыш сынағы өшірілген."</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Қосымша әрекеттің және безендірудің демо нұсқасы"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Қосымша әрекетті сынау"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Қосымша әрекет қана таңдалады."</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Безендіруді сынау"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Қосымша әрекеттер және безендіру"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Жолды да таңдауға болады."</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Қосымша әрекет таңдалды."</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Жол үшін негізгі әрекет таңдалды."</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"\"Басқалары\" үлгісінің демо нұсқасы"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Презентацияның демо нұсқасы"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Формат үлгісі (демо нұсқалары)"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access демо нұсқасының экраны"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Пайдаланушы әрекеттері"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Рұқсат сұрау операциясының демо нұсқасы"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Қолданбаның қосымша мәзірін тексеру құралы"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Көлікті тұраққа қойылған күйден жүргізу күйіне өзгерту кезінде"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"келесі үлгілерді тексеріп көріңіз."</string>
     <string name="perm_group" msgid="3834918337351876270">"Рұқсат тобы"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase қолданбасының рұқсат тобы"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Нақты локацияны пайдалану"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-km/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-km/strings.xml
index 99666c01..afb1fc5 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-km/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-km/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"បានឈានដល់​ដែនកំណត់កិច្ចការហើយ\nការបន្តទៀត​នឹងបង្ខំឱ្យកម្មវិធីបញ្ឈប់"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"ជំហានកិច្ចការទី %1$d នៃ %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ចុចដើម្បីបន្ត"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"សូមចូលមើលទម្រង់គំរូផ្សេងៗ និងធ្វើឱ្យប្រាកដថា រថយន្តស្ថិតក្នុងមុខងារបើកបរ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"គំរូបង្ហាញនៃប៊ូតុងបិទ/បើក"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ការធ្វើតេស្ត​ប៊ូតុងបិទ/បើក"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ការផ្លាស់ប្ដូរ​តាមស្ថានភាពត្រូវបានអនុញ្ញាត"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"បានអនុញ្ញាត​ការដំឡើងកំណែ​នៅលើ​ប្រតិបត្តិការ​ថយក្រោយ។"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"បានបើកការធ្វើតេស្ត​ប៊ូតុងបិទ/បើក"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"បានបិទការធ្វើតេស្ត​ប៊ូតុងបិទ/បើក"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"គំរូបង្ហាញការតុបតែង និងសកម្មភាពបន្ទាប់បន្សំ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"តេស្តសកម្មភាពបន្ទាប់បន្សំ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"អាចជ្រើសរើសបានតែសកម្មភាពបន្ទាប់បន្សំប៉ុណ្ណោះ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"តេស្តនៃការតុបតែង"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ការតុបតែង និងសកម្មភាពបន្ទាប់បន្សំ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ជួរដេកក៏អាចត្រូវបានជ្រើសរើសផងដែរ"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"សកម្មភាពបន្ទាប់បន្សំត្រូវបានជ្រើសរើស"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"សកម្មភាពចម្បងជួរដេកត្រូវបានជ្រើសរើស"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"គំរូបង្ហាញនៃ​ទម្រង់គំរូផ្សេងៗ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"គំរូបង្ហាញអំពីការតាំងរំលេច"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"គំរូបង្ហាញនៃប្លង់​ទម្រង់គំរូ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"អេក្រង់គំរូបង្ហាញនៃ​ការចូលប្រើប្រាស់តាមរយៈសំឡេង"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"អន្តរកម្មរបស់អ្នកប្រើប្រាស់"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"គំរូបង្ហាញនៃ​ការស្នើសុំការអនុញ្ញាត"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ឧបករណ៍បញ្ជាក់ភាពលើសចំណុះកម្មវិធី"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"សូមធ្វើតេស្តទម្រង់គំរូដូចខាងក្រោម ពេលផ្លាស់ប្ដូរ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"យានជំនិះពីស្ថានភាពចតទៅជាស្ថានភាពបើកបរ"</string>
     <string name="perm_group" msgid="3834918337351876270">"ក្រុមអនុញ្ញាត"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ក្រុមអនុញ្ញាតសម្រាប់កម្មវិធី Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"សិទ្ធិចូលប្រើ​ទីតាំងជាក់លាក់"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-kn/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-kn/strings.xml
index c85df6b..196f9f0 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-kn/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-kn/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ಕಾರ್ಯದ ಮಿತಿಯನ್ನು ತಲುಪಿದ್ದೀರಿ\nಮುಂದುವರಿಸಿದರೆ ಆ್ಯಪ್ ಅನ್ನು ಬಲವಂತವಾಗಿ ನಿಲ್ಲಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"ಕಾರ್ಯದ ಹಂತ %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ಮುಂದೆ ಹೋಗಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"ವಿವಿಧ ಟೆಂಪ್ಲೇಟ್‌ಗಳಿಗೆ ಭೇಟಿ ನೀಡಿ ಮತ್ತು ಕಾರು, ಡ್ರೈವಿಂಗ್ ಮೋಡ್‌ನಲ್ಲಿರುವುದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ಟಾಗಲ್ ಬಟನ್ ಡೆಮೋ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ಟಾಗಲ್ ಟೆಸ್ಟ್"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ಪುನಃ ಸ್ಥಾಪಿಸಬಹುದಾದ ಬದಲಾವಣೆಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ಹಿನ್ನೆಲೆ ಕಾರ್ಯಾಚರಣೆಗಳಿಗಾಗಿ ಅಪ್‌ಡೇಟ್‌ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"ಟಾಗಲ್ ಟೆಸ್ಟ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"ಟಾಗಲ್ ಟೆಸ್ಟ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ದ್ವಿತೀಯಕ ಕ್ರಿಯೆ ಮತ್ತು ಅಲಂಕಾರ ಡೆಮೊ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ದ್ವಿತೀಯಕ ಕ್ರಿಯೆಯ ಪರೀಕ್ಷೆ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"ದ್ವಿತೀಯಕ ಕ್ರಿಯೆಯನ್ನು ಮಾತ್ರ ಆಯ್ಕೆ ಮಾಡಬಹುದು"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ಅಲಂಕಾರ ಪರೀಕ್ಷೆ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ದ್ವಿತೀಯಕ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಅಲಂಕಾರ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ಸಾಲನ್ನು ಸಹ ಆಯ್ಕೆ ಮಾಡಬಹುದು"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ದ್ವಿತೀಯಕ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"ಸಾಲಿನ ಪ್ರಾಥಮಿಕ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"ಇತರ ಟೆಂಪ್ಲೇಟ್‌ಗಳ ಡೆಮೋಗಳು"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase ಡೆಮೋಗಳು"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"ಟೆಂಪ್ಲೇಟ್ ಲೇಔಟ್ ಡೆಮೋಗಳು"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"ಧ್ವನಿ ಆ್ಯಕ್ಸೆಸ್ ಡೆಮೋ ಸ್ಕ್ರೀನ್"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ಬಳಕೆದಾರರ ಸಂವಹನಗಳು"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"ಅನುಮತಿಗಳ ಡೆಮೋಗಳನ್ನು ವಿನಂತಿಸಿ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ಅಪ್ಲಿಕೇಶನ್ ಓವರ್‌ಫ್ಲೋ ಮೌಲ್ಯಮಾಪಕ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"ಬದಲಾಯಿಸುವಾಗ ಕೆಳಗಿನ ಟೆಂಪ್ಲೇಟ್‌ಗಳನ್ನು ಪರೀಕ್ಷಿಸಿ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ನಿಲುಗಡೆಯಿಂದ ಚಾಲನೆಯ ಸ್ಥಿತಿಗೆ ಬಂದ ವಾಹನ"</string>
     <string name="perm_group" msgid="3834918337351876270">"ಅನುಮತಿ ಗುಂಪು"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ಶೋಕೇಸ್ ಆ್ಯಪ್‌ನ ಅನುಮತಿ ಗುಂಪು"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ನಿಖರವಾದ ಸ್ಥಳಕ್ಕೆ ಆ್ಯಕ್ಸೆಸ್"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ko/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ko/strings.xml
index 9aa1ed8..20f9cf1 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ko/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ko/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"작업 제한에 도달함\n계속 진행하면 앱이 강제 종료됩니다"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"작업 단계 %1$d/%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"클릭하여 진행"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"다른 템플릿을 방문하여 자동차가 운전 모드인지 확인하세요."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"전환 버튼 데모"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"전환 테스트"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"스테이트풀(Stateful) 변경은 허용됨"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"뒤로 작업에서 업데이트가 허용되었습니다."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"전환 테스트 사용 설정됨"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"전환 테스트 사용 중지됨"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"보조 작업 및 장식 데모"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"보조 작업 테스트"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"보조 작업만 선택할 수 있습니다."</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"장식 테스트"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"보조 작업 및 장식"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"행도 선택할 수 있습니다."</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"보조 작업 선택됨"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"행 기본 작업 선택됨"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"기타 템플릿 데모"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"쇼케이스 데모"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"템플릿 레이아웃 데모"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"음성 액세스 데모 화면"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"사용자 상호작용"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"권한 요청 데모"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"애플리케이션 오버플로 검사기"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"변경하는 동안 다음 템플릿을 테스트하세요."</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"차량을 주차 상태에서 운전 상태로"</string>
     <string name="perm_group" msgid="3834918337351876270">"권한 그룹"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"쇼케이스 앱에 대한 권한 그룹"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"정확한 위치 액세스"</string>
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 486cba8..4c8ad5c 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
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Тапшырманын чегине жетти\nАлдыга жылсаңыз, колдонмо мажбурлап токтотулат"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Тапшырма кадамы %1$d of %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Алдыга өтүү үчүн чыкылдатыңыз"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Башка үлгүлөргө өтүп, унаа айдоо режиминде экенин текшериңиз"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Күйгүзүү/өчүрүү баскычынын демосу"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Өчүрүү/күйгүзүү сыноосу"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Абалы сакталган өзгөртүүлөргө уруксат берилген"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Артка операцияларында жаңыртууларга уруксат берет."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Өчүрүү/күйгүзүү сыноосу иштетилди"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Өчүрүү/күйгүзүү сыноосу өчүрүлдү"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Кошумча аракет жана Жасалгалоо демосу"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Кошумча аракетти сыноо"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Кошумча аракетти гана тандоого болот"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Жасалгалоону сыноо"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Кошумча аракеттер жана Жасалгалоо"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Сапты да тандоого болот"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Кошумча аракет тандалды"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Негизги аракет сабы тандалды"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Башка үлгүлөрдүн демолору"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase демолору"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Үлгү калыптарынын демолору"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access демо экраны"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Колдонуучунун мамилелери"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Демо версияларга уруксат суроо"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Ашыкча колдонмолорду текшергич"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Өзгөртүп жатканда төмөнкү үлгүлөрдү сынап көрүңүз:"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"токтоп турган унааны айдоо абалы"</string>
     <string name="perm_group" msgid="3834918337351876270">"Уруксаттар тобу"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Колдонмону көрсөтүү үчүн уруксаттар тобу"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Так жайгашкан жерди көрүү"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-lo/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-lo/strings.xml
index c1ad5d5..1b5d9ec 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-lo/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-lo/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ຮອດຂີດຈຳກັດໜ້າວຽກແລ້ວ\nຕໍ່ໄປຈະບັງຄັບຢຸດແອັບ"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"ຂັ້ນຕອນໜ້າວຽກທີ %1$d ຈາກທັງໝົດ %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ຄລິກເພື່ອໄປໜ້າ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"ກະລຸນາເຂົ້າໄປແມ່ແບບອື່ນ ແລະ ກວດໃຫ້ແນ່ໃຈວ່າລົດຢູ່ໃນໂໝດຂັບຂີ່"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ເດໂມປຸ່ມເປີດປິດ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ສະຫຼັບການທົດສອບ"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ອະນຸຍາດໃຫ້ມີການປ່ຽນແປງສະຖານະໄດ້"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ອະນຸຍາດໃຫ້ອັບເດດໃນການດຳເນີນການເບື້ອງຫຼັງ."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"ເປີດການນຳໃຊ້ການທົດສອບການສະຫຼັບ"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"ປິດການນຳໃຊ້ການທົດສອບການສະຫຼັບ"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ການສາທິດຄຳສັ່ງສຳຮອງ ແລະ ການຕົກແຕ່ງ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ການທົດສອບຄຳສັ່ງສຳຮອງ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"ສາມາດເລືອກໄດ້ສະເພາະຄຳສັ່ງສຳຮອງເທົ່ານັ້ນ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ການທົດສອບການຕົກແຕ່ງ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ຄຳສັ່ງສຳຮອງ ແລະ ການຕົກແຕ່ງ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ນອກຈາກນັ້ນຍັງເລືອກແຖວໄດ້ນຳ"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ເລືອກຄຳສັ່ງສຳຮອງຂອງແຖວແລ້ວ"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"ເລືອກຄຳສັ່ງຫຼັກຂອງແຖວແລ້ວ"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"ເດໂມແມ່ແບບອື່ນໆ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ເດໂມ Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"ເດໂມໂຄງຮ່າງແມ່ແບບ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"ໜ້າຈໍເດໂມການເຂົ້າເຖິງສຽງ"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ການໂຕ້ຕອບຂອງຜູ້ໃຊ້"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"ຮ້ອງຂໍການອະນຸຍາດເດໂມ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ໂປຣແກຣມກວດສອບລາຍການເພີ່ມເຕີມຂອງແອັບພລິເຄຊັນ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"ກະລຸນາທົດສອບແມ່ແບບຕໍ່ໄປນີ້ໃນຂະນະທີ່ປ່ຽນແປງ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ສະຖານະຂອງພາຫະນະຈາກຈອດຢູ່ເປັນກຳລັງຂັບຂີ່"</string>
     <string name="perm_group" msgid="3834918337351876270">"ກຸ່ມການອະນຸຍາດ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ກຸ່ມການອະນຸຍາດສຳລັບແອັບ Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ສິດເຂົ້າເຖິງສະຖານທີ່ແບບລະອຽດ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-lt/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-lt/strings.xml
index ac2a584..31e4669 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-lt/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-lt/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Pasiektas užduočių apribojimas\nTęsiant programa bus priverstinai sustabdyta"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d užduoties veiksmas iš %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Spustelėkite, jei norite tęsti"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Peržiūrėkite kitus šablonus ir įsitikinkite, kad automobilis veikia vairavimo režimu"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Perjungimo mygtuko demonstracinė versija"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Perjungti bandymą"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Leidžiami būsenos pakeitimai"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Naujiniai leidžiami ankstesnėms operacijoms."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Bandymo perjungimas įgalintas"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Bandymo perjungimas išjungtas"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Antrinio veiksmo ir dekoracijų demonstracinė versija"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Antrinio veiksmo bandymas"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Galima pasirinkti tik antrinį veiksmą"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekoracijų bandymas"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Antriniai veiksmai ir dekoracijos"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Taip pat galima pasirinkti eilutę"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Pasirinktas antrinis veiksmas"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Pasirinktas pagrindinis eilutės veiksmas"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Įvairių šablonų demonstracinės versijos"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Rodyti demonstracines versijas"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Šablonų išdėstymo demonstracinės versijos"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Prieigos balsu demonstracinės versijos ekranas"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Naudotojo sąveikos"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Leidimų prašymo demonstracinės versijos"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Programos perpildymo patvirtinimo priemonė"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Išbandykite toliau nurodytus šablonus įkraudami"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"transporto priemonė iš stovėjimo į važiavimo būseną"</string>
     <string name="perm_group" msgid="3834918337351876270">"Leidimų grupė"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Demonstracinės programos leidimų grupė"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Prieiga prie tikslios vietovės"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-lv/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-lv/strings.xml
index baa904c..6b4b746 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-lv/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-lv/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Sasniegts uzdevumu ierobežojums\nTurpinot lietotnes darbība tiks apturēta piespiedu kārtā."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Uzdevuma darbība: %1$d. no %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Noklikšķiniet, lai dotos tālāk"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Lūdzu, skatiet dažādas veidnes un nodrošiniet, ka automašīna ir braukšanas režīmā."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Pārslēgšanas pogas demonstrācija"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Pārslēgšanas tests"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stāvokļa izmaiņas ir atļautas"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Pārejai atpakaļ ir atļauti atjauninājumi."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Pārslēgšanas tests ir iespējots"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Pārslēgšanas tests ir atspējots"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Sekundārās darbības un noformējuma demonstrācija"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Sekundārās darbības tests"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Atlasīt var tikai sekundāro darbību"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Noformējuma tests"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundārās darbības un noformējums"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Arī rindu var atlasīt"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Atlasīta sekundārā darbība"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Atlasīta rindas primārā darbība"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Dažādu veidņu demonstrācijas"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase demonstrācijas"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Veidņu izkārtojumu demonstrācijas"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Balss piekļuves demonstrācijas ekrāns"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Lietotāju mijiedarbība"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demonstrācija: atļauju pieprasīšana"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Lietojumprogrammu pārpildes pārbaudes rīks"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Lūdzu, testējiet tālāk norādītās veidnes, kamēr maināt"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"transportlīdzekļa režīmu no apturēta uz braukšanas režīmu."</string>
     <string name="perm_group" msgid="3834918337351876270">"Atļauju grupa"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Atļauju grupa demonstrācijas lietotnei"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Piekļuve precīzai atrašanās vietai"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-mk/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-mk/strings.xml
index 8bbd60e..4eab700 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-mk/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-mk/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Достигнато е ограничувањето за задачи\nАко продолжите, апликацијата ќе се исклучи присилно"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Преземете чекор %1$d од %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Кликнете за да одите нанапред"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Одете на различните шаблони и погрижете се автомобилот да е во режим на возење"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Демо на копче за вклучување/исклучување"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Тест за вклучување/исклучување"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Дозволени се промени на зачувувањето на состојбата"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Ажурирањата се дозволени при операции на враќање назад."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Овозможено тест за вклучување/исклучување"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Оневозможено тест за вклучување/исклучување"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Демо за секундарно дејство и украсување"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Проба за секундарно дејство"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Само секундарното дејство може да се избере"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Проба за украсување"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Секундарни дејства и украсување"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Редот исто така може да се избере"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Избрано е секундарно дејство"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Избрано е примарно дејство на ред"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Разни демоа за шаблони"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Демоа за прикажување"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Демоа за распоред на шаблони"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Екран за демо за „Пристап со глас“"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Кориснички интеракции"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Побарајте дозволи за демо"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Алатка за потврдување прелевање на апликацијата"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Тестирајте ги следните шаблони додека менувате"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"возилото од паркирана во состојба на возење"</string>
     <string name="perm_group" msgid="3834918337351876270">"Група дозволи"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Група дозволи за апликација за вести избрани од издавачи"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Пристап до точна локација"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ml/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ml/strings.xml
index 0cfe4d8..1fe8d05 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ml/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ml/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ടാസ്ക്ക് പരിധിയെത്തി\nമുന്നോട്ട് പോകുന്നത് ആപ്പ് നിർബന്ധിതമായി നിർത്താൻ കാരണമാകും"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$d ടാസ്ക്ക് ഘട്ടങ്ങളിൽ %1$d -ാമത്തേത്"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"മുന്നോട്ട് പോകാൻ ക്ലിക്ക് ചെയ്യുക"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"വ്യത്യസ്ത ടെംപ്ലേറ്റുകൾ സന്ദർശിച്ച്, ഡ്രൈവിംഗ് മോഡിലാണ് കാർ ഉള്ളതെന്ന് ഉറപ്പാക്കുക"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ടോഗിൾ ബട്ടൺ ഡെമോ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ടെസ്റ്റ് മാറ്റുക"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"സ്റ്റേറ്റ്ഫുള്ളായ മാറ്റങ്ങൾ അനുവദനീയമാണ്"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access ഡെമോ സ്ക്രീൻ"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ഉപയോക്തൃ ഇടപഴകലുകൾ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"അനുമതി ഡെമോകൾ അഭ്യർത്ഥിക്കുക"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ആപ്ലിക്കേഷൻ ഓവർഫ്ലോ വാലിഡേറ്റർ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"പാർക്കിംഗിൽ നിന്ന് ഡ്രൈവിംഗ് നിലയിലേക്ക് വാഹനം"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"മാറ്റുമ്പോൾ, ഇനിപ്പറയുന്ന ടെംപ്ലേറ്റുകൾ പരിശോധിക്കുക"</string>
     <string name="perm_group" msgid="3834918337351876270">"അനുമതി ഗ്രൂപ്പ്"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase ആപ്പിനുള്ള അനുമതി ഗ്രൂപ്പ്"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ഫൈൻ ലൊക്കേഷനിലേക്കുള്ള ആക്സസ്"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-mn/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-mn/strings.xml
index faf65e2..512e67c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-mn/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-mn/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Ажлын хязгаарт хүрсэн\nҮргэлжлүүлснээр аппыг хүчээр зогсооно"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Ажлын %2$d-н %1$d-р алхам"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Үргэлжлүүлэхийн тулд товшино уу"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Өөр загварт зочилж, машин нь втомашин жолоодох горимд байгаа эсэхийг баталгаажуулна уу"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Асаах товчийн демо"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Асаах/Унтраах туршилт"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Төлөвтэй өөрчлөлтийг зөвшөөрнө"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Шинэчлэлтүүдийг арын үйл ажиллагаанд хийхийг зөвшөөрдөг."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Асаах/Унтраах туршилтыг идэвхжүүлсэн"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Асаах/Унтраах туршилтыг идэвхгүй болгосон"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Хоёрдогч үйлдэл ба чимэглэлийн демо"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Хоёрдогч үйлдлийн тест"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Зөвхөн хоёрдогч үйлдлийг сонгох боломжтой"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Чимэглэлийн туршилт"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Хоёрдогч үйлдлүүд ба чимэглэл"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Мөрийг мөн сонгож болно"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Хоёрдогч үйлдлийг сонгосон"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Мөрийн үндсэн үйлдлийг сонгосон"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Холимог загварын демо"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase-н демо"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Загварын бүдүүвч бүхий демо"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access-н демо дэлгэц"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Хэрэглэгчийн харилцан үйлдлүүд"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Зөвшөөрлийн демогийн хүсэлт тавих"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Аппликэйшний илүү ашиглалтыг баталгаажуулагч"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Цэнэглэх үедээ дараах загварыг туршина уу"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"зогсоолд байснаас жолоодох төлөв рүү сэлгэсэн тээврийн хэрэгсэл"</string>
     <string name="perm_group" msgid="3834918337351876270">"Зөвшөөрлийн бүлэг"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase аппын зөвшөөрлийн бүлэг"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Нарийвчилсан байршилд хандах"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-mr/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-mr/strings.xml
index d95f041..36e204a 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-mr/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-mr/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"टास्कची मर्यादा गाठली आहे\nपुढे सुरू ठेवल्यास, अ‍ॅप सक्तीने थांबवले जाईल"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"टास्कची %1$d पैकी %2$d पायरी"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"पुढे जाण्यासाठी क्लिक करा"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"कृपया विविध टेंप्लेटना भेट द्या आणि कार ही ड्रायव्हिंग मोडमध्ये असल्याची खात्री करा"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"टॉगल बटण डेमो"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"टॉगल करण्याशी संबंधित चाचणी"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"स्थितीशी संबंधित बदलांना अनुमती आहे"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"बॅक ऑपरेशनवर अपडेटना अनुमती दिली आहे."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"टॉगल करण्याशी संबंधित चाचणी सुरू केली"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"टॉगल करण्याशी संबंधित चाचणी बंद केली"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"दुय्यम कृती आणि सजावट डेमो"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"दुय्यम कृती चाचणी"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"फक्त दुय्यम कृती निवडली जाऊ शकते"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"सजावट चाचणी"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"दुय्यम कृती आणि सजावट"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"पंक्तीदेखील निवडली जाऊ शकते"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"दुय्यम कृती निवडली आहे"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"पंक्तीशी संबंधित प्राथमिक कृती निवडली आहे"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"इतर टेंप्लेटचे डेमो"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"डेमो दाखवा"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"टेंप्लेट लेआउट डेमो"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access डेमो स्क्रीन"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"वापरकर्ता संवाद"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"परवानग्या डेमोची विनंती करा"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"अ‍ॅप्लिकेशन ओव्हरफ्लो व्हॅलिडेटर"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"बदलताना कृपया पुढील टेंप्लेटची चाचणी घ्या"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"कार पार्क करण्यापासून ते ड्रायव्हिंगच्या परिस्थितीपर्यंत"</string>
     <string name="perm_group" msgid="3834918337351876270">"परवानगी गट"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase अ‍ॅपसाठी परवानगी गट"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"अचूक स्थान याचा अ‍ॅक्सेस"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ms/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ms/strings.xml
index 1530d05..afd924c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ms/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ms/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Had tugasan dicapai\nMaju ke hadapan akan henti paksa apl"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Langkah tugasan %1$d daripada %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klik untuk maju"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Sila lawati templat yang berbeza dan pastikan kereta berada dalam mod memandu"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo Butang Togol"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Togol ujian"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Perubahan keadaan dibenarkan"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Kemaskinian dibenarkan pada operasi belakang."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Ujian Togol Didayakan"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Ujian Togol Dilumpuhkan"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Tindakan Sekunder dan Demonstrasi Perhiasan"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Ujian Tindakan Sekunder"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Hanya tindakan sekunder boleh dipilih"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Ujian Perhiasan"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Tindakan Sekunder dan Perhiasan"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Baris ini juga boleh dipilih"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Tindakan Sekunder dipilih"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Tindakan utama baris dipilih"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Pelbagai Demo Templat"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demo Wadah"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo Reka Letak Templat"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Skrin Demo Akses Suara"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interaksi Pengguna"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demo Minta Kebenaran"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Pengesah Limpahan Aplikasi"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Sila uji templat yang berikut semasa membuat penukaran"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"kenderaan daripada keadaan diletakkan kepada memandu"</string>
     <string name="perm_group" msgid="3834918337351876270">"Kumpulan Kebenaran"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Kumpulan Kebenaran untuk Apl Wadah"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Akses kepada Lokasi Halus"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-my/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-my/strings.xml
index da967bc0c..f005fa7 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-my/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-my/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"လုပ်ဆောင်စရာကန့်သတ်ချက် ရောက်သွားပြီ\nရှေ့ဆက်သွားခြင်းက အက်ပ်ကို မဖြစ်မနေရပ်ခိုင်းမည်"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"လုပ်ဆောင်စရာအဆင့် %2$d ခုအနက် %1$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ရှေ့ဆက်သွားရန် နှိပ်ပါ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"ပုံစံအမျိုးမျိုးကို ဝင်ကြည့်ပြီး ကားသည် မောင်းနှင်မုဒ်တွင်ရှိကြောင်း သေချာပါစေ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ဖွင့်ပိတ် ခလုတ် သရုပ်ပြချက်"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"စစ်ဆေးမှု ပြောင်းခြင်း"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"အနေအထားအပြည့် အပြောင်းအလဲများ ခွင့်ပြုထားသည်"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ပြန်ရွှေ့ခြင်းများတွင် အပ်ဒိတ်များကို ခွင့်ပြုသည်။"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"စမ်းသပ်ခလုတ် ဖွင့်ထားသည်"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"စမ်းသပ်ခလုတ် ပိတ်ထားသည်"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ဒုတိယဦးစားပေး လုပ်ဆောင်ချက်နှင့် တန်ဆာဆင်မှု သရုပ်ပြခြင်း"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ဒုတိယဦးစားပေးလုပ်ဆောင်ချက် စမ်းသပ်ခြင်း"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"ဒုတိယဦးစားပေးလုပ်ဆောင်ချက်ကိုသာ ရွေးနိုင်သည်"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"တန်ဆာဆင်မှု စမ်းသပ်ခြင်း"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ဒုတိယဦးစားပေးလုပ်ဆောင်ချက်များနှင့် တန်ဆာဆင်ခြင်း"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"အတန်းကိုလည်း ရွေးနိုင်သည်"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ဒုတိယဦးစားပေး လုပ်ဆောင်ချက်ကို ရွေးထားသည်"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"အတန်း၏ ပထမဦးစားပေး လုပ်ဆောင်ချက်ကို ရွေးထားသည်"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"အထွေထွေ ပုံစံသရုပ်ပြချက်များ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase သရုပ်ပြချက်များ"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"နမူနာပုံစံ သရုပ်ပြချက်များ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access သရုပ်ပြချက်စခရင်"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"အသုံးပြုသူ ပြန်လှန်တုံ့ပြန်မှုများ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"ခွင့်ပြုချက်များ တောင်းဆိုရန် သရုပ်ပြချက်"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"အပလီကေးရှင်းအပို စိစစ်မှုစနစ်"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"အားသွင်းစဉ်အတွင်း အောက်ပါပုံစံများကို စမ်းသပ်ပါ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ယာဉ်ရပ်နားသည်မှ မောင်းနှင်သည့် အခြေအနေသို့"</string>
     <string name="perm_group" msgid="3834918337351876270">"ခွင့်ပြုချက်အုပ်စု"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"‘စင်မြင့် အက်ပ်’ အတွက် ခွင့်ပြုချက်အုပ်စု"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"‘တည်နေရာအချော’ သုံးခွင့်"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-nb/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-nb/strings.xml
index 44e9320..8936507 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-nb/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-nb/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Oppgavegrensen er nådd\nHvis du fortsetter, blir appen tvunget til å avslutte"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Oppgavetrinn %1$d av %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klikk for å fortsette"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Gå til de ulike malene, og forsikre deg om at bilen er i kjøremodus"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo av av/på-knapp"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test av/på-knapp"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Dynamiske endringer er tillatt"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Oppdateringer tillates ved tilbakeoperasjoner."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test av av/på-knapp er aktivert"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test av av/på-knapp er deaktivert"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo av sekundærhandling og dekorasjon"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test av sekundærhandling"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Bare sekundærhandlingen kan velges"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekorasjonstest"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundærhandling og dekorasjon"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Raden kan også velges"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Sekundærhandlingen er valgt"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Hovedhandlingen til raden er valgt"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demoer av diverse maler"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demoer i fokus"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demoer av mallayout"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demoskjerm for Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Brukerinteraksjoner"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demoer for forespørsler om tillatelser"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Valideringsverktøy for appoverflyt"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Test disse malene når du bytter"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"fra parkerings- til kjøretilstand for kjøretøyet"</string>
     <string name="perm_group" msgid="3834918337351876270">"Tillatelsesgruppe"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Tillatelsesgruppe for Showcase-appen"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Tilgang til nøyaktig posisjon"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ne/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ne/strings.xml
index 19fcf1e..82567d5 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ne/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ne/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"कार्यको सीमा सकियो\nतपाईं अगाडि बढ्नुभयो भने एप जबरजस्ती रोकिने छ"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$d कार्यको %1$d औँ चरण"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"अगाडि बढ्न क्लिक गर्नुहोस्"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"कृपया फरक-फरक टेम्प्लेट प्रयोग गर्नुहोस् र कार ड्राइभिङ मोडमा छ भन्ने कुरा सुनिश्चित गर्नुहोस्"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"टगल गर्ने बटनको डेमो"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"टगल टेस्ट"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"स्टेटफुल परिवर्तन गर्ने अनुमति छ"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"अघिल्लो पेजमा गई परिवर्तन गर्न सकिन्छ।"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"टगल टेस्ट अन गरिएको छ"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"टगल टेस्ट अफ गरिएको छ"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"सेकेन्डरी एक्सन तथा डेकोरेसन डेमो"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"सेकेन्डरी एक्सन टेस्ट"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"सेकेन्डरी एक्सन मात्र चयन गर्न सकिन्छ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"डेकोरेसन टेस्ट"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"सेकेन्डरी एक्सन तथा डेकोरेसन"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"रो पनि चयन गर्न सकिन्छ"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"सेकेन्डरी एक्सन चयन गरिएको छ"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"रोको प्राइमरी एक्सन चयन गरिएको छ"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"टेम्प्लेटका विविध डेमोहरू"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"सोकेसहरूको डेमो"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"टेम्प्लेट लेआउटका डेमोहरू"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access को डेमो स्क्रिन"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"प्रयोगकर्ताले गरेका अन्तर्क्रिया"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"अनुमतिहरूका डेमोहरू माग्नुहोस्"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ऐप्लिकेसन ओभरफ्लो भ्यालिडेटर"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"कृपया SIM बदलक्ने बेलामा निम्न टेम्प्लेटहरूको परिक्षण गर्नुहोस्"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"पार्क गरिएको अवस्थाबाट चलाउने अवस्थामा लगिएको कार"</string>
     <string name="perm_group" msgid="3834918337351876270">"अनुमतिको समूह"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase एपलाई दिइएको अनुमतिको समूह"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"सटीक लोकेसन प्रयोग गर्ने अनुमति"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-nl/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-nl/strings.xml
index 076d9d2..41c1879 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-nl/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-nl/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Taaklimiet bereikt\nAls je doorgaat, wordt de app geforceerd gestopt"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Taakstap %1$d van %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klik om verder te gaan"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Open de verschillende templates en zorg dat de auto in de rijstand staat"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo voor schakelaar"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test aan-/uitzetten"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Stateful wijzigingen zijn toegestaan"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Updates toegestaan bij teruggaan in de weergavestapel."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Schakeltest aangezet"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Schakeltest uitgezet"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo voor secundaire actie en decoratie"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test voor secundaire actie"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Alleen de secundaire actie kan worden geselecteerd"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test voor decoratie"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Secundaire acties en decoratie"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"De rij kan ook worden geselecteerd"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Secundaire actie is geselecteerd"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Rij voor primaire actie is geselecteerd"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Diverse templatedemo\'s"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demo\'s laten zien"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo\'s voor opmaaktemplate"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demoscherm voor Spraaktoegang"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Gebruikersinteracties"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Rechtendemo\'s aanvragen"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Application Overflow Validator"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Test de volgende templates terwijl je het voertuig"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"van de parkeerstand in de rijstand zet"</string>
     <string name="perm_group" msgid="3834918337351876270">"Rechtengroep"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Rechtengroep voor Showcase-app"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Toegang tot exacte locatie"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-or/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-or/strings.xml
index 93bc94e..4a7ea67 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-or/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-or/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ଟାସ୍କର ସୀମାରେ ପହଞ୍ଚିଯାଇଛି\nଆଗକୁ ଗଲେ ଆପଟି ବାଧ୍ୟତାର ସହ ବନ୍ଦ ହୋଇଯିବ"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$dଟିରୁ %1$d ନମ୍ବର ଟାସ୍କର ଷ୍ଟେପ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ଆଗକୁ ଯିବା ପାଇଁ କ୍ଲିକ କରନ୍ତୁ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"ଦୟାକରି ବିଭିନ୍ନ ଟେମ୍ପଲେଟକୁ ଭିଜିଟ କରନ୍ତୁ ଏବଂ କାରଟି ଡ୍ରାଇଭିଂ ମୋଡରେ ଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ଟୋଗଲ ବଟନର ଡେମୋ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ପରୀକ୍ଷା ଟୋଗଲ କରନ୍ତୁ"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ଷ୍ଟେଟଫୁଲ ପରିବର୍ତ୍ତନଗୁଡ଼ିକୁ ଅନୁମତି ଦିଆଯାଇଛି"</string>
@@ -307,35 +306,24 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ପୃଷ୍ଠପଟର ଅପରେସନଗୁଡ଼ିକରେ ଅପଡେଟଗୁଡ଼ିକୁ ଅନୁମତି ଦିଆଯାଇଛି।"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"\"ପରୀକ୍ଷା ଟୋଗଲ କରିବା\" ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"\"ପରୀକ୍ଷା ଟୋଗଲ କରିବା\" ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ଦ୍ୱିତୀୟ କାର୍ଯ୍ୟ ଏବଂ ଡେକୋରେସନ ଡେମୋ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ଦ୍ୱିତୀୟ କାର୍ଯ୍ୟ ଟେଷ୍ଟ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"କେବଳ ଦ୍ୱିତୀୟ କାର୍ଯ୍ୟକୁ ଚୟନ କରାଯାଇପାରିବ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ଡେକୋରେସନ ଟେଷ୍ଟ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ଦ୍ୱିତୀୟ କାର୍ଯ୍ୟ ଏବଂ ଡେକୋରେସନ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ଏହି ଧାଡ଼ିଟିକୁ ମଧ୍ୟ ଚୟନ କରାଯାଇପାରିବ"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ଦ୍ୱିତୀୟ କାର୍ଯ୍ୟ ଚୟନ କରାଯାଇଛି"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"ଧାଡ଼ିର ପ୍ରାଥମିକ କାର୍ଯ୍ୟ ଚୟନ କରାଯାଇଛି"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"ବିବିଧ ଟେମ୍ପଲେଟର ଡେମୋ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Showcase ଡେମୋ"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"ଟେମ୍ପଲେଟ ଲେଆଉଟର ଡେମୋଗୁଡ଼ିକ"</string>
     <string name="grid_template_menu_demo_title" msgid="7096285873490705119">"ଗ୍ରିଡ ଟେମ୍ପଲେଟର ଡେମୋଗୁଡ଼ିକ"</string>
     <string name="voice_access_demo_title" msgid="3825223890895361496">"ଡେମୋ ସ୍କ୍ରିନକୁ ଭଏସ ଆକ୍ସେସ"</string>
-    <string name="user_interactions_demo_title" msgid="1356952319161314986">"ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ଇଣ୍ଟରାକ୍ସନ"</string>
+    <string name="user_interactions_demo_title" msgid="1356952319161314986">"ୟୁଜର ଇଣ୍ଟରାକ୍ସନ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"ଅନୁମତିର ଡେମୋ ପାଇଁ ଅନୁରୋଧ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ଆପ୍ଲିକେସନ ଓଭରଫ୍ଲୋ ଭାଲିଡେଟର"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"ପରିବର୍ତ୍ତନ କରିବା ବେଳେ ଦୟାକରି ନିମ୍ନୋକ୍ତ ଟେମ୍ପଲେଟଗୁଡ଼ିକୁ ପରୀକ୍ଷା କରନ୍ତୁ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ପାର୍କ କରାଯାଇଥିବାରୁ ଡ୍ରାଇଭିଂ ସ୍ଥିତି ପର୍ଯ୍ୟନ୍ତ ଗାଡ଼ି"</string>
     <string name="perm_group" msgid="3834918337351876270">"ଅନୁମତି ଗୋଷ୍ଠୀ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase ଆପ ପାଇଁ ଅନୁମତି ଗୋଷ୍ଠୀ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ସଠିକ୍ ଲୋକେସନକୁ ଆକ୍ସେସ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-pa/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-pa/strings.xml
index 3fb771d..80e73db 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-pa/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-pa/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ਕਾਰਜ ਸੀਮਾ ਪੂਰੀ ਹੋ ਗਈ\nਜਾਰੀ ਰੱਖਣ \'ਤੇ ਐਪ ਜ਼ਬਰਦਸਤੀ ਬੰਦ ਹੋ ਜਾਵੇਗੀ"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$d ਵਿੱਚੋਂ %1$d ਕਾਰਜ ਪੜਾਅ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ਅੱਗੇ ਜਾਣ ਲਈ ਕਲਿੱਕ ਕਰੋ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"ਕਿਰਪਾ ਕਰਕੇ ਵੱਖ-ਵੱਖ ਟੈਮਪਲੇਟਾਂ \'ਤੇ ਜਾਓ ਅਤੇ ਪੱਕਾ ਕਰੋ ਕਿ ਕਾਰ ਡਰਾਈਵਿੰਗ ਮੋਡ ਵਿੱਚ ਹੈ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ਟੌਗਲ ਬਟਨ ਦਾ ਡੈਮੋ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ਟੈਸਟ ਨੂੰ ਟੌਗਲ ਕਰੋ"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"ਸਪਸ਼ਟ ਤਬਦੀਲੀਆਂ ਕਰਨ ਦੀ ਆਗਿਆ ਹੈ"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"ਪਿਛਲੇ ਪੰਨੇ \'ਤੇ ਅੱਪਡੇਟ ਕਰਨ ਦੀ ਆਗਿਆ ਹੈ।"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"\'ਟੈਸਟ ਨੂੰ ਟੌਗਲ ਕਰੋ\' ਚਾਲੂ ਹੈ"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"\'ਟੈਸਟ ਨੂੰ ਟੌਗਲ ਕਰੋ\' ਬੰਦ ਹੈ"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ਸੈਕੰਡਰੀ ਕਾਰਵਾਈ ਅਤੇ ਸਜਾਵਟ ਦਾ ਡੈਮੋ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ਸੈਕੰਡਰੀ ਕਾਰਵਾਈ ਜਾਂਚ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"ਸਿਰਫ਼ ਸੈਕੰਡਰੀ ਕਾਰਵਾਈ ਨੂੰ ਹੀ ਚੁਣਿਆ ਜਾ ਸਕਦਾ ਹੈ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ਸਜਾਵਟ ਜਾਂਚ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ਸੈਕੰਡਰੀ ਕਾਰਵਾਈਆਂ ਅਤੇ ਸਜਾਵਟ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"ਕਤਾਰ ਨੂੰ ਵੀ ਚੁਣਿਆ ਜਾ ਸਕਦਾ ਹੈ"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ਸੈਕੰਡਰੀ ਕਾਰਵਾਈ ਚੁਣੀ ਗਈ ਹੈ"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"ਕਤਾਰ ਨਾਲ ਸੰਬੰਧਿਤ ਪ੍ਰਾਇਮਰੀ ਕਾਰਵਾਈ ਚੁਣੀ ਗਈ ਹੈ"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"ਫੁਟਕਲ ਟੈਮਪਲੇਟਾਂ ਦੇ ਡੈਮੋ"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ਸ਼ੋਅਕੇਸ ਦੇ ਡੈਮੋ"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"ਟੈਮਪਲੇਟ ਖਾਕੇ ਦੇ ਡੈਮੋ"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"ਅਵਾਜ਼ੀ ਪਹੁੰਚ ਡੈਮੋ ਸਕ੍ਰੀਨ"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"ਵਰਤੋਂਕਾਰ ਦੀਆਂ ਅੰਤਰਕਿਰਿਆਵਾਂ"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"ਇਜਾਜ਼ਤਾਂ ਦੀ ਬੇਨਤੀ ਦਾ ਡੈਮੋ"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ਐਪਲੀਕੇਸ਼ਨ ਓਵਰਫ਼ਲੋ ਵੈਲੀਡੇਟਰ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"ਕਿਰਪਾ ਕਰਕੇ ਵਾਹਨ ਨੂੰ ਪਾਰਕ ਤੋਂ ਡਰਾਈਵਿੰਗ ਸਥਿਤੀ ਵਿੱਚ ਬਦਲਦੇ ਸਮੇਂ"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ਅੱਗੇ ਦਿੱਤੇ ਟੈਮਪਲੇਟਾਂ ਨੂੰ ਅਜ਼ਮਾਓ"</string>
     <string name="perm_group" msgid="3834918337351876270">"ਇਜਾਜ਼ਤ ਗਰੁੱਪ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ਸ਼ੋਅਕੇਸ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਗਰੁੱਪ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ਸਟੀਕ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-pl/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-pl/strings.xml
index a355377..bb11ae2 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-pl/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-pl/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Osiągnięto limit zadań\nKontynuowanie spowoduje wymuszenie zatrzymania aplikacji"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Krok zadania %1$d z %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknij, aby przejść dalej"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Sprawdź różne szablony i upewnij się, że samochód jest w trybie jazdy"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Wersja demonstracyjna przycisku przełączania"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test przełączania"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Zmiany stanu są dozwolone"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Aktualizacje dozwolone na operacjach cofania."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test przełączania został włączony"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test przełączania został wyłączony"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Działanie alternatywne i wersja demonstracyjna dekoracji"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test działania alternatywnego"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Można wybrać tylko działanie alternatywne"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test dekoracji"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Działania alternatywne i dekoracja"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Można wybrać również wiersz"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Wybrano działanie alternatywne"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Wybrano wiersz z działaniem głównym"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Wersje demonstracyjne różnych szablonów"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Wersje demonstracyjne do prezentacji"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Wersje demonstracyjne szablonów układu"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ekran wersji demonstracyjnej Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interakcje użytkownika"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Wersje demonstracyjne próśb o uprawnienia"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Walidator przepełnienia aplikacji"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Przetestuj te szablony, gdy przełączasz"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"samochód ze stanu zaparkowania do stanu jazdy"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupa uprawnień"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupa uprawnień dotyczących aplikacji Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Dostęp do dokładnej lokalizacji"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-pt-rBR/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-pt-rBR/strings.xml
index e06208c..3ab19fd 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-pt-rBR/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-pt-rBR/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Limite da tarefa atingido\nContinuar vai forçar a parada do app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Etapa da tarefa: %1$d de %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Clique para continuar"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Visite os diferentes modelos e confira se o veículo está no modo carro"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstração de botão de ativação"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Alternar teste"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Mudanças com estado são permitidas"</string>
@@ -307,35 +306,24 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Atualizações permitidas em operações de retorno."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Alternância de teste ativada"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Alternância de teste desativada"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demonstração de ação secundária e de decoração"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Teste de ação secundária"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Apenas a ação secundária pode ser selecionada"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Teste de decoração"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Ações secundárias e decoração"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"A linha também pode ser selecionada"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"A ação secundária está selecionada"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"A ação principal da linha está selecionada"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstração de modelos diversos"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demonstrações em destaque"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstrações de modelos de layout"</string>
     <string name="grid_template_menu_demo_title" msgid="7096285873490705119">"Demonstrações de modelo de grade"</string>
-    <string name="voice_access_demo_title" msgid="3825223890895361496">"Tela de demonstração do Acesso por voz"</string>
+    <string name="voice_access_demo_title" msgid="3825223890895361496">"Tela de demonstração do Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interações do usuário"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Solicitar demonstração de permissões"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador do menu flutuante do aplicativo"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Teste os seguintes modelos durante a mudança"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"o veículo do estado de estacionamento para o de condução"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo de permissões"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo de permissões do app Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acesso à localização precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-pt-rPT/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-pt-rPT/strings.xml
index de619c2..90157c4 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-pt-rPT/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-pt-rPT/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"O limite de tarefas foi atingido\nSe avançar, vai forçar a paragem da app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Passo da tarefa %1$d de %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Clique para avançar"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Visite os diferentes modelos e certifique-se de que o carro está no modo de condução"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstração do botão ativar/desativar"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Ativar/desativar teste"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"São permitidas alterações com estado"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ecrã de demonstração do Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interações do utilizador"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demonstrações sobre como pedir autorizações"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador de menu adicional da aplicação"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Teste os seguintes modelos durante o carregamento"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"o veículo de estacionado para o estado de condução"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo de autorizações"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo de autorizações da app Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acesso à localização exata"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-pt/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-pt/strings.xml
index e06208c..3ab19fd 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-pt/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-pt/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Limite da tarefa atingido\nContinuar vai forçar a parada do app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Etapa da tarefa: %1$d de %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Clique para continuar"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Visite os diferentes modelos e confira se o veículo está no modo carro"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstração de botão de ativação"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Alternar teste"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Mudanças com estado são permitidas"</string>
@@ -307,35 +306,24 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Atualizações permitidas em operações de retorno."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Alternância de teste ativada"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Alternância de teste desativada"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demonstração de ação secundária e de decoração"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Teste de ação secundária"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Apenas a ação secundária pode ser selecionada"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Teste de decoração"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Ações secundárias e decoração"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"A linha também pode ser selecionada"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"A ação secundária está selecionada"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"A ação principal da linha está selecionada"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstração de modelos diversos"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demonstrações em destaque"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstrações de modelos de layout"</string>
     <string name="grid_template_menu_demo_title" msgid="7096285873490705119">"Demonstrações de modelo de grade"</string>
-    <string name="voice_access_demo_title" msgid="3825223890895361496">"Tela de demonstração do Acesso por voz"</string>
+    <string name="voice_access_demo_title" msgid="3825223890895361496">"Tela de demonstração do Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interações do usuário"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Solicitar demonstração de permissões"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validador do menu flutuante do aplicativo"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Teste os seguintes modelos durante a mudança"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"o veículo do estado de estacionamento para o de condução"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo de permissões"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo de permissões do app Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acesso à localização precisa"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ro/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ro/strings.xml
index fb087ba..8e0262c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ro/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ro/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"A fost atinsă limita pentru activități\nDacă alegi să continui, aplicația se va opri forțat"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Pasul activității: %1$d din %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Dă clic pentru a merge înainte"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Accesează diferitele șabloane și asigură-te că mașina este în modul Cu mașina"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstrație cu buton de comutare"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Activează / dezactivează testul"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Modificările cu menținere de stare sunt permise"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Sunt permise actualizările operațiunilor în fundal."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Testul de comutare este activat"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Testul de comutare este dezactivat"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demonstrație pentru acțiunea secundară și decorație"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test pentru acțiunea secundară"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Numai acțiunea secundară poate fi selectată"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test pentru decorație"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Acțiuni secundare și decorație"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Și rândul poate fi selectat"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Acțiunea secundară a fost selectată"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Acțiunea principală de pe rând a fost selectată"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstrații diverse cu șabloane"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demonstrații pentru Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstrații cu aspecte de șablon"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ecran demonstrativ pentru accesul vocal"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interacțiunile utilizatorilor"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Solicită demonstrații privind permisiunile"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Program de validare a meniului suplimentar al aplicației"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testează următoarele șabloane în timpul schimbării"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"stării vehiculului din Parcat în Cu mașina"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grup de permisiuni"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grup de permisiuni pentru aplicația Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Acces la locația fină"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ru/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ru/strings.xml
index 940b3c6..8bd8eff 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ru/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ru/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Достигнут предел по числу задач.\nЕсли продолжить, работа приложения будет остановлена."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Шаг задачи: %1$d из %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Нажмите, чтобы продолжить"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Посмотрите разные шаблоны и убедитесь, что автомобиль находится в режиме вождения"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Переключатель вида \"включено/отключено\" (режим демонстрации)"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Проверка переключения"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Изменения с отслеживанием состояния разрешены"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Обновления разрешены для обратных операций."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Проверка переключения включена"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Проверка переключения отключена"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Демонстрация второстепенного действия и оформления"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Тест второстепенного действия"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Можно выбрать только второстепенное действие"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Тест оформления"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Второстепенные действия и оформление"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Можно также выбрать строку"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Выбрано второстепенное действие."</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Выбрано главное действие для строки."</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Демонстрации прочих шаблонов"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Демонстрации Showcase"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Макет шаблона (режим демонстрации)"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Экран демонстрации Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Взаимодействие пользователя"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Демонстрации запроса разрешений"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Проверка дополнительного меню приложения"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Протестируйте следующие шаблоны при переходе"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"транспортного средства из режима парковки в режим вождения"</string>
     <string name="perm_group" msgid="3834918337351876270">"Группа разрешений"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Группа разрешений для приложения \"Витрина\""</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Доступ к данным о точном местоположении"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-si/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-si/strings.xml
index 612fcd6..8ffa434 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-si/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-si/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"කාර්ය සීමාව ළඟා විය\nඉදිරියට යාම යෙදුම බලෙන් නවත්වනු ඇත"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$d කින් %1$dවන කාර්ය පියවර"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ඉදිරියට යාමට ක්ලික් කරන්න"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"විවිධ අච්චු වෙත පැමිණ මෝටර් රථය ධාවන ප්‍රකාරයේ ඇති බව තහවුරු කර ගන්න"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"බොත්තම් ආදර්ශනය ටොගල් කරන්න"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ටොගල පරීක්ෂාව"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"රාජ්‍ය වෙනස් කිරීම්වලට ඉඩ දේ"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"පසු මෙහෙයුම්වල යාවත්කාලීන කිරීම් ඉඩ දෙනු ලැබේ."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"ටොගල පරීක්ෂාව සබලයි"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"ටොගල පරීක්ෂාව අබලයි"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ද්විතීයික ක්‍රියා සහ සැරසිලි ආදර්ශනය"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ද්විතියික ක්‍රියා පරීක්ෂණය"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"ද්විතියික ක්‍රියාව පමණක් තෝරා ගත හැක"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"සැරසිලි පරීක්ෂණය"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ද්විතියික ක්‍රියා සහ සැරසිලි"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"පේළිය ද තෝරා ගත හැක"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ද්විතියික ක්‍රියාව තෝරා ඇත"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"පේළියේ මූලික ක්‍රියාව තෝරා ඇත"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"විවිධ අච්චු ආදර්ශන"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ප්‍රකාශක තේරූ ආදර්ශන"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"අච්චු පිරිසැලසුම් ආදර්ශන"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"හඬ ප්‍රවේශ ආදර්ශන තිරය"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"පරිශීලක අන්තර්ක්‍රියා"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"අවසර ආදර්ශන ඉල්ලන්න"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"යෙදුම් ඉතිරියෑම් වලංගුකරණය"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"වෙනස් කරන අතරතුර පහත සඳහන් අච්චු පරීක්ෂා කරන්න"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"වාහනය ගාල් කළ තත්ත්වයේ සිට ධාවන තත්ත්වයට"</string>
     <string name="perm_group" msgid="3834918337351876270">"අවසර සමූහය"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ප්‍රදර්ශන යෙදුම සඳහා අවසර සමූහය"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"නිවැරදි ස්ථානයට ප්‍රවේශය"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sk/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sk/strings.xml
index e09222bf..d039c09 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sk/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sk/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Bolo dosiahnuté obmedzenie úlohy\nAk budete pokračovať, aplikácia sa vynútene zastaví"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Krok úlohy: %1$d z %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Pokračujte kliknutím"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Prejdite na rôzne šablóny a uistite sa, že auto je režime v aute"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo prepínača"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test prepínača"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Zmeny so stavom sú povolené"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Aktualizácie sú povolené pre operácie na pozadí."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test prepínača bol aktivovaný"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test prepínača bol deaktivovaný"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Sekundárna akcia a demo dekorácie"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test sekundárnej akcie"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Vybrať sa dá iba sekundárna akcia"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Test dekorácie"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundárne akcie a dekorácia"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Môžete vybrať aj daný riadok"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Bola vybraná sekundárna akcia"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Bola vybraná primárna akcia riadka"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Rôzne šablóny – demá"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Výber – demá"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demo rozložení šablóny"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Obrazovka demo verzie aplikácie Voice Access"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Interakcie používateľov"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Vyžadovať demá povolení"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Nástroj na overenie nadbytku aplikácií"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Otestujte tieto šablóny pri zmene"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"vozidla zo zaparkovaného stavu na stav jazdy"</string>
     <string name="perm_group" msgid="3834918337351876270">"Skupina povolení"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Skupina povolení pre aplikáciu Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Prístup k presnej polohe"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sl/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sl/strings.xml
index c210245..8a2083c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sl/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sl/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Dosežena je omejitev opravil.\nČe nadaljujete, bo aplikacija prisilno ustavljena."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Korak opravila %1$d od %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliknite, če želite nadaljevati."</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Odprite različne predloge in poskrbite, da je avtomobil v načinu vožnje."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Predstavitvena različica preklopnega gumba"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Preizkus preklopa"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Spremembe stanj so dovoljene."</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Posodobitve so dovoljene pri pomikih nazaj."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Preizkus preklopa je omogočen."</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Preizkus preklopa je onemogočen."</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Predstavitvena različica sekundarnega dejanja in okrasitve"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Preizkus sekundarnega dejanja"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Izbrati je mogoče samo sekundarno dejanje."</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Preizkus okrasitve"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundarna dejanja in okrasitve"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Izbrati je mogoče tudi vrstico."</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Sekundarno dejanje je izbrano."</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Glavno dejanje vrstice je izbrano."</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Predstavitvene različice različnih predlog"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Predstavitvene različice izpostavljenih stvari"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Predstavitvene različice postavitev predlog"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Predstavitvena različica zaslona za glasovni dostop"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Uporabniške interakcije"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Predstavitvene različice zahtev za dovoljenja"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Orodje za preverjanje presežkov aplikacije"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Preizkusite te predloge,"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ko preklapljate vozilo iz stanja parkiranosti v stanje vožnje."</string>
     <string name="perm_group" msgid="3834918337351876270">"Skupina dovoljenj"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Skupina dovoljenj za aplikacijo Predstavitev"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Dostop do natančne lokacije"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sq/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sq/strings.xml
index 4e5475c..588afb4 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sq/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sq/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"U arrit kufiri i detyrës\nVazhdimi përpara do ta ndalojë aplikacionin me forcë"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Hapi i detyrës: %1$d nga %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Kliko për të vazhduar përpara"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Vizito shabllonet e ndryshme dhe sigurohu që makina të jetë në modalitetin e lëvizjes"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demonstrimi i butonit të aktivizimit/çaktivizimit"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Testimi i butonit aktivizo/çaktivizo"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Lejohen ndryshimet në monitorim"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Përditësimet lejohen në veprimet e mëparshme."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Testimi i butonit aktivizo/çaktivizo u aktivizua"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Testimi i butonit aktivizo/çaktivizo u çaktivizua"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Veprimi dytësor dhe demonstrimi i dekorimit"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Testimi i veprimit dytësor"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Mund të zgjidhet vetëm veprimi dytësor"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Testimi i dekorimit"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Veprimet dytësore dhe dekorimi"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Rreshti mund të zgjidhet gjithashtu"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"U zgjodh veprimi dytësor"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"U zgjodh veprimi kryesor i rreshtit"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demonstrime shabllonesh të ndryshme"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Demonstrime të prezantimit"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demonstrimet e strukturës së shabllonit"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Ekrani demonstrues i \"Qasjes me zë\""</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Ndërveprimet e përdoruesit"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demonstrimet e kërkesës për leje"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Verifikuesi i tejkalimit të aplikacionit"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testo shabllonet e mëposhtme gjatë ndryshimit"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"të automjetit nga gjendja e parkimit në gjendjen e lëvizjes"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupi i lejeve"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupi i lejeve për aplikacionin Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Qasje në vendndodhjen e saktë"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sr/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sr/strings.xml
index ec69183..c0d4d7f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sr/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sr/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Достигнуто је ограничење задатака\nАко наставите, апликација ће се принудно зауставити"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d. корак задатка од %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Кликните да бисте ишли напред"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Посетите различите шаблоне и уверите се да је аутомобил у режиму вожње"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Демонстрација дугмета за укључивање/искључивање"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Укључи/искључи тест"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Промене стања су дозвољене"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Ажурирања су дозвољена за операције у позадини."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Тест укључивања/искључивања је омогућен"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Тест укључивања/искључивања је онемогућен"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Демонстрација секундарне радње и декорације"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Тест секундарне радње"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Може да се изабере само секундарна радња"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Тест декорације"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Секундарне радње и декорација"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Може да се изабере и ред"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Секундарна радња је изабрана"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Примарна радња реда је изабрана"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Демонстрације различитих шаблона"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Демонстрације приказивања"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Демонстрације изгледа шаблона"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Екран демонстрације приступа гласу"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Корисничке интеракције"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Демонстрације захтева за дозволе"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Валидатор прекорачења апликације"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Тестирајте следеће шаблоне током пуњења"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"статус возила из паркираног у вожња"</string>
     <string name="perm_group" msgid="3834918337351876270">"Група дозвола"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Група дозвола за истицање апликације"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Приступ прецизној локацији"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sv/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sv/strings.xml
index 135c174..8aa06dc 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sv/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sv/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Gränsen för antal uppgifter har uppnåtts\nOm du fortsätter tvingas appen att avslutas"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Uppgiftssteg %1$d av %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Klicka för att gå vidare"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Öppna de olika mallarna och se till att bilen är i körläge"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo för på/av-knapp"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Test för att aktivera och inaktivera"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Tillståndsbaserade ändringar är tillåtna"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Uppdateringar tillåtet i bakåtåtgärder."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Test av aktivera/inaktivera har aktiverats"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Test av aktivera/inaktivera har inaktiverats"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Demo av den sekundära åtgärden och dekoration"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Test av den sekundära åtgärden"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Det går endast att välja den sekundära åtgärden"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Dekorationstest"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Sekundära åtgärder och dekoration"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Det går även att välja raden"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Den sekundära åtgärden har valts"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Radens primära åtgärd har valts"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Demor för övriga mallar"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Visa demor"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Demor för mallayouter"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demoskärm för röststyrning"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Användarinteraktioner"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demor av behörighetsförfrågningar"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validering av appspill"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Testa följande mallar när du byter"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"från parkeringsläge till körläge i fordonet"</string>
     <string name="perm_group" msgid="3834918337351876270">"Behörighetsgrupp"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Behörighetsgrupp för exempelapp"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Åtkomst till exakt plats"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-sw/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-sw/strings.xml
index d49aa0a..e9b8e2f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-sw/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-sw/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Kikomo cha shughuli kimefikiwa\nKuendelea kutalazimisha kuzima programu"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Hatua ya shughuli %1$d kati ya %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Bofya ili uendelee"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Tafadhali tembelea violezo tofauti na uhakikishe kuwa gari liko katika hali ya kuendesha gari"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Onyesho la Kitufe cha Kugeuza"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Jaribio la kipengele cha kuwasha/kuzima"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Mabadiliko yanayoweza kurudiwa mara kwa mara yanaruhusiwa"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Masasisho yameruhusiwa kwenye shughuli za nyuma."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Jaribio la Kipengele cha Kuwasha/Kuzima Limewashwa"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Jaribio la Kipengele cha Kuwasha/Kuzima Limezimwa"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Onyesho la Kitendo cha Upili na Jaribio la Usanifu"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Jaribio la Kitendo cha Upili"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Kitendo cha upili tu ndiyo kinaweza kuchaguliwa"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Jaribio la Usanifu"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Matendo ya Upili na Usanifu"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Safu mlalo pia inaweza kuchaguliwa"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Kitendo cha Upili kimechaguliwa"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Kitendo cha msingi cha safu mlalo kimechaguliwa"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Maonyesho ya Violezo Anuwai"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Maonyesho ya Kuangazia"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Maonyesho ya Kiolezo cha Muundo"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Skrini ya Toleo la Kujaribu la Kufikia kwa Kutamka"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Shughuli za Mtumiaji"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Omba Matoleo ya Kujaribu ya Ruhusa"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Kithibitishaji cha Vipengee vya ziada vya Programu"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Tafadhali jaribu violezo vifuatavyo huku ukibadilisha"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"gari limeondolewa katika hali ya kuegeshwa na kuwekwa katika hali ya kuendesha"</string>
     <string name="perm_group" msgid="3834918337351876270">"Kikundi cha Ruhusa"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Kikundi cha Ruhusa cha Programu ya Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Ufikiaji wa Eneo Mahususi"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ta/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ta/strings.xml
index 801c17c..81fa068 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ta/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ta/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"பணி வரம்பை எட்டிவிட்டது.\nமேலும் தொடர்ந்தால் ஆப்ஸ் உடனே நிறுத்தப்படும்"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d / %2$d படியை எடுங்கள்"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"முன்னேறிச் செல்ல கிளிக் செய்யவும்"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"வெவ்வேறு டெம்ப்ளேட்களைப் பாருங்கள். கார் \'வாகனம் ஓட்டும் பயன்முறையில்\' இருப்பதை உறுதிசெய்துகொள்ளுங்கள்."</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"நிலைமாற்றும் பட்டனின் டெமோ"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"நிலைமாற்றப் பரிசோதனை"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"நிலை மாற்றங்கள் அனுமதிக்கப்படுகின்றன"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"முந்தைய பக்கத்திற்குச் சென்று மாற்றங்களைச் செய்யலாம்."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"நிலைமாற்றப் பரிசோதனை இயக்கப்பட்டது"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"நிலைமாற்றப் பரிசோதனை முடக்கப்பட்டது"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"இரண்டாம்நிலைச் செயல் மற்றும் அலங்காரத்திற்கான டெமோ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"இரண்டாம்நிலைச் செயலுக்கான பரிசோதனை"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"இரண்டாம்நிலைச் செயலை மட்டுமே தேர்ந்தெடுக்க முடியும்"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"அலங்காரப் பரிசோதனை"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"இரண்டாம்நிலைச் செயல்கள் மற்றும் அலங்காரம்"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"வரிசையையும் தேர்ந்தெடுக்க முடியும்"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"இரண்டாம்நிலைச் செயல் தேர்ந்தெடுக்கப்பட்டது"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"வரிசையின் முதன்மைச் செயல் தேர்ந்தெடுக்கப்பட்டது"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"மற்ற டெம்ப்ளேட்டுகளின் டெமோக்கள்"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ஷோகேஸின் டெமோக்கள்"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"டெம்ப்ளேட் தளவமைப்பின் டெமோக்கள்"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"குரல் அணுகல் டெமோ திரை"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"பயனர் செயல்பாடுகள்"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"அனுமதிகள் டெமோக்களைக் கோருங்கள்"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ஆப்ஸ் ஓவர்ஃப்லோ பரிசோதிப்பான்"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"மாற்றும்போது பின்வரும் டெம்ப்ளேட்களைப் பரிசோதித்துப் பாருங்கள்"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"வாகனத்தின் நிலையைப் பார்க்கிங்கில் இருந்து இயக்கத்திற்கு மாற்றுங்கள்"</string>
     <string name="perm_group" msgid="3834918337351876270">"அனுமதிக் குழு"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"ஷோகேஸ் ஆப்ஸிற்கான அனுமதிக் குழு"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"சரியான இருப்பிடத்திற்கான அணுகல்"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-te/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-te/strings.xml
index c440829..556538c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-te/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-te/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"టాస్క్‌ల పరిమితిని చేరుకున్నారు\nఇంకా టాస్క్‌లను ఎంచుకుంటే యాప్ ఫోర్స్ స్టాప్ అవుతుంది"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%2$dలో %1$d టాస్క్ దశ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"ముందుకు వెళ్లడానికి క్లిక్ చేయండి"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"దయచేసి వివిధ టెంప్లేట్‌లను సందర్శించండి, కారు డ్రైవింగ్ మోడ్‌లో ఉందని నిర్ధారించుకోండి"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"టోగుల్ బటన్ డెమో"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"టోగుల్ టెస్ట్"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"స్టేట్‌ఫుల్ మార్పులు అనుమతించబడతాయి"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"బ్యాక్‌గ్రౌండ్ ఆపరేషన్‌ల కోసం అప్‌డేట్‌లు అనుమతించబడ్డాయి."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"టోగుల్ టెస్ట్ ఎనేబుల్ చేయబడింది"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"టోగుల్ టెస్ట్ డిజేబుల్ చేయబడింది"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"రెండవ చర్య, డెకరేషన్ డెమో"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"రెండవ చర్య పరీక్ష"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"రెండవ చర్యను మాత్రమే ఎంచుకోవచ్చు"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"డెకరేషన్ టెస్ట్"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"రెండవ చర్య, డెకరేషన్"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"అడ్డు వరుసను కూడా ఎంచుకోవచ్చు"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"రెండవ చర్య ఎంచుకోబడింది"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"అడ్డు వరుస ప్రాథమిక చర్య ఎంచుకోబడింది"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"ఇతర టెంప్లేట్‌ల డెమోలు"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"డెమోలను ప్రదర్శించండి"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"టెంప్లేట్ లేఅవుట్ డెమోలు"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access డెమో స్క్రీన్"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"యూజర్ ఇంటరాక్షన్‌లు"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"అనుమతుల డెమోలను రిక్వెస్ట్ చేయండి"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"అప్లికేషన్ ఓవర్‌ఫ్లో వాలిడేటర్"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"దయచేసి మార్చేటప్పుడు కింది టెంప్లేట్‌లను పరీక్షించండి"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"వాహనం పార్క్ నుండి డ్రైవింగ్ స్టేట్‌కు మారండి"</string>
     <string name="perm_group" msgid="3834918337351876270">"అనుమతి గ్రూప్"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Showcase యాప్ కోసం అనుమతి గ్రూప్"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"ఖచ్చితమైన లొకేషన్ యాక్సెస్"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-th/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-th/strings.xml
index 409e74f..e6fcd8f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-th/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-th/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ถึงขีดจำกัดงานแล้ว\nการดำเนินการต่อจะบังคับให้แอปหยุด"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"งานขั้นตอนที่ %1$d จาก %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"คลิกเพื่อดำเนินการต่อ"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"โปรดไปที่เทมเพลตอื่นและตรวจสอบว่ารถอยู่ในโหมดขับรถ"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"การสาธิตปุ่มเปิด/ปิด"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"การทดสอบการสลับ"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"อนุญาตการเปลี่ยนแปลงแบบเก็บสถานะ"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"หน้าจอสาธิตการเข้าถึงด้วยเสียง"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"การโต้ตอบของผู้ใช้"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"การสาธิตการขอสิทธิ์"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"โปรแกรมตรวจสอบรายการเพิ่มเติมของแอปพลิเคชัน"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"โปรดทดสอบเทมเพลตต่อไปนี้ขณะเปลี่ยน"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"สถานะยานพาหนะจากจอดอยู่เป็นกำลังขับ"</string>
     <string name="perm_group" msgid="3834918337351876270">"กลุ่มสิทธิ์"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"กลุ่มสิทธิ์สำหรับแอป Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"เข้าถึงตำแหน่งอย่างละเอียด"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-tl/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-tl/strings.xml
index bcc8aba..554ce6c 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-tl/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-tl/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Naabot na ang limitasyon ng gawain\nSapilitang ihihinto ang app kapag nagpatuloy"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Gawin ang hakbang %1$d sa %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Mag-click para magpatuloy"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Pakibisita ang iba\'t ibang template at tiyaking nasa driving mode ang kotse"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo ng Toggle Button"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"I-toggle ang test"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Pinapayagan ang mga pagbabago sa status"</string>
@@ -322,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Screen ng Demo ng Pag-access gamit ang Boses"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Mga Pakikipag-ugnayan ng User"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Humiling ng Mga Demo ng Pahintulot"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Validator ng Overflow ng Application"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Pakisubukan ang mga sumusunod na template habang binabago"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"ang status ng sasakyan mula naka-park patungong nagmamaneho"</string>
     <string name="perm_group" msgid="3834918337351876270">"Grupo ng Pahintulot"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Grupo ng Pahintulot para sa Showcase App"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Access sa Eksaktong Lokasyon"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-tr/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-tr/strings.xml
index 5dc17de..28e0de1 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-tr/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-tr/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Görev sınırına ulaşıldı\nDevam ederseniz uygulama zorla durdurulacak"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"%1$d/%2$d görev adımı"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Devam etmek için tıklayın"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Lütfen farklı şablonları inceleyip arabanın sürüş modunda olduğundan emin olun"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Açma/Kapatma Düğmesi Demosu"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Açma/kapatma testi"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Durum bilgili değişikliklere izin verilir"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Önceki işlemlerde güncellemelere izin verilir."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Açma/Kapatma Testi Etkin"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Açma/Kapatma Testi Devre Dışı"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"İkincil İşlem ve Süsleme Demosu"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"İkincil İşlem Testi"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Yalnızca ikincil işlem seçilebilir"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Süsleme Testi"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"İkincil İşlemler ve Süsleme"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Satır da seçilebilir"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"İkincil işlem seçildi"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Satırdaki birincil işlem seçildi"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Çeşitli Şablon Demoları"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Öne Çıkan Demoları"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Şablon Düzeni Demoları"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Sesli Erişim Demo Ekranı"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Kullanıcı Etkileşimleri"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"İzin İsteme Demoları"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Uygulama Taşma Doğrulayıcı"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Park halindeki aracı sürüş durumuna geçirirken"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"lütfen aşağıdaki şablonları test edin"</string>
     <string name="perm_group" msgid="3834918337351876270">"İzin Grubu"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Vitrin Uygulamasının İzin Grubu"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Hassas Konuma Erişim"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-uk/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-uk/strings.xml
index 1b79a87..937028f 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-uk/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-uk/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Досягнуто ліміту завдань\nЯкщо продовжити, програму буде примусово зупинено"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Крок завдання %1$d з %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Натисніть, щоб продовжити"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Перегляньте різні шаблони й переконайтеся, що автомобіль перебуває в режимі кермування"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Демонстрація перемикача"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Змінити перевірку"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Дозволено змінювати стан"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Оновлення дозволено для операцій повернення."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Перевірку перемикача ввімкнено"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Перевірку перемикача вимкнено"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Демонстрація додаткової дії й оформлення"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Перевірка додаткової дії"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Можна вибрати лише додаткову дію"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Перевірка оформлення"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Додаткові дії й оформлення"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Рядок також можна вибрати"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Вибрано додаткову дію"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Вибрано основну дію рядка"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Демонстрації інших шаблонів"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Увімкнути демонстрації"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Демонстрації макетів шаблонів"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Демонстрація екрана Голосового доступу"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Взаємодія з користувачем"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Демонстрації запитів на отримання дозволів"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Перевірка додаткового меню додатка"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Перевірте наведені далі шаблони,"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"коли змінюватимете режим паркування на кермування автомобілем"</string>
     <string name="perm_group" msgid="3834918337351876270">"Група дозволів"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Група дозволів для демонстраційного додатка"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Доступ до даних про точне місцезнаходження"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-ur/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-ur/strings.xml
index 9a3b163..0608c26 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-ur/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-ur/strings.xml
@@ -296,8 +296,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"ٹاسک کی حد پوری ہو گئی\nآگے بڑھنے سے ایپ کو زبردستی روک دیا جائے گا"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"‏%2$d میں سے ‎%1$d ٹاسک کا مرحلہ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"آگے بڑھنے کے لیے کلک کریں"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"براہ کرم مختلف ٹیمپلیٹس دیکھیں اور یقینی بنائیں کہ کار ڈرائیونگ موڈ میں ہے"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"ٹوگل بٹن کا ڈیمو"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"ٹیسٹ کو ٹوگل کریں"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"اسٹیٹ فل تبدیلیوں کی اجازت ہے"</string>
@@ -311,22 +310,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"اپ ڈیٹس پچھلے صفحے پر جانے کی اجازت دی گئی۔"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"ٹیسٹ ٹوگل کرنے کی سہولت فعال ہے"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"ٹیسٹ ٹوگل کرنے کی سہولت غیر فعال ہے"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"ثانوی کارروائی اور ڈیکوریشن ڈیمو"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"ثانوی کارروائی ٹیسٹ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"صرف ثانوی کارروائی کا انتخاب کیا جا سکتا ہے"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"ڈیکوریشن ٹیسٹ"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"ثانوی کارروائیاں اور ڈیکوریشن"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"قطار بھی منتخب کی جا سکتی ہے"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"ثانوی کارروائی کا انتخاب کیا گیا ہے"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"قطار کی بنیادی کارروائی کا انتخاب کیا گیا ہے"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"متفرق تمثیلات کے ڈیموز"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"ڈیموز دکھائیں"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"تمثیل کے لے آؤٹ کے ڈیموز"</string>
@@ -334,12 +325,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"صوتی رسائی کی ڈیمو سکرین"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"صارف کے تعاملات"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"اجازتوں کے ڈیموز کی درخواست کریں"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"ایپلیکیشن اوور فلو کا تصدیق کنندہ"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"براہ کرم تبدیل کرتے وقت درج ذیل ٹیمپلیٹس کی جانچ کریں"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"گاڑی پارک کرنے سے ڈرائیونگ کی حالت تک"</string>
     <string name="perm_group" msgid="3834918337351876270">"اجازت کا گروپ"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"شوکیس ایپ کے لیے اجازت کا گروپ"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"درست مقام تک رسائی"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-uz/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-uz/strings.xml
index 5c718b9..b2801a5 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-uz/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-uz/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Vazifa chekloviga yetildi\nDavom etish ilovani majburiy toʻxtatadi."</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Vazifa qadami: %1$d / %2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Oldinga oʻtish uchun bosing"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Turli andozalarni ochib koʻring va avtomobil haydash rejimida ekanini tekshiring"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Demo ekran tugmasi"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Almashtirish tekshiruvi"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Vaziyatni oʻzgartirishga ruxsat beriladi"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Teskari amallarda yangilanishlarga ruxsat berilgan."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Testni oʻchirish/yoqish faollashtirildi"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Testni oʻchirish/yoqish faolsizlantirildi"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Ikkilamchi amal va bezak demosi"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Ikkilamchi amal testi"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Faqat ikkilamchi amal tanlanishi mumkin"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Bezak testi"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Ikkilamchi amallar va bezak"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Qator ham tanlanishi mumkin"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Ikkilamchi amal tanlandi"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Asosiy amal qatori tanlandi"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Aralash andozalar demolari"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Namoyish demolari"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Andoza dizayni demolari"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Demo ekranida ovozli boshqaruv"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Foydalanuvchi harakatlari"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Demolarga ruxsatlarni talab qilish"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Ilovani chuqur tekshirish vositasi"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Tahrirlash vaqtida quyidagi andozalarni sinang"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"parklangan avtomobil rejimidan haydash rejimiga"</string>
     <string name="perm_group" msgid="3834918337351876270">"Ruxsatlar guruhi"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Vitrina ilovasi uchun ruxsatlar guruhi"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Aniq joylashuv axborotiga ruxsat"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-vi/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-vi/strings.xml
index 807875a1..2bd3d63 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-vi/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-vi/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Đã đạt đến giới hạn nhiệm vụ\nNếu tiếp tục sẽ buộc phải dừng ứng dụng"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Bước %1$d trong số %2$d của nhiệm vụ"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Nhấp để tiếp tục"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Vui lòng truy cập nhiều mẫu riêng biệt và đảm bảo xe đang ở chế độ lái"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Bản minh hoạ nút bật tắt"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Kiểm tra chuyển đổi"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Các thay đổi rõ ràng được phép"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Cho phép cập nhật đối với các thiết bị chạy ngầm."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Đã bật tính năng chuyển đổi"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Đã tắt tính năng kiểm tra chuyển đổi"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Bản minh hoạ phần trang trí và hành động phụ"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Thử nghiệm hành động phụ"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Bạn chỉ có thể chọn hành động phụ"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Thử nghiệm phần trang trí"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Phần trang trí và hành động phụ"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Bạn cũng có thể chọn hàng"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Đã chọn hành động phụ"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Đã chọn hành động chính cho hàng"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Bản demo biểu mẫu Misc"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Bản demo nổi bật"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Bản minh hoạ bố cục mẫu"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Màn hình minh hoạ chức năng Điều khiển bằng giọng nói"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Hoạt động tương tác của người dùng"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Bản minh hoạ về yêu cầu quyền"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Trình xác thực chế độ kết xuất bổ sung của ứng dụng"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Vui lòng kiểm tra các mẫu sau trong khi thay đổi"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"chiếc xe từ trạng thái đỗ sang trạng thái lái"</string>
     <string name="perm_group" msgid="3834918337351876270">"Nhóm quyền"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Nhóm quyền dành cho ứng dụng Showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Truy cập vào thông tin vị trí chính xác"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-zh-rCN/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-zh-rCN/strings.xml
index db8258f..5c20e7e 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-zh-rCN/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-zh-rCN/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"已达到任务限制\n继续会强制停止应用"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"任务第 %1$d 步(共 %2$d 步)"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"点击以继续"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"请访问不同模板并确保此车辆处于驾驶模式"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"切换按钮演示"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"切换测试"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"允许有状态更改"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"返回操作允许更新。"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"切换测试已启用"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"切换测试已停用"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"次要操作和装饰演示"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"次要操作测试"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"只能选择次要操作"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"装饰测试"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"次要操作和装饰"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"也可以选择行"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"次要操作处于选中状态"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"行主要操作处于选中状态"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"其他模板演示"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"展示演示"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"模板布局演示"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access 演示屏幕"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"用户互动"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"请求权限演示"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"应用溢出验证器"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"更改时请测试以下模板"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"从停车状态变为驾驶状态的车辆"</string>
     <string name="perm_group" msgid="3834918337351876270">"权限组"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"“展示”应用的权限组"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"访问精确位置信息"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-zh-rHK/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-zh-rHK/strings.xml
index d62fa2d..b5b7c32 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-zh-rHK/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-zh-rHK/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"工作已達上限\n繼續使用將強制停止應用程式"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"工作步驟 %1$d,共 %2$d 個步驟"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"點擊即可繼續使用"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"請查看各種範本,並確保汽車處於駕駛模式"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"「切換按鈕」示範"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"切換測試"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"允許有狀態的變更"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"允許在返回時更新。"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"已啟用切換測試"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"已停用切換測試"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"次要動作及裝飾示範"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"次要動作測試"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"只可選取次要動作"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"裝飾測試"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"次要動作及裝飾"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"亦可選取列"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"已選取次要動作"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"已選取列的主要動作"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"其他範本示範"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"展示示範"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"「範本版面配置」示範"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"語音操控示範畫面"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"使用者互動"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"「要求權限」示範"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"應用程式展開式驗證工具"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"請在變更時測試以下範本"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"從泊車狀態轉為行駛狀態的汽車"</string>
     <string name="perm_group" msgid="3834918337351876270">"權限群組"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"「展示」應用程式的權限群組"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"存取精確位置"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-zh-rTW/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-zh-rTW/strings.xml
index 5fed181..8e2921b 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-zh-rTW/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-zh-rTW/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"工作已達上限\n繼續使用將強制停止應用程式"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"工作步驟 %1$d,共 %2$d 個步驟"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"點選即可繼續使用"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"請前往不同範本並確認車輛處於行車模式"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"「切換鈕」示範"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"切換測試"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"允許有狀態的變更"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"允許返回上一頁更新。"</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"切換測試已啟用"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"切換測試已停用"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"次要動作和裝飾示範"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"次要動作測試"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"只可以選取次要動作"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"裝飾測試"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"次要動作與裝飾"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"也可以選取列"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"已選取次要動作"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"已選取列的主要動作"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"其他範本示範"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"「展示」示範"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"「範本版面配置」示範"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Voice Access 示範畫面"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"使用者互動"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"要求權限示範"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"應用程式溢位驗證工具"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"請在變更時測試以下範本"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"從停車狀態轉為行駛狀態的車輛"</string>
     <string name="perm_group" msgid="3834918337351876270">"權限群組"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"「展示」應用程式的權限群組"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"精確位置存取權"</string>
diff --git a/car/app/app-samples/showcase/common/src/main/res/values-zu/strings.xml b/car/app/app-samples/showcase/common/src/main/res/values-zu/strings.xml
index 2adeb6d..45c51e3 100644
--- a/car/app/app-samples/showcase/common/src/main/res/values-zu/strings.xml
+++ b/car/app/app-samples/showcase/common/src/main/res/values-zu/strings.xml
@@ -292,8 +292,7 @@
     <string name="task_limit_reached_msg" msgid="6038763366777119364">"Umkhawulo womsebenzi ufinyelelwe\nUkuqhubekela phambili kuzophoqa ukumisa i-app"</string>
     <string name="task_step_of_title" msgid="2791717962535723839">"Isinyathelo somsebenzi %1$d kwengu-%2$d"</string>
     <string name="task_step_of_text" msgid="4646729781462227219">"Chofoza ukuze uye phambili"</string>
-    <!-- no translation found for task_content_allowed (545061986612431190) -->
-    <skip />
+    <string name="task_content_allowed" msgid="545061986612431190">"Sicela uvakashele izifanekiso ezahlukene futhi uqinisekise ukuthi imoto ikumodi yokushayela"</string>
     <string name="toggle_button_demo_title" msgid="3179103600967398928">"Inkinobho Yokuguqula I-demo"</string>
     <string name="toggle_test_title" msgid="924485265152862631">"Guqula ukuhlola"</string>
     <string name="toggle_test_text" msgid="8107217216013312857">"Izinguquko ezisemthethweni zivunyelwe"</string>
@@ -307,22 +306,14 @@
     <string name="additional_data_text" msgid="2846223398214158872">"Izibuyekezo zivunyelwe ukusebenza ngemuva."</string>
     <string name="toggle_test_enabled" msgid="982370904182034076">"Ukuhlola Kokuguqula Kunikwe Amandla"</string>
     <string name="toggle_test_disabled" msgid="8366040658408451664">"Ukuhlola Kokuguqula Kukhutshaziwe"</string>
-    <!-- no translation found for secondary_actions_decoration_button_demo_title (3710817648501132309) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_title (3664453747553733613) -->
-    <skip />
-    <!-- no translation found for secondary_actions_test_subtitle (6985282813402073703) -->
-    <skip />
-    <!-- no translation found for decoration_test_title (8450127046762442244) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_title (6282873404859209490) -->
-    <skip />
-    <!-- no translation found for secondary_actions_decoration_test_subtitle (155884606592724532) -->
-    <skip />
-    <!-- no translation found for secondary_action_toast (5076434693504006565) -->
-    <skip />
-    <!-- no translation found for row_primary_action_toast (756516694751965204) -->
-    <skip />
+    <string name="secondary_actions_decoration_button_demo_title" msgid="3710817648501132309">"Idemo Yesibili Yesenzo Nokuhlobisa"</string>
+    <string name="secondary_actions_test_title" msgid="3664453747553733613">"Ukuhlolwa Kwesenzo Kwesibili"</string>
+    <string name="secondary_actions_test_subtitle" msgid="6985282813402073703">"Isenzo sesibili kuphela esingakhethwa"</string>
+    <string name="decoration_test_title" msgid="8450127046762442244">"Ukuhlolwa Kokuhlobisa"</string>
+    <string name="secondary_actions_decoration_test_title" msgid="6282873404859209490">"Izenzo Zesibili Nokuhlobisa"</string>
+    <string name="secondary_actions_decoration_test_subtitle" msgid="155884606592724532">"Umugqa ungabuye ukhethwe"</string>
+    <string name="secondary_action_toast" msgid="5076434693504006565">"Isenzo Sesibili Sikhethiwe"</string>
+    <string name="row_primary_action_toast" msgid="756516694751965204">"Isenzo esiyinhloko somugqa sikhethiwe"</string>
     <string name="misc_templates_demos_title" msgid="6077169010255928114">"Amademo Ezifanekiso Ezixubile"</string>
     <string name="showcase_demos_title" msgid="1542092687878113304">"Bonisa Amademo"</string>
     <string name="template_layouts_demo_title" msgid="788249269446087847">"Ama-demo Esakhiwo Sesifanekiso"</string>
@@ -330,12 +321,9 @@
     <string name="voice_access_demo_title" msgid="3825223890895361496">"Isikrini Sedemo Sokufinyelela Ngezwi"</string>
     <string name="user_interactions_demo_title" msgid="1356952319161314986">"Ukusebenzisana Komsebenzisi"</string>
     <string name="request_permission_menu_demo_title" msgid="4796486779527427017">"Cela Amademo Ezimvume"</string>
-    <!-- no translation found for application_overflow_title (396427940886169325) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle1 (7429415605726615529) -->
-    <skip />
-    <!-- no translation found for application_overflow_subtitle2 (4385123036846369714) -->
-    <skip />
+    <string name="application_overflow_title" msgid="396427940886169325">"Isiqinisekisi sokuchichima se-app"</string>
+    <string name="application_overflow_subtitle1" msgid="7429415605726615529">"Sicela uhlole izifanekiso ezilandelayo ngenkathi ushintsha"</string>
+    <string name="application_overflow_subtitle2" msgid="4385123036846369714">"imoto isuka lapho imile iye esimweni sokushayela"</string>
     <string name="perm_group" msgid="3834918337351876270">"Iqembu Lemvume"</string>
     <string name="perm_group_description" msgid="7348847631139139024">"Iqembu Lemvume Le-app Ye-showcase"</string>
     <string name="perm_fine_location" msgid="5438874642600304118">"Ukufinyelela Endaweni Enhle"</string>
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
index aab5ed0..7aac595 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
@@ -350,6 +350,9 @@
 
     fun Offset.reverseIfNeeded(): Offset = if (reverseDirection) this * -1f else this
 
+    /**
+     * @return the amount of scroll that was consumed
+     */
     fun ScrollScope.dispatchScroll(availableDelta: Offset, source: NestedScrollSource): Offset {
         val scrollDelta = availableDelta.singleAxisOffset()
         val overscrollPreConsumed = overscrollPreConsumeDelta(scrollDelta, source)
@@ -376,7 +379,7 @@
             source
         )
 
-        return leftForParent - parentConsumed
+        return overscrollPreConsumed + preConsumedByParent + axisConsumed + parentConsumed
     }
 
     fun overscrollPreConsumeDelta(
@@ -447,8 +450,7 @@
         var result: Velocity = available
         scrollableState.scroll {
             val outerScopeScroll: (Offset) -> Offset = { delta ->
-                val consumed = this.dispatchScroll(delta.reverseIfNeeded(), Fling)
-                delta - consumed.reverseIfNeeded()
+                dispatchScroll(delta.reverseIfNeeded(), Fling).reverseIfNeeded()
             }
             val scope = object : ScrollScope {
                 override fun scrollBy(pixels: Float): Float {
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 be6e663..4e62a3d 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
@@ -119,6 +119,10 @@
     val sourceSet = project.getMultiplatformSourceSet(KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME)
     val generatedSrcMainDirectory = buildDirectory.resolve(IconGenerationTask.GeneratedSrcMain)
     sourceSet.kotlin.srcDir(project.files(generatedSrcMainDirectory).builtBy(task))
+    // add it to the multiplatform sources as well.
+    project.tasks.named("multiplatformSourceJar", Jar::class.java).configure {
+        it.from(task.map { generatedSrcMainDirectory })
+    }
     project.addToSourceJar(generatedSrcMainDirectory, task)
 }
 
diff --git a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
index 10da79f..1258e7e 100644
--- a/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
+++ b/compose/material/material/src/androidAndroidTest/kotlin/androidx/compose/material/swipeable/SwipeableV2StateTest.kt
@@ -91,6 +91,18 @@
         rule.waitForIdle()
         assertThat(state.targetValue).isEqualTo(B)
 
+        // Assert that swipe below threshold upward settles at current state
+        rule.onNodeWithTag(swipeableTestTag)
+            .performTouchInput { swipeUp(endY = bottom * 0.95f, durationMillis = 1000) }
+        rule.waitForIdle()
+        assertThat(state.targetValue).isEqualTo(B)
+
+        // Assert that swipe below threshold downward settles at current state
+        rule.onNodeWithTag(swipeableTestTag)
+            .performTouchInput { swipeDown(endY = bottom * 0.05f) }
+        rule.waitForIdle()
+        assertThat(state.targetValue).isEqualTo(B)
+
         rule.onNodeWithTag(swipeableTestTag)
             .performTouchInput { swipeDown(endY = bottom * 0.9f) }
         rule.waitForIdle()
diff --git a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
index a9df38a..70c2766 100644
--- a/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
+++ b/compose/material/material/src/commonMain/kotlin/androidx/compose/material/SwipeableV2.kt
@@ -368,7 +368,13 @@
                 val distance = abs(currentAnchor - currentAnchors.getValue(lower))
                 val relativeThreshold = abs(positionalThreshold(density, distance))
                 val absoluteThreshold = abs(currentAnchor - relativeThreshold)
-                if (offset > absoluteThreshold) currentValue else lower
+                if (offset < 0) {
+                    // For negative offsets, larger absolute thresholds are closer to lower anchors
+                    // than smaller ones.
+                    if (abs(offset) < absoluteThreshold) currentValue else lower
+                } else {
+                    if (offset > absoluteThreshold) currentValue else lower
+                }
             }
         }
     }
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index bc57514..f96b55a 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -103,6 +103,9 @@
     method @androidx.compose.runtime.Composable public static void TextButton(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.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, 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);
   }
 
+  public final class CalendarModelKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class CardColors {
   }
 
@@ -681,6 +684,9 @@
 
 package androidx.compose.material3.internal {
 
+  public final class AndroidDatePickerModel_androidKt {
+  }
+
   public final class ExposedDropdownMenuPopupKt {
   }
 
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index 906e393..c815b0b 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -132,6 +132,9 @@
     method @androidx.compose.runtime.Composable public static void TextButton(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.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, 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);
   }
 
+  public final class CalendarModelKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class CardColors {
   }
 
@@ -1013,6 +1016,9 @@
 
 package androidx.compose.material3.internal {
 
+  public final class AndroidDatePickerModel_androidKt {
+  }
+
   public final class ExposedDropdownMenuPopupKt {
   }
 
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index bc57514..f96b55a 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -103,6 +103,9 @@
     method @androidx.compose.runtime.Composable public static void TextButton(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.compose.material3.ButtonColors colors, optional androidx.compose.material3.ButtonElevation? elevation, 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);
   }
 
+  public final class CalendarModelKt {
+  }
+
   @androidx.compose.runtime.Immutable public final class CardColors {
   }
 
@@ -681,6 +684,9 @@
 
 package androidx.compose.material3.internal {
 
+  public final class AndroidDatePickerModel_androidKt {
+  }
+
   public final class ExposedDropdownMenuPopupKt {
   }
 
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CalendarModelTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CalendarModelTest.kt
new file mode 100644
index 0000000..9b5997e
--- /dev/null
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/CalendarModelTest.kt
@@ -0,0 +1,151 @@
+/*
+ * 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.compose.material3
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.material3.internal.CalendarModelImpl
+import androidx.compose.material3.internal.LegacyCalendarModelImpl
+import androidx.test.filters.MediumTest
+import com.google.common.truth.Truth.assertThat
+import java.util.Locale
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@MediumTest
+@RunWith(Parameterized::class)
+@OptIn(ExperimentalMaterial3Api::class)
+@RequiresApi(Build.VERSION_CODES.O)
+internal class CalendarModelTest(private val model: CalendarModel) {
+
+    @Test
+    fun dateCreation() {
+        val date = model.getDate(January2022Millis) // 1/1/2022
+        assertThat(date.year).isEqualTo(2022)
+        assertThat(date.month).isEqualTo(1)
+        assertThat(date.dayOfMonth).isEqualTo(1)
+        assertThat(date.utcTimeMillis).isEqualTo(January2022Millis)
+    }
+
+    @Test
+    fun dateRestore() {
+        val date =
+            CalendarDate(year = 2022, month = 1, dayOfMonth = 1, utcTimeMillis = January2022Millis)
+        assertThat(model.getDate(date.utcTimeMillis)).isEqualTo(date)
+    }
+
+    @Test
+    fun monthCreation() {
+        val date =
+            CalendarDate(year = 2022, month = 1, dayOfMonth = 1, utcTimeMillis = January2022Millis)
+        val monthFromDate = model.getMonth(date)
+        val monthFromMilli = model.getMonth(January2022Millis)
+        val monthFromYearMonth = model.getMonth(year = 2022, month = 1)
+        assertThat(monthFromDate).isEqualTo(monthFromMilli)
+        assertThat(monthFromDate).isEqualTo(monthFromYearMonth)
+    }
+
+    @Test
+    fun monthRestore() {
+        val month = model.getMonth(year = 1999, month = 12)
+        assertThat(model.getMonth(month.startUtcTimeMillis)).isEqualTo(month)
+    }
+
+    @Test
+    fun plusMinusMonth() {
+        val month = model.getMonth(January2022Millis) // 1/1/2022
+        val expectedNextMonth = model.getMonth(month.endUtcTimeMillis + 1) // 2/1/2022
+        val plusMonth = model.plusMonths(from = month, addedMonthsCount = 1)
+        assertThat(plusMonth).isEqualTo(expectedNextMonth)
+        assertThat(model.minusMonths(from = plusMonth, subtractedMonthsCount = 1)).isEqualTo(month)
+    }
+
+    @Test
+    fun parseDate() {
+        val expectedDate =
+            CalendarDate(year = 2022, month = 1, dayOfMonth = 1, utcTimeMillis = January2022Millis)
+        val parsedDate = model.parse("1/1/2022", "M/d/yyyy")
+        assertThat(parsedDate).isEqualTo(expectedDate)
+    }
+
+    @Test
+    fun formatDate() {
+        val date =
+            CalendarDate(year = 2022, month = 1, dayOfMonth = 1, utcTimeMillis = January2022Millis)
+        val month = model.plusMonths(model.getMonth(date), 2)
+        assertThat(model.format(date, "MM/dd/yyyy")).isEqualTo("01/01/2022")
+        assertThat(model.format(month, "MM/dd/yyyy")).isEqualTo("03/01/2022")
+    }
+
+    @Test
+    fun weekdayNames() {
+        // Ensure we are running on a US locale for this test.
+        Locale.setDefault(Locale.US)
+        val weekDays = model.weekdayNames
+        assertThat(weekDays).hasSize(DaysInWeek)
+        // Check that the first day is always "Monday", per ISO-8601 standard.
+        assertThat(weekDays.first().first).ignoringCase().contains("Monday")
+        weekDays.forEach {
+            assertThat(it.second.first().lowercaseChar()).isEqualTo(
+                it.first.first().lowercaseChar()
+            )
+        }
+    }
+
+    @Test
+    fun equalModelsOutput() {
+        // Note: This test ignores the parameters and just runs a few equality tests for the output.
+        // It will execute twice, but that should to tolerable :)
+        val newModel = CalendarModelImpl()
+        val legacyModel = LegacyCalendarModelImpl()
+
+        val date = newModel.getDate(January2022Millis) // 1/1/2022
+        val legacyDate = legacyModel.getDate(January2022Millis)
+        val month = newModel.getMonth(date)
+        val legacyMonth = legacyModel.getMonth(date)
+
+        assertThat(newModel.today).isEqualTo(legacyModel.today)
+        assertThat(month).isEqualTo(legacyMonth)
+        assertThat(newModel.plusMonths(month, 3)).isEqualTo(legacyModel.plusMonths(month, 3))
+        assertThat(date).isEqualTo(legacyDate)
+        assertThat(newModel.getDayOfWeek(date)).isEqualTo(legacyModel.getDayOfWeek(date))
+        assertThat(newModel.format(date, "MMM d, yyyy")).isEqualTo(
+            legacyModel.format(
+                date,
+                "MMM d, yyyy"
+            )
+        )
+        assertThat(newModel.format(month, "MMM yyyy")).isEqualTo(
+            legacyModel.format(
+                month,
+                "MMM yyyy"
+            )
+        )
+    }
+
+    internal companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun parameters() = arrayOf(
+            CalendarModelImpl(),
+            LegacyCalendarModelImpl()
+        )
+    }
+}
+
+private const val January2022Millis = 1640995200000
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AndroidDatePickerModel.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AndroidDatePickerModel.android.kt
new file mode 100644
index 0000000..089aeb0
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/AndroidDatePickerModel.android.kt
@@ -0,0 +1,357 @@
+/*
+ * 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.compose.material3.internal
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.material3.CalendarDate
+import androidx.compose.material3.CalendarModel
+import androidx.compose.material3.CalendarMonth
+import androidx.compose.material3.DaysInWeek
+import androidx.compose.material3.ExperimentalMaterial3Api
+import java.text.DateFormatSymbols
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.time.DayOfWeek
+import java.time.Instant
+import java.time.LocalDate
+import java.time.LocalTime
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import java.time.format.DateTimeParseException
+import java.time.format.TextStyle
+import java.time.temporal.WeekFields
+import java.util.Calendar
+import java.util.Locale
+import java.util.TimeZone
+
+/**
+ * Creates a [CalendarModel] to be used by the date picker.
+ */
+@ExperimentalMaterial3Api
+internal fun createDefaultCalendarModel(): CalendarModel {
+    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+        CalendarModelImpl()
+    } else {
+        LegacyCalendarModelImpl()
+    }
+}
+
+/**
+ * A [CalendarModel] implementation for API < 26.
+ */
+@OptIn(ExperimentalMaterial3Api::class)
+internal class LegacyCalendarModelImpl : CalendarModel {
+
+    override val today
+        get(): CalendarDate {
+            val systemCalendar = Calendar.getInstance()
+            systemCalendar[Calendar.HOUR_OF_DAY] = 0
+            systemCalendar[Calendar.MINUTE] = 0
+            systemCalendar[Calendar.SECOND] = 0
+            systemCalendar[Calendar.MILLISECOND] = 0
+            val utcOffset =
+                systemCalendar.get(Calendar.ZONE_OFFSET) + systemCalendar.get(Calendar.DST_OFFSET)
+            return CalendarDate(
+                year = systemCalendar[Calendar.YEAR],
+                month = systemCalendar[Calendar.MONTH] + 1,
+                dayOfMonth = systemCalendar[Calendar.DAY_OF_MONTH],
+                utcTimeMillis = systemCalendar.timeInMillis + utcOffset
+            )
+        }
+
+    override val firstDayOfWeek: Int = dayInISO8601(Calendar.getInstance().firstDayOfWeek)
+
+    override val weekdayNames: List<Pair<String, String>> = buildList {
+        val weekdays = DateFormatSymbols(Locale.getDefault()).weekdays
+        val shortWeekdays = DateFormatSymbols(Locale.getDefault()).shortWeekdays
+        // Skip the first item, as it's empty, and the second item, as it represents Sunday while it
+        // should be last according to ISO-8601.
+        weekdays.drop(2).forEachIndexed { index, day ->
+            add(Pair(day, shortWeekdays[index + 2]))
+        }
+        // Add Sunday to the end.
+        add(Pair(weekdays[1], shortWeekdays[1]))
+    }
+
+    override fun getDate(timeInMillis: Long): CalendarDate {
+        val calendar = Calendar.getInstance(utcTimeZone)
+        calendar.timeInMillis = timeInMillis
+        return CalendarDate(
+            year = calendar[Calendar.YEAR],
+            month = calendar[Calendar.MONTH] + 1,
+            dayOfMonth = calendar[Calendar.DAY_OF_MONTH],
+            utcTimeMillis = timeInMillis
+        )
+    }
+
+    override fun getMonth(timeInMillis: Long): CalendarMonth {
+        val firstDayCalendar = Calendar.getInstance(utcTimeZone)
+        firstDayCalendar.timeInMillis = timeInMillis
+        firstDayCalendar[Calendar.DAY_OF_MONTH] = 1
+        return getMonth(firstDayCalendar)
+    }
+
+    override fun getMonth(date: CalendarDate): CalendarMonth {
+        return getMonth(date.year, date.month)
+    }
+
+    override fun getMonth(year: Int, month: Int): CalendarMonth {
+        val firstDayCalendar = Calendar.getInstance(utcTimeZone)
+        firstDayCalendar.clear()
+        firstDayCalendar[Calendar.YEAR] = year
+        firstDayCalendar[Calendar.MONTH] = month - 1
+        firstDayCalendar[Calendar.DAY_OF_MONTH] = 1
+        return getMonth(firstDayCalendar)
+    }
+
+    override fun getDayOfWeek(date: CalendarDate): Int {
+        return dayInISO8601(date.toCalendar(TimeZone.getDefault())[Calendar.DAY_OF_WEEK])
+    }
+
+    override fun plusMonths(from: CalendarMonth, addedMonthsCount: Int): CalendarMonth {
+        if (addedMonthsCount <= 0) return from
+
+        val laterMonth = from.toCalendar()
+        laterMonth.add(Calendar.MONTH, addedMonthsCount)
+        return getMonth(laterMonth)
+    }
+
+    override fun minusMonths(from: CalendarMonth, subtractedMonthsCount: Int): CalendarMonth {
+        if (subtractedMonthsCount <= 0) return from
+
+        val earlierMonth = from.toCalendar()
+        earlierMonth.add(Calendar.MONTH, -subtractedMonthsCount)
+        return getMonth(earlierMonth)
+    }
+
+    override fun format(month: CalendarMonth, pattern: String): String {
+        val dateFormat = SimpleDateFormat(pattern, Locale.getDefault())
+        dateFormat.timeZone = utcTimeZone
+        dateFormat.isLenient = false
+        return dateFormat.format(month.toCalendar().timeInMillis)
+    }
+
+    override fun format(date: CalendarDate, pattern: String): String {
+        val dateFormat = SimpleDateFormat(pattern, Locale.getDefault())
+        dateFormat.timeZone = utcTimeZone
+        dateFormat.isLenient = false
+        return dateFormat.format(date.toCalendar(utcTimeZone).timeInMillis)
+    }
+
+    override fun parse(date: String, pattern: String): CalendarDate? {
+        val dateFormat = SimpleDateFormat(pattern)
+        dateFormat.timeZone = utcTimeZone
+        dateFormat.isLenient = false
+        return try {
+            val parsedDate = dateFormat.parse(date) ?: return null
+            val calendar = Calendar.getInstance(utcTimeZone)
+            calendar.time = parsedDate
+            CalendarDate(
+                year = calendar[Calendar.YEAR],
+                month = calendar[Calendar.MONTH] + 1,
+                dayOfMonth = calendar[Calendar.DAY_OF_MONTH],
+                utcTimeMillis = calendar.timeInMillis
+            )
+        } catch (pe: ParseException) {
+            null
+        }
+    }
+
+    /**
+     * Returns a given [Calendar] day number as a day representation under ISO-8601, where the first
+     * day is defined as Monday.
+     */
+    private fun dayInISO8601(day: Int): Int {
+        val shiftedDay = (day + 6) % 7
+        return if (shiftedDay == 0) return /* Sunday */ 7 else shiftedDay
+    }
+
+    private fun getMonth(firstDayCalendar: Calendar): CalendarMonth {
+        val difference = dayInISO8601(firstDayCalendar[Calendar.DAY_OF_WEEK]) - firstDayOfWeek
+        val daysFromStartOfWeekToFirstOfMonth = if (difference < 0) {
+            difference + DaysInWeek
+        } else {
+            difference
+        }
+        return CalendarMonth(
+            year = firstDayCalendar[Calendar.YEAR],
+            month = firstDayCalendar[Calendar.MONTH] + 1,
+            numberOfDays = firstDayCalendar.getActualMaximum(Calendar.DAY_OF_MONTH),
+            daysFromStartOfWeekToFirstOfMonth = daysFromStartOfWeekToFirstOfMonth,
+            startUtcTimeMillis = firstDayCalendar.timeInMillis
+        )
+    }
+
+    private fun CalendarMonth.toCalendar(): Calendar {
+        val calendar = Calendar.getInstance(utcTimeZone)
+        calendar.timeInMillis = this.startUtcTimeMillis
+        return calendar
+    }
+
+    private fun CalendarDate.toCalendar(timeZone: TimeZone): Calendar {
+        val calendar = Calendar.getInstance(timeZone)
+        calendar.clear()
+        calendar[Calendar.YEAR] = this.year
+        calendar[Calendar.MONTH] = this.month - 1
+        calendar[Calendar.DAY_OF_MONTH] = this.dayOfMonth
+        return calendar
+    }
+
+    private var utcTimeZone = TimeZone.getTimeZone("UTC")
+}
+
+/**
+ * A [CalendarModel] implementation for API >= 26.
+ */
+@OptIn(ExperimentalMaterial3Api::class)
+@RequiresApi(Build.VERSION_CODES.O)
+internal class CalendarModelImpl : CalendarModel {
+
+    override val today
+        get(): CalendarDate {
+            val systemLocalDate = LocalDate.now()
+            return CalendarDate(
+                year = systemLocalDate.year,
+                month = systemLocalDate.monthValue,
+                dayOfMonth = systemLocalDate.dayOfMonth,
+                utcTimeMillis = systemLocalDate.atTime(LocalTime.MIDNIGHT)
+                    .atZone(utcTimeZoneId).toInstant().toEpochMilli()
+            )
+        }
+
+    override val firstDayOfWeek: Int = WeekFields.of(Locale.getDefault()).firstDayOfWeek.value
+
+    override val weekdayNames: List<Pair<String, String>> =
+        // This will start with Monday as the first day, according to ISO-8601.
+        with(Locale.getDefault()) {
+            DayOfWeek.values().map {
+                it.getDisplayName(
+                    TextStyle.FULL,
+                    /* locale = */ this
+                ) to it.getDisplayName(
+                    TextStyle.NARROW,
+                    /* locale = */ this
+                )
+            }
+        }
+
+    override fun getDate(timeInMillis: Long): CalendarDate {
+        val localDate =
+            Instant.ofEpochMilli(timeInMillis).atZone(utcTimeZoneId).toLocalDate()
+        return CalendarDate(
+            year = localDate.year,
+            month = localDate.monthValue,
+            dayOfMonth = localDate.dayOfMonth,
+            utcTimeMillis = timeInMillis
+        )
+    }
+
+    override fun getMonth(timeInMillis: Long): CalendarMonth {
+        return getMonth(
+            Instant.ofEpochMilli(timeInMillis).atZone(utcTimeZoneId).toLocalDate()
+        )
+    }
+
+    override fun getMonth(date: CalendarDate): CalendarMonth {
+        return getMonth(LocalDate.of(date.year, date.month, 1))
+    }
+
+    override fun getMonth(year: Int, month: Int): CalendarMonth {
+        return getMonth(LocalDate.of(year, month, 1))
+    }
+
+    override fun getDayOfWeek(date: CalendarDate): Int {
+        return date.toLocalDate().dayOfWeek.value
+    }
+
+    override fun plusMonths(from: CalendarMonth, addedMonthsCount: Int): CalendarMonth {
+        if (addedMonthsCount <= 0) return from
+
+        val firstDayLocalDate = from.toLocalDate()
+        val laterMonth = firstDayLocalDate.plusMonths(addedMonthsCount.toLong())
+        return getMonth(laterMonth)
+    }
+
+    override fun minusMonths(from: CalendarMonth, subtractedMonthsCount: Int): CalendarMonth {
+        if (subtractedMonthsCount <= 0) return from
+
+        val firstDayLocalDate = from.toLocalDate()
+        val earlierMonth = firstDayLocalDate.minusMonths(subtractedMonthsCount.toLong())
+        return getMonth(earlierMonth)
+    }
+
+    override fun format(month: CalendarMonth, pattern: String): String {
+        val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern(pattern)
+        return month.toLocalDate().format(formatter)
+    }
+
+    override fun format(date: CalendarDate, pattern: String): String {
+        val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern(pattern)
+        return date.toLocalDate().format(formatter)
+    }
+
+    override fun parse(date: String, pattern: String): CalendarDate? {
+        // TODO: A DateTimeFormatter can be reused.
+        val formatter = DateTimeFormatter.ofPattern(pattern)
+        return try {
+            val localDate = LocalDate.parse(date, formatter)
+            CalendarDate(
+                year = localDate.year,
+                month = localDate.month.value,
+                dayOfMonth = localDate.dayOfMonth,
+                utcTimeMillis = localDate.atTime(LocalTime.MIDNIGHT)
+                    .atZone(utcTimeZoneId).toInstant().toEpochMilli()
+            )
+        } catch (pe: DateTimeParseException) {
+            null
+        }
+    }
+
+    private fun getMonth(firstDayLocalDate: LocalDate): CalendarMonth {
+        val difference = firstDayLocalDate.dayOfWeek.value - firstDayOfWeek
+        val daysFromStartOfWeekToFirstOfMonth = if (difference < 0) {
+            difference + DaysInWeek
+        } else {
+            difference
+        }
+        val firstDayEpochMillis =
+            firstDayLocalDate.atTime(LocalTime.MIDNIGHT).atZone(utcTimeZoneId).toInstant()
+                .toEpochMilli()
+        return CalendarMonth(
+            year = firstDayLocalDate.year,
+            month = firstDayLocalDate.monthValue,
+            numberOfDays = firstDayLocalDate.lengthOfMonth(),
+            daysFromStartOfWeekToFirstOfMonth = daysFromStartOfWeekToFirstOfMonth,
+            startUtcTimeMillis = firstDayEpochMillis
+        )
+    }
+
+    private fun CalendarMonth.toLocalDate(): LocalDate {
+        return Instant.ofEpochMilli(startUtcTimeMillis).atZone(utcTimeZoneId).toLocalDate()
+    }
+
+    private fun CalendarDate.toLocalDate(): LocalDate {
+        return LocalDate.of(
+            this.year,
+            this.month,
+            this.dayOfMonth
+        )
+    }
+
+    private val utcTimeZoneId = ZoneId.of("UTC")
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt
new file mode 100644
index 0000000..54cbd7b
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/CalendarModel.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.compose.material3
+
+@ExperimentalMaterial3Api
+internal interface CalendarModel {
+
+    /**
+     * A [CalendarDate] representing the current day.
+     */
+    val today: CalendarDate
+
+    /**
+     * Hold the first day of the week at the current `Locale` as an integer. The integer value
+     * follows the ISO-8601 standard and refer to Monday as 1, and Sunday as 7.
+     */
+    val firstDayOfWeek: Int
+
+    /**
+     * Holds a list of weekday names, starting from Monday as the first day in the list.
+     *
+     * Each item in this list is a [Pair] that holds the full name of the day, and its short
+     * abbreviation letter(s).
+     *
+     * Newer APIs (i.e. API 26+), a [Pair] will hold a full name and the first letter of the
+     * day.
+     * Older APIs that predate API 26 will hold a full name and the first three letters of the day.
+     */
+    val weekdayNames: List<Pair<String, String>>
+
+    /**
+     * Returns a [CalendarDate] from a given _UTC_ time in milliseconds.
+     *
+     * @param timeInMillis UTC milliseconds from the epoch
+     */
+    fun getDate(timeInMillis: Long): CalendarDate
+
+    /**
+     * Returns a [CalendarMonth] from a given _UTC_ time in milliseconds.
+     *
+     * @param timeInMillis UTC milliseconds from the epoch for the first day the month
+     */
+    fun getMonth(timeInMillis: Long): CalendarMonth
+
+    /**
+     * Returns a [CalendarMonth] from a given [CalendarDate].
+     *
+     * Note: This function ignores the [CalendarDate.dayOfMonth] value and just uses the date's
+     * year and month to resolve a [CalendarMonth].
+     *
+     * @param date a [CalendarDate] to resolve into a month
+     */
+    fun getMonth(date: CalendarDate): CalendarMonth
+
+    /**
+     * Returns a [CalendarMonth] from a given [year] and [month].
+     *
+     * @param year the month's year
+     * @param month an integer representing a month (e.g. JANUARY as 1, December as 12)
+     */
+    fun getMonth(year: Int, /* @IntRange(from = 1, to = 12) */ month: Int): CalendarMonth
+
+    /**
+     * Returns a day of week from a given [CalendarDate].
+     *
+     * @param date a [CalendarDate] to resolve
+     */
+    fun getDayOfWeek(date: CalendarDate): Int
+
+    /**
+     * Returns a [CalendarMonth] that is computed by adding a number of months, given as
+     * [addedMonthsCount], to a given month.
+     *
+     * @param from the [CalendarMonth] to add to
+     * @param addedMonthsCount the number of months to add
+     */
+    fun plusMonths(from: CalendarMonth, addedMonthsCount: Int): CalendarMonth
+
+    /**
+     * Returns a [CalendarMonth] that is computed by subtracting a number of months, given as
+     * [subtractedMonthsCount], from a given month.
+     *
+     * @param from the [CalendarMonth] to subtract from
+     * @param subtractedMonthsCount the number of months to subtract
+     */
+    fun minusMonths(from: CalendarMonth, subtractedMonthsCount: Int): CalendarMonth
+
+    /**
+     * Formats a [CalendarMonth] into a string with a given date format pattern.
+     *
+     * @param month a [CalendarMonth] to format
+     * @param pattern a date format pattern
+     */
+    fun format(month: CalendarMonth, pattern: String): String
+
+    /**
+     * Formats a [CalendarDate] into a string with a given date format pattern.
+     *
+     * @param date a [CalendarDate] to format
+     * @param pattern a date format pattern
+     */
+    fun format(date: CalendarDate, pattern: String): String
+
+    /**
+     * Parses a date string into a [CalendarDate].
+     *
+     * @param date a date string
+     * @param pattern the expected date pattern to be used for parsing the date string
+     * @return a [CalendarDate], or a `null` in case the parsing failed
+     */
+    fun parse(date: String, pattern: String): CalendarDate?
+}
+
+/**
+ * Represents a calendar date.
+ *
+ * @param year the date's year
+ * @param month the date's month
+ * @param dayOfMonth the date's day of month
+ * @param utcTimeMillis the date representation in _UTC_ milliseconds from the epoch
+ */
+@ExperimentalMaterial3Api
+internal data class CalendarDate(
+    val year: Int,
+    val month: Int,
+    val dayOfMonth: Int,
+    val utcTimeMillis: Long
+) : Comparable<CalendarDate> {
+    override operator fun compareTo(other: CalendarDate): Int =
+        this.utcTimeMillis.compareTo(other.utcTimeMillis)
+}
+
+/**
+ * Represents a calendar month.
+ *
+ * @param year the month's year
+ * @param month the calendar month as an integer (e.g. JANUARY as 1, December as 12)
+ * @param numberOfDays the number of days in the month
+ * @param daysFromStartOfWeekToFirstOfMonth the number of days from the start of the week to the
+ * first day of the month
+ * @param startUtcTimeMillis the first day of the month in _UTC_ milliseconds from the epoch
+ */
+@ExperimentalMaterial3Api
+internal data class CalendarMonth(
+    val year: Int,
+    val month: Int,
+    val numberOfDays: Int,
+    val daysFromStartOfWeekToFirstOfMonth: Int,
+    val startUtcTimeMillis: Long
+) {
+
+    /**
+     * The last _UTC_ milliseconds from the epoch of the month (i.e. the last millisecond of the
+     * last day of the month)
+     */
+    val endUtcTimeMillis: Long = startUtcTimeMillis + (numberOfDays * MillisecondsIn24Hours) - 1
+
+    /**
+     * Returns the position of a [CalendarMonth] within given years range.
+     */
+    internal fun indexIn(years: IntRange): Int {
+        return (year - years.first) * 12 + month - 1
+    }
+}
+
+internal const val DaysInWeek: Int = 7
+internal const val MillisecondsIn24Hours = 86400000L
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 d7bd6ef..4849ec9 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
@@ -369,7 +369,13 @@
                 val distance = abs(currentAnchor - currentAnchors.getValue(lower))
                 val relativeThreshold = abs(positionalThreshold(density, distance))
                 val absoluteThreshold = abs(currentAnchor - relativeThreshold)
-                if (offset > absoluteThreshold) currentState else lower
+                if (offset < 0) {
+                    // For negative offsets, larger absolute thresholds are closer to lower anchors
+                    // than smaller ones.
+                    if (abs(offset) < absoluteThreshold) currentState else lower
+                } else {
+                    if (offset > absoluteThreshold) currentState else lower
+                }
             }
         }
     }
diff --git a/compose/runtime/runtime/api/current.ignore b/compose/runtime/runtime/api/current.ignore
index 801ddf6..e6959b9 100644
--- a/compose/runtime/runtime/api/current.ignore
+++ b/compose/runtime/runtime/api/current.ignore
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+AddedAbstractMethod: androidx.compose.runtime.Composer#disableSourceInformation():
+    Added method androidx.compose.runtime.Composer.disableSourceInformation()
 AddedAbstractMethod: androidx.compose.runtime.Composer#endToMarker(int):
     Added method androidx.compose.runtime.Composer.endToMarker(int)
 AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentMarker():
diff --git a/compose/runtime/runtime/api/current.txt b/compose/runtime/runtime/api/current.txt
index 4210434..4e98ddb 100644
--- a/compose/runtime/runtime/api/current.txt
+++ b/compose/runtime/runtime/api/current.txt
@@ -113,6 +113,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
     method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
     method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
+    method public void disableSourceInformation();
     method @androidx.compose.runtime.ComposeCompilerApi public void enableReusing();
     method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
@@ -984,14 +985,18 @@
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface CompositionGroup extends androidx.compose.runtime.tooling.CompositionData {
     method public Iterable<java.lang.Object> getData();
+    method public default int getGroupSize();
     method public default Object? getIdentity();
     method public Object getKey();
     method public Object? getNode();
+    method public default int getSlotsSize();
     method public String? getSourceInfo();
     property public abstract Iterable<java.lang.Object> data;
+    property public default int groupSize;
     property public default Object? identity;
     property public abstract Object key;
     property public abstract Object? node;
+    property public default int slotsSize;
     property public abstract String? sourceInfo;
   }
 
diff --git a/compose/runtime/runtime/api/public_plus_experimental_current.txt b/compose/runtime/runtime/api/public_plus_experimental_current.txt
index ce05da6..3688ea9 100644
--- a/compose/runtime/runtime/api/public_plus_experimental_current.txt
+++ b/compose/runtime/runtime/api/public_plus_experimental_current.txt
@@ -120,6 +120,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
     method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
     method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
+    method public void disableSourceInformation();
     method @androidx.compose.runtime.ComposeCompilerApi public void enableReusing();
     method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
@@ -1060,14 +1061,18 @@
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface CompositionGroup extends androidx.compose.runtime.tooling.CompositionData {
     method public Iterable<java.lang.Object> getData();
+    method public default int getGroupSize();
     method public default Object? getIdentity();
     method public Object getKey();
     method public Object? getNode();
+    method public default int getSlotsSize();
     method public String? getSourceInfo();
     property public abstract Iterable<java.lang.Object> data;
+    property public default int groupSize;
     property public default Object? identity;
     property public abstract Object key;
     property public abstract Object? node;
+    property public default int slotsSize;
     property public abstract String? sourceInfo;
   }
 
diff --git a/compose/runtime/runtime/api/restricted_current.ignore b/compose/runtime/runtime/api/restricted_current.ignore
index 801ddf6..e6959b9 100644
--- a/compose/runtime/runtime/api/restricted_current.ignore
+++ b/compose/runtime/runtime/api/restricted_current.ignore
@@ -1,4 +1,6 @@
 // Baseline format: 1.0
+AddedAbstractMethod: androidx.compose.runtime.Composer#disableSourceInformation():
+    Added method androidx.compose.runtime.Composer.disableSourceInformation()
 AddedAbstractMethod: androidx.compose.runtime.Composer#endToMarker(int):
     Added method androidx.compose.runtime.Composer.endToMarker(int)
 AddedAbstractMethod: androidx.compose.runtime.Composer#getCurrentMarker():
diff --git a/compose/runtime/runtime/api/restricted_current.txt b/compose/runtime/runtime/api/restricted_current.txt
index 6fcdd3c..5b1424f 100644
--- a/compose/runtime/runtime/api/restricted_current.txt
+++ b/compose/runtime/runtime/api/restricted_current.txt
@@ -115,6 +115,7 @@
     method @androidx.compose.runtime.ComposeCompilerApi public <T> void createNode(kotlin.jvm.functions.Function0<? extends T> factory);
     method @androidx.compose.runtime.ComposeCompilerApi public void deactivateToEndGroup(boolean changed);
     method @androidx.compose.runtime.ComposeCompilerApi public void disableReusing();
+    method public void disableSourceInformation();
     method @androidx.compose.runtime.ComposeCompilerApi public void enableReusing();
     method @androidx.compose.runtime.ComposeCompilerApi public void endDefaults();
     method @androidx.compose.runtime.ComposeCompilerApi public void endMovableGroup();
@@ -1025,14 +1026,18 @@
 
   @kotlin.jvm.JvmDefaultWithCompatibility public interface CompositionGroup extends androidx.compose.runtime.tooling.CompositionData {
     method public Iterable<java.lang.Object> getData();
+    method public default int getGroupSize();
     method public default Object? getIdentity();
     method public Object getKey();
     method public Object? getNode();
+    method public default int getSlotsSize();
     method public String? getSourceInfo();
     property public abstract Iterable<java.lang.Object> data;
+    property public default int groupSize;
     property public default Object? identity;
     property public abstract Object key;
     property public abstract Object? node;
+    property public default int slotsSize;
     property public abstract String? sourceInfo;
   }
 
diff --git a/compose/runtime/runtime/integration-tests/build.gradle b/compose/runtime/runtime/integration-tests/build.gradle
index 36e4ef4..b9b65e5 100644
--- a/compose/runtime/runtime/integration-tests/build.gradle
+++ b/compose/runtime/runtime/integration-tests/build.gradle
@@ -107,3 +107,75 @@
         freeCompilerArgs += "-Xcontext-receivers"
     }
 }
+
+public File findFile() {
+    project.file("src/androidAndroidTest/kotlin/androidx/compose/runtime/GroupSizeTests.kt")
+}
+
+class UpdateExpectedGroupSizes extends DefaultTask {
+    @Internal
+    File source
+
+    @Internal
+    String sizes
+
+    @TaskAction
+    def exec() {
+        def newExpected = sizes.split(",")
+        if (newExpected.length != 3) {
+            if (newExpected.length < 3)
+                parameterError("Not enough parameters")
+            parameterError("Too many parameters")
+        }
+        if (!newExpected[1].isInteger()) {
+            parameterError("Groups field is not an integer")
+        }
+        if (!newExpected[1].isInteger()) {
+            parameterError("Slots field is not an integer")
+        }
+        def testName = newExpected[0]
+        def newGroups = newExpected[1] as Integer
+        def newSlots = newExpected[2] as Integer
+
+        def lines = source.readLines()
+        def modified = false
+
+        def namePattern = "\"$testName\""
+        for (int i = 0; i < lines.size(); i++) {
+            String line = lines[i]
+            if (line.contains(namePattern)) {
+                def newGroupsIndex = lines[i + 1].indexOf("noMoreGroupsThan")
+                if (newGroupsIndex < 0) error("Group line not found for test $namePattern")
+                lines[i + 1] = lines[i + 1].replaceFirst(/[0-9]+/, "$newGroups")
+                def newSlotsIndex = lines[i + 2].indexOf("noMoreSlotsThan")
+                if (newSlotsIndex < 0) error("Group line not found for test $namePattern")
+                lines[i + 2] = lines[i + 2].replaceFirst(/[0-9]+/, "$newSlots")
+                modified = true
+            }
+        }
+        if (!modified) error("Could not find test $namePattern")
+
+        // Update the file
+        def writer = source.newWriter()
+        lines.forEach {line ->
+            writer.write("$line\n")
+        }
+        writer.close()
+    }
+
+    def parameterError(String message) {
+        error("$message, expected newExpectedGroups to look like " +
+                "<testsName>,<newGroups>,<newSlots>")
+    }
+
+    def error(String message) {
+        throw new GradleException(message)
+    }
+}
+
+afterEvaluate {
+    tasks.register("updateExpectedGroupSizes", UpdateExpectedGroupSizes) { task ->
+        task.source = findFile()
+        task.sizes = project.findProperty("compose.newExpectedSizes")
+    }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/GroupSizeTests.kt b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/GroupSizeTests.kt
new file mode 100644
index 0000000..4731f73
--- /dev/null
+++ b/compose/runtime/runtime/integration-tests/src/androidAndroidTest/kotlin/androidx/compose/runtime/GroupSizeTests.kt
@@ -0,0 +1,188 @@
+/*
+ * 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.compose.runtime
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.material.Checkbox
+import androidx.compose.material.Text
+import androidx.compose.runtime.tooling.CompositionData
+import androidx.compose.runtime.tooling.CompositionGroup
+import androidx.compose.ui.Modifier
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class GroupSizeTests : BaseComposeTest() {
+    @get:Rule
+    override val activityRule = makeTestActivityRule()
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun spacerSize() {
+        slotExpect(
+            "spacerSize",
+            noMoreGroupsThan = 8,
+            noMoreSlotsThan = 10
+        ) {
+            Spacer(Modifier)
+        }
+    }
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun checkboxSize() {
+        slotExpect(
+            "checkboxSize",
+            noMoreGroupsThan = 154,
+            noMoreSlotsThan = 179,
+        ) {
+            Checkbox(true,  })
+        }
+    }
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun textSize() {
+        slotExpect(
+            "textSize",
+            noMoreGroupsThan = 13,
+            noMoreSlotsThan = 12
+        ) {
+            Text("")
+        }
+    }
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun boxSize() {
+        slotExpect(
+            "boxSize",
+            noMoreGroupsThan = 9,
+            noMoreSlotsThan = 10
+        ) {
+            Box { }
+        }
+    }
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun buttonSize() {
+        slotExpect(
+            "buttonSize",
+            noMoreGroupsThan = 165,
+            noMoreSlotsThan = 193,
+        ) {
+            androidx.compose.material.Button({ }) {
+                Text("Click me")
+            }
+        }
+    }
+
+    @Test
+    @MediumTest
+    @Ignore("Only run explicitly to check framework")
+    fun columnSize() {
+        slotExpect(
+            "columnSize",
+            noMoreGroupsThan = 9,
+            noMoreSlotsThan = 13
+        ) {
+            Column { }
+        }
+    }
+
+    private fun slotExpect(
+        name: String,
+        noMoreGroupsThan: Int,
+        noMoreSlotsThan: Int,
+        content: @Composable () -> Unit
+    ) {
+        var compositionData: CompositionData? = null
+        compose {
+            compositionData = currentComposer.compositionData
+            currentComposer.disableSourceInformation()
+            Marker { content() }
+        }.then {
+            val group = findMarkerGroup(compositionData!!)
+            val receivedGroups = group.groupSize
+            val receivedSlots = group.slotsSize
+
+            if (receivedGroups > noMoreGroupsThan || receivedSlots > noMoreSlotsThan) {
+                error("Expected $noMoreGroupsThan groups and $noMoreSlotsThan slots " +
+                    "but received $receivedGroups and $receivedSlots\n" +
+                    "If this was expected execute the gradlew command:\n   ${
+                        updateTestCommand(name, receivedGroups, receivedSlots)
+                    }"
+                )
+            }
+            if (receivedSlots < noMoreSlotsThan || receivedGroups < noMoreGroupsThan) {
+                println(
+                    "WARNING: Improvement detected. Update test GroupSizeTests.$name to\n" +
+                    "If this was expected, running the gradle command:\n\n" +
+                    "   ${updateTestCommand(name, receivedGroups, receivedSlots)}\n\n" +
+                    "is recommended"
+                )
+            }
+        }
+    }
+}
+
+private fun updateTestCommand(name: String, newGroups: Int, newSlots: Int) =
+    "./gradlew  -P \"compose.newExpectedSizes=$name,$newGroups,$newSlots\"  " +
+        ":compose:runtime:runtime:integration-test:updateExpectedGroupSizes"
+
+private const val MarkerGroup = -441660990
+
+private fun findMarkerGroup(compositionData: CompositionData): CompositionGroup {
+    fun findGroup(groups: Iterable<CompositionGroup>, key: Int): CompositionGroup? {
+        for (group in groups) {
+            if (group.key == key) return group
+            findGroup(group.compositionGroups, key)?.let { return it }
+        }
+        return null
+    }
+
+    return findGroup(compositionData.compositionGroups, MarkerGroup)
+        ?.compositionGroups
+        ?.firstOrNull()
+        ?: error("Could not find marker")
+}
+
+@Composable
+private inline fun Marker(content: @Composable () -> Unit) = content()
+
+// left unused for debugging. This is useful for debugging differences in the slot table
+@Suppress("unused")
+private fun CompositionGroup.asString(): String {
+    fun stringOf(group: CompositionGroup, indent: String): String =
+        "$indent ${group.key} ${group.groupSize}:${group.slotsSize}:\n${
+            group.compositionGroups.joinToString("") {
+                stringOf(it, "$indent  ")
+            }}"
+    return stringOf(this, "")
+}
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
index dcbc8dc..03e25a0 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
@@ -1058,6 +1058,8 @@
     val composition: ControlledComposition
         @TestOnly get
 
+    fun disableSourceInformation()
+
     companion object {
         /**
          * A special value used to represent no value was stored (e.g. an empty slot). This is
@@ -1254,6 +1256,7 @@
     private var childrenComposing: Int = 0
     private var snapshot = currentSnapshot()
     private var compositionToken: Int = 0
+    private var sourceInformationEnabled = true
 
     private val invalidateStack = Stack<RecomposeScopeImpl>()
 
@@ -3202,19 +3205,25 @@
 
     @ComposeCompilerApi
     override fun sourceInformation(sourceInformation: String) {
-        if (inserting) {
+        if (inserting && sourceInformationEnabled) {
             writer.insertAux(sourceInformation)
         }
     }
 
     @ComposeCompilerApi
     override fun sourceInformationMarkerStart(key: Int, sourceInformation: String) {
-        start(key, objectKey = null, isNode = false, data = sourceInformation)
+        if (sourceInformationEnabled)
+            start(key, objectKey = null, isNode = false, data = sourceInformation)
     }
 
     @ComposeCompilerApi
     override fun sourceInformationMarkerEnd() {
-        end(isNode = false)
+        if (sourceInformationEnabled)
+            end(isNode = false)
+    }
+
+    override fun disableSourceInformation() {
+        sourceInformationEnabled = false
     }
 
     /**
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
index 3ce6db5..bff9d04 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SlotTable.kt
@@ -3025,6 +3025,16 @@
         )
     }
 
+    override val groupSize: Int get() = table.groups.groupSize(group)
+
+    override val slotsSize: Int
+        get() {
+            val nextGroup = group + groupSize
+            val nextSlot = if (nextGroup < table.groupsSize) table.groups.dataAnchor(nextGroup)
+                else table.slotsSize
+            return nextSlot - table.groups.dataAnchor(group)
+        }
+
     private fun validateRead() {
         if (table.version != version) {
             throw ConcurrentModificationException()
diff --git a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/tooling/CompositionData.kt b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/tooling/CompositionData.kt
index 16e9076..0bad0ed 100644
--- a/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/tooling/CompositionData.kt
+++ b/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/tooling/CompositionData.kt
@@ -92,4 +92,11 @@
      */
     val identity: Any?
       get() = null
-}
\ No newline at end of file
+
+    /**
+     * The total number of groups, including itself, that this group contains.
+     */
+    val groupSize: Int get() = 0
+
+    val slotsSize: Int get() = 0
+}
diff --git a/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt
new file mode 100644
index 0000000..8945723
--- /dev/null
+++ b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/GroupSizeValidationTests.kt
@@ -0,0 +1,629 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("RemoveEmptyClassBody")
+
+package androidx.compose.runtime
+
+import androidx.compose.runtime.mock.CompositionTestScope
+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 {
+
+    @Test
+    fun spacerLike() = compositionTest {
+        slotExpect(
+            name = "SpacerLike",
+            noMoreGroupsThan = 6,
+            noMoreSlotsThan = 9,
+        ) {
+            SpacerLike(Modifier)
+        }
+    }
+
+    @Test
+    fun columnLikeSize() = compositionTest {
+        slotExpect(
+            name = "ColumnLike",
+            noMoreGroupsThan = 9,
+            noMoreSlotsThan = 8,
+        ) {
+            ColumnLike { }
+        }
+    }
+
+    @Test
+    fun textLikeSize() = compositionTest {
+        slotExpect(
+            name = "TextLike",
+            noMoreGroupsThan = 13,
+            noMoreSlotsThan = 15
+        ) {
+            TextLike("")
+        }
+    }
+
+    @Test
+    fun checkboxLike() = compositionTest {
+        slotExpect(
+            name = "CheckboxLike",
+            noMoreGroupsThan = 13,
+            noMoreSlotsThan = 20
+        ) {
+            CheckboxLike(checked = false,  })
+        }
+    }
+}
+
+// The following are a sketch of how compose ui uses composition to produce some important
+// composable functions. These are derived from the implementation as of Oct 2022.
+
+// The slot usage should be validated against the actual usage in GroupSizeTests in the
+// integration-tests periodically to avoid these skewing too far.
+
+@Stable
+private fun interface MeasurePolicy {
+    fun measure()
+}
+
+private val LocalDensity = staticCompositionLocalOf { 0 }
+private val LocalLayoutDirection = staticCompositionLocalOf { 0 }
+private val LocalViewConfiguration = staticCompositionLocalOf { 0 }
+
+private object ViewHelper {
+    val Constructor = ::View
+    val SetModifier: View.(Modifier) -> Unit = { attributes["modifier"] = it }
+    val SetMeasurePolicy: View.(MeasurePolicy) -> Unit = { attributes["measurePolicy"] = it }
+    val SetDensity: View.(Int) -> Unit = { attributes["density"] = it }
+    val SetLayoutDirection: View.(Int) -> Unit = { attributes["layoutDirection"] = it }
+    val SetViewConfiguration: View.(Int) -> Unit = { attributes["viewConfiguration"] = it }
+}
+
+@Composable
+private inline fun LayoutLike(
+    content: @Composable () -> Unit,
+    modifier: Modifier = Modifier,
+    measurePolicy: MeasurePolicy
+) {
+    val density = LocalDensity.current
+    val layoutDirection = LocalLayoutDirection.current
+    val viewConfiguration = LocalViewConfiguration.current
+    ReusableComposeNode<View, Applier<Any>>(
+        factory = ViewHelper.Constructor,
+        update = {
+            set(modifier, ViewHelper.SetModifier)
+            set(measurePolicy, ViewHelper.SetMeasurePolicy)
+            set(density, ViewHelper.SetDensity)
+            set(layoutDirection, ViewHelper.SetLayoutDirection)
+            set(viewConfiguration, ViewHelper.SetViewConfiguration)
+        },
+        content = content
+    )
+}
+
+@Composable
+@NonRestartableComposable
+private fun LayoutLike(modifier: Modifier, measurePolicy: MeasurePolicy) {
+    val density = LocalDensity.current
+    val layoutDirection = LocalLayoutDirection.current
+    val viewConfiguration = LocalViewConfiguration.current
+    ReusableComposeNode<View, Applier<Any>>(
+        factory = ViewHelper.Constructor,
+        update = {
+            set(modifier, ViewHelper.SetModifier)
+            set(measurePolicy, ViewHelper.SetMeasurePolicy)
+            set(density, ViewHelper.SetDensity)
+            set(layoutDirection, ViewHelper.SetLayoutDirection)
+            set(viewConfiguration, ViewHelper.SetViewConfiguration)
+        }
+    )
+}
+
+@Stable
+private interface Modifier {
+    companion object : Modifier
+}
+
+@Immutable
+private object Arrangement {
+    @Stable
+    interface Vertical
+
+    @Stable
+    val Top = object : Vertical { }
+}
+
+@Immutable
+private object Alignment {
+    @Stable
+    interface Horizontal
+
+    @Stable
+    val Start = object : Horizontal { }
+}
+
+private object SpacerMeasurePolicy : MeasurePolicy {
+    override fun measure() { }
+}
+
+@Composable
+private fun SpacerLike(modifier: Modifier) {
+    LayoutLike(measurePolicy = SpacerMeasurePolicy, modifier = modifier)
+}
+
+@Immutable
+private interface ColumnScope
+
+private object ColumnScopeInstance : ColumnScope
+
+// A stable version of Column used for group size tests
+@Composable
+private inline fun ColumnLike(
+    modifier: Modifier = Modifier,
+    verticalArrangement: Arrangement.Vertical = Arrangement.Top,
+    horizontalAlignment: Alignment.Horizontal = Alignment.Start,
+    content: @Composable ColumnScope.() -> Unit
+) {
+    val measurePolicy =
+        columnMeasurePolicy(verticalArrangement, horizontalAlignment)
+    LayoutLike(
+        content = { ColumnScopeInstance.content() },
+        measurePolicy = measurePolicy,
+        modifier = modifier
+    )
+}
+
+private object DefaultColumnRowMeasurePolicy : MeasurePolicy {
+    override fun measure() { }
+}
+
+@Composable private fun columnMeasurePolicy(
+    verticalArrangement: Arrangement.Vertical,
+    horizontalAlignment: Alignment.Horizontal
+) = if (verticalArrangement == Arrangement.Top && horizontalAlignment == Alignment.Start) {
+    DefaultColumnRowMeasurePolicy
+} else {
+    remember(verticalArrangement, horizontalAlignment) {
+        DefaultColumnRowMeasurePolicy
+    }
+}
+
+@Immutable
+@JvmInline
+private value class Color(val value: ULong) {
+
+    @Stable
+    @Suppress("UNUSED_PARAMETER")
+    fun copy(
+        alpha: Float = 0f,
+        red: Float = 0f,
+        green: Float = 0f,
+        blue: Float = 0f
+    ): Color = this
+
+    companion object {
+        @Stable
+        val Unspecified = Color(0u)
+    }
+}
+private val Color.isSpecified: Boolean get() = this != Color.Unspecified
+
+private inline fun Color.takeOrElse(block: () -> Color): Color = if (isSpecified) this else block()
+
+@Immutable
+@JvmInline
+private value class TextUnit(val packedValue: Long) {
+    companion object {
+        @Stable
+        val Unspecified = TextUnit(0)
+    }
+}
+
+@JvmInline
+value class FontStyle(val value: Int)
+
+@Immutable
+@Suppress("unused")
+private class FontWeight(val weight: Int)
+
+@Immutable
+@Suppress("UNUSED_PARAMETER")
+private sealed class FontFamily(canLoadSynchronously: Boolean) {
+    @Stable
+    interface Resolver {
+        companion object {
+            val Default = object : Resolver { }
+        }
+    }
+}
+
+private val LocalFontFamilyResolver = staticCompositionLocalOf { FontFamily.Resolver.Default }
+
+@Immutable
+@Suppress("unused")
+private class TextDecoration(val mask: Int)
+
+@JvmInline
+@Suppress("unused")
+private value class TextAlign(val value: Int)
+
+@JvmInline
+private value class TextOverflow(val value: Int) {
+    companion object {
+        @Stable
+        val Clip = TextOverflow(1)
+    }
+}
+
+private class TextLayoutResult
+
+@Immutable
+@Suppress("unused")
+private class TextStyle(
+    val color: Color = Color.Unspecified,
+    val fontSize: TextUnit = TextUnit.Unspecified,
+    val fontWeight: FontWeight? = null,
+    val textAlign: TextAlign? = null,
+    val lineHeight: TextUnit = TextUnit.Unspecified,
+    val fontFamily: FontFamily? = null,
+    val textDecoration: TextDecoration? = null,
+    val fontStyle: FontStyle? = null,
+    val letterSpacing: TextUnit = TextUnit.Unspecified
+) {
+    @Stable
+    @Suppress("UNUSED_PARAMETER")
+    fun merge(other: TextStyle? = null) = this
+
+    companion object {
+        val Default = TextStyle()
+    }
+}
+
+private interface SelectionRegistrar {
+    fun nextSelectableId(): Long
+
+    companion object {
+        const val InvalidSelectableId = 0L
+    }
+}
+
+private object DefaultSelectionRegister : SelectionRegistrar {
+    override fun nextSelectableId() = 0L
+}
+
+private val DefaultTextStyle = TextStyle()
+private val LocalTextStyle = staticCompositionLocalOf { DefaultTextStyle }
+private val LocalContentColor = staticCompositionLocalOf { Color.Unspecified }
+private val LocalContentAlpha = staticCompositionLocalOf { 1f }
+private val LocalSelectionRegistrar = staticCompositionLocalOf<SelectionRegistrar?> {
+    DefaultSelectionRegister
+}
+
+@Composable
+private fun TextLike(
+    text: String,
+    modifier: Modifier = Modifier,
+    color: Color = Color.Unspecified,
+    fontSize: TextUnit = TextUnit.Unspecified,
+    fontStyle: FontStyle? = null,
+    fontWeight: FontWeight? = null,
+    fontFamily: FontFamily? = null,
+    letterSpacing: TextUnit = TextUnit.Unspecified,
+    textDecoration: TextDecoration? = null,
+    textAlign: TextAlign? = null,
+    lineHeight: TextUnit = TextUnit.Unspecified,
+    overflow: TextOverflow = TextOverflow.Clip,
+    softWrap: Boolean = true,
+    maxLines: Int = Int.MAX_VALUE,
+    minLines: Int = 1,
+    onTextLayout: (TextLayoutResult) -> Unit = {},
+    style: TextStyle = LocalTextStyle.current
+) {
+
+    val textColor = color.takeOrElse {
+        style.color.takeOrElse {
+            LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
+        }
+    }
+
+    val mergedStyle = style.merge(
+        TextStyle(
+            color = textColor,
+            fontSize = fontSize,
+            fontWeight = fontWeight,
+            textAlign = textAlign,
+            lineHeight = lineHeight,
+            fontFamily = fontFamily,
+            textDecoration = textDecoration,
+            fontStyle = fontStyle,
+            letterSpacing = letterSpacing
+        )
+    )
+
+    BasicTextLike(
+        text = text,
+        modifier = modifier,
+        style = mergedStyle,
+        >
+        overflow = overflow,
+        softWrap = softWrap,
+        maxLines = maxLines,
+        minLines = minLines
+    )
+}
+
+private fun CompositionTestScope.slotExpect(
+    name: String,
+    noMoreGroupsThan: Int,
+    noMoreSlotsThan: Int,
+    content: @Composable () -> Unit
+) {
+    var compositionData: CompositionData? = null
+    compose {
+        compositionData = currentComposer.compositionData
+        currentComposer.disableSourceInformation()
+        Marker { content() }
+    }
+
+    val group = findMarkerGroup(compositionData!!)
+    val receivedGroups = group.groupSize
+    val receivedSlots = group.slotsSize
+
+    if (receivedGroups > noMoreGroupsThan || receivedSlots > noMoreSlotsThan) {
+        error("Expected $noMoreGroupsThan groups and $noMoreSlotsThan slots " +
+            "but received $receivedGroups and $receivedSlots\n"
+        )
+    }
+    if (receivedSlots < noMoreSlotsThan || receivedGroups < noMoreGroupsThan) {
+        println(
+            "WARNING: Improvement detected. Update test GroupSizeTests.$name to " +
+                "$receivedGroups groups and $receivedSlots slots"
+        )
+    }
+}
+
+@Suppress("unused")
+private class AnnotatedString(val text: String)
+
+@Suppress("unused")
+private class TextState(
+    val textDelegate: TextDelegate,
+    val selectionId: Long
+) {
+    var selectionBackgroundColor: Color = Color.Unspecified
+    var onTextLayout: (TextLayoutResult) -> Unit = { }
+}
+
+@Suppress("unused")
+private class TextDelegate(
+    val text: AnnotatedString,
+    val style: TextStyle,
+    val maxLines: Int = Int.MAX_VALUE,
+    val minLines: Int = 1,
+    val softWrap: Boolean = true,
+    val overflow: TextOverflow = TextOverflow.Clip,
+    val density: Int,
+    val fontFamilyResolver: FontFamily.Resolver
+)
+
+@Suppress("UNUSED_PARAMETER")
+private fun updateTextDelegate(
+    current: TextDelegate,
+    text: String,
+    style: TextStyle,
+    density: Int,
+    fontFamilyResolver: FontFamily.Resolver,
+    softWrap: Boolean = true,
+    overflow: TextOverflow = TextOverflow.Clip,
+    maxLines: Int = Int.MAX_VALUE,
+    minLines: Int = 1,
+): TextDelegate = current
+
+@Suppress("UNUSED_PARAMETER")
+private class TextController(val state: TextState) {
+    val measurePolicy: MeasurePolicy = DefaultColumnRowMeasurePolicy
+    fun setTextDelegate(updateTextDelegate: TextDelegate) { }
+    fun update(selectionRegistrar: SelectionRegistrar?) { }
+}
+
+@Immutable
+@Suppress("unused")
+private class TextSelectionColors(
+    val handleColor: Color,
+    val backgroundColor: Color
+) {
+    companion object {
+        val Default = TextSelectionColors(Color.Unspecified, Color.Unspecified)
+    }
+}
+
+private val LocalTextSelectionColors = staticCompositionLocalOf { TextSelectionColors.Default }
+
+@Composable
+private fun BasicTextLike(
+    text: String,
+    modifier: Modifier = Modifier,
+    style: TextStyle = TextStyle.Default,
+    onTextLayout: (TextLayoutResult) -> Unit = {},
+    overflow: TextOverflow = TextOverflow.Clip,
+    softWrap: Boolean = true,
+    maxLines: Int = Int.MAX_VALUE,
+    minLines: Int = 1
+) {
+    // selection registrar, if no SelectionContainer is added ambient value will be null
+    val selectionRegistrar = LocalSelectionRegistrar.current
+    val density = LocalDensity.current
+    val fontFamilyResolver = LocalFontFamilyResolver.current
+
+    // The ID used to identify this CoreText. If this CoreText is removed from the composition
+    // tree and then added back, this ID should stay the same.
+    // Notice that we need to update selectable ID when the input text or selectionRegistrar has
+    // been updated.
+    // When text is updated, the selection on this CoreText becomes invalid. It can be treated
+    // as a brand new CoreText.
+    // When SelectionRegistrar is updated, CoreText have to request a new ID to avoid ID collision.
+
+    // NOTE(text-perf-review): potential bug. selectableId is regenerated here whenever text
+    // changes, but it is only saved in the initial creation of TextState.
+    val selectableId = if (selectionRegistrar == null) {
+        SelectionRegistrar.InvalidSelectableId
+    } else {
+        remember(text, selectionRegistrar) {
+            selectionRegistrar.nextSelectableId()
+        }
+    }
+
+    val controller = remember {
+        TextController(
+            TextState(
+                TextDelegate(
+                    text = AnnotatedString(text),
+                    style = style,
+                    density = density,
+                    softWrap = softWrap,
+                    fontFamilyResolver = fontFamilyResolver,
+                    overflow = overflow,
+                    maxLines = maxLines,
+                    minLines = minLines,
+                ),
+                selectableId
+            )
+        )
+    }
+    val state = controller.state
+    if (!currentComposer.inserting) {
+        controller.setTextDelegate(
+            updateTextDelegate(
+                current = state.textDelegate,
+                text = text,
+                style = style,
+                density = density,
+                softWrap = softWrap,
+                fontFamilyResolver = fontFamilyResolver,
+                overflow = overflow,
+                maxLines = maxLines,
+                minLines = minLines,
+            )
+        )
+    }
+    state.>
+    controller.update(selectionRegistrar)
+    if (selectionRegistrar != null) {
+        state.selectionBackgroundColor = LocalTextSelectionColors.current.backgroundColor
+    }
+
+    LayoutLike(modifier = modifier, measurePolicy = controller.measurePolicy)
+}
+
+// Unlike this above, this one is much more speculative as it removes the materialized modifiers
+// and interactions and focus just on the wrapper pattern used by Checkbox
+
+@Composable
+private fun CheckboxLike(
+    checked: Boolean,
+    onCheckedChange: ((Boolean) -> Unit)?,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true
+) {
+    TriStateCheckboxLike(
+        state = ToggleableState(checked),
+         (onCheckedChange != null) { { onCheckedChange(!checked) } } else null,
+        enabled = enabled,
+        modifier = modifier
+    )
+}
+
+@Suppress("unused")
+private enum class ToggleableState {
+    On,
+    Off,
+    Indeterminate
+}
+
+private fun ToggleableState(value: Boolean) = if (value) ToggleableState.On else ToggleableState.Off
+
+@Suppress("UNUSED_PARAMETER")
+@Composable
+private fun TriStateCheckboxLike(
+    state: ToggleableState,
+    onClick: (() -> Unit)?,
+    modifier: Modifier = Modifier,
+    enabled: Boolean = true
+) {
+    CheckboxImplLike(
+        enabled = enabled,
+        value = state,
+        modifier = modifier
+    )
+}
+
+@Suppress("UNUSED_EXPRESSION")
+@Composable
+private fun CheckboxImplLike(
+    enabled: Boolean,
+    value: ToggleableState,
+    modifier: Modifier
+) {
+    CanvasLike(modifier) {
+        enabled
+        value
+    }
+}
+
+private interface DrawScope
+
+@Suppress("UNUSED_PARAMETER")
+@Composable
+private fun CanvasLike(modifier: Modifier, onDraw: DrawScope.() -> Unit) =
+    SpacerLike(modifier)
+
+// Utility functions for the tests
+
+@Composable
+private inline fun Marker(content: @Composable () -> Unit) = content()
+
+// left unused for debugging. This is useful for debugging differences in the slot table
+@Suppress("unused")
+private fun CompositionGroup.asString(): String {
+    fun stringOf(group: CompositionGroup, indent: String): String =
+        "$indent ${group.key} ${group.groupSize}:${group.slotsSize}:\n${
+            group.compositionGroups.joinToString("") {
+                stringOf(it, "$indent  ")
+            }}"
+    return stringOf(this, "")
+}
+
+private const val MarkerGroup = -340126117
+
+private fun findMarkerGroup(compositionData: CompositionData): CompositionGroup {
+    fun findGroup(groups: Iterable<CompositionGroup>, key: Int): CompositionGroup? {
+        for (group in groups) {
+            if (group.key == key) return group
+            findGroup(group.compositionGroups, key)?.let { return it }
+        }
+        return null
+    }
+
+    return findGroup(compositionData.compositionGroups, MarkerGroup)
+        ?.compositionGroups
+        ?.firstOrNull()
+        ?: error("Could not find marker:\n${compositionData.compositionGroups.first().asString()}")
+}
diff --git a/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/mock/View.kt b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/mock/View.kt
index 32cd5cf..2794899 100644
--- a/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/mock/View.kt
+++ b/compose/runtime/runtime/src/commonTest/kotlin/androidx/compose/runtime/mock/View.kt
@@ -16,12 +16,18 @@
 
 package androidx.compose.runtime.mock
 
+import androidx.compose.runtime.Stable
 import androidx.compose.runtime.snapshots.fastForEach
 
 fun indent(indent: Int, builder: StringBuilder) {
     repeat(indent) { builder.append(' ') }
 }
 
+@Stable
+interface Modifier {
+    companion object : Modifier { }
+}
+
 open class View {
     var name: String = ""
     val children = mutableListOf<View>()
@@ -123,7 +129,7 @@
         it.toString()
     }
 
-    fun findFirstOrNull(predicate: (view: View) -> Boolean): View? {
+    private fun findFirstOrNull(predicate: (view: View) -> Boolean): View? {
         if (predicate(this)) return this
         for (child in children) {
             child.findFirstOrNull(predicate)?.let { return it }
diff --git a/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/VectorBenchmarkWithTracing.kt b/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/VectorBenchmarkWithTracing.kt
deleted file mode 100644
index 67f4487..0000000
--- a/compose/ui/ui-graphics/benchmark/src/androidTest/java/androidx/compose/ui/graphics/benchmark/VectorBenchmarkWithTracing.kt
+++ /dev/null
@@ -1,36 +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.compose.ui.graphics.benchmark
-
-import androidx.benchmark.junit4.PerfettoTraceRule
-import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.LargeTest
-import org.junit.Rule
-import org.junit.runner.RunWith
-
-/**
- * Duplicate of [VectorBenchmark], but which adds tracing.
- */
-@Suppress("ClassName")
-@LargeTest
-@RunWith(AndroidJUnit4::class)
-class VectorBenchmarkWithTracing : VectorBenchmark() {
-    @OptIn(ExperimentalPerfettoCaptureApi::class)
-    @get:Rule
-    val perfettoTraceRule = PerfettoTraceRule()
-}
\ No newline at end of file
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
index 663d460..f4b52f8 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/AndroidParagraphTest.kt
@@ -21,6 +21,7 @@
 import android.text.TextPaint
 import android.text.style.AbsoluteSizeSpan
 import android.text.style.BackgroundColorSpan
+import android.text.style.CharacterStyle
 import android.text.style.ForegroundColorSpan
 import android.text.style.LeadingMarginSpan
 import android.text.style.LocaleSpan
@@ -1447,6 +1448,18 @@
     }
 
     @Test
+    fun testSpanStyle_textDecoration_underline_appliedAsSpan() {
+        val text = "abc"
+        val paragraph = simpleParagraph(
+            text = text,
+            style = TextStyle(textDecoration = TextDecoration.Underline),
+            width = 0.0f
+        )
+
+        assertThat(paragraph.charSequence).hasSpan(CharacterStyle::class, 0, text.length)
+    }
+
+    @Test
     fun testSpanStyle_textDecoration_lineThrough_appliedOnTextPaint() {
         val paragraph = simpleParagraph(
             text = "",
@@ -1970,6 +1983,38 @@
         assertThat(shaderBrush.callCount).isEqualTo(1)
     }
 
+    @Test
+    fun drawText_withUnderlineStyle_equalToUnderlinePaint() = with(defaultDensity) {
+        val fontSize = 30.sp
+        val fontSizeInPx = fontSize.toPx()
+        val text = "レンズ(単焦点)"
+        val spanStyle = SpanStyle(textDecoration = TextDecoration.Underline)
+        val paragraph = simpleParagraph(
+            text = text,
+            style = TextStyle(fontSize = fontSize),
+            spanStyles = listOf(AnnotatedString.Range(spanStyle, 0, text.length)),
+            width = fontSizeInPx * 20
+        )
+
+        val paragraph2 = simpleParagraph(
+            text = text,
+            style = TextStyle(
+                fontSize = fontSize,
+                textDecoration = TextDecoration.Underline
+            ),
+            width = fontSizeInPx * 20
+        )
+
+        val bitmapWithSpan = paragraph.bitmap()
+        // Our text rendering stack relies on the fact that given textstyle is also passed to draw
+        // functions of TextLayoutResult, MultiParagraph, Paragraph. If Underline is not specified
+        // here, it would be removed while drawing the MultiParagraph. We are simply mimicking
+        // what TextPainter does.
+        val bitmapNoSpan = paragraph2.bitmap(textDecoration = TextDecoration.Underline)
+
+        assertThat(bitmapWithSpan).isEqualToBitmap(bitmapNoSpan)
+    }
+
     private fun simpleParagraph(
         text: String = "",
         spanStyles: List<AnnotatedString.Range<SpanStyle>> = listOf(),
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
index fce67fc..7088ec4 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/MultiParagraphIntegrationTest.kt
@@ -31,6 +31,7 @@
 import androidx.compose.ui.text.matchers.isZero
 import androidx.compose.ui.text.style.ResolvedTextDirection
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.text.style.TextDirection
 import androidx.compose.ui.text.style.TextIndent
 import androidx.compose.ui.unit.Constraints
@@ -1155,6 +1156,39 @@
     }
 
     @Test
+    fun drawText_withUnderlineStyle_equalToUnderlinePaint() = with(defaultDensity) {
+        val fontSize = 30.sp
+        val fontSizeInPx = fontSize.toPx()
+        val multiParagraph = simpleMultiParagraph(
+            text = buildAnnotatedString {
+                withStyle(SpanStyle(textDecoration = TextDecoration.Underline)) {
+                    append("レンズ(単焦点)")
+                }
+            },
+            style = TextStyle(fontSize = fontSize),
+            width = fontSizeInPx * 20
+        )
+
+        val multiParagraph2 = simpleMultiParagraph(
+            text = AnnotatedString("レンズ(単焦点)"),
+            style = TextStyle(
+                fontSize = fontSize,
+                textDecoration = TextDecoration.Underline
+            ),
+            width = fontSizeInPx * 20
+        )
+
+        val bitmapWithSpan = multiParagraph.bitmap()
+        // Our text rendering stack relies on the fact that given textstyle is also passed to draw
+        // functions of TextLayoutResult, MultiParagraph, Paragraph. If Underline is not specified
+        // here, it would be removed while drawing the MultiParagraph. We are simply mimicking
+        // what TextPainter does.
+        val bitmapNoSpan = multiParagraph2.bitmap(textDecoration = TextDecoration.Underline)
+
+        assertThat(bitmapWithSpan).isEqualToBitmap(bitmapNoSpan)
+    }
+
+    @Test
     fun textIndent_onFirstLine() {
         with(defaultDensity) {
             val text = createAnnotatedString("aaa", "\u05D0\u05D0\u05D0")
diff --git a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/ApplySpanStyleTest.kt b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/ApplySpanStyleTest.kt
index 3b2cca6..e4e8f33 100644
--- a/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/ApplySpanStyleTest.kt
+++ b/compose/ui/ui-text/src/androidAndroidTest/kotlin/androidx/compose/ui/text/platform/ApplySpanStyleTest.kt
@@ -28,6 +28,7 @@
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.platform.extensions.applySpanStyle
 import androidx.compose.ui.text.style.BaselineShift
+import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.text.style.TextGeometricTransform
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.TextUnit
@@ -257,8 +258,8 @@
         assertThat(notApplied.background).isEqualTo(Color.Unspecified)
     }
 
-    /*@Test
-    fun textDecorationUnderline_shouldBeLeftAsSpan() {
+    @Test
+    fun textDecorationUnderline_shouldBeAppliedToPaint() {
         val textDecoration = TextDecoration.Underline
         val spanStyle = SpanStyle(textDecoration = textDecoration)
         val tp = AndroidTextPaint(0, density.density)
@@ -266,12 +267,12 @@
 
         val notApplied = tp.applySpanStyle(spanStyle, resolveTypeface, density)
 
-        assertThat(tp.isUnderlineText).isEqualTo(false)
-        assertThat(notApplied.textDecoration).isEqualTo(textDecoration)
+        assertThat(tp.isUnderlineText).isEqualTo(true)
+        assertThat(notApplied.textDecoration).isEqualTo(null)
     }
 
     @Test
-    fun textDecorationLineThrough_shouldBeLeftAsSpan() {
+    fun textDecorationLineThrough_shouldBeAppliedToPaint() {
         val textDecoration = TextDecoration.LineThrough
         val spanStyle = SpanStyle(textDecoration = textDecoration)
         val tp = AndroidTextPaint(0, density.density)
@@ -279,13 +280,14 @@
 
         val notApplied = tp.applySpanStyle(spanStyle, resolveTypeface, density)
 
-        assertThat(tp.isStrikeThruText).isEqualTo(false)
-        assertThat(notApplied.textDecoration).isEqualTo(textDecoration)
+        assertThat(tp.isStrikeThruText).isEqualTo(true)
+        assertThat(notApplied.textDecoration).isEqualTo(null)
     }
 
     @Test
-    fun textDecorationNone_shouldNotBeLeftAsSpan() {
-        val textDecoration = TextDecoration.None
+    fun textDecorationCombined_shouldBeAppliedToPaint() {
+        val textDecoration =
+            TextDecoration.combine(listOf(TextDecoration.LineThrough, TextDecoration.Underline))
         val spanStyle = SpanStyle(textDecoration = textDecoration)
         val tp = AndroidTextPaint(0, density.density)
         tp.isUnderlineText = false
@@ -293,10 +295,10 @@
 
         val notApplied = tp.applySpanStyle(spanStyle, resolveTypeface, density)
 
-        assertThat(tp.isUnderlineText).isEqualTo(false)
-        assertThat(tp.isStrikeThruText).isEqualTo(false)
-        assertThat(notApplied.textDecoration).isNull()
-    }*/
+        assertThat(tp.isUnderlineText).isEqualTo(true)
+        assertThat(tp.isStrikeThruText).isEqualTo(true)
+        assertThat(notApplied.textDecoration).isEqualTo(null)
+    }
 
     @Test
     fun shadow_shouldBeAppliedTo_shadowLayer() {
diff --git a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
index 60832dd..9c943d0 100644
--- a/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
+++ b/compose/ui/ui-text/src/androidMain/kotlin/androidx/compose/ui/text/platform/AndroidParagraphHelper.android.kt
@@ -18,6 +18,8 @@
 
 import android.graphics.Typeface
 import android.text.SpannableString
+import android.text.TextPaint
+import android.text.style.CharacterStyle
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.DefaultIncludeFontPadding
 import androidx.compose.ui.text.ExperimentalTextApi
@@ -31,9 +33,11 @@
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.platform.extensions.setLineHeight
 import androidx.compose.ui.text.platform.extensions.setPlaceholders
+import androidx.compose.ui.text.platform.extensions.setSpan
 import androidx.compose.ui.text.platform.extensions.setSpanStyles
 import androidx.compose.ui.text.platform.extensions.setTextIndent
 import androidx.compose.ui.text.style.LineHeightStyle
+import androidx.compose.ui.text.style.TextDecoration
 import androidx.compose.ui.text.style.TextIndent
 import androidx.compose.ui.unit.Density
 import androidx.compose.ui.unit.isUnspecified
@@ -58,6 +62,15 @@
 
     val spannableString = SpannableString(text)
 
+    // b/199939617
+    // Due to a bug in the platform's native drawText stack, some CJK characters cause a bolder
+    // than intended underline to be painted when TextDecoration is set to Underline.
+    // If there's a CharacterStyle span that takes the entire length of the text, even if
+    // it's no-op, it causes a different native call to render the text that prevents the bug.
+    if (contextTextStyle.textDecoration == TextDecoration.Underline) {
+        spannableString.setSpan(NoopSpan, 0, text.length)
+    }
+
     if (contextTextStyle.isIncludeFontPaddingEnabled() &&
         contextTextStyle.lineHeightStyle == null
     ) {
@@ -95,4 +108,8 @@
 @Suppress("DEPRECATION")
 internal fun TextStyle.isIncludeFontPaddingEnabled(): Boolean {
     return platformStyle?.paragraphStyle?.includeFontPadding ?: DefaultIncludeFontPadding
+}
+
+private val NoopSpan = object : CharacterStyle() {
+    override fun updateDrawState(p0: TextPaint?) {}
 }
\ No newline at end of file
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 82c974c..81a7dee 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -440,12 +440,12 @@
   }
 
   public static final class CompositingStrategy.Companion {
-    method public int getAlways();
     method public int getAuto();
     method public int getModulateAlpha();
-    property public final int Always;
+    method public int getOffscreen();
     property public final int Auto;
     property public final int ModulateAlpha;
+    property public final int Offscreen;
   }
 
   public final class GraphicsLayerModifierKt {
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index 3651c6e..d68bb29 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -565,12 +565,12 @@
   }
 
   public static final class CompositingStrategy.Companion {
-    method public int getAlways();
     method public int getAuto();
     method public int getModulateAlpha();
-    property public final int Always;
+    method public int getOffscreen();
     property public final int Auto;
     property public final int ModulateAlpha;
+    property public final int Offscreen;
   }
 
   public final class GraphicsLayerModifierKt {
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 9c494ff..a921986 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -440,12 +440,12 @@
   }
 
   public static final class CompositingStrategy.Companion {
-    method public int getAlways();
     method public int getAuto();
     method public int getModulateAlpha();
-    property public final int Always;
+    method public int getOffscreen();
     property public final int Auto;
     property public final int ModulateAlpha;
+    property public final int Offscreen;
   }
 
   public final class GraphicsLayerModifierKt {
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 8caae0c..a8403cb 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -53,8 +53,8 @@
         implementation(libs.kotlinCoroutinesCore)
 
         // when updating the runtime version please also update the runtime-saveable version
-        implementation("androidx.compose.runtime:runtime:1.3.0-rc01")
-        api("androidx.compose.runtime:runtime-saveable:1.3.0-rc01")
+        implementation(project(":compose:runtime:runtime"))
+        api(project(":compose:runtime:runtime-saveable"))
 
         api(project(":compose:ui:ui-geometry"))
         api(project(":compose:ui:ui-graphics"))
diff --git a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayerModifierSamples.kt b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayerModifierSamples.kt
index 21cf8c6..6089322 100644
--- a/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayerModifierSamples.kt
+++ b/compose/ui/ui/samples/src/main/java/androidx/compose/ui/samples/LayerModifierSamples.kt
@@ -70,7 +70,7 @@
         // CompositingStrategy.ModulateAlpha ends up with the overlapping region
         // of the 2 draw rect calls to blend transparent blue and transparent red
         // against the black background instead of just transparent blue which is what would
-        // occur with CompositingStrategy.Auto or CompositingStrategy.Always
+        // occur with CompositingStrategy.Auto or CompositingStrategy.Offscreen
         inset(0f, 0f, size.width / 3, size.height / 3) {
             drawRect(color = Color.Red)
         }
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
index 738a1e2..792181a 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/AndroidLayoutDrawTest.kt
@@ -280,28 +280,28 @@
                 // Use public RenderNode API
                 in Build.VERSION_CODES.Q..Int.MAX_VALUE ->
                     verifyRenderNode29CompositingStrategy(
-                        CompositingStrategy.Always,
+                        CompositingStrategy.Offscreen,
                         expectedCompositing = true,
                         expectedOverlappingRendering = true
                     )
                 // Cannot access private APIs on P
                 Build.VERSION_CODES.P ->
                     verifyViewLayerCompositingStrategy(
-                        CompositingStrategy.Always,
+                        CompositingStrategy.Offscreen,
                         View.LAYER_TYPE_HARDWARE,
                         true
                     )
                 // Use stub access to framework RenderNode API
                 in Build.VERSION_CODES.M..Int.MAX_VALUE ->
                     verifyRenderNode23CompositingStrategy(
-                        CompositingStrategy.Always,
+                        CompositingStrategy.Offscreen,
                         expectedLayerType = View.LAYER_TYPE_HARDWARE,
                         expectedOverlappingRendering = true
                     )
                 // No RenderNodes, use Views instead
                 else ->
                     verifyViewLayerCompositingStrategy(
-                        CompositingStrategy.Always,
+                        CompositingStrategy.Offscreen,
                         View.LAYER_TYPE_HARDWARE,
                         true
                     )
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerTest.kt
index 38e267e..de8dd50 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/draw/GraphicsLayerTest.kt
@@ -1210,7 +1210,7 @@
                     .size((dimen / LocalDensity.current.density).dp)
                     .background(Color.LightGray)
                     .graphicsLayer(
-                        compositingStrategy = CompositingStrategy.Always
+                        compositingStrategy = CompositingStrategy.Offscreen
                     )
             ) {
                 inset(0f, 0f, size.width / 3, size.height / 3) {
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 0958df1..8b27e39 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
@@ -216,7 +216,7 @@
         get() = internalCompositingStrategy
         set(value) {
             when (value) {
-                CompositingStrategy.Always -> {
+                CompositingStrategy.Offscreen -> {
                     renderNode.setLayerType(View.LAYER_TYPE_HARDWARE)
                     renderNode.setHasOverlappingRendering(true)
                 }
@@ -233,7 +233,7 @@
         }
 
     internal fun getLayerType(): Int = when (internalCompositingStrategy) {
-        CompositingStrategy.Always -> View.LAYER_TYPE_HARDWARE
+        CompositingStrategy.Offscreen -> View.LAYER_TYPE_HARDWARE
         else -> View.LAYER_TYPE_NONE
     }
 
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi29.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi29.android.kt
index fd1c8cc..bddbb59 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi29.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/RenderNodeApi29.android.kt
@@ -160,7 +160,7 @@
         set(value) {
             with(renderNode) {
                 when (value) {
-                    CompositingStrategy.Always -> {
+                    CompositingStrategy.Offscreen -> {
                         setUseCompositingLayer(true, null)
                         setHasOverlappingRendering(true)
                     }
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
index baadbdf..46f3139 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ViewLayer.android.kt
@@ -193,7 +193,7 @@
         }
 
         mHasOverlappingRendering = when (compositingStrategy) {
-            CompositingStrategy.Always -> {
+            CompositingStrategy.Offscreen -> {
                 setLayerType(LAYER_TYPE_HARDWARE, null)
                 true
             }
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerModifier.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerModifier.kt
index 77848a3..f3ce5e4 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerModifier.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerModifier.kt
@@ -322,7 +322,7 @@
  * an offscreen buffer. This is useful in order to optimize alpha usages with
  * [CompositingStrategy.ModulateAlpha] which will skip the overhead of an offscreen buffer but can
  * generate different rendering results depending on whether or not the contents of the layer are
- * overlapping. Similarly leveraging [CompositingStrategy.Always] is useful in situations where
+ * overlapping. Similarly leveraging [CompositingStrategy.Offscreen] is useful in situations where
  * creating an offscreen buffer is preferred usually in conjunction with [BlendMode] usage.
  *
  * Note that if you provide a non-zero [shadowElevation] and if the passed [shape] is concave the
@@ -478,7 +478,7 @@
          * For example, the contents can be drawn into this graphics layer and masked out by drawing
          * additional shapes with [BlendMode.Clear]
          */
-        val Always = CompositingStrategy(1)
+        val Offscreen = CompositingStrategy(1)
 
         /**
          * Modulates alpha for each of the drawing instructions recorded within the graphicsLayer.
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 5871e7f..4241f32 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
@@ -214,7 +214,7 @@
      * layer, any content rendered outside of the specified size will be clipped.
      */
     val size: Size
-        get() = Size.Zero
+        get() = Size.Unspecified
 }
 
 /**
@@ -239,7 +239,7 @@
     override var shape: Shape = RectangleShape
     override var clip: Boolean = false
     override var compositingStrategy: CompositingStrategy = CompositingStrategy.Auto
-    override var size: Size = Size.Zero
+    override var size: Size = Size.Unspecified
 
     internal var graphicsDensity: Density = Density(1.0f)
 
@@ -269,6 +269,6 @@
         clip = false
         renderEffect = null
         compositingStrategy = CompositingStrategy.Auto
-        size = Size.Zero
+        size = Size.Unspecified
     }
 }
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 3b07d10..4091d4a 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
@@ -264,7 +264,7 @@
             val requiresLayer =
                 (alpha < 1 && compositingStrategy != CompositingStrategy.ModulateAlpha) ||
                 currentRenderEffect != null ||
-                compositingStrategy == CompositingStrategy.Always
+                compositingStrategy == CompositingStrategy.Offscreen
             if (requiresLayer) {
                 canvas.saveLayer(
                     bounds,
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
index 3aa9cbc..97e898c 100644
--- a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/graphics/GraphicsLayerScopeTest.kt
@@ -96,6 +96,6 @@
         assertThat(transformOrigin).isEqualTo(TransformOrigin.Center)
         assertThat(shape).isEqualTo(RectangleShape)
         assertThat(clip).isEqualTo(false)
-        assertThat(size).isEqualTo(Size.Zero)
+        assertThat(size).isEqualTo(Size.Unspecified)
     }
 }
diff --git a/constraintlayout/constraintlayout-compose/api/current.txt b/constraintlayout/constraintlayout-compose/api/current.txt
index 888c103..0c83242 100644
--- a/constraintlayout/constraintlayout-compose/api/current.txt
+++ b/constraintlayout/constraintlayout-compose/api/current.txt
@@ -36,6 +36,7 @@
     method public androidx.constraintlayout.compose.HorizontalAnchorable getBottom();
     method public androidx.constraintlayout.compose.VerticalAnchorable getEnd();
     method public androidx.constraintlayout.compose.Dimension getHeight();
+    method public float getHorizontalBias();
     method public float getHorizontalChainWeight();
     method public androidx.constraintlayout.compose.ConstrainedLayoutReference getParent();
     method public float getPivotX();
@@ -50,6 +51,7 @@
     method public float getTranslationX();
     method public float getTranslationY();
     method public float getTranslationZ();
+    method public float getVerticalBias();
     method public float getVerticalChainWeight();
     method public androidx.constraintlayout.compose.Visibility getVisibility();
     method public androidx.constraintlayout.compose.Dimension getWidth();
@@ -60,6 +62,7 @@
     method public void resetTransforms();
     method public void setAlpha(float);
     method public void setHeight(androidx.constraintlayout.compose.Dimension);
+    method public void setHorizontalBias(float);
     method public void setHorizontalChainWeight(float);
     method public void setPivotX(float);
     method public void setPivotY(float);
@@ -71,6 +74,7 @@
     method public void setTranslationX(float);
     method public void setTranslationY(float);
     method public void setTranslationZ(float);
+    method public void setVerticalBias(float);
     method public void setVerticalChainWeight(float);
     method public void setVisibility(androidx.constraintlayout.compose.Visibility);
     method public void setWidth(androidx.constraintlayout.compose.Dimension);
@@ -81,6 +85,7 @@
     property public final androidx.constraintlayout.compose.HorizontalAnchorable bottom;
     property public final androidx.constraintlayout.compose.VerticalAnchorable end;
     property public final androidx.constraintlayout.compose.Dimension height;
+    property public final float horizontalBias;
     property public final float horizontalChainWeight;
     property public final androidx.constraintlayout.compose.ConstrainedLayoutReference parent;
     property public final float pivotX;
@@ -95,6 +100,7 @@
     property public final float translationX;
     property public final float translationY;
     property public final float translationZ;
+    property public final float verticalBias;
     property public final float verticalChainWeight;
     property public final androidx.constraintlayout.compose.Visibility visibility;
     property public final androidx.constraintlayout.compose.Dimension width;
@@ -151,6 +157,9 @@
     method public final androidx.constraintlayout.compose.VerticalChainReference createVerticalChain(androidx.constraintlayout.compose.LayoutReference![] elements, optional androidx.constraintlayout.compose.ChainStyle chainStyle);
     method protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> getTasks();
     method public void reset();
+    method public final androidx.constraintlayout.compose.LayoutReference withChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float topMargin, optional float endMargin, optional float bottomMargin, optional float startGoneMargin, optional float topGoneMargin, optional float endGoneMargin, optional float bottomGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withHorizontalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float endMargin, optional float startGoneMargin, optional float endGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withVerticalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float topMargin, optional float bottomMargin, optional float topGoneMargin, optional float bottomGoneMargin, optional float weight);
     property protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> tasks;
   }
 
diff --git a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
index 9bd9dc8..fd40d95 100644
--- a/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout-compose/api/public_plus_experimental_current.txt
@@ -67,6 +67,7 @@
     method public androidx.constraintlayout.compose.HorizontalAnchorable getBottom();
     method public androidx.constraintlayout.compose.VerticalAnchorable getEnd();
     method public androidx.constraintlayout.compose.Dimension getHeight();
+    method public float getHorizontalBias();
     method public float getHorizontalChainWeight();
     method public androidx.constraintlayout.compose.ConstrainedLayoutReference getParent();
     method public float getPivotX();
@@ -81,6 +82,7 @@
     method public float getTranslationX();
     method public float getTranslationY();
     method public float getTranslationZ();
+    method public float getVerticalBias();
     method public float getVerticalChainWeight();
     method public androidx.constraintlayout.compose.Visibility getVisibility();
     method public androidx.constraintlayout.compose.Dimension getWidth();
@@ -91,6 +93,7 @@
     method public void resetTransforms();
     method public void setAlpha(float);
     method public void setHeight(androidx.constraintlayout.compose.Dimension);
+    method public void setHorizontalBias(float);
     method public void setHorizontalChainWeight(float);
     method public void setPivotX(float);
     method public void setPivotY(float);
@@ -102,6 +105,7 @@
     method public void setTranslationX(float);
     method public void setTranslationY(float);
     method public void setTranslationZ(float);
+    method public void setVerticalBias(float);
     method public void setVerticalChainWeight(float);
     method public void setVisibility(androidx.constraintlayout.compose.Visibility);
     method public void setWidth(androidx.constraintlayout.compose.Dimension);
@@ -112,6 +116,7 @@
     property public final androidx.constraintlayout.compose.HorizontalAnchorable bottom;
     property public final androidx.constraintlayout.compose.VerticalAnchorable end;
     property public final androidx.constraintlayout.compose.Dimension height;
+    property public final float horizontalBias;
     property public final float horizontalChainWeight;
     property public final androidx.constraintlayout.compose.ConstrainedLayoutReference parent;
     property public final float pivotX;
@@ -126,6 +131,7 @@
     property public final float translationX;
     property public final float translationY;
     property public final float translationZ;
+    property public final float verticalBias;
     property public final float verticalChainWeight;
     property public final androidx.constraintlayout.compose.Visibility visibility;
     property public final androidx.constraintlayout.compose.Dimension width;
@@ -182,6 +188,9 @@
     method public final androidx.constraintlayout.compose.VerticalChainReference createVerticalChain(androidx.constraintlayout.compose.LayoutReference![] elements, optional androidx.constraintlayout.compose.ChainStyle chainStyle);
     method protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> getTasks();
     method public void reset();
+    method public final androidx.constraintlayout.compose.LayoutReference withChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float topMargin, optional float endMargin, optional float bottomMargin, optional float startGoneMargin, optional float topGoneMargin, optional float endGoneMargin, optional float bottomGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withHorizontalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float endMargin, optional float startGoneMargin, optional float endGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withVerticalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float topMargin, optional float bottomMargin, optional float topGoneMargin, optional float bottomGoneMargin, optional float weight);
     property protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> tasks;
   }
 
diff --git a/constraintlayout/constraintlayout-compose/api/restricted_current.txt b/constraintlayout/constraintlayout-compose/api/restricted_current.txt
index b2a7877..d11ace4 100644
--- a/constraintlayout/constraintlayout-compose/api/restricted_current.txt
+++ b/constraintlayout/constraintlayout-compose/api/restricted_current.txt
@@ -36,6 +36,7 @@
     method public androidx.constraintlayout.compose.HorizontalAnchorable getBottom();
     method public androidx.constraintlayout.compose.VerticalAnchorable getEnd();
     method public androidx.constraintlayout.compose.Dimension getHeight();
+    method public float getHorizontalBias();
     method public float getHorizontalChainWeight();
     method public androidx.constraintlayout.compose.ConstrainedLayoutReference getParent();
     method public float getPivotX();
@@ -50,6 +51,7 @@
     method public float getTranslationX();
     method public float getTranslationY();
     method public float getTranslationZ();
+    method public float getVerticalBias();
     method public float getVerticalChainWeight();
     method public androidx.constraintlayout.compose.Visibility getVisibility();
     method public androidx.constraintlayout.compose.Dimension getWidth();
@@ -60,6 +62,7 @@
     method public void resetTransforms();
     method public void setAlpha(float);
     method public void setHeight(androidx.constraintlayout.compose.Dimension);
+    method public void setHorizontalBias(float);
     method public void setHorizontalChainWeight(float);
     method public void setPivotX(float);
     method public void setPivotY(float);
@@ -71,6 +74,7 @@
     method public void setTranslationX(float);
     method public void setTranslationY(float);
     method public void setTranslationZ(float);
+    method public void setVerticalBias(float);
     method public void setVerticalChainWeight(float);
     method public void setVisibility(androidx.constraintlayout.compose.Visibility);
     method public void setWidth(androidx.constraintlayout.compose.Dimension);
@@ -81,6 +85,7 @@
     property public final androidx.constraintlayout.compose.HorizontalAnchorable bottom;
     property public final androidx.constraintlayout.compose.VerticalAnchorable end;
     property public final androidx.constraintlayout.compose.Dimension height;
+    property public final float horizontalBias;
     property public final float horizontalChainWeight;
     property public final androidx.constraintlayout.compose.ConstrainedLayoutReference parent;
     property public final float pivotX;
@@ -95,6 +100,7 @@
     property public final float translationX;
     property public final float translationY;
     property public final float translationZ;
+    property public final float verticalBias;
     property public final float verticalChainWeight;
     property public final androidx.constraintlayout.compose.Visibility visibility;
     property public final androidx.constraintlayout.compose.Dimension width;
@@ -151,6 +157,9 @@
     method public final androidx.constraintlayout.compose.VerticalChainReference createVerticalChain(androidx.constraintlayout.compose.LayoutReference![] elements, optional androidx.constraintlayout.compose.ChainStyle chainStyle);
     method protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> getTasks();
     method public void reset();
+    method public final androidx.constraintlayout.compose.LayoutReference withChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float topMargin, optional float endMargin, optional float bottomMargin, optional float startGoneMargin, optional float topGoneMargin, optional float endGoneMargin, optional float bottomGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withHorizontalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float startMargin, optional float endMargin, optional float startGoneMargin, optional float endGoneMargin, optional float weight);
+    method public final androidx.constraintlayout.compose.LayoutReference withVerticalChainParams(androidx.constraintlayout.compose.LayoutReference, optional float topMargin, optional float bottomMargin, optional float topGoneMargin, optional float bottomGoneMargin, optional float weight);
     property protected final java.util.List<kotlin.jvm.functions.Function1<androidx.constraintlayout.compose.State,kotlin.Unit>> tasks;
     field @kotlin.PublishedApi internal int helpersHashCode;
   }
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/build.gradle b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/build.gradle
new file mode 100644
index 0000000..7b273f9
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/build.gradle
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+plugins {
+    id("AndroidXPlugin")
+    id("AndroidXComposePlugin")
+    id("com.android.application")
+    id("org.jetbrains.kotlin.android")
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 26
+    }
+    namespace "androidx.constraintlayout.compose.integration.macrobenchmark.target"
+
+    buildTypes {
+        release {
+            minifyEnabled true
+            shrinkResources true
+            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"),
+                    'proguard-rules.pro'
+            signingConfig signingConfigs.debug
+        }
+    }
+}
+
+dependencies {
+    implementation 'androidx.recyclerview:recyclerview:1.2.1'
+
+    implementation(libs.kotlinStdlib)
+    implementation(project(":activity:activity-compose"))
+    implementation("androidx.appcompat:appcompat:1.4.1")
+    implementation("androidx.cardview:cardview:1.0.0")
+    // 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(project(":constraintlayout:constraintlayout-compose"))
+    implementation(project(":compose:foundation:foundation-layout"))
+    implementation(project(":compose:foundation:foundation"))
+    implementation(project(":compose:material:material"))
+    implementation(project(":compose:runtime:runtime"))
+    implementation(project(":compose:runtime:runtime-tracing"))
+    implementation(project(":compose:ui:ui"))
+    implementation(project(":compose:ui:ui-tooling"))
+    implementation(project(":profileinstaller:profileinstaller"))
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/proguard-rules.pro b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/proguard-rules.pro
new file mode 100644
index 0000000..0674e77
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/proguard-rules.pro
@@ -0,0 +1 @@
+-dontobfuscate
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a38483c
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<!--
+  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
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <application
+        android:label="Jetpack Compose Macrobenchmark Target"
+        android:allowBackup="false"
+        android:supportsRtl="true"
+        android:icon="@mipmap/ic_launcher"
+        tools:ignore="GoogleAppIndexingWarning">
+
+        <!-- Profileable to enable macrobenchmark profiling -->
+        <profileable android:shell="true"/>
+
+        <!--
+        Activities need to be exported so the macrobenchmark can discover them
+        under the new package visibility changes for Android 11.
+         -->
+        <activity android:name=".MotionLayoutActivity"
+            android:exported="true"
+            android:theme="@android:style/Theme.Material.Light.NoActionBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+            <intent-filter>
+                <action android:name="androidx.constraintlayout.compose.integration.macrobenchmark.target.MOTION_LAYOUT_ACTIVITY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/ic_launcher-web.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/ic_launcher-web.png
new file mode 100644
index 0000000..88e5f3b
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/ic_launcher-web.png
Binary files differ
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
new file mode 100644
index 0000000..24ae735
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/MotionLayoutActivity.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.integration.macrobenchmark.target.motionlayout.newmessage.NewMotionMessagePreview
+import androidx.compose.integration.macrobenchmark.target.motionlayout.newmessage.NewMotionMessagePreviewWithDsl
+import androidx.compose.integration.macrobenchmark.target.motionlayout.toolbar.MotionCollapseToolbarPreview
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTagsAsResourceId
+
+class MotionLayoutActivity : ComponentActivity() {
+
+    @OptIn(ExperimentalComposeUiApi::class)
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        val name = intent.getStringExtra("ComposableName")
+        setContent {
+            MaterialTheme {
+                // A surface container using the 'background' color from the theme
+                Surface(
+                    modifier = Modifier
+                        .fillMaxSize()
+                        // Required to reference UI elements by Macrobenchmark
+                        .semantics { testTagsAsResourceId = true },
+                    color = MaterialTheme.colors.background
+                ) {
+                    // Here we resolve the Composable requested by Macrobenchark
+                    when (name) {
+                        "NewMessageJson" -> {
+                            NewMotionMessagePreview()
+                        }
+                        "NewMessageDsl" -> {
+                            NewMotionMessagePreviewWithDsl()
+                        }
+                        "CollapsibleToolbar" -> {
+                            MotionCollapseToolbarPreview()
+                        }
+                        else -> {
+                            throw IllegalArgumentException("No Composable with name: $name")
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..30960cf
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/CardSample.kt
@@ -0,0 +1,136 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target.common.components
+
+import androidx.annotation.DrawableRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+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
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.ConstraintSet
+import androidx.constraintlayout.compose.Dimension
+
+@Preview
+@Composable
+private fun CardSamplePreview() {
+    Column(
+        modifier = Modifier
+            .fillMaxSize()
+            .background(Color.LightGray)
+            .verticalScroll(rememberScrollState()),
+        verticalArrangement = Arrangement.spacedBy(12.dp)
+    ) {
+        for (i in 0 until 15) {
+            CardSample(
+                Modifier
+                    .height(80.dp)
+                    .background(Color.White, RoundedCornerShape(10.dp))
+            )
+        }
+    }
+}
+
+private val cardSampleConstraintSet = ConstraintSet {
+    val image = createRefFor("image")
+    val title = createRefFor("title")
+    val description = createRefFor("description")
+    val time = createRefFor("timestamp")
+
+    constrain(image) {
+        width = Dimension.ratio("1:1")
+        height = Dimension.fillToConstraints
+        top.linkTo(parent.top)
+        bottom.linkTo(parent.bottom)
+        start.linkTo(parent.start)
+    }
+    constrain(title) {
+        width = Dimension.preferredWrapContent
+        top.linkTo(parent.top)
+
+        linkTo(image.end, time.start, 8.dp, 8.dp, bias = 0f)
+    }
+    constrain(description) {
+        width = Dimension.fillToConstraints
+
+        linkTo(image.end, parent.end, 8.dp, bias = 0f)
+        bottom.linkTo(parent.bottom)
+    }
+    constrain(time) {
+        top.linkTo(parent.top)
+        end.linkTo(parent.end)
+    }
+}
+
+@Composable
+fun CardSample(
+    modifier: Modifier = Modifier,
+    @DrawableRes drawableRes: Int = randomAvatarId(),
+    title: String = randomFullName(),
+    description: String = LoremIpsum.words(50).shuffled().joinToString(" "),
+    timeStamp: String = newHourMinuteTimeStamp()
+) {
+    ConstraintLayout(
+        modifier = Modifier
+            .defaultMinSize(minWidth = 200.dp, minHeight = 50.dp)
+            .then(modifier)
+            .padding(4.dp),
+        constraintSet = cardSampleConstraintSet
+    ) {
+        Image(
+            modifier = Modifier
+                .layoutId("image")
+                .clip(RoundedCornerShape(10.dp)),
+            painter = painterResource(id = drawableRes),
+            contentDescription = null
+        )
+        Text(
+            modifier = Modifier.layoutId("title"),
+            text = title,
+            maxLines = 1,
+            overflow = TextOverflow.Ellipsis
+        )
+        Text(modifier = Modifier.layoutId("timestamp"), text = timeStamp)
+        Text(
+            modifier = Modifier.layoutId("description"),
+            text = description,
+            maxLines = 1,
+            overflow = TextOverflow.Ellipsis
+        )
+    }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/SearchBar.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/SearchBar.kt
new file mode 100644
index 0000000..8cc4339
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/SearchBar.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target.common.components
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Icon
+import androidx.compose.material.OutlinedTextField
+import androidx.compose.material.Text
+import androidx.compose.material.TextFieldDefaults
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Search
+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.focus.onFocusChanged
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+
+@Preview
+@Composable
+private fun SearchBarPreview() {
+    Column(
+        verticalArrangement = Arrangement.spacedBy(10.dp)
+    ) {
+        SearchBar(Modifier.fillMaxWidth())
+        OutlinedSearchBar(Modifier.fillMaxWidth())
+    }
+}
+
+@Composable
+fun SearchBar(
+    modifier: Modifier = Modifier,
+    backgroundColor: Color = Color.LightGray
+) {
+    CommonSearchBar(
+        modifier = modifier,
+        outlined = false,
+        borderOrBackgroundColor = backgroundColor
+    )
+}
+
+@Composable
+fun OutlinedSearchBar(
+    modifier: Modifier = Modifier,
+    borderColor: Color = Color.LightGray
+) {
+    CommonSearchBar(
+        modifier = modifier,
+        outlined = true,
+        borderOrBackgroundColor = borderColor
+    )
+}
+
+@Composable
+private fun CommonSearchBar(
+    modifier: Modifier,
+    outlined: Boolean,
+    borderOrBackgroundColor: Color
+) {
+    var placeholder: String by remember { mutableStateOf("Search...") }
+    val backgroundModifier = if (outlined) {
+        Modifier.border(BorderStroke(2.dp, borderOrBackgroundColor), RoundedCornerShape(32.dp))
+    } else {
+        Modifier.background(borderOrBackgroundColor, RoundedCornerShape(32.dp))
+    }
+    OutlinedTextField(
+        modifier = modifier
+            .then(backgroundModifier)
+            .onFocusChanged {
+                placeholder = if (it.isFocused) {
+                    "I'm not implemented yet!"
+                } else {
+                    "Search..."
+                }
+            },
+        value = "",
+         _ ->
+        },
+        placeholder = {
+            Text(text = placeholder, maxLines = 1, overflow = TextOverflow.Clip)
+        },
+        trailingIcon = {
+            Icon(imageVector = Icons.Default.Search, contentDescription = null)
+        },
+        singleLine = true,
+        colors = TextFieldDefaults.textFieldColors(
+            focusedIndicatorColor = Color.Transparent,
+            unfocusedIndicatorColor = Color.Transparent,
+            backgroundColor = Color.Transparent,
+        )
+    )
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/TestableButton.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/TestableButton.kt
new file mode 100644
index 0000000..9beb710
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/components/TestableButton.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target.common.components
+
+import androidx.compose.material.Button
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+
+/**
+ * Button with text.
+ *
+ * [text] is also applied to [Modifier.testTag] so that it's addressable by UI Automator.
+ */
+@Composable
+internal fun TestableButton(
+    onClick: () -> Unit,
+    text: String,
+    modifier: Modifier = Modifier,
+) {
+    Button(
+        modifier = modifier.testTag(text),
+        >
+    ) {
+        Text(text = text)
+    }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Images.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Images.kt
new file mode 100644
index 0000000..08f4781
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Images.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata
+
+import android.content.ContentResolver
+import android.content.Context
+import android.net.Uri
+import androidx.annotation.DrawableRes
+import androidx.constraintlayout.compose.integration.macrobenchmark.target.R
+
+@DrawableRes
+private val avatarsIdList: Array<Int> = arrayOf(
+    R.drawable.avatar_1,
+    R.drawable.avatar_2,
+    R.drawable.avatar_3,
+    R.drawable.avatar_4,
+    R.drawable.avatar_5,
+    R.drawable.avatar_6,
+    R.drawable.avatar_7,
+    R.drawable.avatar_8,
+    R.drawable.avatar_9,
+    R.drawable.avatar_10,
+    R.drawable.avatar_11,
+    R.drawable.avatar_12,
+    R.drawable.avatar_13,
+    R.drawable.avatar_14,
+    R.drawable.avatar_15,
+    R.drawable.avatar_16,
+)
+
+@DrawableRes
+internal fun randomAvatarId(): Int = avatarsIdList.random()
+
+internal fun Context.drawableUriOf(@DrawableRes resourceId: Int): Uri =
+    with(resources) {
+        Uri.Builder()
+            .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+            .authority(getResourcePackageName(resourceId))
+            .appendPath(getResourceTypeName(resourceId))
+            .appendPath(getResourceEntryName(resourceId))
+            .build()
+    }
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Strings.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Strings.kt
new file mode 100644
index 0000000..c062956
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Strings.kt
@@ -0,0 +1,135 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark.target.common.sampledata
+
+/**
+ * From [androidx.compose.ui.tooling.preview.datasource.LoremIpsum]
+ */
+private val LOREM_IPSUM = """
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer sodales
+laoreet commodo. Phasellus a purus eu risus elementum consequat. Aenean eu
+elit ut nunc convallis laoreet non ut libero. Suspendisse interdum placerat
+risus vel ornare. Donec vehicula, turpis sed consectetur ullamcorper, ante
+nunc egestas quam, ultricies adipiscing velit enim at nunc. Aenean id diam
+neque. Praesent ut lacus sed justo viverra fermentum et ut sem. Fusce
+convallis gravida lacinia. Integer semper dolor ut elit sagittis lacinia.
+Praesent sodales scelerisque eros at rhoncus. Duis posuere sapien vel ipsum
+ornare interdum at eu quam. Vestibulum vel massa erat. Aenean quis sagittis
+purus. Phasellus arcu purus, rutrum id consectetur non, bibendum at nibh.
+
+Duis nec erat dolor. Nulla vitae consectetur ligula. Quisque nec mi est. Ut
+quam ante, rutrum at pellentesque gravida, pretium in dui. Cras eget sapien
+velit. Suspendisse ut sem nec tellus vehicula eleifend sit amet quis velit.
+Phasellus quis suscipit nisi. Nam elementum malesuada tincidunt. Curabitur
+iaculis pretium eros, malesuada faucibus leo eleifend a. Curabitur congue
+orci in neque euismod a blandit libero vehicula.""".trim()
+
+private val LOREM_IPSUM_WORDS = LOREM_IPSUM.split(" ")
+
+private val names = listOf(
+    "Jacob",
+    "Sophia",
+    "Noah",
+    "Emma",
+    "Mason",
+    "Isabella",
+    "William",
+    "Olivia",
+    "Ethan",
+    "Ava",
+    "Liam",
+    "Emily",
+    "Michael",
+    "Abigail",
+    "Alexander",
+    "Mia",
+    "Jayden",
+    "Madison",
+    "Daniel",
+    "Elizabeth",
+    "Aiden",
+    "Chloe",
+    "James",
+    "Ella",
+    "Elijah",
+    "Avery",
+    "Matthew",
+    "Charlotte",
+    "Benjamin",
+    "Sofia"
+)
+
+private val surnames = arrayOf(
+    "Smith",
+    "Johnson",
+    "Williams",
+    "Brown",
+    "Jones",
+    "Garcia",
+    "Miller",
+    "Davis",
+    "Rodriguez",
+    "Martinez"
+)
+
+private val cities = arrayOf(
+    "Shanghai",
+    "Karachi",
+    "Beijing",
+    "Delhi",
+    "Lagos",
+    "Tianjin",
+    "Istanbul",
+    "Tokyo",
+    "Guangzhou",
+    "Mumbai",
+    "Moscow",
+    "São Paulo",
+    "Shenzhen",
+    "Jakarta",
+    "Lahore",
+    "Seoul",
+    "Wuhan",
+    "Kinshasa",
+    "Cairo",
+    "Mexico City",
+    "Lima",
+    "London",
+    "New York City"
+)
+
+internal fun randomFirstName(): String = names.random()
+
+internal fun randomLastName(): String = surnames.random()
+
+internal fun randomFullName(): String = randomFirstName() + " " + randomLastName()
+
+internal fun randomCity(): String = cities.random()
+
+internal object LoremIpsum {
+    fun string(wordCount: Int, withLineBreaks: Boolean = false): String =
+        words(wordCount, withLineBreaks).joinToString(separator = " ")
+
+    fun words(wordCount: Int, withLineBreaks: Boolean = false): List<String> =
+        if (withLineBreaks) {
+            // Source includes line breaks
+            LOREM_IPSUM_WORDS.take(wordCount.coerceIn(1, LOREM_IPSUM_WORDS.size))
+        } else {
+            LOREM_IPSUM.filter { it != '\n' }.split(' ')
+                .take(wordCount.coerceIn(1, LOREM_IPSUM_WORDS.size))
+        }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Time.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Time.kt
new file mode 100644
index 0000000..53944f9
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/common/sampledata/Time.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.integration.macrobenchmark.target.common.sampledata
+
+import java.text.SimpleDateFormat
+import java.time.Instant
+import java.util.Date
+import java.util.Locale
+
+internal fun newHourMinuteTimeStamp(): String {
+    return SimpleDateFormat("hh:mma", Locale.US).format(Date.from(Instant.now()))
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..8f99fe2
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessage.kt
@@ -0,0 +1,758 @@
+/*
+ * 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.
+ */
+
+@file:OptIn(ExperimentalMotionApi::class)
+
+package androidx.compose.integration.macrobenchmark.target.motionlayout.newmessage
+
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+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
+import androidx.compose.material.LocalTextStyle
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.OutlinedTextField
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.material.TextField
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.material.icons.filled.Delete
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material.icons.filled.KeyboardArrowDown
+import androidx.compose.material.icons.filled.Send
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.toArgb
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTagsAsResourceId
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.ConstraintSet
+import androidx.constraintlayout.compose.Dimension
+import androidx.constraintlayout.compose.ExperimentalMotionApi
+import androidx.constraintlayout.compose.MotionLayout
+import androidx.constraintlayout.compose.MotionLayoutScope
+import androidx.constraintlayout.compose.MotionScene
+import androidx.constraintlayout.compose.Visibility
+
+// Copied from ComposeMail project
+
+@Preview
+@Composable
+fun NewMotionMessagePreview() {
+    NewMotionMessageWithControls(useDsl = false)
+}
+
+@Preview
+@Composable
+fun NewMotionMessagePreviewWithDsl() {
+    NewMotionMessageWithControls(useDsl = true)
+}
+
+@OptIn(ExperimentalComposeUiApi::class, ExperimentalMotionApi::class)
+@Composable
+fun NewMotionMessageWithControls(
+    useDsl: Boolean
+) {
+    val initialLayout = NewMessageLayout.Full
+    val newMessageState = rememberNewMessageState(initialLayoutState = initialLayout)
+    val motionScene = if (useDsl) {
+        messageMotionSceneDsl(initialState = initialLayout)
+    } else {
+        messageMotionScene(initialState = initialLayout)
+    }
+    Column(Modifier.semantics { testTagsAsResourceId = true }) {
+        Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
+            TestableButton(
+                >
+                text = "Fab"
+            )
+            TestableButton(
+                >
+                text = "Full"
+            )
+            TestableButton(
+                >
+                text = "Mini"
+            )
+        }
+        NewMessageButton(
+            modifier = Modifier.fillMaxSize(),
+            motionScene = motionScene,
+            state = newMessageState,
+        )
+    }
+}
+
+@OptIn(ExperimentalMotionApi::class)
+@Composable
+private fun messageMotionSceneDsl(initialState: NewMessageLayout): MotionScene {
+    val startState = remember { initialState }
+    val endState = when (startState) {
+        NewMessageLayout.Fab -> NewMessageLayout.Full
+        NewMessageLayout.Mini -> NewMessageLayout.Fab
+        NewMessageLayout.Full -> NewMessageLayout.Fab
+    }
+
+    val primary = MaterialTheme.colors.primary
+    val primaryVariant = MaterialTheme.colors.primaryVariant
+    val >
+    val surface = MaterialTheme.colors.surface
+    val >
+
+    return MotionScene {
+        val box = createRefFor("box")
+        val minIcon = createRefFor("minIcon")
+        val editClose = createRefFor("editClose")
+        val title = createRefFor("title")
+        val content = createRefFor("content")
+
+        val fab = constraintSet(NewMessageLayout.Fab.name) {
+            constrain(box) {
+                width = Dimension.value(50.dp)
+                height = Dimension.value(50.dp)
+                end.linkTo(parent.end, 12.dp)
+                bottom.linkTo(parent.bottom, 12.dp)
+                customColor("background", primary)
+            }
+            constrain(minIcon) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                end.linkTo(editClose.start, 8.dp)
+                top.linkTo(editClose.top)
+                customColor("content", onPrimary)
+            }
+            constrain(editClose) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                centerTo(box)
+
+                customColor("content", onPrimary)
+            }
+            constrain(title) {
+                width = Dimension.fillToConstraints
+                top.linkTo(box.top)
+                bottom.linkTo(editClose.bottom)
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(minIcon.start, 8.dp)
+                customColor("content", onPrimary)
+
+                visibility = Visibility.Gone
+            }
+            constrain(content) {
+                width = Dimension.fillToConstraints
+                height = Dimension.fillToConstraints
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(box.end, 8.dp)
+
+                top.linkTo(editClose.bottom, 8.dp)
+                bottom.linkTo(box.bottom, 8.dp)
+
+                visibility = Visibility.Gone
+            }
+        }
+        val full = constraintSet(NewMessageLayout.Full.name) {
+            constrain(box) {
+                width = Dimension.fillToConstraints
+                height = Dimension.fillToConstraints
+                start.linkTo(parent.start, 12.dp)
+                end.linkTo(parent.end, 12.dp)
+                bottom.linkTo(parent.bottom, 12.dp)
+                top.linkTo(parent.top, 40.dp)
+                customColor("background", surface)
+            }
+            constrain(minIcon) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                end.linkTo(editClose.start, 8.dp)
+                top.linkTo(editClose.top)
+                customColor("content", onSurface)
+            }
+            constrain(editClose) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                end.linkTo(box.end, 4.dp)
+                top.linkTo(box.top, 4.dp)
+                customColor("content", onSurface)
+            }
+            constrain(title) {
+                width = Dimension.fillToConstraints
+                top.linkTo(box.top)
+                bottom.linkTo(editClose.bottom)
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(minIcon.start, 8.dp)
+                customColor("content", onSurface)
+            }
+            constrain(content) {
+                width = Dimension.fillToConstraints
+                height = Dimension.fillToConstraints
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(box.end, 8.dp)
+                top.linkTo(editClose.bottom, 8.dp)
+                bottom.linkTo(box.bottom, 8.dp)
+            }
+        }
+        val mini = constraintSet(NewMessageLayout.Mini.name) {
+            constrain(box) {
+                width = Dimension.value(220.dp)
+                height = Dimension.value(50.dp)
+
+                end.linkTo(parent.end, 12.dp)
+                bottom.linkTo(parent.bottom, 12.dp)
+
+                customColor("background", primaryVariant)
+            }
+            constrain(minIcon) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                end.linkTo(editClose.start, 8.dp)
+                top.linkTo(editClose.top)
+
+                rotationZ = 180f
+
+                customColor("content", onPrimary)
+            }
+            constrain(editClose) {
+                width = Dimension.value(40.dp)
+                height = Dimension.value(40.dp)
+
+                end.linkTo(box.end, 4.dp)
+                top.linkTo(box.top, 4.dp)
+                customColor("content", onPrimary)
+            }
+            constrain(title) {
+                width = Dimension.fillToConstraints
+                top.linkTo(box.top)
+                bottom.linkTo(editClose.bottom)
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(minIcon.start, 8.dp)
+                customColor("content", onPrimary)
+            }
+            constrain(content) {
+                width = Dimension.fillToConstraints
+                start.linkTo(box.start, 8.dp)
+                end.linkTo(box.end, 8.dp)
+
+                top.linkTo(editClose.bottom, 8.dp)
+                bottom.linkTo(box.bottom, 8.dp)
+
+                visibility = Visibility.Gone
+            }
+        }
+
+        fun constraintSetFor(layoutState: NewMessageLayout) =
+            when (layoutState) {
+                NewMessageLayout.Full -> full
+                NewMessageLayout.Mini -> mini
+                NewMessageLayout.Fab -> fab
+            }
+        defaultTransition(
+            from = constraintSetFor(startState),
+            to = constraintSetFor(endState)
+        )
+    }
+}
+
+@OptIn(ExperimentalMotionApi::class)
+@Composable
+private fun messageMotionScene(initialState: NewMessageLayout): MotionScene {
+    val startState = remember { initialState }
+    val endState = when (startState) {
+        NewMessageLayout.Fab -> NewMessageLayout.Full
+        NewMessageLayout.Mini -> NewMessageLayout.Fab
+        NewMessageLayout.Full -> NewMessageLayout.Fab
+    }
+
+    val startStateName = startState.name
+    val endStateName = endState.name
+    val primary = MaterialTheme.colors.primary.toHexString()
+    val primaryVariant = MaterialTheme.colors.primaryVariant.toHexString()
+    val >
+    val surface = MaterialTheme.colors.surface.toHexString()
+    val >
+
+    return MotionScene(
+        content =
+        """
+        {
+          ConstraintSets: {
+            ${NewMessageLayout.Fab.name}: {
+              box: {
+                width: 50, height: 50,
+                end: ['parent', 'end', 12],
+                bottom: ['parent', 'bottom', 12],
+                custom: {
+                  background: '#$primary'
+                }
+              },
+              minIcon: {
+                width: 40, height: 40,
+                end: ['editClose', 'start', 8],
+                top: ['editClose', 'top', 0],
+                visibility: 'gone',
+                custom: {
+                  content: '#$onPrimary'
+                }
+              },
+              editClose: {
+                width: 40, height: 40,
+                centerHorizontally: 'box',
+                centerVertically: 'box',
+                custom: {
+                  content: '#$onPrimary'
+                }
+              },
+              title: {
+                width: 'spread',
+                top: ['box', 'top', 0],
+                bottom: ['editClose', 'bottom', 0],
+                start: ['box', 'start', 8],
+                end: ['minIcon', 'start', 8],
+                custom: {
+                  content: '#$onPrimary'
+                }
+                
+                visibility: 'gone'
+              },
+              content: {
+                width: 'spread', height: 'spread',
+                start: ['box', 'start', 8],
+                end: ['box', 'end', 8],
+                
+                top: ['editClose', 'bottom', 8],
+                bottom: ['box', 'bottom', 8],
+                
+                visibility: 'gone'
+              }
+            },
+            ${NewMessageLayout.Full.name}: {
+              box: {
+                width: 'spread', height: 'spread',
+                start: ['parent', 'start', 12],
+                end: ['parent', 'end', 12],
+                bottom: ['parent', 'bottom', 12],
+                top: ['parent', 'top', 40],
+                custom: {
+                  background: '#$surface'
+                }
+              },
+              minIcon: {
+                width: 40, height: 40,
+                end: ['editClose', 'start', 8],
+                top: ['editClose', 'top', 0],
+                custom: {
+                  content: '#$onSurface'
+                }
+              },
+              editClose: {
+                width: 40, height: 40,
+                end: ['box', 'end', 4],
+                top: ['box', 'top', 4],
+                custom: {
+                  content: '#$onSurface'
+                }
+              },
+              title: {
+                width: 'spread',
+                top: ['box', 'top', 0],
+                bottom: ['editClose', 'bottom', 0],
+                start: ['box', 'start', 8],
+                end: ['minIcon', 'start', 8],
+                custom: {
+                  content: '#$onSurface'
+                }
+              },
+              content: {
+                width: 'spread', height: 'spread',
+                start: ['box', 'start', 8],
+                end: ['box', 'end', 8],
+                
+                top: ['editClose', 'bottom', 8],
+                bottom: ['box', 'bottom', 8]
+              }
+            },
+            ${NewMessageLayout.Mini.name}: {
+              box: {
+                width: 180, height: 50,
+                bottom: ['parent', 'bottom', 12],
+                end: ['parent', 'end', 12],
+                custom: {
+                  background: '#$primaryVariant'
+                }
+              },
+              minIcon: {
+                width: 40, height: 40,
+                end: ['editClose', 'start', 8],
+                top: ['editClose', 'top', 0],
+                rotationZ: 180,
+                custom: {
+                  content: '#$onPrimary'
+                }
+              },
+              editClose: {
+                width: 40, height: 40,
+                end: ['box', 'end', 4],
+                top: ['box', 'top', 4],
+                custom: {
+                  content: '#$onPrimary'
+                }
+              },
+              title: {
+                width: 'spread',
+                top: ['box', 'top', 0],
+                bottom: ['editClose', 'bottom', 0],
+                start: ['box', 'start', 8],
+                end: ['minIcon', 'start', 8],
+                custom: {
+                  content: '#$onPrimary'
+                }
+              },
+              content: {
+                width: 'spread', height: 'spread',
+                start: ['box', 'start', 8],
+                end: ['box', 'end', 8],
+                
+                top: ['editClose', 'bottom', 8],
+                bottom: ['box', 'bottom', 8],
+                
+                visibility: 'gone'
+              }
+            }
+          },
+          Transitions: {
+            default: {
+              from: '$startStateName',
+              to: '$endStateName'
+            }
+          }
+        }
+    """
+    )
+}
+
+@OptIn(ExperimentalMotionApi::class)
+@Composable
+internal fun MotionLayoutScope.MotionMessageContent(
+    state: NewMessageState
+) {
+    val currentState = state.currentState
+    val focusManager = LocalFocusManager.current
+    val dialogName = remember(currentState) {
+        when (currentState) {
+            NewMessageLayout.Mini -> "Draft"
+            else -> "Message"
+        }
+    }
+    Surface(
+        modifier = Modifier.layoutId("box"),
+        color = motionColor(id = "box", name = "background"),
+        elevation = 4.dp,
+        shape = RoundedCornerShape(8.dp)
+    ) {}
+    ColorableIconButton(
+        modifier = Modifier.layoutId("editClose"),
+        imageVector = when (currentState) {
+            NewMessageLayout.Fab -> Icons.Default.Edit
+            else -> Icons.Default.Close
+        },
+        color = motionColor("editClose", "content"),
+        enabled = true
+    ) {
+        when (currentState) {
+            NewMessageLayout.Fab -> state.setToFull()
+            else -> state.setToFab()
+        }
+    }
+    ColorableIconButton(
+        modifier = Modifier.layoutId("minIcon"),
+        imageVector = Icons.Default.KeyboardArrowDown,
+        color = motionColor("minIcon", "content"),
+        enabled = true
+    ) {
+        when (currentState) {
+            NewMessageLayout.Full -> state.setToMini()
+            else -> state.setToFull()
+        }
+    }
+    CheapText(
+        text = dialogName,
+        modifier = Modifier.layoutId("title"),
+        color = motionColor("title", "content"),
+        style = MaterialTheme.typography.h6
+    )
+    MessageWidget(modifier = Modifier.layoutId("content"), >
+        focusManager.clearFocus()
+        state.setToFab()
+    })
+//            MessageWidgetCol(
+//                modifier = Modifier
+//                    .layoutId("content")
+//                    .padding(start = 4.dp, end = 4.dp, bottom = 4.dp)
+//            )
+}
+
+@Composable
+private fun NewMessageButton(
+    modifier: Modifier = Modifier,
+    motionScene: MotionScene,
+    state: NewMessageState
+) {
+    val currentStateName = state.currentState.name
+    MotionLayout(
+        motionScene = motionScene,
+        animationSpec = tween(700),
+        constraintSetName = currentStateName,
+        modifier = modifier
+    ) {
+        MotionMessageContent(state = state)
+    }
+}
+
+@OptIn(ExperimentalMaterialApi::class)
+@Composable
+internal fun ColorableIconButton(
+    modifier: Modifier,
+    imageVector: ImageVector,
+    color: Color,
+    enabled: Boolean,
+    onClick: () -> Unit
+) {
+    Surface(
+        modifier = modifier,
+        color = Color.Transparent,
+        contentColor = color,
+        >
+        enabled = enabled
+    ) {
+        Icon(
+            imageVector = imageVector,
+            contentDescription = null,
+            modifier = Modifier.fillMaxSize()
+        )
+    }
+}
+
+// With column
+@Composable
+internal fun MessageWidgetCol(modifier: Modifier) {
+    Column(
+        modifier = modifier,
+        verticalArrangement = Arrangement.spacedBy(8.dp),
+        horizontalAlignment = Alignment.CenterHorizontally
+    ) {
+        TextField(
+            modifier = Modifier.fillMaxWidth(),
+            value = "",
+            >
+            placeholder = {
+                Text("Recipients")
+            }
+        )
+        TextField(
+            modifier = Modifier.fillMaxWidth(),
+            value = "",
+            >
+            placeholder = {
+                Text("Subject")
+            }
+        )
+        TextField(
+            modifier = Modifier
+                .fillMaxWidth()
+                .weight(weight = 2.0f, fill = true),
+            value = "",
+            >
+            placeholder = {
+                Text("Message")
+            }
+        )
+        Row(
+            modifier = Modifier.fillMaxWidth(),
+            horizontalArrangement = Arrangement.SpaceBetween,
+        ) {
+            Button( /*TODO*/ }) {
+                Row {
+                    Text(text = "Send")
+                    Spacer(modifier = Modifier.width(8.dp))
+                    Icon(
+                        imageVector = Icons.Default.Send,
+                        contentDescription = "Send Mail",
+                    )
+                }
+            }
+            Button( /*TODO*/ }) {
+                Icon(
+                    imageVector = Icons.Default.Delete,
+                    contentDescription = "Delete Draft",
+                )
+            }
+        }
+    }
+}
+
+// With ConstraintLayout
+@Preview
+@Composable
+private fun MessageWidgetPreview() {
+    MessageWidget(modifier = Modifier.fillMaxSize())
+}
+
+@Composable
+internal fun MessageWidget(
+    modifier: Modifier,
+    onDelete: () -> Unit = {}
+) {
+    val constraintSet = remember {
+        ConstraintSet(
+            """
+                {
+                    gl1: { type: 'hGuideline', end: 50 },
+                    recipient: {
+                      top: ['parent', 'top', 2],
+                      width: 'spread',
+                      centerHorizontally: 'parent',
+                    },
+                    subject: { 
+                      top: ['recipient', 'bottom', 8],
+                      width: 'spread',
+                      centerHorizontally: 'parent',
+                    },
+                    message: {
+                      height: 'spread',
+                      width: 'spread',
+                      centerHorizontally: 'parent',
+                      top: ['subject', 'bottom', 8],
+                      bottom: ['gl1', 'bottom', 4],
+                    },
+                    delete: {
+                      height: 'spread',
+                      top: ['gl1', 'bottom', 0],
+                      bottom: ['parent', 'bottom', 4],
+                      start: ['parent', 'start', 0]
+                    },
+                    send: {
+                      height: 'spread',
+                      top: ['gl1', 'bottom', 0],
+                      bottom: ['parent', 'bottom', 4],
+                      end: ['parent', 'end', 0]
+                    }
+                }
+            """.trimIndent()
+        )
+    }
+    ConstraintLayout(
+        modifier = modifier.padding(top = 4.dp, start = 8.dp, end = 8.dp, bottom = 0.dp),
+        constraintSet = constraintSet
+    ) {
+        OutlinedTextField(
+            modifier = Modifier.layoutId("recipient"),
+            value = "",
+            >
+            label = {
+                CheapText("To")
+            }
+        )
+        OutlinedTextField(
+            modifier = Modifier.layoutId("subject"),
+            value = "",
+            >
+            label = {
+                CheapText("Subject")
+            }
+        )
+        OutlinedTextField(
+            modifier = Modifier
+                .layoutId("message")
+                .fillMaxHeight(),
+            value = "",
+            >
+            label = {
+                CheapText("Message")
+            }
+        )
+        Button(
+            modifier = Modifier.layoutId("send"),
+             // TODO: Do something different for Send onClick
+        ) {
+            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+                CheapText(text = "Send")
+                Icon(
+                    imageVector = Icons.Default.Send,
+                    contentDescription = "Send Mail",
+                )
+            }
+        }
+        Button(
+            modifier = Modifier.layoutId("delete"),
+            >
+        ) {
+            Icon(
+                imageVector = Icons.Default.Delete,
+                contentDescription = "Delete Draft",
+            )
+        }
+    }
+}
+
+/**
+ * [Text] Composable constrained to one line for better animation performance.
+ */
+@Composable
+private fun CheapText(
+    text: String,
+    modifier: Modifier = Modifier,
+    color: Color = Color.Unspecified,
+    style: TextStyle = LocalTextStyle.current,
+    overflow: TextOverflow = TextOverflow.Clip
+) {
+    Text(
+        text = text,
+        modifier = modifier,
+        color = color,
+        style = style,
+        maxLines = 1,
+        overflow = overflow,
+    )
+}
+
+private fun Color.toHexString() = toArgb().toUInt().toString(16)
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessageState.kt b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessageState.kt
new file mode 100644
index 0000000..677182e
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/newmessage/NewMessageState.kt
@@ -0,0 +1,54 @@
+/*
+ * 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.compose.integration.macrobenchmark.target.motionlayout.newmessage
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+
+@Composable
+internal fun rememberNewMessageState(
+    key: Any = Unit,
+    initialLayoutState: NewMessageLayout
+): NewMessageState {
+    return remember(key) { NewMessageState(initialLayoutState) }
+}
+
+internal class NewMessageState(initialLayoutState: NewMessageLayout) {
+    private var _currentState = mutableStateOf(initialLayoutState)
+
+    val currentState: NewMessageLayout
+        get() = _currentState.value
+
+    fun setToFull() {
+        _currentState.value = NewMessageLayout.Full
+    }
+
+    fun setToMini() {
+        _currentState.value = NewMessageLayout.Mini
+    }
+
+    fun setToFab() {
+        _currentState.value = NewMessageLayout.Fab
+    }
+}
+
+internal enum class NewMessageLayout {
+    Full,
+    Mini,
+    Fab
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..50ab5bc
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/target/toolbar/CollapsibleToolbar.kt
@@ -0,0 +1,243 @@
+/*
+ * 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.compose.integration.macrobenchmark.target.motionlayout.toolbar
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+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.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
+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.shadow
+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.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.constraintlayout.compose.ConstraintSet
+import androidx.constraintlayout.compose.Dimension
+import androidx.constraintlayout.compose.ExperimentalMotionApi
+import androidx.constraintlayout.compose.MotionLayout
+import kotlin.math.absoluteValue
+
+@Preview
+@Composable
+fun MotionCollapseToolbarPreview() {
+    MotionCollapseToolbar(
+        Modifier
+            .fillMaxSize()
+    )
+}
+
+@Composable
+fun MotionCollapseToolbar(
+    modifier: Modifier = Modifier,
+) {
+    val collapsibleToolbarState = rememberCollapsibleToolbarState()
+    Box(modifier.nestedScroll(collapsibleToolbarState)) {
+        LazyColumn(
+            modifier = Modifier
+                .fillMaxWidth()
+                .testTag("LazyColumn"),
+            verticalArrangement = Arrangement.spacedBy(8.dp),
+            horizontalAlignment = Alignment.CenterHorizontally,
+            contentPadding = PaddingValues(top = collapsibleToolbarState.currentHeight)
+        ) {
+            items(count = 20) {
+                CardSample(
+                    Modifier
+                        .width(250.dp)
+                        .height(80.dp)
+                        .shadow(4.dp, RoundedCornerShape(10.dp))
+                        .background(Color.White, RoundedCornerShape(10.dp))
+                        .padding(4.dp)
+                )
+            }
+        }
+        CollapsibleToolbar(
+            modifier = Modifier
+                .fillMaxWidth()
+                .height(210.dp),
+            toolbarState = collapsibleToolbarState
+        )
+    }
+}
+
+private val expandedCSet = ConstraintSet {
+    val title = createRefFor("title")
+    val toolbar = createRefFor("toolbar")
+    val container = createRefFor("container")
+
+    constrain(container) {
+        width = Dimension.fillToConstraints
+        height = Dimension.value(200.dp)
+
+        start.linkTo(parent.start)
+        end.linkTo(parent.end)
+        top.linkTo(parent.top)
+    }
+
+    constrain(title) {
+        centerHorizontallyTo(container)
+        top.linkTo(container.top)
+
+        scaleX = 1.5f
+        scaleY = 1.5f
+    }
+    constrain(toolbar) {
+        width = Dimension.fillToConstraints
+        centerHorizontallyTo(container)
+        bottom.linkTo(container.bottom)
+    }
+}
+
+private val collapsedCSet = ConstraintSet(expandedCSet) {
+    val title = createRefFor("title")
+    val toolbar = createRefFor("toolbar")
+    val container = createRefFor("container")
+
+    constrain(container) {
+        height = Dimension.value(70.dp)
+    }
+
+    constrain(title) {
+        clearConstraints()
+        resetTransforms()
+
+        top.linkTo(toolbar.top)
+        start.linkTo(container.start)
+        bottom.linkTo(toolbar.bottom)
+    }
+
+    constrain(toolbar) {
+        clearHorizontal()
+
+        top.linkTo(container.top)
+        end.linkTo(container.end)
+        start.linkTo(title.end, 12.dp)
+    }
+}
+
+@Composable
+fun rememberCollapsibleToolbarState(): CollapsibleToolbarState {
+    val density = LocalDensity.current
+    return remember { CollapsibleToolbarState(density) }
+}
+
+class CollapsibleToolbarState internal constructor(
+    private val density: Density
+) : NestedScrollConnection {
+    private val maximumHeight = 200.dp
+    private var minimumHeight = 70.dp
+
+    private val consumableHeight = maximumHeight - minimumHeight
+
+    internal val currentHeight: Dp
+        get() = maximumHeight - consumedHeight
+
+    internal val progress: Float
+        get() = (consumedHeight.value / consumableHeight.value)
+
+    private var consumedHeight by mutableStateOf(0.dp)
+
+    private fun consumeDeltaScroll(scrollDelta: Float): Float {
+        val remainingHeight = consumableHeight - consumedHeight
+        val remainingPx = with(density) { remainingHeight.toPx() }
+        val maxHeightPx = with(density) { consumableHeight.toPx() }
+
+        // TODO: Simplify, no need to differentiate positive/negative scroll
+        if (scrollDelta < 0) {
+            // Going down
+            val diff = remainingPx + scrollDelta
+            if (diff > 0) {
+                consumedHeight += with(density) { scrollDelta.absoluteValue.toDp() }
+                return scrollDelta
+            } else {
+                consumedHeight = consumableHeight
+                return remainingPx * -1f
+            }
+        } else if (scrollDelta > 0) {
+            // Going up
+            val diff = remainingPx + scrollDelta
+            if (diff < maxHeightPx) {
+                consumedHeight -= with(density) { scrollDelta.absoluteValue.toDp() }
+                return scrollDelta
+            } else {
+                val toConsume = with(density) { consumedHeight.toPx() }
+                consumedHeight = 0.dp
+                return toConsume
+            }
+        } else {
+            return 0f
+        }
+    }
+
+    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+        consumeDeltaScroll(available.y)
+        return Offset.Zero
+    }
+}
+
+@OptIn(ExperimentalMotionApi::class)
+@Composable
+fun CollapsibleToolbar(
+    modifier: Modifier = Modifier,
+    toolbarState: CollapsibleToolbarState
+) {
+    MotionLayout(
+        modifier = modifier,
+        start = expandedCSet,
+        end = collapsedCSet,
+        progress = toolbarState.progress
+    ) {
+        Box(
+            Modifier
+                .layoutId("container")
+                .background(Color.White)
+        )
+        Text(
+            modifier = Modifier.layoutId("title"),
+            text = "MotionLayout",
+            maxLines = 1,
+            fontSize = 18.sp
+        )
+        OutlinedSearchBar(modifier = Modifier.layoutId("toolbar"))
+    }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_1.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_1.png
new file mode 100644
index 0000000..22ff80a
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_1.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_10.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_10.png
new file mode 100644
index 0000000..f65c0b2
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_10.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_11.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_11.png
new file mode 100644
index 0000000..18b842b
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_11.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_12.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_12.png
new file mode 100644
index 0000000..fd71f8c
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_12.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_13.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_13.png
new file mode 100644
index 0000000..b97517f
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_13.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_14.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_14.png
new file mode 100644
index 0000000..fb7a871
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_14.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_15.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_15.png
new file mode 100644
index 0000000..2860447
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_15.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_16.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_16.png
new file mode 100644
index 0000000..52ee27a
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_16.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_2.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_2.png
new file mode 100644
index 0000000..0126588d
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_2.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_3.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_3.png
new file mode 100644
index 0000000..8ecc7fb
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_3.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_4.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_4.png
new file mode 100644
index 0000000..a04de0a
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_4.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_5.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_5.png
new file mode 100644
index 0000000..b0ebf8c
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_5.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_6.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_6.png
new file mode 100644
index 0000000..410f7ee
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_6.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_7.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_7.png
new file mode 100644
index 0000000..42df954
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_7.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_8.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_8.png
new file mode 100644
index 0000000..ea62706d
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_8.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_9.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_9.png
new file mode 100644
index 0000000..e612b7a
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/avatar_9.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_background.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..2aea1e0
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,90 @@
+<?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.
+  -->
+
+<vector
+    android:height="108dp"
+    android:width="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#008577"
+          android:pathData="M0,0h108v108h-108z"/>
+    <path android:fillColor="#00000000" android:pathData="M9,0L9,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,0L19,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M29,0L29,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M39,0L39,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M49,0L49,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M59,0L59,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M69,0L69,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M79,0L79,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M89,0L89,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M99,0L99,108"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,9L108,9"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,19L108,19"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,29L108,29"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,39L108,39"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,49L108,49"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,59L108,59"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,69L108,69"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,79L108,79"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,89L108,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M0,99L108,99"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,29L89,29"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,39L89,39"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,49L89,49"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,59L89,59"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,69L89,69"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M19,79L89,79"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M29,19L29,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M39,19L39,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M49,19L49,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M59,19L59,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M69,19L69,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+    <path android:fillColor="#00000000" android:pathData="M79,19L79,89"
+          android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
+</vector>
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_foreground.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..f5d459c
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,50 @@
+<!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="108dp"
+    android:height="108dp"
+    android:viewportHeight="108"
+    android:viewportWidth="108">
+    <path
+        android:fillType="evenOdd"
+        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1">
+        <aapt:attr name="android:fillColor">
+            <gradient
+                android:endX="78.5885"
+                android:endY="90.9159"
+                android:startX="48.7653"
+                android:startY="61.0927"
+                android:type="linear">
+                <item
+                    android:color="#44000000"
+                    android:offset="0.0" />
+                <item
+                    android:color="#00000000"
+                    android:offset="1.0" />
+            </gradient>
+        </aapt:attr>
+    </path>
+    <path
+        android:fillColor="#FFFFFF"
+        android:fillType="nonZero"
+        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
+        android:strokeColor="#00000000"
+        android:strokeWidth="1" />
+</vector>
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-anydpi/ic_launcher.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-anydpi/ic_launcher.xml
new file mode 100644
index 0000000..bbd3e02
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-anydpi/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@drawable/ic_launcher_background"/>
+    <foreground android:drawable="@drawable/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-hdpi/ic_launcher.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-mdpi/ic_launcher.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xhdpi/ic_launcher.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed4659
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxhdpi/ic_launcher.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark-target/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle
new file mode 100644
index 0000000..00320cd
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/build.gradle
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.test")
+    id("kotlin-android")
+}
+
+android {
+    defaultConfig {
+        minSdkVersion 26
+    }
+    namespace "androidx.constraintlayout.compose.integration.macrobenchmark"
+
+    // We need animations to work for MotionLayout
+    testOptions.animationsDisabled  false
+
+    targetProjectPath = ":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark-target"
+    // Enable the benchmark to run separately from the app process
+    experimentalProperties["android.experimental.self-instrumenting"] = true
+
+    buildTypes {
+        // declare a build type to match the target app's build type
+        benchmark {
+            debuggable = true
+            signingConfig = debug.signingConfig
+            // Selects release buildType if the benchmark buildType not available in other modules.
+            matchingFallbacks = ['release']
+        }
+    }
+}
+
+androidComponents {
+    beforeVariants(selector().all()) {
+        // enable only the benchmark buildType, since we only want to measure close to release performance
+        enabled = buildType == 'benchmark'
+    }
+}
+
+dependencies {
+    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)
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8e90956
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?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/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/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
new file mode 100644
index 0000000..d15fad9
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/macrobenchmark/src/main/java/androidx/constraintlayout/compose/integration/macrobenchmark/MotionLayoutBenchmark.kt
@@ -0,0 +1,141 @@
+/*
+ * 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.constraintlayout.compose.integration.macrobenchmark
+
+import android.content.Intent
+import androidx.benchmark.macro.CompilationMode
+import androidx.benchmark.macro.FrameTimingMetric
+import androidx.benchmark.macro.MacrobenchmarkScope
+import androidx.benchmark.macro.StartupMode
+import androidx.benchmark.macro.junit4.MacrobenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.test.uiautomator.By
+import kotlin.math.roundToInt
+import org.junit.Rule
+import org.junit.Test
+
+private const val PACKAGE_NAME =
+    "androidx.constraintlayout.compose.integration.macrobenchmark.target"
+private const val ACTION =
+    "androidx.constraintlayout.compose.integration.macrobenchmark.target.MOTION_LAYOUT_ACTIVITY"
+
+/**
+ * Run locally using `./gradlew :constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark:connectedCheck`
+ */
+@LargeTest
+class MotionLayoutBenchmark {
+
+    @get:Rule
+    val benchmarkRule = MacrobenchmarkRule()
+
+    /**
+     * Transitions the Layout through its three different ConstraintSets using the MotionScene DSL.
+     */
+    @Test
+    fun messageDsl() = benchmarkRule.testNewMessage(NewMessageMode.Dsl)
+
+    /**
+     * Transitions the Layout through its three different ConstraintSets using the MotionScene JSON.
+     */
+    @Test
+    fun messageJson() = benchmarkRule.testNewMessage(NewMessageMode.Json)
+
+    @Test
+    fun collapsibleToolbar() = benchmarkRule.testCollapsibleToolbar()
+
+    /**
+     * The base method to benchmark FrameTimings of a Composable from the macrobenchmark-app module.
+     *
+     * [composableName] should be a registered Composable in **MotionLayoutBenchmarkActivity**
+     *
+     * The [setupBlock] is run after the activity starts with the given [composableName]. You may use
+     * this as a chance to set the UI in the way you wish it to be measured.
+     *
+     * The [measureBlock] is called after the setup. [FrameTimingMetric] measures UI performance during
+     * this block.
+     */
+    private fun MacrobenchmarkRule.motionBenchmark(
+        composableName: String,
+        setupBlock: MacrobenchmarkScope.() -> Unit = {},
+        measureBlock: MacrobenchmarkScope.() -> Unit
+    ) {
+        measureRepeated(
+            packageName = PACKAGE_NAME,
+            metrics = listOf(FrameTimingMetric()),
+            compilationMode = CompilationMode.DEFAULT,
+            iterations = 10,
+            // HOT causes issues with the measure block logic where multiple click actions are
+            // triggered at once
+            startupMode = StartupMode.WARM,
+            setupBlock = {
+                val intent = Intent()
+                intent.action = ACTION
+                intent.putExtra("ComposableName", composableName)
+                startActivityAndWait(intent)
+                device.waitForIdle()
+                setupBlock()
+            },
+            measureBlock = measureBlock
+        )
+    }
+
+    private fun MacrobenchmarkRule.testCollapsibleToolbar() =
+        motionBenchmark("CollapsibleToolbar") {
+            val column = device.findObject(By.res("LazyColumn"))
+            val bounds = column.visibleBounds
+
+            // Margin to reduce the amount of pixels scrolled
+            val vMargin = (bounds.height() * 0.2f).roundToInt()
+            val x = (bounds.width() * 0.5f).roundToInt()
+            val y1 = bounds.bottom - vMargin
+            val y2 = bounds.top + vMargin
+
+            // Swipe down
+            device.swipe(x, y1, x, y2, 50)
+            device.waitForIdle()
+
+            // Swipe up
+            device.swipe(x, y2, x, y1, 50)
+            device.waitForIdle()
+        }
+
+    private fun MacrobenchmarkRule.testNewMessage(
+        mode: NewMessageMode
+    ) {
+        motionBenchmark(
+            mode.composableName
+        ) {
+            val toFab = device.findObject(By.res("Fab"))
+            val toFull = device.findObject(By.res("Full"))
+            val toMini = device.findObject(By.res("Mini"))
+
+            toMini.click()
+            device.waitForIdle()
+
+            toFab.click()
+            device.waitForIdle()
+
+            toFull.click()
+            device.waitForIdle()
+        }
+    }
+
+    internal enum class NewMessageMode(val composableName: String) {
+        Json("NewMessageJson"),
+        Dsl("NewMessageDsl")
+    }
+}
diff --git a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ChainsTest.kt b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ChainsTest.kt
index bbfe49b..5fb7268 100644
--- a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ChainsTest.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ChainsTest.kt
@@ -21,7 +21,9 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertPositionInRootIsEqualTo
+import androidx.compose.ui.test.assertWidthIsEqualTo
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.unit.dp
@@ -114,7 +116,11 @@
         val boxSizes = arrayOf(10.dp, 20.dp, 30.dp)
         val margin = 10.dp
         rule.setContent {
-            ConstraintLayout(Modifier.size(rootSize)) {
+            ConstraintLayout(
+                Modifier
+                    .background(Color.LightGray)
+                    .size(rootSize)
+            ) {
                 val (box0, box1, box2) = createRefs()
                 val chain0 = createHorizontalChain(box0, box1, chainStyle = ChainStyle.Packed)
                 constrain(chain0) {
@@ -170,4 +176,288 @@
         rule.onNodeWithTag("box1").assertPositionInRootIsEqualTo(box1Left, box1Top)
         rule.onNodeWithTag("box2").assertPositionInRootIsEqualTo(margin, margin)
     }
+
+    @Test
+    fun testHorizontalPacked_withMargins() {
+        val rootSize = 100.dp
+        val boxSizes = arrayOf(10.dp, 20.dp, 30.dp)
+        val boxMargin = 5.dp
+        val boxGoneMargin = 7.dp
+        val constraintSet = ConstraintSet {
+            val box0 = createRefFor("box0")
+            val boxGone = createRefFor("boxGone")
+            val box1 = createRefFor("box1")
+            val box2 = createRefFor("box2")
+
+            createHorizontalChain(
+                box0.withChainParams(
+                    startMargin = 0.dp,
+                    endMargin = boxMargin, // Not applied since the next box is Gone
+                    endGoneMargin = boxGoneMargin
+                ),
+                boxGone.withChainParams(
+                    // None of these margins should apply since it's Gone
+                    startMargin = 100.dp,
+                    endMargin = 100.dp,
+                    startGoneMargin = 100.dp,
+                    endGoneMargin = 100.dp
+                ),
+                box1,
+                box2.withHorizontalChainParams(startMargin = boxMargin, endMargin = 0.dp),
+                chainStyle = ChainStyle.Packed
+            )
+
+            constrain(box0) {
+                width = Dimension.value(boxSizes[0])
+                height = Dimension.value(boxSizes[0])
+                centerVerticallyTo(parent)
+            }
+            constrain(boxGone) {
+                width = Dimension.value(boxSizes[1])
+                height = Dimension.value(boxSizes[1])
+                centerVerticallyTo(box0)
+
+                visibility = Visibility.Gone
+            }
+            constrain(box1) {
+                width = Dimension.value(boxSizes[1])
+                height = Dimension.value(boxSizes[1])
+                centerVerticallyTo(box0)
+            }
+            constrain(box2) {
+                width = Dimension.value(boxSizes[2])
+                height = Dimension.value(boxSizes[2])
+                centerVerticallyTo(box0)
+            }
+        }
+        rule.setContent {
+            ConstraintLayout(
+                modifier = Modifier
+                    .background(Color.LightGray)
+                    .size(rootSize),
+                constraintSet = constraintSet
+            ) {
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .layoutTestId("box0")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Blue)
+                        .layoutTestId("box1")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Green)
+                        .layoutTestId("box2")
+                )
+            }
+        }
+        rule.waitForIdle()
+
+        val totalMargins = boxMargin + boxGoneMargin
+        val totalChainSpace = boxSizes[0] + boxSizes[1] + boxSizes[2] + totalMargins
+
+        val box0Left = (rootSize - totalChainSpace) * 0.5f
+        val box0Top = (rootSize - boxSizes[0]) * 0.5f
+
+        val box1Left = box0Left + boxSizes[0] + boxGoneMargin
+        val box1Top = (rootSize - boxSizes[1]) * 0.5f
+
+        val box2Left = box1Left + boxSizes[1] + boxMargin
+        val box2Top = (rootSize - boxSizes[2]) * 0.5f
+
+        rule.onNodeWithTag("box0").assertPositionInRootIsEqualTo(box0Left, box0Top)
+        rule.onNodeWithTag("box1").assertPositionInRootIsEqualTo(box1Left, box1Top)
+        rule.onNodeWithTag("box2").assertPositionInRootIsEqualTo(box2Left, box2Top)
+    }
+
+    @Test
+    fun testVerticalPacked_withMargins() {
+        val rootSize = 100.dp
+        val boxSizes = arrayOf(10.dp, 20.dp, 30.dp)
+        val boxMargin = 5.dp
+        val boxGoneMargin = 7.dp
+        val constraintSet = ConstraintSet {
+            val box0 = createRefFor("box0")
+            val boxGone = createRefFor("boxGone")
+            val box1 = createRefFor("box1")
+            val box2 = createRefFor("box2")
+
+            createVerticalChain(
+                box0.withChainParams(
+                    topMargin = 0.dp,
+                    bottomMargin = boxMargin, // Not applied since the next box is Gone
+                    bottomGoneMargin = boxGoneMargin
+                ),
+                boxGone.withChainParams(
+                    // None of these margins should apply since it's Gone
+                    topMargin = 100.dp,
+                    bottomMargin = 100.dp,
+                    topGoneMargin = 100.dp,
+                    bottomGoneMargin = 100.dp
+                ),
+                box1,
+                box2.withVerticalChainParams(topMargin = boxMargin, bottomMargin = 0.dp),
+                chainStyle = ChainStyle.Packed
+            )
+
+            constrain(box0) {
+                width = Dimension.value(boxSizes[0])
+                height = Dimension.value(boxSizes[0])
+                centerHorizontallyTo(parent)
+            }
+            constrain(boxGone) {
+                width = Dimension.value(100.dp) // Dimensions won't matter since it's Gone
+                height = Dimension.value(100.dp) // Dimensions won't matter since it's Gone
+                centerHorizontallyTo(box0)
+
+                visibility = Visibility.Gone
+            }
+            constrain(box1) {
+                width = Dimension.value(boxSizes[1])
+                height = Dimension.value(boxSizes[1])
+                centerHorizontallyTo(box0)
+            }
+            constrain(box2) {
+                width = Dimension.value(boxSizes[2])
+                height = Dimension.value(boxSizes[2])
+                centerHorizontallyTo(box0)
+            }
+        }
+        rule.setContent {
+            ConstraintLayout(
+                modifier = Modifier
+                    .background(Color.LightGray)
+                    .size(rootSize),
+                constraintSet = constraintSet
+            ) {
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .layoutTestId("box0")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Blue)
+                        .layoutTestId("box1")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Green)
+                        .layoutTestId("box2")
+                )
+            }
+        }
+        rule.waitForIdle()
+
+        val totalMargins = boxMargin + boxGoneMargin
+        val totalChainSpace = boxSizes[0] + boxSizes[1] + boxSizes[2] + totalMargins
+
+        val box0Left = (rootSize - boxSizes[0]) * 0.5f
+        val box0Top = (rootSize - totalChainSpace) * 0.5f
+
+        val box1Left = (rootSize - boxSizes[1]) * 0.5f
+        val box1Top = box0Top + boxSizes[0] + boxGoneMargin
+
+        val box2Left = (rootSize - boxSizes[2]) * 0.5f
+        val box2Top = box1Top + boxSizes[1] + boxMargin
+
+        rule.onNodeWithTag("box0").assertPositionInRootIsEqualTo(box0Left, box0Top)
+        rule.onNodeWithTag("box1").assertPositionInRootIsEqualTo(box1Left, box1Top)
+        rule.onNodeWithTag("box2").assertPositionInRootIsEqualTo(box2Left, box2Top)
+    }
+
+    @Test
+    fun testHorizontalWeight_withConstraintSet() {
+        val rootSize = 100.dp
+        val boxSize = 10.dp
+
+        rule.setContent {
+            ConstraintLayout(
+                modifier = Modifier
+                    .background(Color.LightGray)
+                    .size(rootSize),
+                constraintSet = ConstraintSet {
+                    val box0 = createRefFor("box0")
+                    val box1 = createRefFor("box1")
+
+                    constrain(box0) {
+                        width = Dimension.fillToConstraints
+                        height = Dimension.value(boxSize)
+
+                        horizontalChainWeight = 1.0f
+                        verticalChainWeight = 2.0f // Ignored in horizontal chain
+                    }
+                    constrain(box1) {
+                        width = Dimension.fillToConstraints
+                        height = Dimension.value(boxSize)
+                    }
+                    createHorizontalChain(box0, box1.withChainParams(weight = 0.5f))
+                }
+            ) {
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .layoutTestId("box0")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Blue)
+                        .layoutTestId("box1")
+                )
+            }
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag("box0").assertWidthIsEqualTo(rootSize * 0.667f)
+        rule.onNodeWithTag("box1").assertPositionInRootIsEqualTo(rootSize * 0.667f, 0.dp)
+        rule.onNodeWithTag("box1").assertWidthIsEqualTo(rootSize * 0.334f)
+    }
+
+    @Test
+    fun testVerticalWeight_withConstraintSet() {
+        val rootSize = 100.dp
+        val boxSize = 10.dp
+
+        rule.setContent {
+            ConstraintLayout(
+                modifier = Modifier
+                    .background(Color.LightGray)
+                    .size(rootSize),
+                constraintSet = ConstraintSet {
+                    val box0 = createRefFor("box0")
+                    val box1 = createRefFor("box1")
+
+                    constrain(box0) {
+                        width = Dimension.value(boxSize)
+                        height = Dimension.fillToConstraints
+
+                        horizontalChainWeight = 2.0f // Ignored in vertical chain
+                        verticalChainWeight = 1.0f
+                    }
+                    constrain(box1) {
+                        width = Dimension.value(boxSize)
+                        height = Dimension.fillToConstraints
+                    }
+                    createVerticalChain(box0, box1.withChainParams(weight = 0.5f))
+                }
+            ) {
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .layoutTestId("box0")
+                )
+                Box(
+                    modifier = Modifier
+                        .background(Color.Blue)
+                        .layoutTestId("box1")
+                )
+            }
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag("box0").assertHeightIsEqualTo(rootSize * 0.667f)
+        rule.onNodeWithTag("box1").assertPositionInRootIsEqualTo(0.dp, rootSize * 0.667f)
+        rule.onNodeWithTag("box1").assertHeightIsEqualTo(rootSize * 0.334f)
+    }
 }
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ConstraintLayoutTest.kt b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ConstraintLayoutTest.kt
index 5c2b507..c93b13f 100644
--- a/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ConstraintLayoutTest.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidAndroidTest/kotlin/androidx/constraintlayout/compose/ConstraintLayoutTest.kt
@@ -1663,4 +1663,68 @@
         rule.onNodeWithTag(boxTag1).assertPositionInRootIsEqualTo(29.5.dp, 0.dp)
         rule.onNodeWithTag(boxTag2).assertPositionInRootIsEqualTo(60.dp, 0.dp)
     }
+
+    @Test
+    fun testBias_withConstraintSet() {
+        val rootSize = 100.dp
+        val boxSize = 10.dp
+        val horBias = 0.2f
+        val verBias = 1f - horBias
+        rule.setContent {
+            ConstraintLayout(
+                modifier = Modifier.size(rootSize),
+                constraintSet = ConstraintSet {
+                    constrain(createRefFor("box")) {
+                        width = Dimension.value(boxSize)
+                        height = Dimension.value(boxSize)
+
+                        centerTo(parent)
+                        horizontalBias = horBias
+                        verticalBias = verBias
+                    }
+                }) {
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .layoutTestId("box")
+                )
+            }
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag("box").assertPositionInRootIsEqualTo(
+            (rootSize - boxSize) * 0.2f,
+            (rootSize - boxSize) * 0.8f
+        )
+    }
+
+    @Test
+    fun testBias_withInlineDsl() {
+        val rootSize = 100.dp
+        val boxSize = 10.dp
+        val horBias = 0.2f
+        val verBias = 1f - horBias
+        rule.setContent {
+            ConstraintLayout(Modifier.size(rootSize)) {
+                val box = createRef()
+                Box(
+                    modifier = Modifier
+                        .background(Color.Red)
+                        .constrainAs(box) {
+                            width = Dimension.value(boxSize)
+                            height = Dimension.value(boxSize)
+
+                            centerTo(parent)
+                            horizontalBias = horBias
+                            verticalBias = verBias
+                        }
+                        .layoutTestId("box")
+                )
+            }
+        }
+        rule.waitForIdle()
+        rule.onNodeWithTag("box").assertPositionInRootIsEqualTo(
+            (rootSize - boxSize) * 0.2f,
+            (rootSize - boxSize) * 0.8f
+        )
+    }
 }
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstrainScope.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstrainScope.kt
index 4e171e2..fb1c981 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstrainScope.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstrainScope.kt
@@ -134,7 +134,7 @@
         set(value) {
             field = value
             addTransform {
-                if (visibility != Visibility.Invisible) {
+                if (this@ConstrainScope.visibility != Visibility.Invisible) {
                     // A bit of a hack, this behavior is not defined in :core
                     // Invisible should override alpha
                     alpha(value)
@@ -260,6 +260,44 @@
             }
         }
 
+    /**
+     * Applied when the widget has constraints on the [start] and [end] anchors. It defines the
+     * position of the widget relative to the space within the constraints, where `0f` is the
+     * left-most position and `1f` is the right-most position.
+     *
+     * &nbsp;
+     *
+     * When layout direction is RTL, the value of the bias is effectively inverted.
+     *
+     * E.g.: For `horizontalBias = 0.3f`, `0.7f` is used for RTL.
+     *
+     * &nbsp;
+     *
+     * Note that the bias may also be applied with calls such as [linkTo].
+     */
+    @FloatRange(0.0, 1.0)
+    var horizontalBias: Float = 0.5f
+        set(value) {
+            field = value
+            tasks.add { state ->
+                state.constraints(id).horizontalBias(value)
+            }
+        }
+
+    /**
+     * Applied when the widget has constraints on the [top] and [bottom] anchors. It defines the
+     * position of the widget relative to the space within the constraints, where `0f` is the
+     * top-most position and `1f` is the bottom-most position.
+     */
+    @FloatRange(0.0, 1.0)
+    var verticalBias: Float = 0.5f
+        set(value) {
+            field = value
+            tasks.add { state ->
+                state.constraints(id).verticalBias(value)
+            }
+        }
+
     private fun addTransform(change: ConstraintReference.() -> Unit) =
         tasks.add { state -> change(state.constraints(id)) }
 
diff --git a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayoutBaseScope.kt b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayoutBaseScope.kt
index 3193e55..d086df2 100644
--- a/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayoutBaseScope.kt
+++ b/constraintlayout/constraintlayout-compose/src/androidMain/kotlin/androidx/constraintlayout/compose/ConstraintLayoutBaseScope.kt
@@ -583,7 +583,7 @@
         updateHelpersHashCode(16)
         elements.forEach { updateHelpersHashCode(it.hashCode()) }
 
-         return ConstrainedLayoutReference(id)
+        return ConstrainedLayoutReference(id)
     }
 
     /**
@@ -592,7 +592,6 @@
      * Use [constrain] with the resulting [HorizontalChainReference] to modify the start/left and
      * end/right constraints of this chain.
      */
-    // TODO(popam, b/157783937): this API should be improved
     fun createHorizontalChain(
         vararg elements: LayoutReference,
         chainStyle: ChainStyle = ChainStyle.Spread
@@ -603,7 +602,17 @@
                 id,
                 androidx.constraintlayout.core.state.State.Helper.HORIZONTAL_CHAIN
             ) as androidx.constraintlayout.core.state.helpers.HorizontalChainReference
-            helper.add(*(elements.map { it.id }.toTypedArray()))
+            elements.forEach { chainElement ->
+                val elementParams = chainElement.getHelperParams() ?: ChainParams.Default
+                helper.addChainElement(
+                    chainElement.id,
+                    elementParams.weight,
+                    state.convertDimension(elementParams.startMargin).toFloat(),
+                    state.convertDimension(elementParams.endMargin).toFloat(),
+                    state.convertDimension(elementParams.startGoneMargin).toFloat(),
+                    state.convertDimension(elementParams.endGoneMargin).toFloat()
+                )
+            }
             helper.style(chainStyle.style)
             helper.apply()
             if (chainStyle.bias != null) {
@@ -622,7 +631,6 @@
      * Use [constrain] with the resulting [VerticalChainReference] to modify the top and
      * bottom constraints of this chain.
      */
-    // TODO(popam, b/157783937): this API should be improved
     fun createVerticalChain(
         vararg elements: LayoutReference,
         chainStyle: ChainStyle = ChainStyle.Spread
@@ -633,7 +641,17 @@
                 id,
                 androidx.constraintlayout.core.state.State.Helper.VERTICAL_CHAIN
             ) as androidx.constraintlayout.core.state.helpers.VerticalChainReference
-            helper.add(*(elements.map { it.id }.toTypedArray()))
+            elements.forEach { chainElement ->
+                val elementParams = chainElement.getHelperParams() ?: ChainParams.Default
+                helper.addChainElement(
+                    chainElement.id,
+                    elementParams.weight,
+                    state.convertDimension(elementParams.topMargin).toFloat(),
+                    state.convertDimension(elementParams.bottomMargin).toFloat(),
+                    state.convertDimension(elementParams.topGoneMargin).toFloat(),
+                    state.convertDimension(elementParams.bottomGoneMargin).toFloat()
+                )
+            }
             helper.style(chainStyle.style)
             helper.apply()
             if (chainStyle.bias != null) {
@@ -645,6 +663,147 @@
         updateHelpersHashCode(chainStyle.hashCode())
         return VerticalChainReference(id)
     }
+
+    /**
+     * Sets the parameters that are used by chains to customize the resulting layout.
+     *
+     * Use margins to customize the space between widgets in the chain.
+     *
+     * Use weight to distribute available space to each widget when their dimensions are not
+     * fixed.
+     *
+     * &nbsp;
+     *
+     * Similarly named parameters available from [ConstrainScope.linkTo] are ignored in
+     * Chains.
+     *
+     * Since margins are only for widgets within the chain: Top, Start and End, Bottom margins are
+     * ignored when the widget is the first or the last element in the chain, respectively.
+     *
+     * @param startMargin Added space from the start of this widget to the previous widget
+     * @param topMargin Added space from the top of this widget to the previous widget
+     * @param endMargin Added space from the end of this widget to the next widget
+     * @param bottomMargin Added space from the bottom of this widget to the next widget
+     * @param startGoneMargin Added space from the start of this widget when the previous widget has [Visibility.Gone]
+     * @param topGoneMargin Added space from the top of this widget when the previous widget has [Visibility.Gone]
+     * @param endGoneMargin Added space from the end of this widget when the next widget has [Visibility.Gone]
+     * @param bottomGoneMargin Added space from the bottom of this widget when the next widget has [Visibility.Gone]
+     * @param weight Defines the proportion of space (relative to the total weight) occupied by this
+     * layout when the corresponding dimension is not a fixed value.
+     * @return The same [LayoutReference] instance with the applied values
+     */
+    fun LayoutReference.withChainParams(
+        startMargin: Dp = 0.dp,
+        topMargin: Dp = 0.dp,
+        endMargin: Dp = 0.dp,
+        bottomMargin: Dp = 0.dp,
+        startGoneMargin: Dp = 0.dp,
+        topGoneMargin: Dp = 0.dp,
+        endGoneMargin: Dp = 0.dp,
+        bottomGoneMargin: Dp = 0.dp,
+        weight: Float = Float.NaN,
+    ): LayoutReference =
+        this.apply {
+            setHelperParams(
+                ChainParams(
+                    startMargin = startMargin,
+                    topMargin = topMargin,
+                    endMargin = endMargin,
+                    bottomMargin = bottomMargin,
+                    startGoneMargin = startGoneMargin,
+                    topGoneMargin = topGoneMargin,
+                    endGoneMargin = endGoneMargin,
+                    bottomGoneMargin = bottomGoneMargin,
+                    weight = weight
+                )
+            )
+        }
+
+    /**
+     * Sets the parameters that are used by horizontal chains to customize the resulting layout.
+     *
+     * Use margins to customize the space between widgets in the chain.
+     *
+     * Use weight to distribute available space to each widget when their horizontal dimension is
+     * not fixed.
+     *
+     * &nbsp;
+     *
+     * Similarly named parameters available from [ConstrainScope.linkTo] are ignored in
+     * Chains.
+     *
+     * Since margins are only for widgets within the chain: Start and End margins are
+     * ignored when the widget is the first or the last element in the chain, respectively.
+     *
+     * @param startMargin Added space from the start of this widget to the previous widget
+     * @param endMargin Added space from the end of this widget to the next widget
+     * @param startGoneMargin Added space from the start of this widget when the previous widget has [Visibility.Gone]
+     * @param endGoneMargin Added space from the end of this widget when the next widget has [Visibility.Gone]
+     * @param weight Defines the proportion of space (relative to the total weight) occupied by this
+     * layout when the width is not a fixed dimension.
+     * @return The same [LayoutReference] instance with the applied values
+     */
+    fun LayoutReference.withHorizontalChainParams(
+        startMargin: Dp = 0.dp,
+        endMargin: Dp = 0.dp,
+        startGoneMargin: Dp = 0.dp,
+        endGoneMargin: Dp = 0.dp,
+        weight: Float = Float.NaN
+    ): LayoutReference =
+        withChainParams(
+            startMargin = startMargin,
+            topMargin = 0.dp,
+            endMargin = endMargin,
+            bottomMargin = 0.dp,
+            startGoneMargin = startGoneMargin,
+            topGoneMargin = 0.dp,
+            endGoneMargin = endGoneMargin,
+            bottomGoneMargin = 0.dp,
+            weight = weight
+        )
+
+    /**
+     * Sets the parameters that are used by vertical chains to customize the resulting layout.
+     *
+     * Use margins to customize the space between widgets in the chain.
+     *
+     * Use weight to distribute available space to each widget when their vertical dimension is not
+     * fixed.
+     *
+     * &nbsp;
+     *
+     * Similarly named parameters available from [ConstrainScope.linkTo] are ignored in
+     * Chains.
+     *
+     * Since margins are only for widgets within the chain: Top and Bottom margins are
+     * ignored when the widget is the first or the last element in the chain, respectively.
+     *
+     * @param topMargin Added space from the top of this widget to the previous widget
+     * @param bottomMargin Added space from the bottom of this widget to the next widget
+     * @param topGoneMargin Added space from the top of this widget when the previous widget has [Visibility.Gone]
+     * @param bottomGoneMargin Added space from the bottom of this widget when the next widget has [Visibility.Gone]
+     * @param weight Defines the proportion of space (relative to the total weight) occupied by this
+     * layout when the height is not a fixed dimension.
+     * @return The same [LayoutReference] instance with the applied values
+     */
+    fun LayoutReference.withVerticalChainParams(
+        topMargin: Dp = 0.dp,
+        bottomMargin: Dp = 0.dp,
+        topGoneMargin: Dp = 0.dp,
+        bottomGoneMargin: Dp = 0.dp,
+        weight: Float = Float.NaN
+    ): LayoutReference =
+        withChainParams(
+            startMargin = 0.dp,
+            topMargin = topMargin,
+            endMargin = 0.dp,
+            bottomMargin = bottomMargin,
+            startGoneMargin = 0.dp,
+            topGoneMargin = topGoneMargin,
+            endGoneMargin = 0.dp,
+            bottomGoneMargin = bottomGoneMargin,
+            weight = weight
+        )
 }
 
 /**
@@ -653,6 +812,11 @@
  */
 @Stable
 abstract class LayoutReference internal constructor(internal open val id: Any) {
+    /**
+     * This map should be used to store one instance of different implementations of [HelperParams].
+     */
+    private val helperParamsMap: MutableMap<String, HelperParams> = mutableMapOf()
+
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (javaClass != other?.javaClass) return false
@@ -667,6 +831,60 @@
     override fun hashCode(): Int {
         return id.hashCode()
     }
+
+    internal fun setHelperParams(helperParams: HelperParams) {
+        // Use the class name to force one instance per implementation
+        helperParamsMap[helperParams.javaClass.simpleName] = helperParams
+    }
+
+    /**
+     * Returns the [HelperParams] that corresponds to the class type [T]. Null if no instance of
+     * type [T] has been set.
+     */
+    internal inline fun <reified T> getHelperParams(): T? where T : HelperParams {
+        return helperParamsMap[T::class.java.simpleName] as? T
+    }
+}
+
+/**
+ * Helpers that need parameters on a per-widget basis may implement this interface to store custom
+ * parameters within [LayoutReference].
+ *
+ * @see [LayoutReference.getHelperParams]
+ * @see [LayoutReference.setHelperParams]
+ */
+internal interface HelperParams
+
+/**
+ * Parameters that may be defined for each widget within a chain.
+ *
+ * These will always be used instead of similarly named parameters defined with other calls such as
+ * [ConstrainScope.linkTo].
+ */
+internal class ChainParams(
+    val startMargin: Dp,
+    val topMargin: Dp,
+    val endMargin: Dp,
+    val bottomMargin: Dp,
+    val startGoneMargin: Dp,
+    val topGoneMargin: Dp,
+    val endGoneMargin: Dp,
+    val bottomGoneMargin: Dp,
+    val weight: Float,
+) : HelperParams {
+    companion object {
+        internal val Default = ChainParams(
+            startMargin = 0.dp,
+            topMargin = 0.dp,
+            endMargin = 0.dp,
+            bottomMargin = 0.dp,
+            startGoneMargin = 0.dp,
+            topGoneMargin = 0.dp,
+            endGoneMargin = 0.dp,
+            bottomGoneMargin = 0.dp,
+            weight = Float.NaN
+        )
+    }
 }
 
 /**
@@ -859,7 +1077,7 @@
 @Immutable
 class Wrap internal constructor(
     internal val mode: Int
-    ) {
+) {
     companion object {
         val None =
             Wrap(androidx.constraintlayout.core.widgets.Flow.WRAP_NONE)
@@ -876,7 +1094,7 @@
 @Immutable
 class VerticalAlign internal constructor(
     internal val mode: Int
-    ) {
+) {
     companion object {
         val Top = VerticalAlign(androidx.constraintlayout.core.widgets.Flow.VERTICAL_ALIGN_TOP)
         val Bottom =
@@ -894,7 +1112,7 @@
 @Immutable
 class HorizontalAlign internal constructor(
     internal val mode: Int
-    ) {
+) {
     companion object {
         val Start =
             HorizontalAlign(androidx.constraintlayout.core.widgets.Flow.HORIZONTAL_ALIGN_START)
@@ -910,7 +1128,7 @@
 @Immutable
 class FlowStyle internal constructor(
     internal val style: Int
-    ) {
+) {
     companion object {
         val Spread = FlowStyle(0)
         val SpreadInside = FlowStyle(1)
diff --git a/constraintlayout/constraintlayout-core/api/current.txt b/constraintlayout/constraintlayout-core/api/current.txt
index ff1bb30..30a9d6c 100644
--- a/constraintlayout/constraintlayout-core/api/current.txt
+++ b/constraintlayout/constraintlayout-core/api/current.txt
@@ -2477,20 +2477,22 @@
   }
 
   public class ChainReference extends androidx.constraintlayout.core.state.HelperReference {
-    ctor public ChainReference(androidx.constraintlayout.core.state.State!, androidx.constraintlayout.core.state.State.Helper!);
-    method public void addChainElement(String!, float, float, float);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! bias(float);
+    ctor public ChainReference(androidx.constraintlayout.core.state.State, androidx.constraintlayout.core.state.State.Helper);
+    method public void addChainElement(String, float, float, float);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference bias(float);
     method public float getBias();
-    method protected float getPostMargin(String!);
-    method protected float getPreMargin(String!);
-    method public androidx.constraintlayout.core.state.State.Chain! getStyle();
-    method protected float getWeight(String!);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! style(androidx.constraintlayout.core.state.State.Chain!);
+    method protected float getPostGoneMargin(String);
+    method protected float getPostMargin(String);
+    method protected float getPreGoneMargin(String);
+    method protected float getPreMargin(String);
+    method public androidx.constraintlayout.core.state.State.Chain getStyle();
+    method protected float getWeight(String);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference style(androidx.constraintlayout.core.state.State.Chain);
     field protected float mBias;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPostMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPreMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapWeights;
-    field protected androidx.constraintlayout.core.state.State.Chain! mStyle;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPostMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPreMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapWeights;
+    field protected androidx.constraintlayout.core.state.State.Chain mStyle;
   }
 
   public interface Facade {
diff --git a/constraintlayout/constraintlayout-core/api/public_plus_experimental_current.txt b/constraintlayout/constraintlayout-core/api/public_plus_experimental_current.txt
index ff1bb30..30a9d6c 100644
--- a/constraintlayout/constraintlayout-core/api/public_plus_experimental_current.txt
+++ b/constraintlayout/constraintlayout-core/api/public_plus_experimental_current.txt
@@ -2477,20 +2477,22 @@
   }
 
   public class ChainReference extends androidx.constraintlayout.core.state.HelperReference {
-    ctor public ChainReference(androidx.constraintlayout.core.state.State!, androidx.constraintlayout.core.state.State.Helper!);
-    method public void addChainElement(String!, float, float, float);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! bias(float);
+    ctor public ChainReference(androidx.constraintlayout.core.state.State, androidx.constraintlayout.core.state.State.Helper);
+    method public void addChainElement(String, float, float, float);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference bias(float);
     method public float getBias();
-    method protected float getPostMargin(String!);
-    method protected float getPreMargin(String!);
-    method public androidx.constraintlayout.core.state.State.Chain! getStyle();
-    method protected float getWeight(String!);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! style(androidx.constraintlayout.core.state.State.Chain!);
+    method protected float getPostGoneMargin(String);
+    method protected float getPostMargin(String);
+    method protected float getPreGoneMargin(String);
+    method protected float getPreMargin(String);
+    method public androidx.constraintlayout.core.state.State.Chain getStyle();
+    method protected float getWeight(String);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference style(androidx.constraintlayout.core.state.State.Chain);
     field protected float mBias;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPostMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPreMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapWeights;
-    field protected androidx.constraintlayout.core.state.State.Chain! mStyle;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPostMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPreMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapWeights;
+    field protected androidx.constraintlayout.core.state.State.Chain mStyle;
   }
 
   public interface Facade {
diff --git a/constraintlayout/constraintlayout-core/api/restricted_current.txt b/constraintlayout/constraintlayout-core/api/restricted_current.txt
index ff1bb30..161a4ec 100644
--- a/constraintlayout/constraintlayout-core/api/restricted_current.txt
+++ b/constraintlayout/constraintlayout-core/api/restricted_current.txt
@@ -2477,20 +2477,23 @@
   }
 
   public class ChainReference extends androidx.constraintlayout.core.state.HelperReference {
-    ctor public ChainReference(androidx.constraintlayout.core.state.State!, androidx.constraintlayout.core.state.State.Helper!);
-    method public void addChainElement(String!, float, float, float);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! bias(float);
+    ctor public ChainReference(androidx.constraintlayout.core.state.State, androidx.constraintlayout.core.state.State.Helper);
+    method public void addChainElement(String, float, float, float);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public void addChainElement(Object, float, float, float, float, float);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference bias(float);
     method public float getBias();
-    method protected float getPostMargin(String!);
-    method protected float getPreMargin(String!);
-    method public androidx.constraintlayout.core.state.State.Chain! getStyle();
-    method protected float getWeight(String!);
-    method public androidx.constraintlayout.core.state.helpers.ChainReference! style(androidx.constraintlayout.core.state.State.Chain!);
+    method protected float getPostGoneMargin(String);
+    method protected float getPostMargin(String);
+    method protected float getPreGoneMargin(String);
+    method protected float getPreMargin(String);
+    method public androidx.constraintlayout.core.state.State.Chain getStyle();
+    method protected float getWeight(String);
+    method public androidx.constraintlayout.core.state.helpers.ChainReference style(androidx.constraintlayout.core.state.State.Chain);
     field protected float mBias;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPostMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapPreMargin;
-    field protected java.util.HashMap<java.lang.String!,java.lang.Float!>! mMapWeights;
-    field protected androidx.constraintlayout.core.state.State.Chain! mStyle;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPostMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapPreMargin;
+    field @Deprecated protected java.util.HashMap<java.lang.String!,java.lang.Float!> mMapWeights;
+    field protected androidx.constraintlayout.core.state.State.Chain mStyle;
   }
 
   public interface Facade {
diff --git a/constraintlayout/constraintlayout-core/build.gradle b/constraintlayout/constraintlayout-core/build.gradle
index 40b4820..329d954 100644
--- a/constraintlayout/constraintlayout-core/build.gradle
+++ b/constraintlayout/constraintlayout-core/build.gradle
@@ -23,6 +23,7 @@
 }
 
 dependencies {
+    api("androidx.annotation:annotation:1.5.0")
     testImplementation(libs.junit)
 }
 
diff --git a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java
index edf122b..a6af993 100644
--- a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java
+++ b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/ConstraintSetParser.java
@@ -811,6 +811,7 @@
                                         postMargin = toPix(state, array.getFloat(3));
                                         break;
                                 }
+                                // TODO: Define how to set gone margin in JSON syntax
                                 chain.addChainElement(id, weight, preMargin, postMargin);
                             }
                         } else {
diff --git a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java
index 4229892..5a22613 100644
--- a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java
+++ b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/ChainReference.java
@@ -18,85 +18,181 @@
 
 import static androidx.constraintlayout.core.widgets.ConstraintWidget.UNKNOWN;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
 import androidx.constraintlayout.core.state.HelperReference;
 import androidx.constraintlayout.core.state.State;
 
 import java.util.HashMap;
 
+/**
+ * {@link HelperReference} for Chains.
+ *
+ * Elements should be added with {@link ChainReference#addChainElement}
+ */
 public class ChainReference extends HelperReference {
 
     protected float mBias = 0.5f;
-    protected HashMap<String ,Float> mMapWeights;
-    protected HashMap<String,Float> mMapPreMargin;
-    protected HashMap<String,Float> mMapPostMargin;
 
-    protected State.Chain mStyle = State.Chain.SPREAD;
+    /**
+     * @deprecated Unintended visibility, use {@link #getWeight(String)} instead
+     */
+    @Deprecated // TODO(b/253515185): Change to private visibility once we change major version
+    protected @NonNull HashMap<String, Float> mMapWeights = new HashMap<>();
 
-    public ChainReference(State state, State.Helper type) {
+    /**
+     * @deprecated Unintended visibility, use {@link #getPreMargin(String)} instead
+     */
+    @Deprecated // TODO(b/253515185): Change to private visibility once we change major version
+    protected @NonNull HashMap<String, Float> mMapPreMargin = new HashMap<>();
+
+    /**
+     * @deprecated Unintended visibility, use {@link #getPostMargin(String)} instead
+     */
+    @Deprecated // TODO(b/253515185): Change to private visibility once we change major version
+    protected @NonNull HashMap<String, Float> mMapPostMargin = new HashMap<>();
+
+    private HashMap<String, Float> mMapPreGoneMargin;
+    private HashMap<String, Float> mMapPostGoneMargin;
+
+    protected @NonNull State.Chain mStyle = State.Chain.SPREAD;
+
+    public ChainReference(@NonNull State state, @NonNull State.Helper type) {
         super(state, type);
     }
 
-    public State.Chain getStyle() {
+    public @NonNull State.Chain getStyle() {
         return State.Chain.SPREAD;
     }
 
-    // @TODO: add description
-    public ChainReference style(State.Chain style) {
+    /**
+     * Sets the {@link State.Chain style}.
+     *
+     * @param style Defines the way the chain will lay out its elements
+     * @return This same instance
+     */
+    @NonNull
+    public ChainReference style(@NonNull State.Chain style) {
         mStyle = style;
         return this;
     }
 
-    public void addChainElement(String id, float weight, float preMargin, float  postMargin ) {
-        super.add(id);
+    /**
+     * Adds the element by the given id to the Chain.
+     *
+     * The order in which the elements are added is important. It will represent the element's
+     * position in the Chain.
+     *
+     * @param id         Id of the element to add
+     * @param weight     Weight used to distribute remaining space to each element
+     * @param preMargin  Additional space in pixels between the added element and the previous one
+     *                   (if any)
+     * @param postMargin Additional space in pixels between the added element and the next one (if
+     *                   any)
+     */
+    public void addChainElement(@NonNull String id,
+            float weight,
+            float preMargin,
+            float postMargin) {
+        addChainElement(id, weight, preMargin, postMargin, 0, 0);
+    }
+
+    /**
+     * Adds the element by the given id to the Chain.
+     *
+     * The object's {@link Object#toString()} result will be used to map the given margins and
+     * weight to it, so it must stable and comparable.
+     *
+     * The order in which the elements are added is important. It will represent the element's
+     * position in the Chain.
+     *
+     * @param id             Id of the element to add
+     * @param weight         Weight used to distribute remaining space to each element
+     * @param preMargin      Additional space in pixels between the added element and the
+     *                       previous one
+     *                       (if any)
+     * @param postMargin     Additional space in pixels between the added element and the next
+     *                       one (if
+     *                       any)
+     * @param preGoneMargin  Additional space in pixels between the added element and the previous
+     *                       one (if any) when the previous element has Gone visibility
+     * @param postGoneMargin Additional space in pixels between the added element and the next
+     *                       one (if any) when the next element has Gone visibility
+     * @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public void addChainElement(@NonNull Object id,
+            float weight,
+            float preMargin,
+            float postMargin,
+            float preGoneMargin,
+            float postGoneMargin) {
+        super.add(id); // Add element id as is, it's expected to return the same given instance
+        String idString = id.toString();
         if (!Float.isNaN(weight)) {
-            if (mMapWeights == null) {
-                mMapWeights = new HashMap<>();
-            }
-            mMapWeights.put(id, weight);
+            mMapWeights.put(idString, weight);
         }
         if (!Float.isNaN(preMargin)) {
-            if (mMapPreMargin == null) {
-                mMapPreMargin = new HashMap<>();
-            }
-            mMapPreMargin.put(id, preMargin);
+            mMapPreMargin.put(idString, preMargin);
         }
         if (!Float.isNaN(postMargin)) {
-            if (mMapPostMargin == null) {
-                mMapPostMargin = new HashMap<>();
+            mMapPostMargin.put(idString, postMargin);
+        }
+        if (!Float.isNaN(preGoneMargin)) {
+            if (mMapPreGoneMargin == null) {
+                mMapPreGoneMargin = new HashMap<>();
             }
-            mMapPostMargin.put(id, postMargin);
+            mMapPreGoneMargin.put(idString, preGoneMargin);
+        }
+        if (!Float.isNaN(postGoneMargin)) {
+            if (mMapPostGoneMargin == null) {
+                mMapPostGoneMargin = new HashMap<>();
+            }
+            mMapPostGoneMargin.put(idString, postGoneMargin);
         }
     }
 
-  protected float getWeight(String id) {
-       if (mMapWeights == null) {
-           return UNKNOWN;
-       }
-       if (mMapWeights.containsKey(id)) {
-           return mMapWeights.get(id);
-       }
-       return UNKNOWN;
+    protected float getWeight(@NonNull String id) {
+        if (mMapWeights.containsKey(id)) {
+            return mMapWeights.get(id);
+        }
+        return UNKNOWN;
     }
 
-    protected float getPostMargin(String id) {
-        if (mMapPostMargin != null  && mMapPostMargin.containsKey(id)) {
+    protected float getPostMargin(@NonNull String id) {
+        if (mMapPostMargin.containsKey(id)) {
             return mMapPostMargin.get(id);
         }
         return 0;
     }
 
-    protected float getPreMargin(String id) {
-        if (mMapPreMargin != null  && mMapPreMargin.containsKey(id)) {
+    protected float getPreMargin(@NonNull String id) {
+        if (mMapPreMargin.containsKey(id)) {
             return mMapPreMargin.get(id);
         }
         return 0;
     }
 
+    protected float getPostGoneMargin(@NonNull String id) {
+        if (mMapPostGoneMargin != null && mMapPostGoneMargin.containsKey(id)) {
+            return mMapPostGoneMargin.get(id);
+        }
+        return 0;
+    }
+
+    protected float getPreGoneMargin(@NonNull String id) {
+        if (mMapPreGoneMargin != null && mMapPreGoneMargin.containsKey(id)) {
+            return mMapPreGoneMargin.get(id);
+        }
+        return 0;
+    }
+
     public float getBias() {
         return mBias;
     }
 
     // @TODO: add description
+    @NonNull
     @Override
     public ChainReference bias(float bias) {
         mBias = bias;
diff --git a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/HorizontalChainReference.java b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/HorizontalChainReference.java
index be09236..32539da 100644
--- a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/HorizontalChainReference.java
+++ b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/HorizontalChainReference.java
@@ -58,14 +58,17 @@
                 } else {
                     // No constraint declared, default to Parent.
                     String refKey = reference.getKey().toString();
-                    first.startToStart(State.PARENT).margin(getPreMargin(refKey));
+                    first.startToStart(State.PARENT).margin(getPreMargin(refKey)).marginGone(
+                            getPreGoneMargin(refKey));
                 }
             }
             if (previous != null) {
                 String preKey = previous.getKey().toString();
                 String refKey = reference.getKey().toString();
-                previous.endToStart(reference.getKey()).margin(getPostMargin(preKey));
-                reference.startToEnd(previous.getKey()).margin(getPreMargin(refKey));
+                previous.endToStart(reference.getKey()).margin(getPostMargin(preKey)).marginGone(
+                        getPostGoneMargin(preKey));
+                reference.startToEnd(previous.getKey()).margin(getPreMargin(refKey)).marginGone(
+                        getPreGoneMargin(refKey));
             }
             float weight = getWeight(key.toString());
             if (weight != UNKNOWN) {
@@ -88,7 +91,8 @@
             } else {
                 // No constraint declared, default to Parent.
                 String preKey = previous.getKey().toString();
-                previous.endToEnd(State.PARENT).margin(getPostMargin(preKey));
+                previous.endToEnd(State.PARENT).margin(getPostMargin(preKey)).marginGone(
+                        getPostGoneMargin(preKey));
             }
         }
 
diff --git a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/VerticalChainReference.java b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/VerticalChainReference.java
index d4fdd23..8d880b1 100644
--- a/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/VerticalChainReference.java
+++ b/constraintlayout/constraintlayout-core/src/main/java/androidx/constraintlayout/core/state/helpers/VerticalChainReference.java
@@ -49,14 +49,17 @@
                 } else {
                     // No constraint declared, default to Parent.
                     String refKey = reference.getKey().toString();
-                    first.topToTop(State.PARENT).margin(getPreMargin(refKey));
+                    first.topToTop(State.PARENT).margin(getPreMargin(refKey)).marginGone(
+                            getPreGoneMargin(refKey));
                 }
             }
             if (previous != null) {
                 String preKey = previous.getKey().toString();
                 String refKey = reference.getKey().toString();
-                previous.bottomToTop(reference.getKey()).margin(getPostMargin(preKey));
-                reference.topToBottom(previous.getKey()).margin(getPreMargin(refKey));
+                previous.bottomToTop(reference.getKey()).margin(getPostMargin(preKey)).marginGone(
+                        getPostGoneMargin(preKey));
+                reference.topToBottom(previous.getKey()).margin(getPreMargin(refKey)).marginGone(
+                        getPreGoneMargin(refKey));
             }
             float weight = getWeight(key.toString());
             if (weight != UNKNOWN) {
@@ -77,7 +80,8 @@
             } else {
                 // No constraint declared, default to Parent.
                 String preKey = previous.getKey().toString();
-                previous.bottomToBottom(State.PARENT).margin(getPostMargin(preKey));
+                previous.bottomToBottom(State.PARENT).margin(getPostMargin(preKey)).marginGone(
+                        getPostGoneMargin(preKey));
             }
         }
 
diff --git a/credentials/credentials/api/current.txt b/credentials/credentials/api/current.txt
index 3544ddf9..b14a46d 100644
--- a/credentials/credentials/api/current.txt
+++ b/credentials/credentials/api/current.txt
@@ -1,12 +1,22 @@
 // Signature format: 4.0
 package androidx.credentials {
 
-  public abstract class CreateCredentialRequest {
-    ctor public CreateCredentialRequest();
+  public class CreateCredentialRequest {
+    ctor public CreateCredentialRequest(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
-  public abstract class CreateCredentialResponse {
-    ctor public CreateCredentialResponse();
+  public class CreateCredentialResponse {
+    ctor public CreateCredentialResponse(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CreatePasswordRequest extends androidx.credentials.CreateCredentialRequest {
@@ -21,8 +31,12 @@
     ctor public CreatePasswordResponse();
   }
 
-  public abstract class Credential {
-    ctor public Credential();
+  public class Credential {
+    ctor public Credential(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CredentialManager {
@@ -51,8 +65,14 @@
     property public final CharSequence? errorMessage;
   }
 
-  public abstract class GetCredentialOption {
-    ctor public GetCredentialOption();
+  public class GetCredentialOption {
+    ctor public GetCredentialOption(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
   public final class GetCredentialRequest {
diff --git a/credentials/credentials/api/public_plus_experimental_current.txt b/credentials/credentials/api/public_plus_experimental_current.txt
index 3544ddf9..b14a46d 100644
--- a/credentials/credentials/api/public_plus_experimental_current.txt
+++ b/credentials/credentials/api/public_plus_experimental_current.txt
@@ -1,12 +1,22 @@
 // Signature format: 4.0
 package androidx.credentials {
 
-  public abstract class CreateCredentialRequest {
-    ctor public CreateCredentialRequest();
+  public class CreateCredentialRequest {
+    ctor public CreateCredentialRequest(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
-  public abstract class CreateCredentialResponse {
-    ctor public CreateCredentialResponse();
+  public class CreateCredentialResponse {
+    ctor public CreateCredentialResponse(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CreatePasswordRequest extends androidx.credentials.CreateCredentialRequest {
@@ -21,8 +31,12 @@
     ctor public CreatePasswordResponse();
   }
 
-  public abstract class Credential {
-    ctor public Credential();
+  public class Credential {
+    ctor public Credential(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CredentialManager {
@@ -51,8 +65,14 @@
     property public final CharSequence? errorMessage;
   }
 
-  public abstract class GetCredentialOption {
-    ctor public GetCredentialOption();
+  public class GetCredentialOption {
+    ctor public GetCredentialOption(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
   public final class GetCredentialRequest {
diff --git a/credentials/credentials/api/restricted_current.txt b/credentials/credentials/api/restricted_current.txt
index 3544ddf9..b14a46d 100644
--- a/credentials/credentials/api/restricted_current.txt
+++ b/credentials/credentials/api/restricted_current.txt
@@ -1,12 +1,22 @@
 // Signature format: 4.0
 package androidx.credentials {
 
-  public abstract class CreateCredentialRequest {
-    ctor public CreateCredentialRequest();
+  public class CreateCredentialRequest {
+    ctor public CreateCredentialRequest(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
-  public abstract class CreateCredentialResponse {
-    ctor public CreateCredentialResponse();
+  public class CreateCredentialResponse {
+    ctor public CreateCredentialResponse(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CreatePasswordRequest extends androidx.credentials.CreateCredentialRequest {
@@ -21,8 +31,12 @@
     ctor public CreatePasswordResponse();
   }
 
-  public abstract class Credential {
-    ctor public Credential();
+  public class Credential {
+    ctor public Credential(String type, android.os.Bundle data);
+    method public final android.os.Bundle getData();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final String type;
   }
 
   public final class CredentialManager {
@@ -51,8 +65,14 @@
     property public final CharSequence? errorMessage;
   }
 
-  public abstract class GetCredentialOption {
-    ctor public GetCredentialOption();
+  public class GetCredentialOption {
+    ctor public GetCredentialOption(String type, android.os.Bundle data, boolean requireSystemProvider);
+    method public final android.os.Bundle getData();
+    method public final boolean getRequireSystemProvider();
+    method public final String getType();
+    property public final android.os.Bundle data;
+    property public final boolean requireSystemProvider;
+    property public final String type;
   }
 
   public final class GetCredentialRequest {
diff --git a/credentials/credentials/build.gradle b/credentials/credentials/build.gradle
index 29d733e..6bb5a52 100644
--- a/credentials/credentials/build.gradle
+++ b/credentials/credentials/build.gradle
@@ -24,6 +24,7 @@
 }
 
 dependencies {
+    api("androidx.annotation:annotation:1.5.0")
     api(libs.kotlinStdlib)
     implementation(libs.kotlinCoroutinesCore)
 
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java
new file mode 100644
index 0000000..953bd5a
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestJavaTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.credentials;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class CreatePasswordRequestJavaTest {
+    @Test
+    public void constructor_nullId_throws() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new CreatePasswordRequest(null, "pwd")
+        );
+    }
+
+    @Test
+    public void constructor_nullPassword_throws() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new CreatePasswordRequest("id", null)
+        );
+    }
+
+    @Test
+    public void constructor_emptyPassword_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> new CreatePasswordRequest("id", "")
+        );
+    }
+
+    @Test
+    public void getter_id() {
+        String idExpected = "id";
+        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, "password");
+        assertThat(request.getId()).isEqualTo(idExpected);
+    }
+
+    @Test
+    public void getter_password() {
+        String passwordExpected = "pwd";
+        CreatePasswordRequest request = new CreatePasswordRequest("id", passwordExpected);
+        assertThat(request.getPassword()).isEqualTo(passwordExpected);
+    }
+
+    @Test
+    public void getter_frameworkProperties() {
+        String idExpected = "id";
+        String passwordExpected = "pwd";
+        Bundle expectedData = new Bundle();
+        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_ID, idExpected);
+        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_PASSWORD, passwordExpected);
+
+        CreatePasswordRequest request = new CreatePasswordRequest(idExpected, passwordExpected);
+
+        assertThat(request.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(request.getData(), expectedData)).isTrue();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt
new file mode 100644
index 0000000..9943eed
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordRequestTest.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.credentials
+
+import android.os.Bundle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.testutils.assertThrows
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class CreatePasswordRequestTest {
+    @Test
+    fun constructor_emptyPassword_throws() {
+        assertThrows<IllegalArgumentException> {
+            CreatePasswordRequest("id", "")
+        }
+    }
+
+    @Test
+    fun getter_id() {
+        val idExpected = "id"
+        val request = CreatePasswordRequest(idExpected, "password")
+        assertThat(request.id).isEqualTo(idExpected)
+    }
+
+    @Test
+    fun getter_password() {
+        val passwordExpected = "pwd"
+        val request = CreatePasswordRequest("id", passwordExpected)
+        assertThat(request.password).isEqualTo(passwordExpected)
+    }
+
+    @Test
+    fun getter_frameworkProperties() {
+        val idExpected = "id"
+        val passwordExpected = "pwd"
+        val expectedData = Bundle()
+        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_ID, idExpected)
+        expectedData.putString(CreatePasswordRequest.BUNDLE_KEY_PASSWORD, passwordExpected)
+
+        val request = CreatePasswordRequest(idExpected, passwordExpected)
+
+        assertThat(request.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        assertThat(equals(request.data, expectedData)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java
new file mode 100644
index 0000000..5f75653
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseJavaTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.credentials;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class CreatePasswordResponseJavaTest {
+    @Test
+    public void getter_frameworkProperties() {
+        CreatePasswordResponse response = new CreatePasswordResponse();
+
+        assertThat(response.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(response.getData(), Bundle.EMPTY)).isTrue();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt
new file mode 100644
index 0000000..84e4102
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePasswordResponseTest.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.credentials
+
+import android.os.Bundle
+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
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class CreatePasswordResponseTest {
+    @Test
+    fun getter_frameworkProperties() {
+        val response = CreatePasswordResponse()
+        Truth.assertThat(response.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        Truth.assertThat(equals(response.data, Bundle.EMPTY)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
index db1a2a9..2604d86 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestJavaTest.java
@@ -16,10 +16,15 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.CreatePublicKeyCredentialBaseRequest.BUNDLE_KEY_REQUEST_JSON;
+import static androidx.credentials.CreatePublicKeyCredentialRequest.BUNDLE_KEY_ALLOW_HYBRID;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
+import android.os.Bundle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -80,4 +85,22 @@
         String testJsonActual = createPublicKeyCredentialReq.getRequestJson();
         assertThat(testJsonActual).isEqualTo(testJsonExpected);
     }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+        boolean allowHybridExpected = false;
+        Bundle expectedData = new Bundle();
+        expectedData.putString(
+                BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
+        expectedData.putBoolean(
+                BUNDLE_KEY_ALLOW_HYBRID, allowHybridExpected);
+
+        CreatePublicKeyCredentialRequest request =
+                new CreatePublicKeyCredentialRequest(requestJsonExpected, allowHybridExpected);
+
+        assertThat(request.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(request.getData(), expectedData)).isTrue();
+        assertThat(request.getRequireSystemProvider()).isFalse();
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedJavaTest.java
index 82adc07..8558cbb 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedJavaTest.java
@@ -16,8 +16,15 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.CreatePublicKeyCredentialBaseRequest.BUNDLE_KEY_REQUEST_JSON;
+import static androidx.credentials.CreatePublicKeyCredentialRequest.BUNDLE_KEY_ALLOW_HYBRID;
+import static androidx.credentials.CreatePublicKeyCredentialRequestPrivileged.BUNDLE_KEY_CLIENT_DATA_HASH;
+import static androidx.credentials.CreatePublicKeyCredentialRequestPrivileged.BUNDLE_KEY_RP;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import android.os.Bundle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -107,4 +114,26 @@
                 createPublicKeyCredentialRequestPrivileged.getClientDataHash();
         assertThat(clientDataHashActual).isEqualTo(clientDataHashExpected);
     }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+        String rpExpected = "RP";
+        String clientDataHashExpected = "X342%4dfd7&";
+        boolean allowHybridExpected = false;
+        Bundle expectedData = new Bundle();
+        expectedData.putString(BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
+        expectedData.putString(BUNDLE_KEY_RP, rpExpected);
+        expectedData.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHashExpected);
+        expectedData.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybridExpected);
+
+        CreatePublicKeyCredentialRequestPrivileged request =
+                new CreatePublicKeyCredentialRequestPrivileged(
+                        requestJsonExpected, rpExpected, clientDataHashExpected,
+                        allowHybridExpected);
+
+        assertThat(request.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(request.getData(), expectedData)).isTrue();
+        assertThat(request.getRequireSystemProvider()).isFalse();
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedTest.kt
index faffbcb..e485003 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivilegedTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -110,4 +111,37 @@
         val clientDataHashActual = createPublicKeyCredentialRequestPrivileged.clientDataHash
         assertThat(clientDataHashActual).isEqualTo(clientDataHashExpected)
     }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val rpExpected = "RP"
+        val clientDataHashExpected = "X342%4dfd7&"
+        val allowHybridExpected = false
+        val expectedData = Bundle()
+        expectedData.putString(
+            CreatePublicKeyCredentialBaseRequest.BUNDLE_KEY_REQUEST_JSON,
+            requestJsonExpected
+        )
+        expectedData.putString(CreatePublicKeyCredentialRequestPrivileged.BUNDLE_KEY_RP, rpExpected)
+        expectedData.putString(
+            CreatePublicKeyCredentialRequestPrivileged.BUNDLE_KEY_CLIENT_DATA_HASH,
+            clientDataHashExpected
+        )
+        expectedData.putBoolean(
+            CreatePublicKeyCredentialRequest.BUNDLE_KEY_ALLOW_HYBRID,
+            allowHybridExpected
+        )
+
+        val request = CreatePublicKeyCredentialRequestPrivileged(
+            requestJsonExpected,
+            rpExpected,
+            clientDataHashExpected,
+            allowHybridExpected
+        )
+
+        assertThat(request.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(request.data, expectedData)).isTrue()
+        assertThat(request.requireSystemProvider).isFalse()
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
index 4058526..32d4365 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialRequestTest.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.credentials.CreatePublicKeyCredentialBaseRequest.Companion.BUNDLE_KEY_REQUEST_JSON
+import androidx.credentials.CreatePublicKeyCredentialRequest.Companion.BUNDLE_KEY_ALLOW_HYBRID
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -69,4 +72,26 @@
         val testJsonActual = createPublicKeyCredentialReq.requestJson
         assertThat(testJsonActual).isEqualTo(testJsonExpected)
     }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val allowHybridExpected = false
+        val expectedData = Bundle()
+        expectedData.putString(
+            BUNDLE_KEY_REQUEST_JSON, requestJsonExpected
+        )
+        expectedData.putBoolean(
+            BUNDLE_KEY_ALLOW_HYBRID, allowHybridExpected
+        )
+
+        val request = CreatePublicKeyCredentialRequest(
+            requestJsonExpected,
+            allowHybridExpected
+        )
+
+        assertThat(request.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(request.data, expectedData)).isTrue()
+        assertThat(request.requireSystemProvider).isFalse()
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
index dc7bdb26..099f367 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseJavaTest.java
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertThrows;
 
+import android.os.Bundle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -59,4 +61,19 @@
         String testJsonActual = createPublicKeyCredentialResponse.getRegistrationResponseJson();
         assertThat(testJsonActual).isEqualTo(testJsonExpected);
     }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        String registrationResponseJsonExpected = "{\"input\":5}";
+        Bundle expectedData = new Bundle();
+        expectedData.putString(
+                CreatePublicKeyCredentialResponse.BUNDLE_KEY_REGISTRATION_RESPONSE_JSON,
+                registrationResponseJsonExpected);
+
+        CreatePublicKeyCredentialResponse response =
+                new CreatePublicKeyCredentialResponse(registrationResponseJsonExpected);
+
+        assertThat(response.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(response.getData(), expectedData)).isTrue();
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
index 9311d59..e2179b9 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/CreatePublicKeyCredentialResponseTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -47,4 +48,19 @@
         val testJsonActual = createPublicKeyCredentialResponse.registrationResponseJson
         assertThat(testJsonActual).isEqualTo(testJsonExpected)
     }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        val registrationResponseJsonExpected = "{\"input\":5}"
+        val expectedData = Bundle()
+        expectedData.putString(
+            CreatePublicKeyCredentialResponse.BUNDLE_KEY_REGISTRATION_RESPONSE_JSON,
+            registrationResponseJsonExpected
+        )
+
+        val response = CreatePublicKeyCredentialResponse(registrationResponseJsonExpected)
+
+        assertThat(response.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(response.data, expectedData)).isTrue()
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java
new file mode 100644
index 0000000..d8050da
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionJavaTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.credentials;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class GetPasswordOptionJavaTest {
+    @Test
+    public void getter_frameworkProperties() {
+        GetPasswordOption option = new GetPasswordOption();
+
+        assertThat(option.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(option.getData(), Bundle.EMPTY)).isTrue();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt
new file mode 100644
index 0000000..2c155af
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPasswordOptionTest.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.credentials
+
+import android.os.Bundle
+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
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class GetPasswordOptionTest {
+    @Test
+    fun getter_frameworkProperties() {
+        val option = GetPasswordOption()
+        Truth.assertThat(option.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        Truth.assertThat(equals(option.data, Bundle.EMPTY)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
index ec3083c..7575d2a 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionJavaTest.java
@@ -16,10 +16,15 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.GetPublicKeyCredentialBaseOption.BUNDLE_KEY_REQUEST_JSON;
+import static androidx.credentials.GetPublicKeyCredentialOption.BUNDLE_KEY_ALLOW_HYBRID;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
 
+import android.os.Bundle;
+
 import org.junit.Test;
 
 public class GetPublicKeyCredentialOptionJavaTest {
@@ -73,4 +78,20 @@
         String testJsonActual = getPublicKeyCredentialOpt.getRequestJson();
         assertThat(testJsonActual).isEqualTo(testJsonExpected);
     }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+        boolean allowHybridExpected = false;
+        Bundle expectedData = new Bundle();
+        expectedData.putString(BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
+        expectedData.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybridExpected);
+
+        GetPublicKeyCredentialOption option =
+                new GetPublicKeyCredentialOption(requestJsonExpected, allowHybridExpected);
+
+        assertThat(option.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(option.getData(), expectedData)).isTrue();
+        assertThat(option.getRequireSystemProvider()).isFalse();
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedJavaTest.java
index 2b18b0d..54efd71 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedJavaTest.java
@@ -16,8 +16,15 @@
 
 package androidx.credentials;
 
+import static androidx.credentials.GetPublicKeyCredentialBaseOption.BUNDLE_KEY_REQUEST_JSON;
+import static androidx.credentials.GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_ALLOW_HYBRID;
+import static androidx.credentials.GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_CLIENT_DATA_HASH;
+import static androidx.credentials.GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_RP;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import android.os.Bundle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -106,4 +113,26 @@
         String clientDataHashActual = getPublicKeyCredentialOptionPrivileged.getClientDataHash();
         assertThat(clientDataHashActual).isEqualTo(clientDataHashExpected);
     }
+
+    @Test
+    public void getter_frameworkProperties_success() {
+        String requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+        String rpExpected = "RP";
+        String clientDataHashExpected = "X342%4dfd7&";
+        boolean allowHybridExpected = false;
+        Bundle expectedData = new Bundle();
+        expectedData.putString(BUNDLE_KEY_REQUEST_JSON, requestJsonExpected);
+        expectedData.putString(BUNDLE_KEY_RP, rpExpected);
+        expectedData.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHashExpected);
+        expectedData.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybridExpected);
+
+        GetPublicKeyCredentialOptionPrivileged option =
+                new GetPublicKeyCredentialOptionPrivileged(
+                        requestJsonExpected, rpExpected, clientDataHashExpected,
+                        allowHybridExpected);
+
+        assertThat(option.getType()).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(option.getData(), expectedData)).isTrue();
+        assertThat(option.getRequireSystemProvider()).isFalse();
+    }
 }
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedTest.kt
index 024070d..e1c1079 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionPrivilegedTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -107,4 +108,35 @@
         val clientDataHashActual = getPublicKeyCredentialOptionPrivileged.clientDataHash
         assertThat(clientDataHashActual).isEqualTo(clientDataHashExpected)
     }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val rpExpected = "RP"
+        val clientDataHashExpected = "X342%4dfd7&"
+        val allowHybridExpected = false
+        val expectedData = Bundle()
+        expectedData.putString(
+            GetPublicKeyCredentialBaseOption.BUNDLE_KEY_REQUEST_JSON,
+            requestJsonExpected
+        )
+        expectedData.putString(GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_RP, rpExpected)
+        expectedData.putString(
+            GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_CLIENT_DATA_HASH,
+            clientDataHashExpected
+        )
+        expectedData.putBoolean(
+            GetPublicKeyCredentialOptionPrivileged.BUNDLE_KEY_ALLOW_HYBRID,
+            allowHybridExpected
+        )
+
+        val option = GetPublicKeyCredentialOptionPrivileged(
+            requestJsonExpected, rpExpected, clientDataHashExpected,
+            allowHybridExpected
+        )
+
+        assertThat(option.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(option.data, expectedData)).isTrue()
+        assertThat(option.requireSystemProvider).isFalse()
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
index 7cc8392..821b580 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/GetPublicKeyCredentialOptionTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -68,4 +69,25 @@
         val testJsonActual = createPublicKeyCredentialReq.requestJson
         assertThat(testJsonActual).isEqualTo(testJsonExpected)
     }
+
+    @Test
+    fun getter_frameworkProperties_success() {
+        val requestJsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val allowHybridExpected = false
+        val expectedData = Bundle()
+        expectedData.putString(
+            GetPublicKeyCredentialBaseOption.BUNDLE_KEY_REQUEST_JSON,
+            requestJsonExpected
+        )
+        expectedData.putBoolean(
+            GetPublicKeyCredentialOption.BUNDLE_KEY_ALLOW_HYBRID,
+            allowHybridExpected
+        )
+
+        val option = GetPublicKeyCredentialOption(requestJsonExpected, allowHybridExpected)
+
+        assertThat(option.type).isEqualTo(PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL)
+        assertThat(equals(option.data, expectedData)).isTrue()
+        assertThat(option.requireSystemProvider).isFalse()
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java
new file mode 100644
index 0000000..c41d985
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialJavaTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.credentials;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PasswordCredentialJavaTest {
+    @Test
+    public void constructor_nullId_throws() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new PasswordCredential(null, "pwd")
+        );
+    }
+
+    @Test
+    public void constructor_nullPassword_throws() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new PasswordCredential("id", null)
+        );
+    }
+
+    @Test
+    public void constructor_emptyPassword_throws() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> new PasswordCredential("id", "")
+        );
+    }
+
+    @Test
+    public void getter_id() {
+        String idExpected = "id";
+        PasswordCredential credential = new PasswordCredential(idExpected, "password");
+        assertThat(credential.getId()).isEqualTo(idExpected);
+    }
+
+    @Test
+    public void getter_password() {
+        String passwordExpected = "pwd";
+        PasswordCredential credential = new PasswordCredential("id", passwordExpected);
+        assertThat(credential.getPassword()).isEqualTo(passwordExpected);
+    }
+
+    @Test
+    public void getter_frameworkProperties() {
+        String idExpected = "id";
+        String passwordExpected = "pwd";
+        Bundle expectedData = new Bundle();
+        expectedData.putString(PasswordCredential.BUNDLE_KEY_ID, idExpected);
+        expectedData.putString(PasswordCredential.BUNDLE_KEY_PASSWORD, passwordExpected);
+
+        CreatePasswordRequest credential = new CreatePasswordRequest(idExpected, passwordExpected);
+
+        assertThat(credential.getType()).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(credential.getData(), expectedData)).isTrue();
+    }
+}
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt
new file mode 100644
index 0000000..c8f425c
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PasswordCredentialTest.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.credentials
+
+import android.os.Bundle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.testutils.assertThrows
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class PasswordCredentialTest {
+    @Test
+    fun constructor_emptyPassword_throws() {
+        assertThrows<IllegalArgumentException> {
+            PasswordCredential("id", "")
+        }
+    }
+
+    @Test
+    fun getter_id() {
+        val idExpected = "id"
+        val credential = PasswordCredential(idExpected, "password")
+        assertThat(credential.id).isEqualTo(idExpected)
+    }
+
+    @Test
+    fun getter_password() {
+        val passwordExpected = "pwd"
+        val credential = PasswordCredential("id", passwordExpected)
+        assertThat(credential.password).isEqualTo(passwordExpected)
+    }
+
+    @Test
+    fun getter_frameworkProperties() {
+        val idExpected = "id"
+        val passwordExpected = "pwd"
+        val expectedData = Bundle()
+        expectedData.putString(PasswordCredential.BUNDLE_KEY_ID, idExpected)
+        expectedData.putString(PasswordCredential.BUNDLE_KEY_PASSWORD, passwordExpected)
+
+        val credential = PasswordCredential(idExpected, passwordExpected)
+
+        assertThat(credential.type).isEqualTo(PasswordCredential.TYPE_PASSWORD_CREDENTIAL)
+        assertThat(equals(credential.data, expectedData)).isTrue()
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
index 86847fa..04223aa 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialJavaTest.java
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertThrows;
 
+import android.os.Bundle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -64,6 +66,20 @@
     }
 
     @Test
+    public void getter_frameworkProperties() {
+        String jsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}";
+        Bundle expectedData = new Bundle();
+        expectedData.putString(
+                PublicKeyCredential.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, jsonExpected);
+
+        PublicKeyCredential publicKeyCredential = new PublicKeyCredential(jsonExpected);
+
+        assertThat(publicKeyCredential.getType()).isEqualTo(
+                PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL);
+        assertThat(TestUtilsKt.equals(publicKeyCredential.getData(), expectedData)).isTrue();
+    }
+
+    @Test
     public void staticProperty_hasCorrectTypeConstantValue() {
         String typeExpected = "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL";
         String typeActual = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL;
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
index 47aecb4..0c67994 100644
--- a/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/PublicKeyCredentialTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.credentials
 
+import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
@@ -54,6 +55,22 @@
     }
 
     @Test
+    fun getter_frameworkProperties() {
+        val jsonExpected = "{\"hi\":{\"there\":{\"lol\":\"Value\"}}}"
+        val expectedData = Bundle()
+        expectedData.putString(
+            PublicKeyCredential.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, jsonExpected
+        )
+
+        val publicKeyCredential = PublicKeyCredential(jsonExpected)
+
+        assertThat(publicKeyCredential.type).isEqualTo(
+            PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL
+        )
+        assertThat(equals(publicKeyCredential.data, expectedData)).isTrue()
+    }
+
+    @Test
     fun staticProperty_hasCorrectTypeConstantValue() {
         val typeExpected = "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
         val typeActual = PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL
diff --git a/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt b/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt
new file mode 100644
index 0000000..4567380
--- /dev/null
+++ b/credentials/credentials/src/androidTest/java/androidx/credentials/TestUtils.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.credentials
+
+import android.os.Bundle
+
+/** True if the two Bundles contain the same elements, and false otherwise. */
+@Suppress("DEPRECATION")
+fun equals(a: Bundle, b: Bundle): Boolean {
+    if (a.keySet().size != b.keySet().size) {
+        return false
+    }
+    for (key in a.keySet()) {
+        if (!b.keySet().contains(key)) {
+            return false
+        }
+
+        val valA = a.get(key)
+        val valB = b.get(key)
+        if (valA is Bundle && valB is Bundle && !equals(valA, valB)) {
+            return false
+        } else {
+            val isEqual = (valA?.equals(valB) ?: (valB == null))
+            if (!isEqual) {
+                return false
+            }
+        }
+    }
+    return true
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
index d630fa7..7c373fe 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialRequest.kt
@@ -16,11 +16,22 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+
 /**
  * Base request class for registering a credential.
  *
  * An application can construct a subtype request and call [CredentialManager.executeCreateCredential] to
  * launch framework UI flows to collect consent and any other metadata needed from the user to
  * register a new user credential.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * @property data the request data in the [Bundle] format
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ *                              otherwise
  */
-abstract class CreateCredentialRequest
\ No newline at end of file
+open class CreateCredentialRequest(
+    val type: String,
+    val data: Bundle,
+    val requireSystemProvider: Boolean,
+)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
index 192d472..5267997 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreateCredentialResponse.kt
@@ -16,5 +16,13 @@
 
 package androidx.credentials
 
-/** Base response class for registering a credential. */
-abstract class CreateCredentialResponse
\ No newline at end of file
+import android.os.Bundle
+
+/**
+ * Base response class for the credential creation operation made with the
+ * [CreateCredentialRequest].
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * @property data the response data in the [Bundle] format
+ */
+open class CreateCredentialResponse(val type: String, val data: Bundle)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
index 2fc0116..f03c633 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordRequest.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A request to save the user password credential with their password provider.
  *
@@ -28,9 +31,29 @@
 class CreatePasswordRequest constructor(
     val id: String,
     val password: String,
-) : CreateCredentialRequest() {
+) : CreateCredentialRequest(
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    toBundle(id, password),
+    false,
+) {
 
     init {
         require(password.isNotEmpty()) { "password should not be empty" }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
+
+        @JvmStatic
+        internal fun toBundle(id: String, password: String): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_ID, id)
+            bundle.putString(BUNDLE_KEY_PASSWORD, password)
+            return bundle
+        }
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
index d70468c..436db69 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePasswordResponse.kt
@@ -16,5 +16,10 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+
 /** A response of a password saving flow. */
-class CreatePasswordResponse : CreateCredentialResponse()
\ No newline at end of file
+class CreatePasswordResponse : CreateCredentialResponse(
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    Bundle(),
+)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialBaseRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialBaseRequest.kt
index e78b5ac..7fbe48a 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialBaseRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialBaseRequest.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * Base request class for registering a public key credential.
  *
@@ -30,10 +33,19 @@
  * @hide
  */
 abstract class CreatePublicKeyCredentialBaseRequest constructor(
-    val requestJson: String
-) : CreateCredentialRequest() {
+    val requestJson: String,
+    type: String,
+    data: Bundle,
+    requireSystemProvider: Boolean,
+) : CreateCredentialRequest(type, data, requireSystemProvider) {
 
     init {
         require(requestJson.isNotEmpty()) { "request json must not be empty" }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+        const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
index d0b2d24..fe79aa99 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequest.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A request to register a passkey from the user's public key credential provider.
  *
@@ -32,4 +35,23 @@
     requestJson: String,
     @get:JvmName("allowHybrid")
     val allowHybrid: Boolean = true
-) : CreatePublicKeyCredentialBaseRequest(requestJson)
\ No newline at end of file
+) : CreatePublicKeyCredentialBaseRequest(
+    requestJson,
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(requestJson, allowHybrid),
+    false,
+) {
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+
+        @JvmStatic
+        internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+            bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+            return bundle
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivileged.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivileged.kt
index 23abbfb..1641f43 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivileged.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialRequestPrivileged.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A privileged request to register a passkey from the user’s public key credential provider, where
  * the caller can modify the rp. Only callers with privileged permission, e.g. user’s default
@@ -38,7 +41,12 @@
     val clientDataHash: String,
     @get:JvmName("allowHybrid")
     val allowHybrid: Boolean = true
-) : CreatePublicKeyCredentialBaseRequest(requestJson) {
+) : CreatePublicKeyCredentialBaseRequest(
+    requestJson,
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(requestJson, rp, clientDataHash, allowHybrid),
+    false,
+) {
 
     init {
         require(rp.isNotEmpty()) { "rp must not be empty" }
@@ -88,4 +96,30 @@
                 this.rp, this.clientDataHash, this.allowHybrid)
         }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_CLIENT_DATA_HASH =
+            "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+
+        @JvmStatic
+        internal fun toBundle(
+            requestJson: String,
+            rp: String,
+            clientDataHash: String,
+            allowHybrid: Boolean
+        ): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+            bundle.putString(BUNDLE_KEY_RP, rp)
+            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
+            bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+            return bundle
+        }
+    }
 }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
index f4cf4b9..7b5cd1d 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/CreatePublicKeyCredentialResponse.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A response of a public key credential (passkey) flow.
  *
@@ -28,10 +31,27 @@
  */
 class CreatePublicKeyCredentialResponse(
     val registrationResponseJson: String
-) : CreateCredentialResponse() {
+) : CreateCredentialResponse(
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(registrationResponseJson)
+) {
 
     init {
         require(registrationResponseJson.isNotEmpty()) { "registrationResponseJson must not be " +
             "empty" }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_REGISTRATION_RESPONSE_JSON =
+            "androidx.credentials.BUNDLE_KEY_REGISTRATION_RESPONSE_JSON"
+
+        @JvmStatic
+        internal fun toBundle(registrationResponseJson: String): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_REGISTRATION_RESPONSE_JSON, registrationResponseJson)
+            return bundle
+        }
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/Credential.kt b/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
index eb19ff8..d1d9629 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/Credential.kt
@@ -16,5 +16,12 @@
 
 package androidx.credentials
 
-/** Base class for a credential with which the user consented to authenticate to the app. */
-abstract class Credential
\ No newline at end of file
+import android.os.Bundle
+
+/**
+ * Base class for a credential with which the user consented to authenticate to the app.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * @property data the credential data in the [Bundle] format.
+ */
+open class Credential(val type: String, val data: Bundle)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/FederatedCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/FederatedCredential.kt
index dfc262c..e5c2bbf 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/FederatedCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/FederatedCredential.kt
@@ -16,6 +16,8 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+
 /**
  * A federated credential fetched from a federated identity provider (FedCM).
  *
@@ -24,7 +26,10 @@
  *
  * @hide
  */
-class FederatedCredential private constructor() {
+class FederatedCredential private constructor() : Credential(
+    TYPE_FEDERATED_CREDENTIAL,
+    Bundle(),
+) {
     companion object {
         /** The type value for federated credential related operations. */
         const val TYPE_FEDERATED_CREDENTIAL: String = "type.federated_credential"
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetCredentialOption.kt
index 2fcd72a..c75a157 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetCredentialOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetCredentialOption.kt
@@ -16,5 +16,21 @@
 
 package androidx.credentials
 
-/** Base request class for getting a registered credential. */
-abstract class GetCredentialOption
\ No newline at end of file
+import android.os.Bundle
+
+/**
+ * Base class for getting a specific type of credentials.
+ *
+ * [GetCredentialRequest] will be composed of a list of [GetCredentialOption] subclasses to indicate
+ * the specific credential types and configurations that your app accepts.
+ *
+ * @property type the credential type determined by the credential-type-specific subclass
+ * @property data the request data in the [Bundle] format
+ * @property requireSystemProvider true if must only be fulfilled by a system provider and false
+ *                              otherwise
+ */
+open class GetCredentialOption(
+    val type: String,
+    val data: Bundle,
+    val requireSystemProvider: Boolean,
+)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
index 920cbf2..a43927e 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPasswordOption.kt
@@ -16,5 +16,11 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+
 /** A request to retrieve the user's saved application password from their password provider. */
-class GetPasswordOption : GetCredentialOption()
\ No newline at end of file
+class GetPasswordOption : GetCredentialOption(
+    PasswordCredential.TYPE_PASSWORD_CREDENTIAL,
+    Bundle(),
+    false,
+)
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialBaseOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialBaseOption.kt
index d42c089..23cd3a3 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialBaseOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialBaseOption.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * Base request class for getting a registered public key credential.
  *
@@ -27,10 +30,19 @@
  * @hide
  */
 abstract class GetPublicKeyCredentialBaseOption constructor(
-    val requestJson: String
-) : GetCredentialOption() {
+    val requestJson: String,
+    type: String,
+    data: Bundle,
+    requireSystemProvider: Boolean,
+) : GetCredentialOption(type, data, requireSystemProvider) {
 
     init {
         require(requestJson.isNotEmpty()) { "request json must not be empty" }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+        const val BUNDLE_KEY_REQUEST_JSON = "androidx.credentials.BUNDLE_KEY_REQUEST_JSON"
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
index d372ffa..7f449d4 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOption.kt
@@ -1,4 +1,4 @@
-package androidx.credentials/*
+/*
  * Copyright 2022 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
+package androidx.credentials
+
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A request to get passkeys from the user's public key credential provider.
  *
@@ -30,4 +35,23 @@
     requestJson: String,
     @get:JvmName("allowHybrid")
     val allowHybrid: Boolean = true,
-) : GetPublicKeyCredentialBaseOption(requestJson)
\ No newline at end of file
+) : GetPublicKeyCredentialBaseOption(
+    requestJson,
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(requestJson, allowHybrid),
+    false
+) {
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+
+        @JvmStatic
+        internal fun toBundle(requestJson: String, allowHybrid: Boolean): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+            bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+            return bundle
+        }
+    }
+}
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOptionPrivileged.kt b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOptionPrivileged.kt
index a8fc6a2..2228e7b 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOptionPrivileged.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/GetPublicKeyCredentialOptionPrivileged.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * A privileged request to get passkeys from the user's public key credential provider. The caller
  * can modify the RP. Only callers with privileged permission (e.g. user's public browser or caBLE)
@@ -38,7 +41,12 @@
     val clientDataHash: String,
     @get:JvmName("allowHybrid")
     val allowHybrid: Boolean = true
-) : GetPublicKeyCredentialBaseOption(requestJson) {
+) : GetPublicKeyCredentialBaseOption(
+    requestJson,
+    PublicKeyCredential.TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(requestJson, rp, clientDataHash, allowHybrid),
+    false,
+) {
 
     init {
         require(rp.isNotEmpty()) { "rp must not be empty" }
@@ -88,4 +96,30 @@
                 this.rp, this.clientDataHash, this.allowHybrid)
         }
     }
+
+    /** @hide */
+    companion object {
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_RP = "androidx.credentials.BUNDLE_KEY_RP"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_CLIENT_DATA_HASH =
+            "androidx.credentials.BUNDLE_KEY_CLIENT_DATA_HASH"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ALLOW_HYBRID = "androidx.credentials.BUNDLE_KEY_ALLOW_HYBRID"
+
+        @JvmStatic
+        internal fun toBundle(
+            requestJson: String,
+            rp: String,
+            clientDataHash: String,
+            allowHybrid: Boolean
+        ): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_REQUEST_JSON, requestJson)
+            bundle.putString(BUNDLE_KEY_RP, rp)
+            bundle.putString(BUNDLE_KEY_CLIENT_DATA_HASH, clientDataHash)
+            bundle.putBoolean(BUNDLE_KEY_ALLOW_HYBRID, allowHybrid)
+            return bundle
+        }
+    }
 }
\ No newline at end of file
diff --git a/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
index 252f4a1..3c42d37 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/PasswordCredential.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * Represents the user's password credential granted by the user for app sign-in.
  *
@@ -28,9 +31,30 @@
 class PasswordCredential constructor(
     val id: String,
     val password: String,
-) : Credential() {
+) : Credential(TYPE_PASSWORD_CREDENTIAL, toBundle(id, password)) {
 
     init {
         require(password.isNotEmpty()) { "password should not be empty" }
     }
+
+    /** @hide */
+    companion object {
+        // TODO: this type is officially defined in the framework. This definition should be
+        // removed when the framework type is available in jetpack.
+        /** @hide */
+        const val TYPE_PASSWORD_CREDENTIAL: String = "android.credentials.TYPE_PASSWORD_CREDENTIAL"
+
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_ID = "androidx.credentials.BUNDLE_KEY_ID"
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_PASSWORD = "androidx.credentials.BUNDLE_KEY_PASSWORD"
+
+        @JvmStatic
+        internal fun toBundle(id: String, password: String): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_ID, id)
+            bundle.putString(BUNDLE_KEY_PASSWORD, password)
+            return bundle
+        }
+    }
 }
diff --git a/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt b/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
index ccfc29c..1a87b3c 100644
--- a/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
+++ b/credentials/credentials/src/main/java/androidx/credentials/PublicKeyCredential.kt
@@ -16,6 +16,9 @@
 
 package androidx.credentials
 
+import android.os.Bundle
+import androidx.annotation.VisibleForTesting
+
 /**
  * Represents the user's passkey credential granted by the user for app sign-in.
  *
@@ -30,7 +33,10 @@
  */
 class PublicKeyCredential constructor(
     val authenticationResponseJson: String
-) : Credential() {
+) : Credential(
+    TYPE_PUBLIC_KEY_CREDENTIAL,
+    toBundle(authenticationResponseJson)
+) {
 
     init {
         require(authenticationResponseJson.isNotEmpty()) {
@@ -40,5 +46,16 @@
         /** The type value for public key credential related operations. */
         const val TYPE_PUBLIC_KEY_CREDENTIAL: String =
             "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"
+
+        @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+        const val BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON =
+            "androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"
+
+        @JvmStatic
+        internal fun toBundle(authenticationResponseJson: String): Bundle {
+            val bundle = Bundle()
+            bundle.putString(BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON, authenticationResponseJson)
+            return bundle
+        }
     }
 }
\ No newline at end of file
diff --git a/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioSerializer.kt b/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioSerializer.kt
index 6b969da..cbd6d75 100644
--- a/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioSerializer.kt
+++ b/datastore/datastore-core-okio/src/commonMain/kotlin/androidx/datastore/core/okio/OkioSerializer.kt
@@ -43,7 +43,7 @@
      *  Marshal object to a Sink.
      *
      *  @param t the data to write to output
-     *  @output the BufferedSink to serialize data to
+     *  @param sink the BufferedSink to serialize data to
      */
     public suspend fun writeTo(t: T, sink: BufferedSink)
 }
\ No newline at end of file
diff --git a/development/diff_published_artifacts/.gitignore b/development/diff_published_artifacts/.gitignore
new file mode 100644
index 0000000..16e340a
--- /dev/null
+++ b/development/diff_published_artifacts/.gitignore
@@ -0,0 +1 @@
+download_staging/*
\ No newline at end of file
diff --git a/development/diff_published_artifacts/diff_published_artifacts.py b/development/diff_published_artifacts/diff_published_artifacts.py
new file mode 100644
index 0000000..036b255
--- /dev/null
+++ b/development/diff_published_artifacts/diff_published_artifacts.py
@@ -0,0 +1,248 @@
+# 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.
+
+import json
+import os
+import subprocess
+import shutil
+import re
+import requests
+import zipfile
+import sys
+
+FETCH_ARTIFACT = "/google/data/ro/projects/android/fetch_artifact"
+BASS = "/google/data/ro/projects/android/bass"
+DEFAULT_CLONE_DEPTH = 100 # chosen arbitrarily, may need to be adjusted
+DEFAULT_BUILD_ARTIFACT_SEARCH_TIME_SPAN_IN_DAYS = 7 # chosen arbitrarily, may need to be adjusted
+GIT_LOG_URL = "https://android.googlesource.com/platform/frameworks/support/+log"
+IGNORE_PATHS = [
+ # includes timestamps
+  "*.xml",
+   # are different because the xml files include timestamps
+  "*.xml.*",
+  "*.sha*",
+  "*.md5",
+  # is different because it references the .sha* files.
+  "*.module"
+]
+
+
+def main(build_id):
+  """
+  This is a script to take a given build_id, and search for a build of the previous commit on ab/
+  If a commit is found, we download the top-of-tree-m2repository-all-{build_id}.zip file from both
+  builds and diff the contents. If an .aar / .jar is different, we will unzip those and diff the
+  contents as well.
+  """
+  staging_dir = prep_staging_dir()
+  build_info_file_path = fetch_build_info(build_id, staging_dir)
+
+  # presubmit BUILD_INFO files include the commit being built as well as the and parent commit
+  if is_presubmit_build(build_id):
+    previous_revision = get_previous_revision_from_build_info(build_info_file_path)
+  # other builds only include the commit being built (as far as I can tell),  we need to
+  # get the previous commit from git log
+  else:
+    current_revision = get_current_revision(build_info_file_path)
+    previous_revision = get_previous_revision_from_git_history(current_revision, staging_dir)
+  previous_build_id = get_previous_build_id(previous_revision)
+  (before, after) = download_and_unzip_repos(staging_dir, build_id, previous_build_id)
+  diff_repos(before, after, staging_dir)
+
+def prep_staging_dir():
+  """
+  remove and recreate the ./download_staging which is located as a sibling of this script.
+  """
+  current_dir = os.path.dirname(os.path.realpath(__file__))
+  staging_dir = current_dir + "/download_staging"
+  if os.path.isdir(staging_dir):
+    shutil.rmtree(staging_dir)
+  os.makedirs(staging_dir, exist_ok=True)
+  return staging_dir
+
+
+def fetch_m2repo(build_id, staging_dir):
+  file_path = f"top-of-tree-m2repository-all-{build_id}.zip"
+  if is_presubmit_build(build_id):
+    file_path = f"incremental/{file_path}"
+  return fetch_artifact(build_id, staging_dir, file_path)
+
+
+def fetch_build_info(build_id, staging_dir):
+  return fetch_artifact(build_id, staging_dir, "BUILD_INFO")
+
+
+def fetch_artifact(build_id, output_dir, file_path):
+  file_name = file_path.split("/")[-1]
+  print(f"fetching {file_name}")
+
+  if is_presubmit_build(build_id):
+    target = "androidx_incremental"
+  else:
+    target = "androidx"
+  return FetchArtifactService().fetch_artifact(build_id, "aosp-androidx-main", target, output_dir, file_path)
+
+
+def get_current_revision(build_info_file_path):
+  print("Getting current revision from BUILD_INFO")
+  with open(build_info_file_path) as f:
+    build_info = json.load(f)
+    support_project = next(
+        project for project in build_info["parsed_manifest"]["projects"] if
+        project["name"] == "platform/frameworks/support")
+    current_revision = support_project["revision"]
+    print(f"Found revision: {current_revision}")
+    return current_revision
+
+
+def get_previous_revision_from_build_info(build_info_file_path):
+  print("Getting previous revision from BUILD_INFO")
+  with open(build_info_file_path) as f:
+    build_info = json.load(f)
+    revision = build_info["git-pull"][0]["revisions"][0]["commit"]["parents"][0]["commitId"]
+    print(f"Found previous revision: {revision}")
+    return revision
+
+def get_previous_revision_from_git_history(current_revision, staging_dir):
+  """
+  Gets previous revision from git log endpoint for androidx-main.
+  """
+  response = requests.get(git_log_url(current_revision))
+  # endpoint returns  some junk in the first line making it invalid json
+  text_with_first_line_removed = "\n".join(response.text.split("\n")[1:])
+  response_json = json.loads(text_with_first_line_removed)
+  previous_revision = response_json["log"][0]["parents"][0]
+  print(f"Found previous revision: {previous_revision}")
+  return previous_revision
+
+
+def get_previous_build_id(previous_revision):
+  print("Searching Android Build server for build matching previous revision")
+  output = BassService().search_builds(
+    DEFAULT_BUILD_ARTIFACT_SEARCH_TIME_SPAN_IN_DAYS,
+    "aosp-androidx-main",
+    "androidx",
+    "BUILD_INFO",
+    previous_revision
+  )
+  match = re.search("BuildID\: (\d+)", output.stdout)
+  if match is None:
+    raise Exception(f"Couldn't find previous build ID for revision {previous_revision}")
+
+  previous_build_id = match.group(1)
+  print(f"Found build matching previous revision: {previous_build_id}")
+  return previous_build_id
+
+def download_and_unzip_repos(staging_dir, build_id, previous_build_id):
+  before_dir = staging_dir + "/before"
+  after_dir = staging_dir + "/after"
+  os.makedirs(before_dir)
+  os.makedirs(after_dir)
+  after_zip = fetch_m2repo(build_id, staging_dir)
+  before_zip = fetch_m2repo(previous_build_id, staging_dir)
+  return (unzip(before_zip, before_dir), unzip(after_zip, after_dir))
+
+def diff_repos(before, after, staging_dir):
+  output = DiffService().diff(before, after, IGNORE_PATHS)
+  for line in output.stdout.splitlines():
+    if line.startswith("Binary files "):
+      for (before_file, after_file) in re.findall("Binary files (.+) and (.+) differ", line):
+        diff_binary(before_file, after_file, staging_dir)
+    else:
+      print(line)
+
+
+def diff_binary(before, after, staging_dir):
+  file_name = before.split("/")[-1]
+  if is_unzippable(before) and is_unzippable(after):
+    before_contents = unzip(before, staging_dir + "/" + file_name + "-before")
+    after_contents = unzip(after, staging_dir + "/" + file_name + "-after")
+    output = DiffService().diff(before_contents, after_contents)
+    # sometimes the binary is "different" but the contents are identical.
+    # It might be interesting to add diff the metadata, but for now just ignore it.
+    if output.stdout.strip() != "":
+      print(output.stdout)
+  else:
+    print(f"Binary files {before} and {after} differ")
+
+def is_unzippable(filename):
+  return filename.endswith(".zip") or filename.endswith(".aar") or filename.endswith(".jar")
+
+def unzip(file, destination):
+  with zipfile.ZipFile(file, 'r') as zip:
+    zip.extractall(destination)
+    return destination
+
+def is_presubmit_build(build_id):
+    return build_id.startswith("P")
+
+def git_log_url(revision):
+    return f"{GIT_LOG_URL}/{revision}?format=JSON"
+
+class DiffService():
+    @staticmethod
+    def diff(before_dir, after_dir, exclude=[]):
+      args = ["diff", "-r"]
+      for pattern in exclude:
+        args.extend(["-x", pattern])
+      args.extend([before_dir, after_dir])
+      return subprocess.run(args, text=True, capture_output=True)
+
+
+class FetchArtifactService():
+    @staticmethod
+    def fetch_artifact(build_id, branch, target, output_dir, file_path):
+      file_name = file_path.split("/")[-1]
+      subprocess.run(
+        [
+          FETCH_ARTIFACT,
+          "--bid",
+          build_id,
+          "--branch",
+          branch,
+          "--target",
+          target,
+          file_path,
+        ],
+        cwd=output_dir,
+        capture_output=True,
+        check=True
+      )
+      return f"{output_dir}/{file_name}"
+
+class BassService():
+    @staticmethod
+    def search_builds(days, branch, target, file_name, query):
+     return subprocess.run([
+          BASS,
+          "--days",
+          str(days),
+          "--successful",
+          "true",
+          "--branch",
+          branch,
+          "--target",
+          target,
+          "--filename",
+          file_name,
+          "--query",
+          query
+      ],
+          capture_output=True,
+          text=True,
+          check=True
+      )
+
+if __name__ == "__main__":
+    main(sys.argv[1])
\ No newline at end of file
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index 5dcc6c6..0ad099d 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -37,16 +37,16 @@
     docs("androidx.biometric:biometric-ktx:1.2.0-alpha05")
     samples("androidx.biometric:biometric-ktx-samples:1.2.0-alpha05")
     docs("androidx.browser:browser:1.5.0-alpha01")
-    docs("androidx.camera:camera-camera2:1.2.0-rc01")
-    docs("androidx.camera:camera-core:1.2.0-rc01")
-    docs("androidx.camera:camera-extensions:1.2.0-rc01")
+    docs("androidx.camera:camera-camera2:1.3.0-alpha01")
+    docs("androidx.camera:camera-core:1.3.0-alpha01")
+    docs("androidx.camera:camera-extensions:1.3.0-alpha01")
     stubs(fileTree(dir: "../camera/camera-extensions-stub", include: ["camera-extensions-stub.jar"]))
-    docs("androidx.camera:camera-lifecycle:1.2.0-rc01")
-    docs("androidx.camera:camera-mlkit-vision:1.2.0-rc01")
+    docs("androidx.camera:camera-lifecycle:1.3.0-alpha01")
+    docs("androidx.camera:camera-mlkit-vision:1.3.0-alpha01")
     docs("androidx.camera:camera-previewview:1.1.0-beta02")
-    docs("androidx.camera:camera-video:1.2.0-rc01")
-    docs("androidx.camera:camera-view:1.2.0-rc01")
-    docs("androidx.camera:camera-viewfinder:1.2.0-rc01")
+    docs("androidx.camera:camera-video:1.3.0-alpha01")
+    docs("androidx.camera:camera-view:1.3.0-alpha01")
+    docs("androidx.camera:camera-viewfinder:1.3.0-alpha01")
     docs("androidx.car.app:app:1.3.0-beta01")
     docs("androidx.car.app:app-automotive:1.3.0-beta01")
     docs("androidx.car.app:app-projected:1.3.0-beta01")
@@ -54,55 +54,55 @@
     docs("androidx.cardview:cardview:1.0.0")
     docs("androidx.collection:collection:1.3.0-alpha02")
     docs("androidx.collection:collection-ktx:1.3.0-alpha02")
-    docs("androidx.compose.animation:animation:1.4.0-alpha01")
-    docs("androidx.compose.animation:animation-core:1.4.0-alpha01")
-    docs("androidx.compose.animation:animation-graphics:1.4.0-alpha01")
-    samples("androidx.compose.animation:animation-samples:1.4.0-alpha01")
-    samples("androidx.compose.animation:animation-core-samples:1.4.0-alpha01")
-    samples("androidx.compose.animation:animation-graphics-samples:1.4.0-alpha01")
-    docs("androidx.compose.foundation:foundation:1.4.0-alpha01")
-    docs("androidx.compose.foundation:foundation-layout:1.4.0-alpha01")
-    samples("androidx.compose.foundation:foundation-layout-samples:1.4.0-alpha01")
-    samples("androidx.compose.foundation:foundation-samples:1.4.0-alpha01")
-    docs("androidx.compose.material3:material3:1.1.0-alpha01")
-    samples("androidx.compose.material3:material3-samples:1.1.0-alpha01")
-    docs("androidx.compose.material3:material3-window-size-class:1.1.0-alpha01")
-    samples("androidx.compose.material3:material3-window-size-class-samples:1.1.0-alpha01")
-    docs("androidx.compose.material:material:1.4.0-alpha01")
-    docs("androidx.compose.material:material-icons-core:1.4.0-alpha01")
-    samples("androidx.compose.material:material-icons-core-samples:1.4.0-alpha01")
-    docs("androidx.compose.material:material-ripple:1.4.0-alpha01")
-    samples("androidx.compose.material:material-samples:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime-livedata:1.4.0-alpha01")
-    samples("androidx.compose.runtime:runtime-livedata-samples:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime-rxjava2:1.4.0-alpha01")
-    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime-rxjava3:1.4.0-alpha01")
-    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime-saveable:1.4.0-alpha01")
-    samples("androidx.compose.runtime:runtime-saveable-samples:1.4.0-alpha01")
-    samples("androidx.compose.runtime:runtime-samples:1.4.0-alpha01")
-    docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha01")
-    docs("androidx.compose.ui:ui:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-geometry:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-graphics:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-graphics-samples:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-test:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-test-junit4:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-test-samples:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-text:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-text-google-fonts:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-text-samples:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-tooling:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-tooling-data:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-tooling-preview:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-unit:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-unit-samples:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-util:1.4.0-alpha01")
-    docs("androidx.compose.ui:ui-viewbinding:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-viewbinding-samples:1.4.0-alpha01")
-    samples("androidx.compose.ui:ui-samples:1.4.0-alpha01")
+    docs("androidx.compose.animation:animation:1.4.0-alpha02")
+    docs("androidx.compose.animation:animation-core:1.4.0-alpha02")
+    docs("androidx.compose.animation:animation-graphics:1.4.0-alpha02")
+    samples("androidx.compose.animation:animation-samples:1.4.0-alpha02")
+    samples("androidx.compose.animation:animation-core-samples:1.4.0-alpha02")
+    samples("androidx.compose.animation:animation-graphics-samples:1.4.0-alpha02")
+    docs("androidx.compose.foundation:foundation:1.4.0-alpha02")
+    docs("androidx.compose.foundation:foundation-layout:1.4.0-alpha02")
+    samples("androidx.compose.foundation:foundation-layout-samples:1.4.0-alpha02")
+    samples("androidx.compose.foundation:foundation-samples:1.4.0-alpha02")
+    docs("androidx.compose.material3:material3:1.1.0-alpha02")
+    samples("androidx.compose.material3:material3-samples:1.1.0-alpha02")
+    docs("androidx.compose.material3:material3-window-size-class:1.1.0-alpha02")
+    samples("androidx.compose.material3:material3-window-size-class-samples:1.1.0-alpha02")
+    docs("androidx.compose.material:material:1.4.0-alpha02")
+    docs("androidx.compose.material:material-icons-core:1.4.0-alpha02")
+    samples("androidx.compose.material:material-icons-core-samples:1.4.0-alpha02")
+    docs("androidx.compose.material:material-ripple:1.4.0-alpha02")
+    samples("androidx.compose.material:material-samples:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime-livedata:1.4.0-alpha02")
+    samples("androidx.compose.runtime:runtime-livedata-samples:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime-rxjava2:1.4.0-alpha02")
+    samples("androidx.compose.runtime:runtime-rxjava2-samples:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime-rxjava3:1.4.0-alpha02")
+    samples("androidx.compose.runtime:runtime-rxjava3-samples:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime-saveable:1.4.0-alpha02")
+    samples("androidx.compose.runtime:runtime-saveable-samples:1.4.0-alpha02")
+    samples("androidx.compose.runtime:runtime-samples:1.4.0-alpha02")
+    docs("androidx.compose.runtime:runtime-tracing:1.0.0-alpha02")
+    docs("androidx.compose.ui:ui:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-geometry:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-graphics:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-graphics-samples:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-test:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-test-junit4:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-test-samples:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-text:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-text-google-fonts:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-text-samples:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-tooling:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-tooling-data:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-tooling-preview:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-unit:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-unit-samples:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-util:1.4.0-alpha02")
+    docs("androidx.compose.ui:ui-viewbinding:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-viewbinding-samples:1.4.0-alpha02")
+    samples("androidx.compose.ui:ui-samples:1.4.0-alpha02")
     docs("androidx.concurrent:concurrent-futures:1.1.0")
     docs("androidx.concurrent:concurrent-futures-ktx:1.1.0")
     docs("androidx.contentpager:contentpager:1.0.0")
@@ -122,14 +122,15 @@
     docs("androidx.cursoradapter:cursoradapter:1.0.0")
     docs("androidx.customview:customview:1.2.0-alpha02")
     docs("androidx.customview:customview-poolingcontainer:1.0.0-rc01")
-    docs("androidx.datastore:datastore:1.0.0")
-    docs("androidx.datastore:datastore-core:1.0.0")
-    docs("androidx.datastore:datastore-preferences:1.0.0")
-    docs("androidx.datastore:datastore-preferences-core:1.0.0")
-    docs("androidx.datastore:datastore-preferences-rxjava2:1.0.0")
-    docs("androidx.datastore:datastore-preferences-rxjava3:1.0.0")
-    docs("androidx.datastore:datastore-rxjava2:1.0.0")
-    docs("androidx.datastore:datastore-rxjava3:1.0.0")
+    docs("androidx.datastore:datastore:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-core:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-core-okio:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-preferences:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-preferences-core:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-preferences-rxjava2:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-preferences-rxjava3:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-rxjava2:1.1.0-alpha01")
+    docs("androidx.datastore:datastore-rxjava3:1.1.0-alpha01")
     docs("androidx.documentfile:documentfile:1.1.0-alpha01")
     docs("androidx.draganddrop:draganddrop:1.0.0")
     docs("androidx.drawerlayout:drawerlayout:1.2.0-alpha01")
@@ -155,7 +156,7 @@
     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.graphics:graphics-core:1.0.0-alpha01")
+    docs("androidx.graphics:graphics-core:1.0.0-alpha02")
     docs("androidx.gridlayout:gridlayout:1.0.0")
     docs("androidx.health.connect:connect-client:1.0.0-alpha07")
     samples("androidx.health.connect:connect-client-samples:1.0.0-alpha07")
@@ -203,22 +204,22 @@
     docs("androidx.media2:media2-session:1.2.1")
     docs("androidx.media2:media2-widget:1.2.1")
     docs("androidx.media:media:1.6.0")
-    docs("androidx.mediarouter:mediarouter:1.3.1")
-    docs("androidx.mediarouter:mediarouter-testing:1.3.1")
+    docs("androidx.mediarouter:mediarouter:1.4.0-alpha01")
+    docs("androidx.mediarouter:mediarouter-testing:1.4.0-alpha01")
     docs("androidx.metrics:metrics-performance:1.0.0-alpha03")
-    docs("androidx.navigation:navigation-common:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-common-ktx:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-compose:2.6.0-alpha03")
-    samples("androidx.navigation:navigation-compose-samples:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-dynamic-features-fragment:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-dynamic-features-runtime:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-fragment:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-fragment-ktx:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-runtime:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-runtime-ktx:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-testing:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-ui:2.6.0-alpha03")
-    docs("androidx.navigation:navigation-ui-ktx:2.6.0-alpha03")
+    docs("androidx.navigation:navigation-common:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-common-ktx:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-compose:2.6.0-alpha04")
+    samples("androidx.navigation:navigation-compose-samples:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-dynamic-features-fragment:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-dynamic-features-runtime:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-fragment:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-fragment-ktx:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-runtime:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-runtime-ktx:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-testing:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-ui:2.6.0-alpha04")
+    docs("androidx.navigation:navigation-ui-ktx:2.6.0-alpha04")
     docs("androidx.paging:paging-common:3.2.0-alpha03")
     docs("androidx.paging:paging-common-ktx:3.2.0-alpha03")
     docs("androidx.paging:paging-compose:1.0.0-alpha17")
@@ -237,31 +238,35 @@
     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.profileinstaller:profileinstaller:1.3.0-alpha01")
+    docs("androidx.privacysandbox.tools:tools:1.0.0-alpha01")
+    docs("androidx.privacysandbox.tools:tools-apigenerator:1.0.0-alpha01")
+    docs("androidx.privacysandbox.tools:tools-apipackager:1.0.0-alpha01")
+    docs("androidx.privacysandbox.tools:tools-core:1.0.0-alpha01")
+    docs("androidx.profileinstaller:profileinstaller:1.3.0-alpha02")
     docs("androidx.recommendation:recommendation:1.0.0")
     docs("androidx.recyclerview:recyclerview:1.3.0-rc01")
     docs("androidx.recyclerview:recyclerview-selection:2.0.0-alpha01")
     docs("androidx.remotecallback:remotecallback:1.0.0-alpha02")
     docs("androidx.resourceinspection:resourceinspection-annotation:1.0.1")
     docs("androidx.resourceinspection:resourceinspection-processor:1.0.1")
-    docs("androidx.room:room-common:2.5.0-beta01")
-    docs("androidx.room:room-guava:2.5.0-beta01")
-    docs("androidx.room:room-ktx:2.5.0-beta01")
-    docs("androidx.room:room-migration:2.5.0-beta01")
-    docs("androidx.room:room-paging:2.5.0-beta01")
-    docs("androidx.room:room-paging-guava:2.5.0-beta01")
-    docs("androidx.room:room-paging-rxjava2:2.5.0-beta01")
-    docs("androidx.room:room-paging-rxjava3:2.5.0-beta01")
-    docs("androidx.room:room-runtime:2.5.0-beta01")
-    docs("androidx.room:room-rxjava2:2.5.0-beta01")
-    docs("androidx.room:room-rxjava3:2.5.0-beta01")
-    docs("androidx.room:room-testing:2.5.0-beta01")
+    docs("androidx.room:room-common:2.5.0-beta02")
+    docs("androidx.room:room-guava:2.5.0-beta02")
+    docs("androidx.room:room-ktx:2.5.0-beta02")
+    docs("androidx.room:room-migration:2.5.0-beta02")
+    docs("androidx.room:room-paging:2.5.0-beta02")
+    docs("androidx.room:room-paging-guava:2.5.0-beta02")
+    docs("androidx.room:room-paging-rxjava2:2.5.0-beta02")
+    docs("androidx.room:room-paging-rxjava3:2.5.0-beta02")
+    docs("androidx.room:room-runtime:2.5.0-beta02")
+    docs("androidx.room:room-rxjava2:2.5.0-beta02")
+    docs("androidx.room:room-rxjava3:2.5.0-beta02")
+    docs("androidx.room:room-testing:2.5.0-beta02")
     docs("androidx.savedstate:savedstate:1.2.0")
     docs("androidx.savedstate:savedstate-ktx:1.2.0")
     docs("androidx.security:security-app-authenticator:1.0.0-alpha02")
     docs("androidx.security:security-app-authenticator-testing:1.0.0-alpha01")
-    docs("androidx.security:security-crypto:1.1.0-alpha03")
-    docs("androidx.security:security-crypto-ktx:1.1.0-alpha02")
+    docs("androidx.security:security-crypto:1.1.0-alpha04")
+    docs("androidx.security:security-crypto-ktx:1.1.0-alpha04")
     docs("androidx.security:security-identity-credential:1.0.0-alpha03")
     docs("androidx.sharetarget:sharetarget:1.2.0")
     docs("androidx.slice:slice-builders:1.1.0-alpha02")
@@ -269,21 +274,21 @@
     docs("androidx.slice:slice-core:1.1.0-alpha02")
     docs("androidx.slice:slice-view:1.1.0-alpha02")
     docs("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
-    docs("androidx.sqlite:sqlite:2.3.0-beta01")
-    docs("androidx.sqlite:sqlite-framework:2.3.0-beta01")
-    docs("androidx.sqlite:sqlite-ktx:2.3.0-beta01")
+    docs("androidx.sqlite:sqlite:2.3.0-beta02")
+    docs("androidx.sqlite:sqlite-framework:2.3.0-beta02")
+    docs("androidx.sqlite:sqlite-ktx:2.3.0-beta02")
     docs("androidx.startup:startup-runtime:1.2.0-alpha01")
     docs("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
     docs("androidx.test.uiautomator:uiautomator:2.3.0-alpha01")
     docs("androidx.textclassifier:textclassifier:1.0.0-alpha04")
     docs("androidx.tracing:tracing:1.2.0-alpha02")
     docs("androidx.tracing:tracing-ktx:1.2.0-alpha02")
-    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha06")
-    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha06")
+    docs("androidx.tracing:tracing-perfetto:1.0.0-alpha07")
+    docs("androidx.tracing:tracing-perfetto-common:1.0.0-alpha07")
     docs("androidx.transition:transition:1.4.1")
     docs("androidx.transition:transition-ktx:1.4.1")
-    docs("androidx.tv:tv-foundation:1.0.0-alpha01")
-    docs("androidx.tv:tv-material:1.0.0-alpha01")
+    docs("androidx.tv:tv-foundation:1.0.0-alpha02")
+    docs("androidx.tv:tv-material:1.0.0-alpha02")
     docs("androidx.tvprovider:tvprovider:1.1.0-alpha01")
     docs("androidx.vectordrawable:vectordrawable:1.2.0-beta01")
     docs("androidx.vectordrawable:vectordrawable-animated:1.2.0-alpha01")
@@ -291,33 +296,33 @@
     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.1.0-beta01")
-    samples("androidx.wear.compose:compose-foundation-samples:1.1.0-beta01")
-    docs("androidx.wear.compose:compose-material:1.1.0-beta01")
-    samples("androidx.wear.compose:compose-material-samples:1.1.0-beta01")
-    docs("androidx.wear.compose:compose-navigation:1.1.0-beta01")
-    samples("androidx.wear.compose:compose-navigation-samples:1.1.0-beta01")
+    docs("androidx.wear.compose:compose-foundation:1.1.0-rc01")
+    samples("androidx.wear.compose:compose-foundation-samples:1.1.0-rc01")
+    docs("androidx.wear.compose:compose-material:1.1.0-rc01")
+    samples("androidx.wear.compose:compose-material-samples:1.1.0-rc01")
+    docs("androidx.wear.compose:compose-navigation:1.1.0-rc01")
+    samples("androidx.wear.compose:compose-navigation-samples:1.1.0-rc01")
     docs("androidx.wear.tiles:tiles:1.1.0")
     docs("androidx.wear.tiles:tiles-material:1.1.0")
     docs("androidx.wear.tiles:tiles-proto:1.1.0")
     docs("androidx.wear.tiles:tiles-renderer:1.1.0")
     docs("androidx.wear.tiles:tiles-testing:1.1.0")
-    docs("androidx.wear.watchface:watchface:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-client:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-client-guava:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-complications:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-complications-data:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0-alpha03")
-    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-data:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-editor:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-editor-guava:1.2.0-alpha03")
-    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-guava:1.2.0-alpha03")
-    samples("androidx.wear.watchface:watchface-samples:1.2.0-alpha03")
-    docs("androidx.wear.watchface:watchface-style:1.2.0-alpha03")
+    docs("androidx.wear.watchface:watchface:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-client:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-client-guava:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-complications:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-complications-data:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-complications-data-source:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-complications-data-source-ktx:1.2.0-alpha04")
+    samples("androidx.wear.watchface:watchface-complications-permission-dialogs-sample:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-complications-rendering:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-data:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-editor:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-editor-guava:1.2.0-alpha04")
+    samples("androidx.wear.watchface:watchface-editor-samples:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-guava:1.2.0-alpha04")
+    samples("androidx.wear.watchface:watchface-samples:1.2.0-alpha04")
+    docs("androidx.wear.watchface:watchface-style:1.2.0-alpha04")
     docs("androidx.wear:wear:1.3.0-alpha03")
     stubs(fileTree(dir: "../wear/wear_stubs/", include: ["com.google.android.wearable-stubs.jar"]))
     docs("androidx.wear:wear-ongoing:1.1.0-alpha01")
@@ -326,19 +331,20 @@
     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.6.0-alpha02")
-    docs("androidx.window:window:1.1.0-alpha03")
+    docs("androidx.webkit:webkit:1.6.0-alpha03")
+    docs("androidx.window:window:1.1.0-alpha04")
     stubs(fileTree(dir: "../window/stubs/", include: ["window-sidecar-release-0.1.0-alpha01.aar"]))
+    docs("androidx.window:window-core:1.1.0-alpha04")
     stubs("androidx.window:window-extensions:1.0.0-alpha01")
-    docs("androidx.window:window-java:1.1.0-alpha03")
-    docs("androidx.window:window-rxjava2:1.1.0-alpha03")
-    docs("androidx.window:window-rxjava3:1.1.0-alpha03")
-    docs("androidx.window:window-testing:1.1.0-alpha03")
-    docs("androidx.work:work-gcm:2.8.0-beta01")
-    docs("androidx.work:work-multiprocess:2.8.0-beta01")
-    docs("androidx.work:work-runtime:2.8.0-beta01")
-    docs("androidx.work:work-runtime-ktx:2.8.0-beta01")
-    docs("androidx.work:work-rxjava2:2.8.0-beta01")
-    docs("androidx.work:work-rxjava3:2.8.0-beta01")
-    docs("androidx.work:work-testing:2.8.0-beta01")
+    docs("androidx.window:window-java:1.1.0-alpha04")
+    docs("androidx.window:window-rxjava2:1.1.0-alpha04")
+    docs("androidx.window:window-rxjava3:1.1.0-alpha04")
+    docs("androidx.window:window-testing:1.1.0-alpha04")
+    docs("androidx.work:work-gcm:2.8.0-beta02")
+    docs("androidx.work:work-multiprocess:2.8.0-beta02")
+    docs("androidx.work:work-runtime:2.8.0-beta02")
+    docs("androidx.work:work-runtime-ktx:2.8.0-beta02")
+    docs("androidx.work:work-rxjava2:2.8.0-beta02")
+    docs("androidx.work:work-rxjava3:2.8.0-beta02")
+    docs("androidx.work:work-testing:2.8.0-beta02")
 }
diff --git a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiView.kt b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiView.kt
index abd602c..bba8664 100644
--- a/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiView.kt
+++ b/emoji2/emoji2-emojipicker/src/main/java/androidx/emoji2/emojipicker/EmojiView.kt
@@ -26,6 +26,7 @@
 import android.text.Spanned
 import android.text.StaticLayout
 import android.text.TextPaint
+import android.util.AttributeSet
 import android.util.TypedValue
 import android.view.View
 import androidx.annotation.RequiresApi
@@ -34,7 +35,9 @@
 /**
  * A customized view to support drawing emojis asynchronously.
  */
-internal class EmojiView(context: Context) : View(context) {
+internal class EmojiView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+    View(context, attrs) {
+
     companion object {
         private const val EMOJI_DRAW_TEXT_SIZE_SP = 30
     }
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-af/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-af/strings.xml
index 204ee00..ba26a9a 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-af/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-af/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"VOORWERPE"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLE"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"VLAE"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Geen emosiekone beskikbaar nie"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-am/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-am/strings.xml
index f2d2255..8bced7b 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-am/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-am/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ነገሮች"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ምልክቶች"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ባንዲራዎች"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ar/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ar/strings.xml
index 06b974b..dbee125 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ar/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ar/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"الأشياء"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"الرموز"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"الأعلام"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-as/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-as/strings.xml
index 0a486a1..27f9a48 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-as/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-as/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"বস্তু"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"চিহ্ন"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"পতাকা"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-az/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-az/strings.xml
index d40c53c..494a404 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-az/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-az/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBYEKTLƏR"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SİMVOLLAR"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BAYRAQLAR"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-b+sr+Latn/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-b+sr+Latn/strings.xml
index 71b377f..082c070 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-b+sr+Latn/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-b+sr+Latn/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ZASTAVE"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-be/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-be/strings.xml
index 66979f9..b7f1775 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-be/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-be/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"АБ\'ЕКТЫ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СІМВАЛЫ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"СЦЯГІ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-bg/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-bg/strings.xml
index b93d21c..5bc64c0 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-bg/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-bg/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ПРЕДМЕТИ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМВОЛИ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ЗНАМЕНА"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-bn/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-bn/strings.xml
index 4e1034c..ce02e6c 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-bn/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-bn/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"অবজেক্ট"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"প্রতীক"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ফ্ল্যাগ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-bs/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-bs/strings.xml
index 7ed5285..f939f3a 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-bs/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-bs/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"PREDMETI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ZASTAVE"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Nije dostupan nijedan emoji"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
index edfa8ac..7b560c7 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ca/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTES"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDERES"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-cs/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-cs/strings.xml
index 9aa5ac6..297d62d 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-cs/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-cs/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTY"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLY"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"VLAJKY"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-da/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-da/strings.xml
index 893f68e..4302216 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-da/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-da/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"TING"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLER"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAG"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-de/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-de/strings.xml
index 23bcc14..4765437 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-de/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-de/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTE"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLE"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGGEN"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-el/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-el/strings.xml
index f5ebd3e..8b49435 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-el/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-el/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ΑΝΤΙΚΕΙΜΕΝΑ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ΣΥΜΒΟΛΑ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ΣΗΜΑΙΕΣ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-en-rAU/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-en-rAU/strings.xml
index 773953d..7b7b1f7 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-en-rAU/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-en-rAU/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"No emojis available"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-en-rCA/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-en-rCA/strings.xml
index 773953d..7b7b1f7 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-en-rCA/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-en-rCA/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"No emojis available"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-en-rGB/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-en-rGB/strings.xml
index 773953d..7b7b1f7 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-en-rGB/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-en-rGB/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"No emojis available"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-en-rIN/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-en-rIN/strings.xml
index 773953d..7b7b1f7 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-en-rIN/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-en-rIN/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"No emojis available"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-en-rXC/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-en-rXC/strings.xml
index de4d6fb..ef401e8 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-en-rXC/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-en-rXC/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎OBJECTS‎‏‎‎‏‎"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎SYMBOLS‎‏‎‎‏‎"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎FLAGS‎‏‎‎‏‎"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎No emojis available‎‏‎‎‏‎"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-es-rUS/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-es-rUS/strings.xml
index 3620abe..688cecb 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-es-rUS/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-es-rUS/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDERAS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"No hay ningún emoji disponible"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-es/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-es/strings.xml
index 1f75326..3047306 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-es/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-es/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDERAS"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-et/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-et/strings.xml
index 3dca6c7..6d9cfc9 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-et/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-et/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTID"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÜMBOLID"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"LIPUD"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-eu/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-eu/strings.xml
index ecd828a..86d8285 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-eu/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-eu/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTUAK"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"IKURRAK"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDERAK"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-fa/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-fa/strings.xml
index 5d05a16..cc8c523 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-fa/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-fa/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"اشیاء"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"نمادها"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"پرچم‌ها"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-fi/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-fi/strings.xml
index 9a4c1c3..9d90888 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-fi/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-fi/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ESINEET"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLIT"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"LIPUT"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-fr-rCA/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-fr-rCA/strings.xml
index 82ce9a2..1d539cd 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-fr-rCA/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-fr-rCA/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLES"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"DRAPEAUX"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-fr/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-fr/strings.xml
index 34fd6ba..1bc01ec 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-fr/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-fr/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLES"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"DRAPEAUX"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-gl/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-gl/strings.xml
index 7cb2985..9a13966 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-gl/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-gl/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBXECTOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDEIRAS"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-gu/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-gu/strings.xml
index 50975a9..d0b15fe 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-gu/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-gu/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ઑબ્જેક્ટ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"પ્રતીકો"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ઝંડા"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-hi/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-hi/strings.xml
index 9b732dd..e3a1b22 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-hi/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-hi/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ऑब्जेक्ट"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"सिंबल"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"झंडे"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-hr/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-hr/strings.xml
index 0bc0396..a2dcb08 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-hr/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-hr/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ZASTAVE"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Nije dostupan nijedan emoji"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-hu/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-hu/strings.xml
index 27f306f..57fbcd8d 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-hu/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-hu/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"TÁRGYAK"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SZIMBÓLUMOK"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ZÁSZLÓK"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-hy/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-hy/strings.xml
index f88c5f0..7842e75 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-hy/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-hy/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ԱՌԱՐԿԱՆԵՐ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ՆՇԱՆՆԵՐ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ԴՐՈՇՆԵՐ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-in/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-in/strings.xml
index 75fe397..fcb4268 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-in/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-in/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEK"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOL"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BENDERA"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-is/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-is/strings.xml
index 8449afb..86c6d24 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-is/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-is/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"HLUTIR"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"TÁKN"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FÁNAR"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-it/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-it/strings.xml
index 7ae073b..91b2d1e 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-it/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-it/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OGGETTI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDIERE"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-iw/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-iw/strings.xml
index 0f72649..2114632 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-iw/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-iw/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"אובייקטים"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"סמלים"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"דגלים"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ja/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ja/strings.xml
index aa5af40..d4bad63 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ja/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ja/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"アイテム"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"記号"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"旗"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ka/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ka/strings.xml
index 550663f..fc2be1d 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ka/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ka/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ობიექტები"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"სიმბოლოები"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"დროშები"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-kk/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-kk/strings.xml
index c59ebb8..9ea1326 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-kk/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-kk/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"НЫСАНДАР"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ТАҢБАЛАР"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ЖАЛАУШАЛАР"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-km/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-km/strings.xml
index 88bb970..180d981 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-km/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-km/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"វត្ថុ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"និមិត្តសញ្ញា"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ទង់ជាតិ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-kn/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-kn/strings.xml
index c1bc2ae..8967259 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-kn/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-kn/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ವಸ್ತುಗಳು"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ಸಂಕೇತಗಳು"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ಫ್ಲ್ಯಾಗ್‌ಗಳು"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ko/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ko/strings.xml
index 92a44db..556d96e 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ko/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ko/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"사물"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"기호"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"깃발"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ky/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ky/strings.xml
index c6c3658..bf96ba5 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ky/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ky/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБЪЕКТТЕР"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМВОЛДОР"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ЖЕЛЕКТЕР"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-lo/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-lo/strings.xml
index 93f8f6a..58728bf 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-lo/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-lo/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ວັດຖຸ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ສັນຍາລັກ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ທຸງ"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"ບໍ່ມີອີໂມຈິໃຫ້ນຳໃຊ້"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-lt/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-lt/strings.xml
index 69c0624..6e243bf 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-lt/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-lt/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTAI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLIAI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"VĖLIAVOS"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-lv/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-lv/strings.xml
index eef9dca..eaae840 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-lv/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-lv/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"KAROGI"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-mk/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-mk/strings.xml
index 3f844e5..194dbfe 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-mk/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-mk/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБЈЕКТИ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМБОЛИ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ЗНАМИЊА"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Нема достапни емоџија"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ml/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ml/strings.xml
index 95f3bb7..6551915 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ml/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ml/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"വസ്‌തുക്കൾ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ചിഹ്നങ്ങൾ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"പതാകകൾ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-mn/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-mn/strings.xml
index dfbe911..0903d6d 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-mn/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-mn/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБЪЕКТ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ТЭМДЭГ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ТУГ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-mr/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-mr/strings.xml
index f84380b..133595a 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-mr/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-mr/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ऑब्जेक्ट"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"चिन्हे"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ध्वज"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ms/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ms/strings.xml
index 4b21953..bbd44a1 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ms/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ms/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEK"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOL"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BENDERA"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Tiada emoji tersedia"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-my/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-my/strings.xml
index 371a93a..22a6327 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-my/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-my/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"အရာဝတ္ထုများ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"သင်္ကေတများ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"အလံများ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-nb/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-nb/strings.xml
index 88e1961..600a1de 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-nb/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-nb/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"GJENSTANDER"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLER"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGG"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ne/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ne/strings.xml
index d60e4cb..0dfae15 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ne/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ne/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"वस्तुहरू"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"चिन्हहरू"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"झन्डाहरू"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-nl/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-nl/strings.xml
index 3a4a9df..b662a97 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-nl/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-nl/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJECTEN"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLEN"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"VLAGGEN"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-or/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-or/strings.xml
index c0a2ce0..00cdd48 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-or/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-or/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ଅବଜେକ୍ଟଗୁଡ଼ିକ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ଚିହ୍ନଗୁଡ଼ିକ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ଫ୍ଲାଗଗୁଡ଼ିକ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-pa/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-pa/strings.xml
index ba141b7..0ee52cb 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-pa/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-pa/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ਵਸਤੂਆਂ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ਚਿੰਨ੍ਹ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ਝੰਡੇ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-pl/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-pl/strings.xml
index 8720f89..427f6be 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-pl/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-pl/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"PRZEDMIOTY"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLE"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGI"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-pt-rBR/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-pt-rBR/strings.xml
index 640b333..b8a0e5f 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-pt-rBR/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-pt-rBR/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDEIRAS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Não há emojis disponíveis"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-pt-rPT/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-pt-rPT/strings.xml
index 59b7ead..c6a2bf9 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-pt-rPT/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-pt-rPT/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDEIRAS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Nenhum emoji disponível"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-pt/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-pt/strings.xml
index 640b333..b8a0e5f 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-pt/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-pt/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJETOS"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SÍMBOLOS"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BANDEIRAS"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Não há emojis disponíveis"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ro/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ro/strings.xml
index 3bbfab6..44e6db0 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ro/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ro/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBIECTE"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLURI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"STEAGURI"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ru/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ru/strings.xml
index 2dec46a..fec27c9 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ru/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ru/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБЪЕКТЫ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМВОЛЫ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ФЛАГИ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-si/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-si/strings.xml
index 9716539..cbd141a 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-si/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-si/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"වස්තු"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"සංකේත"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ධජ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sk/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sk/strings.xml
index 745a0a0..93a8089 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sk/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sk/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"PREDMETY"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLY"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"VLAJKY"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Nie sú k dispozícii žiadne emodži"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sl/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sl/strings.xml
index 3e9a4bd..5f8cd6a 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sl/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sl/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"PREDMETI"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ZASTAVE"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sq/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sq/strings.xml
index 116b1e4..91bcd77 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sq/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sq/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBJEKTE"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SIMBOLE"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAMUJ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sr/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sr/strings.xml
index dac0c3e..f088321 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sr/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sr/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБЈЕКТИ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМБОЛИ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ЗАСТАВЕ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sv/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sv/strings.xml
index 57e3a2a..69b54ae 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sv/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sv/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"FÖREMÅL"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SYMBOLER"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"FLAGGOR"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-sw/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-sw/strings.xml
index ae733c2..9897f9b 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-sw/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-sw/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"VITU"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"ISHARA"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BENDERA"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ta/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ta/strings.xml
index b250ef6..f1959f6 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ta/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ta/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"பொருட்கள்"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"சின்னங்கள்"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"கொடிகள்"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-te/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-te/strings.xml
index 7af3e30..194ae55 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-te/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-te/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ఆబ్జెక్ట్‌లు"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"గుర్తులు"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ఫ్లాగ్‌లు"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-th/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-th/strings.xml
index 4a5f1b7..f6f3782 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-th/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-th/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"วัตถุ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"สัญลักษณ์"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ธง"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"ไม่มีอีโมจิ"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-tl/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-tl/strings.xml
index 41f0d3b..b0b0961 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-tl/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-tl/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"MGA BAGAY"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"MGA SIMBOLO"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"MGA BANDILA"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-tr/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-tr/strings.xml
index 1ed37d1c..a6cddbf 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-tr/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-tr/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"NESNELER"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"SEMBOLLER"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BAYRAKLAR"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-uk/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-uk/strings.xml
index ec58aa6..bb41434 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-uk/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-uk/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ОБ’ЄКТИ"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"СИМВОЛИ"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"ПРАПОРИ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-ur/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-ur/strings.xml
index d11be3d..5ba39c4 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-ur/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-ur/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"آبجیکٹس"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"علامات"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"جھنڈے"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-uz/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-uz/strings.xml
index a51d22f..5107f5e 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-uz/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-uz/strings.xml
@@ -26,4 +26,5 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"OBYEKTLAR"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"BELGILAR"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"BAYROQCHALAR"</string>
+    <string name="emoji_empty_non_recent_category" msgid="288822832574892625">"Hech qanday emoji mavjud emas"</string>
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-vi/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-vi/strings.xml
index 4a3f34a..4583227 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-vi/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-vi/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"ĐỒ VẬT"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"BIỂU TƯỢNG"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"CỜ"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rCN/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rCN/strings.xml
index d1438f6..509d61e 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rCN/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rCN/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"物体"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"符号"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"旗帜"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rHK/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rHK/strings.xml
index 32b5850..ff47ce4 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rHK/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rHK/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"物件"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"符號"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"旗幟"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rTW/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rTW/strings.xml
index afd04e4..135da04 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-zh-rTW/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-zh-rTW/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"物品"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"符號"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"旗幟"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
diff --git a/emoji2/emoji2-emojipicker/src/main/res/values-zu/strings.xml b/emoji2/emoji2-emojipicker/src/main/res/values-zu/strings.xml
index fd576f9..332f6e4 100644
--- a/emoji2/emoji2-emojipicker/src/main/res/values-zu/strings.xml
+++ b/emoji2/emoji2-emojipicker/src/main/res/values-zu/strings.xml
@@ -26,4 +26,6 @@
     <string name="emoji_category_objects" msgid="6106115586332708067">"IZINTO"</string>
     <string name="emoji_category_symbols" msgid="5626171724310261787">"AMASIMBULI"</string>
     <string name="emoji_category_flags" msgid="6185639503532784871">"AMAFULEGI"</string>
+    <!-- no translation found for emoji_empty_non_recent_category (288822832574892625) -->
+    <skip />
 </resources>
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 b5ce3e7..10cd1d2 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentContainerViewTest.kt
@@ -31,7 +31,7 @@
 import androidx.core.view.OnApplyWindowInsetsListener
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowInsetsCompat
-import androidx.fragment.app.test.FragmentTestActivity
+import androidx.fragment.app.test.EmptyFragmentTestActivity
 import androidx.fragment.test.R
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -46,13 +46,19 @@
 import org.junit.runner.RunWith
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
+import leakcanary.DetectLeaksAfterTestSuccess
+import org.junit.rules.RuleChain
 
 @MediumTest
 @RunWith(AndroidJUnit4::class)
 class FragmentContainerViewTest {
     @Suppress("DEPRECATION")
+    val activityRule = androidx.test.rule.ActivityTestRule(EmptyFragmentTestActivity::class.java)
+
     @get:Rule
-    var activityRule = androidx.test.rule.ActivityTestRule(FragmentTestActivity::class.java)
+    val ruleChain: RuleChain = RuleChain.outerRule(DetectLeaksAfterTestSuccess())
+        .around(activityRule)
+
     lateinit var context: Context
 
     @Before
@@ -421,6 +427,8 @@
             .that(drawnFirstCountDownLatch.await(1, TimeUnit.SECONDS))
             .isTrue()
         assertThat(drawnFirst!!).isEqualTo(frag1View)
+
+        drawnFirst = null
     }
 
     // Disappearing child views should be drawn last if transaction is a pop.
@@ -479,6 +487,8 @@
             .isTrue()
         // The popped Fragment will be drawn last and therefore will be on top
         assertThat(drawnFirst!!).isNotEqualTo(frag2View)
+
+        drawnFirst = null
     }
 
     @Test
@@ -543,6 +553,8 @@
             .that(drawnFirstCountDownLatch.await(1, TimeUnit.SECONDS))
             .isTrue()
         assertThat(drawnFirst!!).isNotEqualTo(frag2View)
+
+        drawnFirst = null
     }
 
     @Test
@@ -610,6 +622,8 @@
             .that(drawnFirstCountDownLatch.await(1, TimeUnit.SECONDS))
             .isTrue()
         assertThat(drawnFirst!!).isNotEqualTo(frag2View)
+
+        drawnFirst = null
     }
 
     @Test
@@ -678,6 +692,8 @@
             .isTrue()
         // The view that was popped is drawn first which means it is on the bottom.
         assertThat(drawnFirst!!).isEqualTo(frag2View)
+
+        drawnFirst = null
     }
 
     @Test
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 df4978c..b897a54 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReceiveResultTest.kt
@@ -30,12 +30,13 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 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
 
 /**
  * Tests for Fragment startActivityForResult and startIntentSenderForResult.
@@ -44,22 +45,18 @@
 @MediumTest
 class FragmentReceiveResultTest {
     @Suppress("DEPRECATION")
-    @get:Rule
     val activityRule = androidx.test.rule.ActivityTestRule(FragmentTestActivity::class.java)
 
-    private lateinit var activity: FragmentTestActivity
-    private lateinit var fragment: TestFragment
-
-    @Before
-    fun setup() {
-        activity = activityRule.activity
-        fragment = attachTestFragment()
-    }
+    // Detect leaks BEFORE and AFTER activity is destroyed
+    @get:Rule
+    val ruleChain: RuleChain = RuleChain.outerRule(DetectLeaksAfterTestSuccess())
+        .around(activityRule)
 
     @Suppress("DEPRECATION")
     @Test
     @UiThreadTest
     fun testNoFragmentOnActivityResult() {
+        val activity = activityRule.activity
         activity.supportFragmentManager.saveAllStateInternal()
 
         // 0xffff is the request code for the startActivityResult launcher in FragmentManager
@@ -70,12 +67,17 @@
     @Test
     fun testNoFragmentOnRequestPermissionsResult() {
         // 0xffff + 2 is the request code for the requestPermissions launcher in FragmentManager
-        activity.onRequestPermissionsResult(0xffff + 2, arrayOf("permission"), intArrayOf(1))
+        activityRule.activity.onRequestPermissionsResult(
+            0xffff + 2,
+            arrayOf("permission"),
+            intArrayOf(1)
+        )
     }
 
     @Test
     fun testStartActivityForResultOk() {
-        startActivityForResult(10, Activity.RESULT_OK, "content 10")
+        val fragment: TestFragment = attachTestFragment()
+        startActivityForResult(fragment, 10, Activity.RESULT_OK, "content 10")
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(10)
@@ -85,8 +87,9 @@
 
     @Test
     fun testMultipleStartActivityForResultOk() {
-        startActivityForResult(10, Activity.RESULT_OK, "content 10")
-        startActivityForResult(20, Activity.RESULT_OK, "content 20")
+        val fragment: TestFragment = attachTestFragment()
+        startActivityForResult(fragment, 10, Activity.RESULT_OK, "content 10")
+        startActivityForResult(fragment, 20, Activity.RESULT_OK, "content 20")
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(10)
@@ -101,7 +104,8 @@
 
     @Test
     fun testStartActivityForResultCanceled() {
-        startActivityForResult(20, Activity.RESULT_CANCELED, "content 20")
+        val fragment: TestFragment = attachTestFragment()
+        startActivityForResult(fragment, 20, Activity.RESULT_CANCELED, "content 20")
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(20)
@@ -111,7 +115,8 @@
 
     @Test
     fun testStartIntentSenderForResultOk() {
-        startIntentSenderForResult(30, Activity.RESULT_OK, "content 30")
+        val fragment: TestFragment = attachTestFragment()
+        startIntentSenderForResult(fragment, 30, Activity.RESULT_OK, "content 30")
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(30)
@@ -121,7 +126,8 @@
 
     @Test
     fun testStartIntentSenderForResultWithOptionsOk() {
-        startIntentSenderForResult(30, Activity.RESULT_OK, "content 30", Bundle())
+        val fragment: TestFragment = attachTestFragment()
+        startIntentSenderForResult(fragment, 30, Activity.RESULT_OK, "content 30", Bundle())
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(30)
@@ -131,7 +137,8 @@
 
     @Test
     fun testStartIntentSenderForResultCanceled() {
-        startIntentSenderForResult(40, Activity.RESULT_CANCELED, "content 40")
+        val fragment: TestFragment = attachTestFragment()
+        startIntentSenderForResult(fragment, 40, Activity.RESULT_CANCELED, "content 40")
 
         assertWithMessage("Fragment should receive result").that(fragment.hasResult[0]).isTrue()
         assertThat(fragment.requestCode[0]).isEqualTo(40)
@@ -140,6 +147,7 @@
     }
 
     private fun attachTestFragment(): TestFragment {
+        val activity = activityRule.activity
         val fragment = TestFragment()
         activityRule.runOnUiThread {
             activity.supportFragmentManager.beginTransaction()
@@ -154,10 +162,12 @@
 
     @Suppress("DEPRECATION")
     private fun startActivityForResult(
+        fragment: TestFragment,
         requestCode: Int,
         resultCode: Int,
         content: String
     ) {
+        val activity = activityRule.activity
         activityRule.runOnUiThread {
             val intent = Intent(activity, FragmentResultActivity::class.java)
             intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode)
@@ -174,11 +184,13 @@
 
     @Suppress("DEPRECATION")
     private fun startIntentSenderForResult(
+        fragment: TestFragment,
         requestCode: Int,
         resultCode: Int,
         content: String,
         options: Bundle? = null
     ) {
+        val activity = activityRule.activity
         activityRule.runOnUiThread {
             val intent = Intent(activity, FragmentResultActivity::class.java)
             intent.putExtra(FragmentResultActivity.EXTRA_RESULT_CODE, resultCode)
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
index fde5c4d..57ffc27 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
@@ -15,7 +15,6 @@
  */
 package androidx.fragment.app
 
-import android.app.Instrumentation
 import android.view.View
 import android.view.ViewGroup
 import android.widget.EditText
@@ -28,9 +27,11 @@
 import androidx.test.platform.app.InstrumentationRegistry
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+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
 
 @SmallTest
@@ -38,25 +39,24 @@
 class FragmentReorderingTest() {
 
     @Suppress("DEPRECATION")
-    @get:Rule
     var activityRule = androidx.test.rule.ActivityTestRule(FragmentTestActivity::class.java)
 
-    private lateinit var container: ViewGroup
-    private lateinit var fm: FragmentManager
-    private lateinit var instrumentation: Instrumentation
+    // Detect leaks BEFORE and AFTER activity is destroyed
+    @get:Rule
+    val ruleChain: RuleChain = RuleChain.outerRule(DetectLeaksAfterTestSuccess())
+        .around(activityRule)
 
     @Before
     fun setup() {
         activityRule.setContentView(R.layout.simple_container)
-        container = activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
-        fm = activityRule.activity.supportFragmentManager
-        instrumentation = InstrumentationRegistry.getInstrumentation()
     }
 
     // Ensure that a replaced fragment is stopped before its replacement is started
     // and vice versa when popped
     @Test
     fun stopBeforeStart() {
+        val fm = activityRule.activity.supportFragmentManager
+
         val fragment1 = StrictViewFragment()
         fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -67,7 +67,7 @@
         val fragment2 = StrictViewFragment()
         lateinit var replaceStateWhenStopped: Lifecycle.State
         lateinit var replaceStateWhenPopStarted: Lifecycle.State
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fragment1.lifecycle.addObserver(
                 LifecycleEventObserver { _, event ->
                     if (event == Lifecycle.Event.ON_STOP) {
@@ -104,6 +104,11 @@
     // actually creates a View.
     @Test
     fun addReplace() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
+
         val fragment1 = CountCallsFragment()
         val fragment2 = StrictViewFragment()
         instrumentation.runOnMainSync {
@@ -134,6 +139,10 @@
     // the same view back again.
     @Test
     fun startWithPop() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
+
         // Start with a single fragment on the back stack
         val fragment1 = CountCallsFragment()
         fm.beginTransaction()
@@ -146,7 +155,7 @@
         assertChildren(container, fragment1)
 
         // Now pop and add
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.popBackStack()
             fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
@@ -166,9 +175,12 @@
     // Popping the back stack in the middle of other operations doesn't fool it.
     @Test
     fun middlePop() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val fragment2 = CountCallsFragment()
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
                 .addToBackStack(null)
@@ -195,9 +207,12 @@
     // View being created. Hide still gets notified.
     @Test
     fun removeRedundantRemove() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         var id = -1
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             id = fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
                 .addToBackStack(null)
@@ -234,6 +249,9 @@
     // Ensure that removing and adding the same view results in no operation
     @Test
     fun removeRedundantAdd() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -243,7 +261,7 @@
         activityRule.executePendingTransactions()
         assertThat(fragment1.onCreateViewCount).isEqualTo(1)
 
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .remove(fragment1)
                 .addToBackStack(null)
@@ -271,6 +289,9 @@
     // detaching, then attaching results in on change. Hide still functions
     @Test
     fun removeRedundantAttach() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -281,7 +302,7 @@
         assertThat(fragment1.onAttachCount).isEqualTo(1)
         assertChildren(container, fragment1)
 
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .detach(fragment1)
                 .addToBackStack(null)
@@ -325,6 +346,9 @@
     // attaching, then detaching shouldn't result in a View being created
     @Test
     fun removeRedundantDetach() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -341,7 +365,7 @@
         assertThat(fragment1.onCreateViewCount).isEqualTo(0)
         assertChildren(container)
 
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .attach(fragment1)
                 .addToBackStack(null)
@@ -383,6 +407,10 @@
     // show, then hide should optimize out
     @Test
     fun removeRedundantHide() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
+        val instrumentation = InstrumentationRegistry.getInstrumentation()
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -494,6 +522,9 @@
     // hiding and showing the same view should optimize out
     @Test
     fun removeRedundantShow() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -505,7 +536,7 @@
         assertThat(fragment1.onHideCount).isEqualTo(0)
         assertChildren(container, fragment1)
 
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .hide(fragment1)
                 .addToBackStack(null)
@@ -544,6 +575,9 @@
     // the transaction completes.
     @Test
     fun viewOrder() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val id = fm.beginTransaction()
             .add(R.id.fragmentContainer, fragment1)
@@ -555,7 +589,7 @@
 
         val fragment2 = CountCallsFragment()
 
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .replace(R.id.fragmentContainer, fragment2)
                 .addToBackStack(null)
@@ -578,8 +612,11 @@
     // Popping an added transaction results in no operation
     @Test
     fun addPopBackStack() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
                 .addToBackStack(null)
@@ -598,9 +635,12 @@
     // optimization.
     @Test
     fun popNonBackStack() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val fragment2 = CountCallsFragment()
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
                 .addToBackStack(null)
@@ -623,9 +663,12 @@
     // transaction should all be run prior to running the ordered transaction.
     @Test
     fun noReordering() {
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
         val fragment1 = CountCallsFragment()
         val fragment2 = CountCallsFragment()
-        instrumentation.runOnMainSync {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
             fm.beginTransaction()
                 .add(R.id.fragmentContainer, fragment1)
                 .addToBackStack(null)
@@ -649,7 +692,9 @@
     @Test
     fun focusedView() {
         activityRule.setContentView(R.layout.double_container)
-        container = activityRule.activity.findViewById<View>(R.id.fragmentContainer1) as ViewGroup
+        val fm = activityRule.activity.supportFragmentManager
+        val container =
+            activityRule.activity.findViewById<View>(R.id.fragmentContainer1) as ViewGroup
         lateinit var firstEditText: EditText
         activityRule.runOnUiThread {
             firstEditText = EditText(container.context)
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
index 5ab086a..6ed9681 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
@@ -53,11 +53,256 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Static library support version of the framework's {@link android.app.DialogFragment}.
- * Used to write apps that run on platforms prior to Android 3.0.  When running
- * on Android 3.0 or above, this implementation is still used; it does not try
- * to switch to the framework's implementation.  See the framework SDK
- * documentation for a class overview.
+ * A fragment that displays a dialog window, floating in the foreground of its
+ * activity's window.  This fragment contains a Dialog object, which it
+ * displays as appropriate based on the fragment's state.  Control of
+ * the dialog (deciding when to show, hide, dismiss it) should be done through
+ * the APIs here, not with direct calls on the dialog.
+ *
+ * <p>Implementations should override this class and implement
+ * {@link #onViewCreated(View, Bundle)} to supply the
+ * content of the dialog.  Alternatively, they can override
+ * {@link #onCreateDialog(Bundle)} to create an entirely custom dialog, such
+ * as an AlertDialog, with its own content.
+ *
+ * <p>Topics covered here:
+ * <ol>
+ * <li><a href="#Lifecycle">Lifecycle</a>
+ * <li><a href="#BasicDialog">Basic Dialog</a>
+ * <li><a href="#AlertDialog">Alert Dialog</a>
+ * <li><a href="#DialogOrEmbed">Selecting Between Dialog or Embedding</a>
+ * </ol>
+ *
+ * <a name="Lifecycle"></a>
+ * <h3>Lifecycle</h3>
+ *
+ * <p>DialogFragment does various things to keep the fragment's lifecycle
+ * driving it, instead of the Dialog.  Note that dialogs are generally
+ * autonomous entities -- they are their own window, receiving their own
+ * input events, and often deciding on their own when to disappear (by
+ * receiving a back key event or the user clicking on a button).
+ *
+ * <p>DialogFragment needs to ensure that what is happening with the Fragment
+ * and Dialog states remains consistent.  To do this, it watches for dismiss
+ * events from the dialog and takes care of removing its own state when they
+ * happen.  This means you should use {@link #show(FragmentManager, String)},
+ * {@link #show(FragmentTransaction, String)}, or {@link #showNow(FragmentManager, String)}
+ * to add an instance of DialogFragment to your UI, as these keep track of
+ * how DialogFragment should remove itself when the dialog is dismissed.
+ *
+ * <a name="BasicDialog"></a>
+ * <h3>Basic Dialog</h3>
+ *
+ * <p>The simplest use of DialogFragment is as a floating container for the
+ * fragment's view hierarchy.  A simple implementation may look like this:
+ *
+ * <pre>{@code
+ * public class MyDialogFragment extends DialogFragment {
+ *     int mNum;
+ *
+ *     // Create a new instance of MyDialogFragment, providing "num" as an argument.
+ *     static MyDialogFragment newInstance(int num) {
+ *         MyDialogFragment f = new MyDialogFragment();
+ *
+ *         // Supply num input as an argument.
+ *         Bundle args = new Bundle();
+ *         args.putInt("num", num);
+ *         f.setArguments(args);
+ *
+ *         return f;
+ *     }
+ *
+ *     {@literal @}Override
+ *     public void onCreate(Bundle savedInstanceState) {
+ *         super.onCreate(savedInstanceState);
+ *         mNum = getArguments().getInt("num");
+ *
+ *         // Pick a style based on the num.
+ *         int style = DialogFragment.STYLE_NORMAL, theme = 0;
+ *         switch ((mNum-1)%6) {
+ *             case 1: style = DialogFragment.STYLE_NO_TITLE; break;
+ *             case 2: style = DialogFragment.STYLE_NO_FRAME; break;
+ *             case 3: style = DialogFragment.STYLE_NO_INPUT; break;
+ *             case 4: style = DialogFragment.STYLE_NORMAL; break;
+ *             case 5: style = DialogFragment.STYLE_NORMAL; break;
+ *             case 6: style = DialogFragment.STYLE_NO_TITLE; break;
+ *             case 7: style = DialogFragment.STYLE_NO_FRAME; break;
+ *             case 8: style = DialogFragment.STYLE_NORMAL; break;
+ *         }
+ *         switch ((mNum-1)%6) {
+ *             case 4: theme = android.R.style.Theme_Holo; break;
+ *             case 5: theme = android.R.style.Theme_Holo_Light_Dialog; break;
+ *             case 6: theme = android.R.style.Theme_Holo_Light; break;
+ *             case 7: theme = android.R.style.Theme_Holo_Light_Panel; break;
+ *             case 8: theme = android.R.style.Theme_Holo_Light; break;
+ *         }
+ *         setStyle(style, theme);
+ *     }
+ *
+ *     {@literal @}Override
+ *     public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ *                              Bundle savedInstanceState) {
+ *         return inflater.inflate(R.layout.fragment_dialog, container, false);
+ *     }
+ *
+ *     {@literal @}Override
+ *     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ *         super.onViewCreated(view, savedInstanceState);
+ *
+ *         // set DialogFragment title
+ *         getDialog().setTitle("Dialog #" + mNum);
+ *     }
+ * }
+ * }</pre>
+ *
+ * <p>An example showDialog() method on the Activity could be:
+ *
+ * <pre>{@code
+ * public void showDialog() {
+ *     mStackLevel++;
+ *
+ *     // DialogFragment.show() will take care of adding the fragment
+ *     // in a transaction.  We also want to remove any currently showing
+ *     // dialog, so make our own transaction and take care of that here.
+ *     FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ *     Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
+ *     if (prev != null) {
+ *         ft.remove(prev);
+ *     }
+ *     ft.addToBackStack(null);
+ *
+ *     // Create and show the dialog.
+ *     DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
+ *     newFragment.show(ft, "dialog");
+ * }
+ * }</pre>
+ *
+ * <p>This removes any currently shown dialog, creates a new DialogFragment
+ * with an argument, and shows it as a new state on the back stack.  When the
+ * transaction is popped, the current DialogFragment and its Dialog will be
+ * destroyed, and the previous one (if any) re-shown.  Note that in this case
+ * DialogFragment will take care of popping the transaction of the Dialog that
+ * is dismissed separately from it.
+ *
+ * <a name="AlertDialog"></a>
+ * <h3>Alert Dialog</h3>
+ *
+ * <p>Instead of (or in addition to) implementing {@link #onViewCreated(View, Bundle)} to
+ * generate the view hierarchy inside of a dialog, you may implement
+ * {@link #onCreateDialog(Bundle)} to create your own custom Dialog object.
+ *
+ * <p>This is most useful for creating an AlertDialog, allowing you
+ * to display standard alerts to the user that are managed by a fragment.
+ * A simple example implementation of this is:
+ *
+ * <pre>{@code
+ * public static class MyAlertDialogFragment extends DialogFragment {
+ *
+ *     public static MyAlertDialogFragment newInstance(int title) {
+ *         MyAlertDialogFragment frag = new MyAlertDialogFragment();
+ *         Bundle args = new Bundle();
+ *         args.putInt("title", title);
+ *         frag.setArguments(args);
+ *         return frag;
+ *     }
+ *
+ *     {@literal @}Override
+ *     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+ *
+ *         return new AlertDialog.Builder(getActivity())
+ *                 .setIcon(R.drawable.alert_dialog_icon)
+ *                 .setTitle(title)
+ *                 .setPositiveButton(R.string.alert_dialog_ok,
+ *                         (dialogInterface, i) -> ((MainActivity)getActivity()).doPositiveClick())
+ *                 .setNegativeButton(R.string.alert_dialog_cancel,
+ *                         (dialogInterface, i) -> ((MainActivity)getActivity()).doNegativeClick())
+ *                 .create();
+ *         return super.onCreateDialog(savedInstanceState);
+ *     }
+ * }
+ * }</pre>
+ *
+ * <p>The activity creating this fragment may have the following methods to
+ * show the dialog and receive results from it:
+ *
+ * <pre>{@code
+ * void showDialog() {
+ *     DialogFragment newFragment = MyAlertDialogFragment.newInstance(
+ *             R.string.alert_dialog_two_buttons_title);
+ *     newFragment.show(getSupportFragmentManager(), "dialog");
+ * }
+ *
+ * public void doPositiveClick() {
+ *     // Do stuff here.
+ *     Log.i("MainActivity", "Positive click!");
+ * }
+ *
+ * public void doNegativeClick() {
+ *     // Do stuff here.
+ *     Log.i("MainActivity", "Negative click!");
+ * }
+ * }</pre>
+ *
+ * <p>Note that in this case the fragment is not placed on the back stack, it
+ * is just added as an indefinitely running fragment.  Because dialogs normally
+ * are modal, this will still operate as a back stack, since the dialog will
+ * capture user input until it is dismissed.  When it is dismissed, DialogFragment
+ * will take care of removing itself from its fragment manager.
+ *
+ * <a name="DialogOrEmbed"></a>
+ * <h3>Selecting Between Dialog or Embedding</h3>
+ *
+ * <p>A DialogFragment can still optionally be used as a normal fragment, if
+ * desired.  This is useful if you have a fragment that in some cases should
+ * be shown as a dialog and others embedded in a larger UI.  This behavior
+ * will normally be automatically selected for you based on how you are using
+ * the fragment, but can be customized with {@link #setShowsDialog(boolean)}.
+ *
+ * <p>For example, here is a simple dialog fragment:
+ *
+ * <pre>{@code
+ * public static class MyDialogFragment extends DialogFragment {
+ *     static MyDialogFragment newInstance() {
+ *         return new MyDialogFragment();
+ *     }
+ *
+ *     {@literal @}Override
+ *     public void onCreate(Bundle savedInstanceState) {
+ *         super.onCreate(savedInstanceState);
+ *
+ *         // this fragment will be displayed in a dialog
+ *         setShowsDialog(true);
+ *     }
+ *
+ *     {@literal @}Override
+ *     public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ *             Bundle savedInstanceState) {
+ *         View v = inflater.inflate(R.layout.hello_world, container, false);
+ *         View tv = v.findViewById(R.id.text);
+ *         ((TextView)tv).setText("This is an instance of MyDialogFragment");
+ *         return v;
+ *     }
+ * }
+ * }</pre>
+ *
+ * <p>An instance of this fragment can be created and shown as a dialog:
+ *
+ * <pre>{@code
+ * void showDialog() {
+ *     // Create the fragment and show it as a dialog.
+ *     DialogFragment newFragment = MyDialogFragment.newInstance();
+ *     newFragment.show(getSupportFragmentManager(), "dialog");
+ * }
+ * }</pre>
+ *
+ * <p>It can also be added as content in a view hierarchy:
+ *
+ * <pre>{@code
+ * FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ * DialogFragment newFragment = MyDialogFragment.newInstance();
+ * ft.add(R.id.embedded, newFragment);
+ * ft.commit();
+ * }</pre>
  */
 public class DialogFragment extends Fragment
         implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/build.gradle b/glance/glance-appwidget/integration-tests/macrobenchmark-target/build.gradle
new file mode 100644
index 0000000..c4be7d4
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/build.gradle
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+
+plugins {
+    id("AndroidXPlugin")
+    id("AndroidXComposePlugin")
+    id("com.android.application")
+    id("org.jetbrains.kotlin.android")
+}
+
+dependencies {
+    implementation(libs.kotlinStdlib)
+    implementation(project(":glance:glance"))
+    implementation(project(":glance:glance-appwidget"))
+}
+
+android {
+    namespace "androidx.glance.appwidget.macrobenchmark.target"
+    buildTypes {
+        release {
+            minifyEnabled true
+            shrinkResources true
+            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"),
+                    'proguard-rules.pro'
+        }
+    }
+
+}
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/proguard-rules.pro b/glance/glance-appwidget/integration-tests/macrobenchmark-target/proguard-rules.pro
new file mode 100644
index 0000000..0674e77
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/proguard-rules.pro
@@ -0,0 +1 @@
+-dontobfuscate
\ No newline at end of file
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2791119
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?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 xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <application
+        android:allowBackup="false"
+        android:label="glance-appwidget macrobenchmark target"
+        android:supportsRtl="true">
+        <!-- Profileable to enable macrobenchmark profiling -->
+        <profileable android:shell="true"/>
+
+        <receiver
+            android:name="androidx.glance.appwidget.macrobenchmark.target.BasicAppWidgetReceiver"
+            android:label="BasicAppWidget Receiver"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+                <action android:name="androidx.glance.appwidget.action.DEBUG_UPDATE" />
+                <action android:name="android.intent.action.LOCALE_CHANGED" />
+            </intent-filter>
+            <meta-data
+                android:name="android.appwidget.provider"
+                android:resource="@xml/default_app_widget_info" />
+        </receiver>
+        <receiver
+            android:name="androidx.glance.appwidget.macrobenchmark.target.BasicAppWidgetWithSessionReceiver"
+            android:label="BasicAppWidget Receiver with sessions enabled"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+                <action android:name="androidx.glance.appwidget.action.DEBUG_UPDATE" />
+                <action android:name="android.intent.action.LOCALE_CHANGED" />
+            </intent-filter>
+            <meta-data
+                android:name="android.appwidget.provider"
+                android:resource="@xml/default_app_widget_info" />
+        </receiver>
+    </application>
+</manifest>
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/java/androidx/glance/appwidget/macrobenchmark/target/BasicAppWidget.kt b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/java/androidx/glance/appwidget/macrobenchmark/target/BasicAppWidget.kt
new file mode 100644
index 0000000..b12aaca
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/java/androidx/glance/appwidget/macrobenchmark/target/BasicAppWidget.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.glance.appwidget.macrobenchmark.target
+
+import androidx.compose.runtime.Composable
+import androidx.datastore.preferences.core.Preferences
+import androidx.glance.GlanceModifier
+import androidx.glance.LocalSize
+import androidx.glance.appwidget.GlanceAppWidget
+import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import androidx.glance.appwidget.SizeMode
+import androidx.glance.appwidget.Tracing
+import androidx.glance.currentState
+import androidx.glance.layout.Column
+import androidx.glance.layout.fillMaxSize
+import androidx.glance.session.GlanceSessionManager
+import androidx.glance.text.Text
+import kotlin.math.roundToInt
+
+open class BasicAppWidget : GlanceAppWidget() {
+    init {
+        // Ensure tracing is enabled before starting updates.
+        Tracing.enabled.set(true)
+    }
+    override val sizeMode: SizeMode = SizeMode.Single
+
+    @Composable
+    override fun Content() {
+        val size = LocalSize.current
+        // Even though this widget does not use it, accessing state will ensure that this
+        // is recomposed every time state updates, which is useful for testing.
+        currentState<Preferences>()
+        Column(
+            modifier = GlanceModifier.fillMaxSize(),
+        ) {
+            Text(
+                " Current size: ${size.width.value.roundToInt()} dp x " +
+                    "${size.height.value.roundToInt()} dp"
+            )
+        }
+    }
+}
+
+class BasicAppWidgetWithSession : BasicAppWidget() {
+    override val sessionManager = GlanceSessionManager
+}
+
+class BasicAppWidgetReceiver : GlanceAppWidgetReceiver() {
+    override val glanceAppWidget: GlanceAppWidget = BasicAppWidget()
+}
+
+class BasicAppWidgetWithSessionReceiver : GlanceAppWidgetReceiver() {
+    override val glanceAppWidget: GlanceAppWidget = BasicAppWidgetWithSession()
+}
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/layout/glance_default_loading_layout.xml b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/layout/glance_default_loading_layout.xml
new file mode 100644
index 0000000..509cb21
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/layout/glance_default_loading_layout.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</LinearLayout>
\ No newline at end of file
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/xml/default_app_widget_info.xml b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/xml/default_app_widget_info.xml
new file mode 100644
index 0000000..35afa69
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark-target/src/main/res/xml/default_app_widget_info.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="100dp"
+    android:minHeight="100dp"
+    android:initialLayout="@layout/glance_default_loading_layout"
+    android:minResizeHeight="40dp"
+    android:minResizeWidth="40dp"
+    android:resizeMode="horizontal|vertical"
+    android:widgetCategory="home_screen" />
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle b/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle
new file mode 100644
index 0000000..8bc801c
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/build.gradle
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+plugins {
+    id("AndroidXPlugin")
+    id("com.android.library")
+    id("kotlin-android")
+}
+
+android {
+    namespace "androidx.glance.appwidget.macrobenchmark"
+}
+
+android.defaultConfig {
+    minSdkVersion 23
+}
+
+dependencies {
+    implementation 'androidx.compose.ui:ui-unit:1.2.1'
+    androidTestImplementation('androidx.benchmark:benchmark-junit4:1.1.0')
+    androidTestImplementation('androidx.benchmark:benchmark-macro-junit4:1.1.0')
+    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)
+}
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
new file mode 100644
index 0000000..05a1d72
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt
new file mode 100644
index 0000000..93939ba
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostRule.kt
@@ -0,0 +1,141 @@
+/*
+ * 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.glance.appwidget.macrobenchmark
+
+import android.Manifest
+import android.appwidget.AppWidgetManager
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.os.Trace
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.dp
+import androidx.glance.appwidget.GlanceAppWidgetReceiver
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.filters.SdkSuppress
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import org.junit.rules.RuleChain
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+@SdkSuppress(minSdkVersion = 29)
+class AppWidgetHostRule(
+    private var mPortraitSize: DpSize = DpSize(200.dp, 300.dp),
+    private var mLandscapeSize: DpSize = DpSize(300.dp, 200.dp),
+    useSession: Boolean = false,
+) : TestRule {
+    private val mInstrumentation = InstrumentationRegistry.getInstrumentation()
+    private val mUiAutomation = mInstrumentation.uiAutomation
+    private val targetComponent =
+        ComponentName(
+            "androidx.glance.appwidget.macrobenchmark.target",
+            if (useSession) {
+                "androidx.glance.appwidget.macrobenchmark.target.BasicAppWidgetWithSessionReceiver"
+            } else {
+                "androidx.glance.appwidget.macrobenchmark.target.BasicAppWidgetReceiver"
+            }
+        )
+
+    private val mActivityRule: ActivityScenarioRule<AppWidgetHostTestActivity> =
+        ActivityScenarioRule(
+            Intent()
+                .setComponent(
+                    ComponentName(
+                        ApplicationProvider.getApplicationContext(),
+                        AppWidgetHostTestActivity::class.java,
+                    )
+                )
+                .putExtra(
+                    AppWidgetHostTestActivity.EXTRA_TARGET_RECEIVER,
+                    targetComponent
+                )
+        )
+
+    private val mUiDevice = UiDevice.getInstance(mInstrumentation)
+
+    // Ensure the screen starts in portrait and restore the orientation on leaving
+    private val mOrientationRule = TestRule { base, _ ->
+        object : Statement() {
+            override fun evaluate() {
+                mUiDevice.freezeRotation()
+                mUiDevice.setOrientationNatural()
+                base.evaluate()
+                mUiDevice.unfreezeRotation()
+            }
+        }
+    }
+
+    private val mInnerRules = RuleChain.outerRule(mActivityRule).around(mOrientationRule)
+
+    private var mHostStarted = false
+    private var mMaybeHostView: TestAppWidgetHostView? = null
+    private var mAppWidgetId = 0
+    private val mContext = ApplicationProvider.getApplicationContext<Context>()
+
+    override fun apply(base: Statement, description: Description) = object : Statement() {
+        override fun evaluate() {
+            mInnerRules.apply(base, description).evaluate()
+            if (mHostStarted) {
+                mUiAutomation.dropShellPermissionIdentity()
+            }
+        }
+    }
+
+    /**
+     * Start the host and bind the app widget.
+     * Measures time from binding an app widget to receiving the first RemoteViews.
+     */
+    fun startHost() {
+        mUiAutomation.adoptShellPermissionIdentity(Manifest.permission.BIND_APPWIDGET)
+        mHostStarted = true
+
+        Trace.beginSection("appWidgetInitialUpdate")
+        mActivityRule.scenario.onActivity { activity ->
+            mMaybeHostView = activity.bindAppWidget(mPortraitSize, mLandscapeSize)
+        }
+
+        val hostView = checkNotNull(mMaybeHostView) { "Host view wasn't successfully started" }
+
+        mAppWidgetId = hostView.appWidgetId
+        hostView.waitForRemoteViews()
+        Trace.endSection()
+    }
+
+    /**
+     * Measures time from sending APPWIDGET_UPDATE broadcast to receiving RemoteViews.
+     */
+    fun updateAppWidget() {
+        val intent = Intent(GlanceAppWidgetReceiver.ACTION_DEBUG_UPDATE)
+            .setPackage("androidx.glance.appwidget.macrobenchmark.target")
+            .setComponent(
+                ComponentName(
+                    "androidx.glance.appwidget.macrobenchmark.target",
+                    "androidx.glance.appwidget.macrobenchmark.target.BasicAppWidgetReceiver"
+                )
+            )
+            .putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, intArrayOf(mAppWidgetId))
+        val hostView = checkNotNull(mMaybeHostView) { "Host view not started" }
+        Trace.beginSection("appWidgetUpdate")
+        hostView.resetRemoteViewsLatch()
+        mContext.sendBroadcast(intent)
+        hostView.waitForRemoteViews()
+        Trace.endSection()
+    }
+}
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/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt
new file mode 100644
index 0000000..41098fc
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetHostTestActivity.kt
@@ -0,0 +1,234 @@
+/*
+ * 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.glance.appwidget.macrobenchmark
+
+import android.app.Activity
+import android.appwidget.AppWidgetHost
+import android.appwidget.AppWidgetHostView
+import android.appwidget.AppWidgetManager
+import android.appwidget.AppWidgetProviderInfo
+import android.content.ComponentName
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.os.LocaleList
+import android.util.DisplayMetrics
+import android.util.Log
+import android.util.SizeF
+import android.util.TypedValue
+import android.view.Gravity
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.widget.RemoteViews
+import androidx.annotation.RequiresApi
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.max
+import androidx.compose.ui.unit.min
+import java.util.Locale
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import org.junit.Assert.fail
+
+@RequiresApi(26)
+class AppWidgetHostTestActivity : Activity() {
+    private var mHost: AppWidgetHost? = null
+    private val mHostViews = mutableListOf<TestAppWidgetHostView>()
+
+    companion object {
+        const val EXTRA_TARGET_RECEIVER = "targetReceiver"
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+        setContentView(android.R.layout.list_content)
+
+        mHost = TestAppWidgetHost(this, 1025).also {
+            it.appWidgetIds.forEach(it::deleteAppWidgetId)
+            it.startListening()
+        }
+    }
+
+    override fun onDestroy() {
+        try {
+            mHost?.stopListening()
+            mHost?.deleteHost()
+        } catch (ex: Throwable) {
+            Log.w("AppWidgetHostTestActivity", "Error stopping the AppWidget Host", ex)
+        }
+        mHost = null
+        super.onDestroy()
+    }
+
+    private fun rootView() =
+        this.findViewById<ViewGroup>(android.R.id.content).getChildAt(0) as ViewGroup
+
+    fun bindAppWidget(portraitSize: DpSize, landscapeSize: DpSize): TestAppWidgetHostView? {
+        val host = mHost ?: error("App widgets can only be bound while the activity is created")
+
+        val appWidgetManager = AppWidgetManager.getInstance(this)
+        val appWidgetId = host.allocateAppWidgetId()
+
+        @Suppress("DEPRECATION")
+        val componentName = intent.getParcelableExtra<ComponentName>(EXTRA_TARGET_RECEIVER)!!
+
+        val wasBound = appWidgetManager.bindAppWidgetIdIfAllowed(
+            appWidgetId,
+            componentName,
+            optionsBundleOf(listOf(portraitSize, landscapeSize))
+        )
+        if (!wasBound) {
+            fail("Failed to bind the app widget")
+            mHost?.deleteHost()
+            mHost = null
+            return null
+        }
+
+        val info = appWidgetManager.getAppWidgetInfo(appWidgetId)
+        val locale = Locale.getDefault()
+        val config = resources.configuration
+        config.setLocales(LocaleList(locale))
+        config.setLayoutDirection(locale)
+        val context = this.createConfigurationContext(config)
+
+        val hostView = host.createView(context, appWidgetId, info) as TestAppWidgetHostView
+        hostView.setPadding(0, 0, 0, 0)
+        rootView().addView(hostView)
+        hostView.setSizes(portraitSize, landscapeSize)
+        hostView.setBackgroundColor(Color.WHITE)
+        mHostViews += hostView
+        return hostView
+    }
+
+    override fun onConfigurationChanged(newConfig: Configuration) {
+        super.onConfigurationChanged(newConfig)
+        updateAllSizes(newConfig.orientation)
+        reapplyRemoteViews()
+    }
+
+    fun updateAllSizes(orientation: Int) {
+        mHostViews.forEach { it.updateSize(orientation) }
+    }
+
+    fun reapplyRemoteViews() {
+        mHostViews.forEach { it.reapplyRemoteViews() }
+    }
+}
+
+@RequiresApi(26)
+class TestAppWidgetHost(context: Context, hostId: Int) : AppWidgetHost(context, hostId) {
+    override fun onCreateView(
+        context: Context,
+        appWidgetId: Int,
+        appWidget: AppWidgetProviderInfo?
+    ): AppWidgetHostView = TestAppWidgetHostView(context)
+}
+
+@RequiresApi(26)
+class TestAppWidgetHostView(context: Context) : AppWidgetHostView(context) {
+
+    init {
+        // Prevent asynchronous inflation of the App Widget
+        setExecutor(null)
+        layoutDirection = View.LAYOUT_DIRECTION_LOCALE
+    }
+
+    private var mLatch: CountDownLatch? = null
+    private var mRemoteViews: RemoteViews? = null
+    private var mPortraitSize: DpSize = DpSize(0.dp, 0.dp)
+    private var mLandscapeSize: DpSize = DpSize(0.dp, 0.dp)
+
+    /**
+     * Wait for the new remote views to be received. If a remote views was already received, return
+     * immediately.
+     */
+    fun waitForRemoteViews() {
+        synchronized(this) {
+            mRemoteViews?.let { return }
+            mLatch = CountDownLatch(1)
+        }
+        val result = mLatch?.await(5, TimeUnit.SECONDS)!!
+        require(result) { "Timeout before getting RemoteViews" }
+    }
+
+    override fun updateAppWidget(remoteViews: RemoteViews?) {
+        super.updateAppWidget(remoteViews)
+        synchronized(this) {
+            mRemoteViews = remoteViews
+            if (remoteViews != null) {
+                mLatch?.countDown()
+            }
+        }
+    }
+
+    /** Reset the latch used to detect the arrival of a new RemoteViews. */
+    fun resetRemoteViewsLatch() {
+        synchronized(this) {
+            mRemoteViews = null
+            mLatch = null
+        }
+    }
+
+    fun setSizes(portraitSize: DpSize, landscapeSize: DpSize) {
+        mPortraitSize = portraitSize
+        mLandscapeSize = landscapeSize
+        updateSize(resources.configuration.orientation)
+    }
+
+    fun updateSize(orientation: Int) {
+        val size = when (orientation) {
+            Configuration.ORIENTATION_LANDSCAPE -> mLandscapeSize
+            Configuration.ORIENTATION_PORTRAIT -> mPortraitSize
+            else -> error("Unknown orientation ${context.resources.configuration.orientation}")
+        }
+        val displayMetrics = resources.displayMetrics
+        val width = size.width.toPixels(displayMetrics)
+        val height = size.height.toPixels(displayMetrics)
+        layoutParams = LayoutParams(width, height, Gravity.CENTER)
+        requestLayout()
+    }
+
+    private fun Dp.toPixels(displayMetrics: DisplayMetrics) =
+        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, displayMetrics).toInt()
+
+    fun reapplyRemoteViews() {
+        mRemoteViews?.let { super.updateAppWidget(it) }
+    }
+}
+
+fun optionsBundleOf(sizes: List<DpSize>): Bundle {
+    require(sizes.isNotEmpty()) { "There must be at least one size" }
+    val (minSize, maxSize) = sizes.fold(sizes[0] to sizes[0]) { acc, s ->
+        DpSize(min(acc.first.width, s.width), min(acc.first.height, s.height)) to
+            DpSize(max(acc.second.width, s.width), max(acc.second.height, s.height))
+    }
+    return Bundle().apply {
+        putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minSize.width.value.toInt())
+        putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minSize.height.value.toInt())
+        putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxSize.width.value.toInt())
+        putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxSize.height.value.toInt())
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            val sizeList = ArrayList<SizeF>(sizes.map { SizeF(it.width.value, it.height.value) })
+            putParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES, sizeList)
+        }
+    }
+}
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/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt
new file mode 100644
index 0000000..578f12f
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/java/androidx/glance/appwidget/macrobenchmark/AppWidgetUpdateBenchmark.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.glance.appwidget.macrobenchmark
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.benchmark.macro.CompilationMode
+import androidx.benchmark.macro.ExperimentalMetricApi
+import androidx.benchmark.macro.StartupMode
+import androidx.benchmark.macro.TraceSectionMetric
+import androidx.benchmark.macro.junit4.MacrobenchmarkRule
+import androidx.test.filters.LargeTest
+import androidx.testutils.createStartupCompilationParams
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@LargeTest
+@RequiresApi(Build.VERSION_CODES.Q)
+@RunWith(Parameterized::class)
+class AppWidgetUpdateBenchmark(
+    private val startupMode: StartupMode,
+    private val compilationMode: CompilationMode,
+    useGlanceSession: Boolean,
+) {
+    @get:Rule
+    val benchmarkRule = MacrobenchmarkRule()
+
+    @get:Rule
+    val appWidgetHostRule = AppWidgetHostRule(useSession = useGlanceSession)
+
+    @OptIn(ExperimentalMetricApi::class)
+    @Test
+    fun initialUpdate() = benchmarkRule.measureRepeated(
+        packageName = "androidx.glance.appwidget.macrobenchmark.target",
+        metrics = listOf(
+            TraceSectionMetric("appWidgetInitialUpdate"),
+            TraceSectionMetric("GlanceAppWidget::update"),
+        ),
+        iterations = 100,
+        compilationMode = compilationMode,
+        startupMode = startupMode,
+    ) {
+        appWidgetHostRule.startHost()
+    }
+
+    @OptIn(ExperimentalMetricApi::class)
+    @Test
+    fun appWidgetUpdate() = benchmarkRule.measureRepeated(
+        packageName = "androidx.glance.appwidget.macrobenchmark.target",
+        metrics = listOf(
+            TraceSectionMetric("appWidgetUpdate"),
+            TraceSectionMetric("GlanceAppWidget::update"),
+        ),
+        iterations = 100,
+        compilationMode = compilationMode,
+        startupMode = startupMode,
+        setupBlock = {
+            appWidgetHostRule.startHost()
+            if (startupMode == StartupMode.COLD) killProcess()
+        }
+    ) {
+        appWidgetHostRule.updateAppWidget()
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "startup={0},compilation={1},useSession={2}")
+        @JvmStatic
+        fun parameters() =
+            createStartupCompilationParams(
+                startupModes = listOf(StartupMode.COLD, StartupMode.WARM),
+                compilationModes = listOf(CompilationMode.DEFAULT)
+            ).flatMap {
+                listOf(
+                    it + true,
+                    it + false,
+                )
+            }
+    }
+}
\ No newline at end of file
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/androidTest/res/layout/app_widget_host_activity.xml
new file mode 100644
index 0000000..aed767b
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/androidTest/res/layout/app_widget_host_activity.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#AAAAAA"/>
diff --git a/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..5b41847
--- /dev/null
+++ b/glance/glance-appwidget/integration-tests/macrobenchmark/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?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/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetSession.kt
index 6bad985..c3ddc3e 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
@@ -144,6 +144,7 @@
             lastRemoteViews = rv
         } finally {
             layoutConfig.save()
+            Tracing.endGlanceAppWidgetUpdate()
         }
     }
 
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetUtils.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetUtils.kt
index e9063f8a..1ae6a21 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetUtils.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/AppWidgetUtils.kt
@@ -18,12 +18,18 @@
 
 import android.appwidget.AppWidgetManager
 import android.appwidget.AppWidgetProviderInfo
+import android.os.Build
 import android.os.Bundle
+import android.os.Trace
 import android.util.DisplayMetrics
 import android.util.Log
 import android.util.SizeF
+import androidx.annotation.DoNotInline
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
+import java.util.concurrent.atomic.AtomicBoolean
 import kotlin.math.ceil
 import kotlin.math.min
 
@@ -148,4 +154,41 @@
 
 internal fun logException(throwable: Throwable) {
     Log.e(GlanceAppWidgetTag, "Error in Glance App Widget", throwable)
+}
+
+/**
+ * [Tracing] contains methods for tracing sections of GlanceAppWidget.
+ *
+ * @suppress
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+object Tracing {
+    val enabled = AtomicBoolean(false)
+
+    fun beginGlanceAppWidgetUpdate() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && enabled.get()) {
+            TracingApi29Impl.beginAsyncSection("GlanceAppWidget::update", 0)
+        }
+    }
+
+    fun endGlanceAppWidgetUpdate() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && enabled.get()) {
+            TracingApi29Impl.endAsyncSection("GlanceAppWidget::update", 0)
+        }
+    }
+}
+
+@RequiresApi(Build.VERSION_CODES.Q)
+internal object TracingApi29Impl {
+    @DoNotInline
+    fun beginAsyncSection(
+        methodName: String,
+        cookie: Int,
+    ) = Trace.beginAsyncSection(methodName, cookie)
+
+    @DoNotInline
+    fun endAsyncSection(
+        methodName: String,
+        cookie: Int,
+    ) = Trace.endAsyncSection(methodName, cookie)
 }
\ No newline at end of file
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
index 49361f2..d12e0c6 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidget.kt
@@ -164,6 +164,7 @@
         appWidgetId: Int,
         options: Bundle? = null,
     ) {
+        Tracing.beginGlanceAppWidgetUpdate()
         sessionManager?.let {
             val glanceId = AppWidgetId(appWidgetId)
             if (!it.isSessionRunning(context, glanceId.toSessionKey())) {
@@ -517,6 +518,8 @@
             logException(throwable)
             val rv = RemoteViews(context.packageName, errorUiLayout)
             appWidgetManager.updateAppWidget(appWidgetId, rv)
+        } finally {
+            Tracing.endGlanceAppWidgetUpdate()
         }
     }
 
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiver.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiver.kt
index 42f64cc..93d8962 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiver.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/GlanceAppWidgetReceiver.kt
@@ -130,10 +130,15 @@
                     val appWidgetManager = AppWidgetManager.getInstance(context)
                     val componentName =
                         ComponentName(context.packageName, checkNotNull(javaClass.canonicalName))
+                    val ids = if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS)) {
+                        intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS)!!
+                    } else {
+                        appWidgetManager.getAppWidgetIds(componentName)
+                    }
                     onUpdate(
                         context,
                         appWidgetManager,
-                        appWidgetManager.getAppWidgetIds(componentName)
+                        ids,
                     )
                 }
                 LambdaActionBroadcasts.ActionTriggerLambda -> {
diff --git a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/ListTemplateLayouts.kt b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/ListTemplateLayouts.kt
index 77ef0cf..b3fb6fa 100644
--- a/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/ListTemplateLayouts.kt
+++ b/glance/glance-appwidget/src/androidMain/kotlin/androidx/glance/appwidget/template/ListTemplateLayouts.kt
@@ -23,6 +23,7 @@
 import androidx.glance.GlanceComposable
 import androidx.glance.GlanceModifier
 import androidx.glance.GlanceTheme
+import androidx.glance.LocalSize
 import androidx.glance.appwidget.lazy.LazyColumn
 import androidx.glance.appwidget.lazy.itemsIndexed
 import androidx.glance.background
@@ -34,6 +35,7 @@
 import androidx.glance.layout.height
 import androidx.glance.layout.padding
 import androidx.glance.layout.width
+import androidx.glance.template.ImageBlock
 import androidx.glance.template.ListStyle
 import androidx.glance.template.ListTemplateData
 import androidx.glance.template.LocalTemplateMode
@@ -86,13 +88,19 @@
             itemsIndexed(data.listContent) { _, item ->
                 val itemSpacer = if (data.listStyle == ListStyle.Full) 8.dp else 0.dp
                 val itemModifier = GlanceModifier.fillMaxSize().padding(vertical = itemSpacer)
+                var itemImageBlock: ImageBlock? = null
+                if (LocalSize.current.width > GlanceTemplateAppWidget.sizeMin &&
+                    LocalSize.current.height > GlanceTemplateAppWidget.sizeMin
+                ) {
+                    itemImageBlock = item.imageBlock
+                }
                 Row(
                     modifier = itemModifier,
                     verticalAlignment = Alignment.Vertical.CenterVertically,
                 ) {
                     TextAndImageBlockTemplate(
                         item.textBlock,
-                        item.imageBlock,
+                        itemImageBlock,
                         GlanceModifier.defaultWeight()
                     )
                     Spacer(modifier = GlanceModifier.width(16.dp))
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/HeartRateRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/HeartRateRecord.kt
index 8d6eee1..068157e 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/HeartRateRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/HeartRateRecord.kt
@@ -119,7 +119,7 @@
     ) {
 
         init {
-            requireNonNegative(value = beatsPerMinute, name = "beatsPerMinute")
+            beatsPerMinute.requireNotLess(other = 1, name = "beatsPerMinute")
             beatsPerMinute.requireNotMore(other = 300, name = "beatsPerMinute")
         }
 
diff --git a/health/connect/connect-client/src/test/java/androidx/health/connect/client/records/HeartRateRecordTest.kt b/health/connect/connect-client/src/test/java/androidx/health/connect/client/records/HeartRateRecordTest.kt
index d5c8715..3152da4 100644
--- a/health/connect/connect-client/src/test/java/androidx/health/connect/client/records/HeartRateRecordTest.kt
+++ b/health/connect/connect-client/src/test/java/androidx/health/connect/client/records/HeartRateRecordTest.kt
@@ -82,4 +82,24 @@
             )
         }
     }
+
+    @Test
+    fun invalidBeatsPerMinute_lessThan1_throws() {
+        assertFailsWith<IllegalArgumentException> {
+            HeartRateRecord.Sample(
+                time = Instant.ofEpochMilli(1235L),
+                beatsPerMinute = 0L,
+            )
+        }
+    }
+
+    @Test
+    fun invalidBeatsPerMinute_moreThan300_throws() {
+        assertFailsWith<IllegalArgumentException> {
+            HeartRateRecord.Sample(
+                time = Instant.ofEpochMilli(1235L),
+                beatsPerMinute = 301L,
+            )
+        }
+    }
 }
diff --git a/input/input-motionprediction/api/current.txt b/input/input-motionprediction/api/current.txt
index a2cdf99..6611119 100644
--- a/input/input-motionprediction/api/current.txt
+++ b/input/input-motionprediction/api/current.txt
@@ -1,11 +1,11 @@
 // Signature format: 4.0
 package androidx.input.motionprediction {
 
-  public interface MotionEventPredictor {
-    method public void dispose();
+  public interface MotionEventPredictor extends java.lang.AutoCloseable {
+    method public void close();
     method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
     method public android.view.MotionEvent? predict();
-    method public void recordMovement(android.view.MotionEvent);
+    method public void record(android.view.MotionEvent);
   }
 
 }
diff --git a/input/input-motionprediction/api/public_plus_experimental_current.txt b/input/input-motionprediction/api/public_plus_experimental_current.txt
index a2cdf99..6611119 100644
--- a/input/input-motionprediction/api/public_plus_experimental_current.txt
+++ b/input/input-motionprediction/api/public_plus_experimental_current.txt
@@ -1,11 +1,11 @@
 // Signature format: 4.0
 package androidx.input.motionprediction {
 
-  public interface MotionEventPredictor {
-    method public void dispose();
+  public interface MotionEventPredictor extends java.lang.AutoCloseable {
+    method public void close();
     method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
     method public android.view.MotionEvent? predict();
-    method public void recordMovement(android.view.MotionEvent);
+    method public void record(android.view.MotionEvent);
   }
 
 }
diff --git a/input/input-motionprediction/api/restricted_current.txt b/input/input-motionprediction/api/restricted_current.txt
index a2cdf99..6611119 100644
--- a/input/input-motionprediction/api/restricted_current.txt
+++ b/input/input-motionprediction/api/restricted_current.txt
@@ -1,11 +1,11 @@
 // Signature format: 4.0
 package androidx.input.motionprediction {
 
-  public interface MotionEventPredictor {
-    method public void dispose();
+  public interface MotionEventPredictor extends java.lang.AutoCloseable {
+    method public void close();
     method public static androidx.input.motionprediction.MotionEventPredictor newInstance(android.view.View);
     method public android.view.MotionEvent? predict();
-    method public void recordMovement(android.view.MotionEvent);
+    method public void record(android.view.MotionEvent);
   }
 
 }
diff --git a/input/input-motionprediction/build.gradle b/input/input-motionprediction/build.gradle
index 9475cdb..8d3d5e2 100644
--- a/input/input-motionprediction/build.gradle
+++ b/input/input-motionprediction/build.gradle
@@ -33,7 +33,7 @@
 
 android {
     defaultConfig {
-        minSdkVersion 16
+        minSdkVersion 19
     }
     namespace "androidx.input.motionprediction"
 }
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
index c27d293..31442ee 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/MotionEventPredictor.java
@@ -33,7 +33,7 @@
  * rendered on the display. Once no more predictions are needed, call {@link #dispose()} to stop it
  * and clean up resources.
  */
-public interface MotionEventPredictor {
+public interface MotionEventPredictor extends AutoCloseable {
     /**
      * Record a user's movement to the predictor. You should call this for every
      * {@link android.view.MotionEvent} that is received by the associated
@@ -41,7 +41,7 @@
      * @param event the {@link android.view.MotionEvent} the associated view received and that
      *              needs to be recorded.
      */
-    void recordMovement(@NonNull MotionEvent event);
+    void record(@NonNull MotionEvent event);
 
     /**
      * Compute a prediction
@@ -55,7 +55,8 @@
      * Notify the predictor that no more predictions are needed. Any subsequent call to
      * {@link #predict()} will return null.
      */
-    void dispose();
+    @Override
+    void close();
 
     /**
      * Create a new motion predictor associated to a specific {@link android.view.View}
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanMotionEventPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanMotionEventPredictor.java
index e5abbd9..df88594 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanMotionEventPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanMotionEventPredictor.java
@@ -31,7 +31,7 @@
 @RestrictTo(LIBRARY)
 public class KalmanMotionEventPredictor implements MotionEventPredictor {
     private MultiPointerPredictor mMultiPointerPredictor;
-    private boolean mDisposed = false;
+    private boolean mClosed = false;
 
     public KalmanMotionEventPredictor() {
         mMultiPointerPredictor = new MultiPointerPredictor();
@@ -43,21 +43,21 @@
     }
 
     @Override
-    public void recordMovement(@NonNull MotionEvent event) {
+    public void record(@NonNull MotionEvent event) {
         mMultiPointerPredictor.onTouchEvent(event);
     }
 
     @Nullable
     @Override
     public MotionEvent predict() {
-        if (mDisposed) {
+        if (mClosed) {
             return null;
         }
         return mMultiPointerPredictor.predict();
     }
 
     @Override
-    public void dispose() {
-        mDisposed = true;
+    public void close() {
+        mClosed = true;
     }
 }
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/InkPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanPredictor.java
similarity index 97%
rename from input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/InkPredictor.java
rename to input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanPredictor.java
index 98f4a44..f655aec 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/InkPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanPredictor.java
@@ -30,7 +30,7 @@
  * @hide
  */
 @RestrictTo(LIBRARY)
-public interface InkPredictor {
+public interface KalmanPredictor {
 
     /** Gets the current prediction target */
     int getPredictionTarget();
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
index c97dd19..1b0b3cd 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
@@ -32,11 +32,11 @@
  * @hide
  */
 @RestrictTo(LIBRARY)
-public class MultiPointerPredictor implements InkPredictor {
+public class MultiPointerPredictor implements KalmanPredictor {
     private static final String TAG = "MultiPointerPredictor";
     private static final boolean DEBUG_PREDICTION = Log.isLoggable(TAG, Log.DEBUG);
 
-    private SparseArray<KalmanInkPredictor> mPredictorMap = new SparseArray<>();
+    private SparseArray<SinglePointerPredictor> mPredictorMap = new SparseArray<>();
     private int mPredictionTargetMs = 0;
     private int mReportRateMs = 0;
 
@@ -77,7 +77,7 @@
         int action = event.getActionMasked();
         int pointerId = event.getPointerId(event.getActionIndex());
         if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) {
-            KalmanInkPredictor predictor = new KalmanInkPredictor();
+            SinglePointerPredictor predictor = new SinglePointerPredictor();
             predictor.setPredictionTarget(mPredictionTargetMs);
             if (mReportRateMs > 0) {
                 predictor.setReportRate(mReportRateMs);
@@ -86,14 +86,14 @@
             predictor.onTouchEvent(event);
             mPredictorMap.put(pointerId, predictor);
         } else if (action == MotionEvent.ACTION_UP) {
-            KalmanInkPredictor predictor = mPredictorMap.get(pointerId);
+            SinglePointerPredictor predictor = mPredictorMap.get(pointerId);
             if (predictor != null) {
                 mPredictorMap.remove(pointerId);
                 predictor.onTouchEvent(event);
             }
             mPredictorMap.clear();
         } else if (action == MotionEvent.ACTION_POINTER_UP) {
-            KalmanInkPredictor predictor = mPredictorMap.get(pointerId);
+            SinglePointerPredictor predictor = mPredictorMap.get(pointerId);
             if (predictor != null) {
                 mPredictorMap.remove(pointerId);
                 predictor.onTouchEvent(event);
@@ -126,7 +126,7 @@
             return null;
         }
         if (pointerCount == 1) {
-            KalmanInkPredictor predictor = mPredictorMap.valueAt(0);
+            SinglePointerPredictor predictor = mPredictorMap.valueAt(0);
             MotionEvent predictedEv = predictor.predict();
             if (DEBUG_PREDICTION) {
                 Log.d(TAG, "predict() -> MotionEvent: " + predictedEv);
@@ -139,7 +139,7 @@
         MotionEvent[] singlePointerEvents = new MotionEvent[pointerCount];
         for (int i = 0; i < pointerCount; ++i) {
             pointerIds[i] = mPredictorMap.keyAt(i);
-            KalmanInkPredictor predictor = mPredictorMap.valueAt(i);
+            SinglePointerPredictor predictor = mPredictorMap.valueAt(i);
             singlePointerEvents[i] = predictor.predict();
             // If predictor consumer expect more sample, generate sample where position and
             // pressure are constant
@@ -161,7 +161,9 @@
 
         if (foundNullPrediction) {
             for (MotionEvent ev : singlePointerEvents) {
-                ev.recycle();
+                if (ev != null) {
+                    ev.recycle();
+                }
             }
             return null;
         }
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PenKalmanFilter.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PointerKalmanFilter.java
similarity index 97%
rename from input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PenKalmanFilter.java
rename to input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PointerKalmanFilter.java
index a70b21e..6a80269 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PenKalmanFilter.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/PointerKalmanFilter.java
@@ -29,7 +29,7 @@
  * @hide
  */
 @RestrictTo(LIBRARY)
-public class PenKalmanFilter {
+public class PointerKalmanFilter {
     private KalmanFilter mXKalman;
     private KalmanFilter mYKalman;
     private KalmanFilter mPKalman;
@@ -54,7 +54,7 @@
      * @param sigmaProcess lower value = more filtering
      * @param sigmaMeasurement higher value = more filtering
      */
-    public PenKalmanFilter(double sigmaProcess, double sigmaMeasurement) {
+    public PointerKalmanFilter(double sigmaProcess, double sigmaMeasurement) {
         mSigmaProcess = sigmaProcess;
         mSigmaMeasurement = sigmaMeasurement;
         mXKalman = createAxisKalmanFilter();
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanInkPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
similarity index 98%
rename from input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanInkPredictor.java
rename to input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
index 73c1f4a..0656734 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/KalmanInkPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
@@ -34,7 +34,7 @@
  * @hide
  */
 @RestrictTo(LIBRARY)
-public class KalmanInkPredictor implements InkPredictor {
+public class SinglePointerPredictor implements KalmanPredictor {
     private static final String TAG = "KalmanInkPredictor";
 
     // Influence of jank during each prediction sample
@@ -67,7 +67,7 @@
     // The Kalman filter is tuned to smooth noise while maintaining fast reaction to direction
     // changes. The stronger the filter, the smoother the prediction result will be, at the
     // cost of possible prediction errors.
-    private final PenKalmanFilter mKalman = new PenKalmanFilter(0.01, 1.0);
+    private final PointerKalmanFilter mKalman = new PointerKalmanFilter(0.01, 1.0);
 
     private final DVector2 mLastPosition = new DVector2();
     private long mPrevEventTime;
@@ -93,7 +93,7 @@
      * achieving close-to-zero latency, prediction errors can be more visible and the target should
      * be reduced to 20ms.
      */
-    public KalmanInkPredictor() {
+    public SinglePointerPredictor() {
         mKalman.reset();
         mPrevEventTime = 0;
     }
diff --git a/lifecycle/lifecycle-common/api/current.txt b/lifecycle/lifecycle-common/api/current.txt
index 1e1ed43..9520799 100644
--- a/lifecycle/lifecycle-common/api/current.txt
+++ b/lifecycle/lifecycle-common/api/current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.lifecycle {
 
-  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver androidx.lifecycle.LifecycleObserver {
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
     method public default void onCreate(androidx.lifecycle.LifecycleOwner);
     method public default void onDestroy(androidx.lifecycle.LifecycleOwner);
     method public default void onPause(androidx.lifecycle.LifecycleOwner);
diff --git a/lifecycle/lifecycle-common/api/public_plus_experimental_current.txt b/lifecycle/lifecycle-common/api/public_plus_experimental_current.txt
index 1e1ed43..9520799 100644
--- a/lifecycle/lifecycle-common/api/public_plus_experimental_current.txt
+++ b/lifecycle/lifecycle-common/api/public_plus_experimental_current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.lifecycle {
 
-  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver androidx.lifecycle.LifecycleObserver {
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
     method public default void onCreate(androidx.lifecycle.LifecycleOwner);
     method public default void onDestroy(androidx.lifecycle.LifecycleOwner);
     method public default void onPause(androidx.lifecycle.LifecycleOwner);
diff --git a/lifecycle/lifecycle-common/api/restricted_current.txt b/lifecycle/lifecycle-common/api/restricted_current.txt
index cdf6954..138ab792 100644
--- a/lifecycle/lifecycle-common/api/restricted_current.txt
+++ b/lifecycle/lifecycle-common/api/restricted_current.txt
@@ -1,7 +1,7 @@
 // Signature format: 4.0
 package androidx.lifecycle {
 
-  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver androidx.lifecycle.LifecycleObserver {
+  public interface DefaultLifecycleObserver extends androidx.lifecycle.LifecycleObserver {
     method public default void onCreate(androidx.lifecycle.LifecycleOwner);
     method public default void onDestroy(androidx.lifecycle.LifecycleOwner);
     method public default void onPause(androidx.lifecycle.LifecycleOwner);
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.java
index e1188a7..63b0688 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.java
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserver.java
@@ -28,7 +28,7 @@
  * annotations will be ignored.
  */
 @SuppressWarnings("unused")
-public interface DefaultLifecycleObserver extends FullLifecycleObserver {
+public interface DefaultLifecycleObserver extends LifecycleObserver {
 
     /**
      * Notifies that {@code ON_CREATE} event occurred.
@@ -38,7 +38,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onCreate(@NonNull LifecycleOwner owner) {
     }
 
@@ -49,7 +48,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onStart(@NonNull LifecycleOwner owner) {
     }
 
@@ -61,7 +59,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onResume(@NonNull LifecycleOwner owner) {
     }
 
@@ -73,7 +70,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onPause(@NonNull LifecycleOwner owner) {
     }
 
@@ -85,7 +81,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onStop(@NonNull LifecycleOwner owner) {
     }
 
@@ -97,7 +92,6 @@
      *
      * @param owner the component, whose state was changed
      */
-    @Override
     default void onDestroy(@NonNull LifecycleOwner owner) {
     }
 }
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserverAdapter.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserverAdapter.java
similarity index 71%
rename from lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserverAdapter.java
rename to lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserverAdapter.java
index 10223d4..8d87eac 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserverAdapter.java
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/DefaultLifecycleObserverAdapter.java
@@ -18,14 +18,14 @@
 
 import androidx.annotation.NonNull;
 
-class FullLifecycleObserverAdapter implements LifecycleEventObserver {
+class DefaultLifecycleObserverAdapter implements LifecycleEventObserver {
 
-    private final FullLifecycleObserver mFullLifecycleObserver;
+    private final DefaultLifecycleObserver mDefaultLifecycleObserver;
     private final LifecycleEventObserver mLifecycleEventObserver;
 
-    FullLifecycleObserverAdapter(FullLifecycleObserver fullLifecycleObserver,
+    DefaultLifecycleObserverAdapter(DefaultLifecycleObserver defaultLifecycleObserver,
             LifecycleEventObserver lifecycleEventObserver) {
-        mFullLifecycleObserver = fullLifecycleObserver;
+        mDefaultLifecycleObserver = defaultLifecycleObserver;
         mLifecycleEventObserver = lifecycleEventObserver;
     }
 
@@ -33,22 +33,22 @@
     public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
         switch (event) {
             case ON_CREATE:
-                mFullLifecycleObserver.onCreate(source);
+                mDefaultLifecycleObserver.onCreate(source);
                 break;
             case ON_START:
-                mFullLifecycleObserver.onStart(source);
+                mDefaultLifecycleObserver.onStart(source);
                 break;
             case ON_RESUME:
-                mFullLifecycleObserver.onResume(source);
+                mDefaultLifecycleObserver.onResume(source);
                 break;
             case ON_PAUSE:
-                mFullLifecycleObserver.onPause(source);
+                mDefaultLifecycleObserver.onPause(source);
                 break;
             case ON_STOP:
-                mFullLifecycleObserver.onStop(source);
+                mDefaultLifecycleObserver.onStop(source);
                 break;
             case ON_DESTROY:
-                mFullLifecycleObserver.onDestroy(source);
+                mDefaultLifecycleObserver.onDestroy(source);
                 break;
             case ON_ANY:
                 throw new IllegalArgumentException("ON_ANY must not been send by anybody");
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserver.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserver.java
deleted file mode 100644
index c959d03..0000000
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/FullLifecycleObserver.java
+++ /dev/null
@@ -1,32 +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.
- */
-
-package androidx.lifecycle;
-
-interface FullLifecycleObserver extends LifecycleObserver {
-
-    void onCreate(LifecycleOwner owner);
-
-    void onStart(LifecycleOwner owner);
-
-    void onResume(LifecycleOwner owner);
-
-    void onPause(LifecycleOwner owner);
-
-    void onStop(LifecycleOwner owner);
-
-    void onDestroy(LifecycleOwner owner);
-}
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.kt
similarity index 80%
rename from lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.java
rename to lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.kt
index 71ce3b1..9c7e5a0 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.java
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/LifecycleObserver.kt
@@ -13,17 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-package androidx.lifecycle;
+package androidx.lifecycle
 
 /**
  * Marks a class as a LifecycleObserver. Don't use this interface directly. Instead implement either
- * {@link DefaultLifecycleObserver} or {@link LifecycleEventObserver} to be notified about
+ * [DefaultLifecycleObserver] or [LifecycleEventObserver] to be notified about
  * lifecycle events.
  *
  * @see Lifecycle Lifecycle - for samples and usage patterns.
  */
-@SuppressWarnings("WeakerAccess")
-public interface LifecycleObserver {
-
-}
+public interface LifecycleObserver
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycling.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycling.java
index 2714780..722f0bf 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycling.java
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycling.java
@@ -67,13 +67,13 @@
     @SuppressWarnings("deprecation")
     static LifecycleEventObserver lifecycleEventObserver(Object object) {
         boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
-        boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
-        if (isLifecycleEventObserver && isFullLifecycleObserver) {
-            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
+        boolean isDefaultLifecycleObserver = object instanceof DefaultLifecycleObserver;
+        if (isLifecycleEventObserver && isDefaultLifecycleObserver) {
+            return new DefaultLifecycleObserverAdapter((DefaultLifecycleObserver) object,
                     (LifecycleEventObserver) object);
         }
-        if (isFullLifecycleObserver) {
-            return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
+        if (isDefaultLifecycleObserver) {
+            return new DefaultLifecycleObserverAdapter((DefaultLifecycleObserver) object, null);
         }
 
         if (isLifecycleEventObserver) {
diff --git a/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/FullLifecycleObserverTest.java b/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/DefaultLifecycleObserverTest.java
similarity index 80%
rename from lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/FullLifecycleObserverTest.java
rename to lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/DefaultLifecycleObserverTest.java
index f706eeb..958274c 100644
--- a/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/FullLifecycleObserverTest.java
+++ b/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/DefaultLifecycleObserverTest.java
@@ -42,7 +42,7 @@
 import org.mockito.Mockito;
 
 @RunWith(JUnit4.class)
-public class FullLifecycleObserverTest {
+public class DefaultLifecycleObserverTest {
     private LifecycleOwner mOwner;
     private Lifecycle mLifecycle;
 
@@ -55,8 +55,8 @@
 
     @Test
     public void eachEvent() {
-        FullLifecycleObserver obj = mock(FullLifecycleObserver.class);
-        FullLifecycleObserverAdapter observer = new FullLifecycleObserverAdapter(obj, null);
+        DefaultLifecycleObserver obj = mock(DefaultLifecycleObserver.class);
+        DefaultLifecycleObserverAdapter observer = new DefaultLifecycleObserverAdapter(obj, null);
         when(mLifecycle.getCurrentState()).thenReturn(CREATED);
 
         observer.onStateChanged(mOwner, ON_CREATE);
@@ -91,36 +91,36 @@
     }
 
     @Test
-    public void fullLifecycleObserverAndLifecycleEventObserver() {
-        class AllObservers implements FullLifecycleObserver, LifecycleEventObserver {
+    public void defaultLifecycleObserverAndLifecycleEventObserver() {
+        class AllObservers implements DefaultLifecycleObserver, LifecycleEventObserver {
 
             @Override
-            public void onCreate(LifecycleOwner owner) {
+            public void onCreate(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStart(LifecycleOwner owner) {
+            public void onStart(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onResume(LifecycleOwner owner) {
+            public void onResume(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onPause(LifecycleOwner owner) {
+            public void onPause(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStop(LifecycleOwner owner) {
+            public void onStop(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onDestroy(LifecycleOwner owner) {
+            public void onDestroy(@NonNull LifecycleOwner owner) {
 
             }
 
@@ -132,7 +132,7 @@
         }
 
         AllObservers obj = mock(AllObservers.class);
-        FullLifecycleObserverAdapter observer = new FullLifecycleObserverAdapter(obj, obj);
+        DefaultLifecycleObserverAdapter observer = new DefaultLifecycleObserverAdapter(obj, obj);
         when(mLifecycle.getCurrentState()).thenReturn(CREATED);
 
         observer.onStateChanged(mOwner, ON_CREATE);
@@ -174,7 +174,7 @@
 
     public void fullLifecycleObserverAndAnnotations() {
         @SuppressWarnings("deprecation")
-        class AnnotatedFullLifecycleObserver implements FullLifecycleObserver {
+        class AnnotatedFullLifecycleObserver implements DefaultLifecycleObserver {
             @OnLifecycleEvent(ON_ANY)
             public void onAny() {
                 throw new IllegalStateException("Annotations in FullLifecycleObserver "
@@ -182,32 +182,32 @@
             }
 
             @Override
-            public void onCreate(LifecycleOwner owner) {
+            public void onCreate(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStart(LifecycleOwner owner) {
+            public void onStart(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onResume(LifecycleOwner owner) {
+            public void onResume(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onPause(LifecycleOwner owner) {
+            public void onPause(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStop(LifecycleOwner owner) {
+            public void onStop(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onDestroy(LifecycleOwner owner) {
+            public void onDestroy(@NonNull LifecycleOwner owner) {
 
             }
         }
diff --git a/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/LifecyclingTest.java b/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/LifecyclingTest.java
index b5ab5fd..0fc7f0e 100644
--- a/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/LifecyclingTest.java
+++ b/lifecycle/lifecycle-common/src/test/java/androidx/lifecycle/LifecyclingTest.java
@@ -116,8 +116,8 @@
     }
 
     @Test
-    public void fullLifecycleObserverAndAnnotations() {
-        class AnnotatedFullLifecycleObserver implements FullLifecycleObserver {
+    public void defaultLifecycleObserverAndAnnotations() {
+        class AnnotatedFullLifecycleObserver implements DefaultLifecycleObserver {
             @SuppressWarnings("deprecation")
             @OnLifecycleEvent(ON_ANY)
             public void onAny() {
@@ -126,32 +126,32 @@
             }
 
             @Override
-            public void onCreate(LifecycleOwner owner) {
+            public void onCreate(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStart(LifecycleOwner owner) {
+            public void onStart(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onResume(LifecycleOwner owner) {
+            public void onResume(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onPause(LifecycleOwner owner) {
+            public void onPause(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onStop(LifecycleOwner owner) {
+            public void onStop(@NonNull LifecycleOwner owner) {
 
             }
 
             @Override
-            public void onDestroy(LifecycleOwner owner) {
+            public void onDestroy(@NonNull LifecycleOwner owner) {
 
             }
         }
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 28ded62..39680f5 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
@@ -1640,6 +1640,23 @@
 
     @UiThreadTest
     @Test
+    fun testNavigateMultipleParentsOnHierarchy() {
+        val navController = createNavController()
+        navController.setGraph(R.navigation.nav_root)
+        assertThat(navController.currentDestination?.id ?: 0).isEqualTo(R.id.root_start)
+
+        // nav_second has two parents: nav_root and nav_first
+        // nav_first has one parent: nav_root
+        // they share common parent of nav_root
+        navController.navigate(Uri.parse("http://www.second.com"))
+        assertThat(navController.currentDestination?.id ?: 0).isEqualTo(R.id.second_start)
+
+        navController.popBackStack()
+        assertThat(navController.currentDestination?.id).isEqualTo(R.id.root_start)
+    }
+
+    @UiThreadTest
+    @Test
     fun testNavigateWithOverriddenDefaultArgs() {
         val args = Bundle()
         args.putString(TEST_OVERRIDDEN_VALUE_ARG, TEST_OVERRIDDEN_VALUE_ARG_VALUE)
diff --git a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_first.xml b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_first.xml
new file mode 100644
index 0000000..5951898
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_first.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:app="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/nav_first"
+            android:label=""
+            app:startDestination="@+id/first_start">
+
+    <include app:graph="@navigation/nav_second" />
+
+    <test android:id="@+id/first_start">
+        <deepLink app:uri="http://www.first.com" />
+    </test>
+</navigation>
diff --git a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_root.xml b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_root.xml
new file mode 100644
index 0000000..df94bf6
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_root.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:app="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/nav_root"
+            android:label=""
+            app:startDestination="@+id/root_start">
+
+    <include app:graph="@navigation/nav_first" />
+    <include app:graph="@navigation/nav_second" />
+
+    <test android:id="@+id/root_start" />
+
+</navigation>
diff --git a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_second.xml b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_second.xml
new file mode 100644
index 0000000..4f77c8f
--- /dev/null
+++ b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_second.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:app="http://schemas.android.com/apk/res-auto"
+            android:id="@+id/nav_second"
+            android:label=""
+            app:startDestination="@+id/second_start">
+
+    <test android:id="@+id/second_start">
+        <deepLink app:uri="http://www.second.com" />
+    </test>
+</navigation>
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 094e8a4..b6c957c 100644
--- a/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
+++ b/navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
@@ -1866,9 +1866,11 @@
         }
 
         // Now collect the set of all intermediate NavGraphs that need to be put onto
-        // the back stack
+        // the back stack. Destinations can have multiple parents, so we check referential
+        // equality to ensure that same destinations with a parent that is not this _graph
+        // will also have their parents added to the hierarchy.
         destination = if (hierarchy.isEmpty()) newDest else hierarchy.first().destination
-        while (destination != null && findDestination(destination.id) == null) {
+        while (destination != null && findDestination(destination.id) !== destination) {
             val parent = destination.parent
             if (parent != null) {
                 val entry = restoredEntries.lastOrNull { restoredEntry ->
diff --git a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
index 83c849d..d5a45dc 100644
--- a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
+++ b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/AppBarConfigurationTest.kt
@@ -24,6 +24,7 @@
 import androidx.navigation.NavHostController
 import androidx.navigation.createGraph
 import androidx.navigation.plusAssign
+import androidx.navigation.ui.test.R
 import androidx.test.annotation.UiThreadTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
diff --git a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/NavigationUITest.kt b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/NavigationUITest.kt
index 0796ff3..992ee49 100644
--- a/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/NavigationUITest.kt
+++ b/navigation/navigation-ui/src/androidTest/java/androidx/navigation/ui/NavigationUITest.kt
@@ -26,6 +26,7 @@
 import androidx.navigation.NavHostController
 import androidx.navigation.NavType
 import androidx.navigation.createGraph
+import androidx.navigation.ui.test.R
 import androidx.test.annotation.UiThreadTest
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
diff --git a/navigation/navigation-ui/src/main/res/menu/menu.xml b/navigation/navigation-ui/src/androidTest/res/menu/menu.xml
similarity index 100%
rename from navigation/navigation-ui/src/main/res/menu/menu.xml
rename to navigation/navigation-ui/src/androidTest/res/menu/menu.xml
diff --git a/navigation/navigation-ui/src/main/res/navigation/menu_item_graph.xml b/navigation/navigation-ui/src/androidTest/res/navigation/menu_item_graph.xml
similarity index 100%
rename from navigation/navigation-ui/src/main/res/navigation/menu_item_graph.xml
rename to navigation/navigation-ui/src/androidTest/res/navigation/menu_item_graph.xml
diff --git a/navigation/navigation-ui/src/main/res/navigation/simple_graph.xml b/navigation/navigation-ui/src/androidTest/res/navigation/simple_graph.xml
similarity index 100%
rename from navigation/navigation-ui/src/main/res/navigation/simple_graph.xml
rename to navigation/navigation-ui/src/androidTest/res/navigation/simple_graph.xml
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
index 368f02f..e168416 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/fullfeaturedsdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
@@ -14,7 +14,7 @@
             stackFrame
         }.toTypedArray()
         throwable.cause?.let {
-            parcel.cause = toThrowableParcel(it)
+            parcel.cause = arrayOf(toThrowableParcel(it))
         }
         parcel.suppressedExceptions =
             throwable.suppressedExceptions.map {
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkruntimelibrarysdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkruntimelibrarysdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
index 368f02f..e168416 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkruntimelibrarysdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/test-data/sdkruntimelibrarysdk/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
@@ -14,7 +14,7 @@
             stackFrame
         }.toTypedArray()
         throwable.cause?.let {
-            parcel.cause = toThrowableParcel(it)
+            parcel.cause = arrayOf(toThrowableParcel(it))
         }
         parcel.suppressedExceptions =
             throwable.suppressedExceptions.map {
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/PrivacySandboxThrowableParcelConverter.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/PrivacySandboxThrowableParcelConverter.kt
index 4b0857c..73d230c 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/PrivacySandboxThrowableParcelConverter.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/interfaces/output/com/sdk/PrivacySandboxThrowableParcelConverter.kt
@@ -9,7 +9,10 @@
         val stackTrace = throwableParcel.stackTrace
         val exception = PrivacySandboxException(
             "[$exceptionClass] $errorMessage",
-            throwableParcel.cause?.let { fromThrowableParcel(it) })
+            throwableParcel.cause?.firstOrNull()?.let {
+                fromThrowableParcel(it)
+            }
+        )
         for (suppressed in throwableParcel.suppressedExceptions) {
             exception.addSuppressed(fromThrowableParcel(suppressed))
         }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
index 42297ec..7797726 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/primitives/output/com/mysdk/PrivacySandboxThrowableParcelConverter.kt
@@ -9,7 +9,10 @@
         val stackTrace = throwableParcel.stackTrace
         val exception = PrivacySandboxException(
             "[$exceptionClass] $errorMessage",
-            throwableParcel.cause?.let { fromThrowableParcel(it) })
+            throwableParcel.cause?.firstOrNull()?.let {
+                fromThrowableParcel(it)
+            }
+        )
         for (suppressed in throwableParcel.suppressedExceptions) {
             exception.addSuppressed(fromThrowableParcel(suppressed))
         }
diff --git a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/PrivacySandboxThrowableParcelConverter.kt b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/PrivacySandboxThrowableParcelConverter.kt
index 34de1d7..d86cb2b 100644
--- a/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/PrivacySandboxThrowableParcelConverter.kt
+++ b/privacysandbox/tools/tools-apigenerator/src/test/test-data/values/output/com/sdkwithvalues/PrivacySandboxThrowableParcelConverter.kt
@@ -9,7 +9,10 @@
         val stackTrace = throwableParcel.stackTrace
         val exception = PrivacySandboxException(
             "[$exceptionClass] $errorMessage",
-            throwableParcel.cause?.let { fromThrowableParcel(it) })
+            throwableParcel.cause?.firstOrNull()?.let {
+                fromThrowableParcel(it)
+            }
+        )
         for (suppressed in throwableParcel.suppressedExceptions) {
             exception.addSuppressed(fromThrowableParcel(suppressed))
         }
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/AidlGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/AidlGenerator.kt
index 4c245ac..1df8157 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/AidlGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/AidlGenerator.kt
@@ -170,7 +170,7 @@
             addProperty("exceptionClass", primitive("String"))
             addProperty("errorMessage", primitive("String"))
             addProperty("stackTrace", AidlTypeSpec(parcelableStackFrameType(), isList = true))
-            addProperty("cause", AidlTypeSpec(throwableParcelType()), isNullable = true)
+            addProperty("cause", AidlTypeSpec(throwableParcelType(), isList = true))
             addProperty(
                 "suppressedExceptions", AidlTypeSpec(throwableParcelType(), isList = true)
             )
diff --git a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ThrowableParcelConverterFileGenerator.kt b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ThrowableParcelConverterFileGenerator.kt
index 4ac7844..b45aca8 100644
--- a/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ThrowableParcelConverterFileGenerator.kt
+++ b/privacysandbox/tools/tools-core/src/main/java/androidx/privacysandbox/tools/core/generator/ThrowableParcelConverterFileGenerator.kt
@@ -77,7 +77,7 @@
                         stackFrame
                     }.toTypedArray()
                     throwable.cause?.let {
-                        parcel.cause = ${toThrowableParcelNameSpec.simpleName}(it)
+                        parcel.cause = arrayOf(${toThrowableParcelNameSpec.simpleName}(it))
                     }
                     parcel.suppressedExceptions =
                         throwable.suppressedExceptions.map {
@@ -103,7 +103,10 @@
                     val stackTrace = throwableParcel.stackTrace
                     val exception = PrivacySandboxException(
                         "[${'$'}exceptionClass] ${'$'}errorMessage",
-                        throwableParcel.cause?.let { ${fromThrowableParcelNameSpec.simpleName}(it) })
+                        throwableParcel.cause?.firstOrNull()?.let {
+                            ${fromThrowableParcelNameSpec.simpleName}(it)
+                        }
+                    )
                     for (suppressed in throwableParcel.suppressedExceptions) {
                         exception.addSuppressed(${fromThrowableParcelNameSpec.simpleName}(suppressed))
                     }
diff --git a/privacysandbox/tools/tools-core/src/test/test-data/aidlinterfacegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl b/privacysandbox/tools/tools-core/src/test/test-data/aidlinterfacegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
index 716a0f9..cff4771 100644
--- a/privacysandbox/tools/tools-core/src/test/test-data/aidlinterfacegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
+++ b/privacysandbox/tools/tools-core/src/test/test-data/aidlinterfacegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
@@ -3,8 +3,8 @@
 import com.mysdk.ParcelableStackFrame;
 
 parcelable PrivacySandboxThrowableParcel {
-    @nullable(heap=true) PrivacySandboxThrowableParcel cause;
     ParcelableStackFrame[] stackTrace;
+    PrivacySandboxThrowableParcel[] cause;
     PrivacySandboxThrowableParcel[] suppressedExceptions;
     String errorMessage;
     String exceptionClass;
diff --git a/privacysandbox/tools/tools-core/src/test/test-data/aidlservicegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl b/privacysandbox/tools/tools-core/src/test/test-data/aidlservicegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
index 716a0f9..cff4771 100644
--- a/privacysandbox/tools/tools-core/src/test/test-data/aidlservicegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
+++ b/privacysandbox/tools/tools-core/src/test/test-data/aidlservicegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
@@ -3,8 +3,8 @@
 import com.mysdk.ParcelableStackFrame;
 
 parcelable PrivacySandboxThrowableParcel {
-    @nullable(heap=true) PrivacySandboxThrowableParcel cause;
     ParcelableStackFrame[] stackTrace;
+    PrivacySandboxThrowableParcel[] cause;
     PrivacySandboxThrowableParcel[] suppressedExceptions;
     String errorMessage;
     String exceptionClass;
diff --git a/privacysandbox/tools/tools-core/src/test/test-data/aidlvaluegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl b/privacysandbox/tools/tools-core/src/test/test-data/aidlvaluegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
index 716a0f9..cff4771 100644
--- a/privacysandbox/tools/tools-core/src/test/test-data/aidlvaluegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
+++ b/privacysandbox/tools/tools-core/src/test/test-data/aidlvaluegeneratortest/output/com/mysdk/PrivacySandboxThrowableParcel.aidl
@@ -3,8 +3,8 @@
 import com.mysdk.ParcelableStackFrame;
 
 parcelable PrivacySandboxThrowableParcel {
-    @nullable(heap=true) PrivacySandboxThrowableParcel cause;
     ParcelableStackFrame[] stackTrace;
+    PrivacySandboxThrowableParcel[] cause;
     PrivacySandboxThrowableParcel[] suppressedExceptions;
     String errorMessage;
     String exceptionClass;
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
index cedb6fb6..b79f94a 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XType.kt
@@ -60,7 +60,11 @@
     val nullability: XNullability
 
     /**
-     * The resolved types of the super classes/interfaces of this type.
+     * The resolved direct super types of this type.
+     *
+     * The interface types, if any, will appear last in the list.
+     *
+     * See [Types#directSupertypes()](https://docs.oracle.com/javase/7/docs/api/javax/lang/model/util/Types.html#directSupertypes(javax.lang.model.type.TypeMirror))
      */
     val superTypes: List<XType>
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
index 80525af..1faa32c9 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
@@ -46,13 +46,6 @@
         get() = superClass
 
     /**
-     * The direct super types of this element.
-     *
-     * See [JLS 4.10.2](https://docs.oracle.com/javase/specs/jls/se18/html/jls-4.html#jls-4.10.2)
-     */
-    val superTypes: List<XType>
-
-    /**
      * The super class of this element if it represents a class.
      */
     val superClass: XType?
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
index 403d6fb..a2beb5a 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
@@ -25,7 +25,6 @@
 import androidx.room.compiler.processing.XMemberContainer
 import androidx.room.compiler.processing.XMethodElement
 import androidx.room.compiler.processing.XNullability
-import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.XTypeParameterElement
 import androidx.room.compiler.processing.collectAllMethods
@@ -36,7 +35,6 @@
 import com.google.auto.common.MoreElements
 import com.google.auto.common.MoreTypes
 import com.squareup.javapoet.ClassName
-import com.squareup.javapoet.TypeName
 import com.squareup.kotlinpoet.javapoet.JClassName
 import javax.lang.model.element.ElementKind
 import javax.lang.model.element.TypeElement
@@ -195,17 +193,6 @@
         )
     }
 
-    override val superTypes: List<XType> by lazy {
-        buildList {
-            if (isInterface() && superInterfaces.isEmpty()) {
-                add(env.requireType(TypeName.OBJECT))
-            } else {
-                superClass?.let { add(it) }
-                addAll(superInterfaces)
-            }
-        }
-    }
-
     override val superClass: JavacType? by lazy {
         // javac models non-existing types as TypeKind.NONE but we prefer to make it nullable.
         // just makes more sense and safer as we don't need to check for none.
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 3e072561..3acfe4a 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
@@ -26,9 +26,13 @@
 import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.devtools.ksp.symbol.KSType
+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.Nullability
+import com.google.devtools.ksp.symbol.Variance
 import com.squareup.javapoet.TypeName
+import com.squareup.javapoet.WildcardTypeName
 import com.squareup.kotlinpoet.javapoet.JTypeName
 import com.squareup.kotlinpoet.javapoet.KTypeName
 import kotlin.reflect.KClass
@@ -91,13 +95,60 @@
     }
 
     override val superTypes: List<XType> by lazy {
-        val declaration = ksType.declaration as? KSClassDeclaration
-        declaration?.superTypes?.toList()?.map {
+        if (typeName == TypeName.OBJECT) {
+            // The object class doesn't have any supertypes.
+            return@lazy emptyList<XType>()
+        }
+        val resolvedTypeArguments: Map<String, KSTypeArgument> =
+            ksType.declaration.typeParameters.mapIndexed { i, parameter ->
+                parameter.name.asString() to ksType.arguments[i]
+            }.toMap()
+        val superTypes = (ksType.declaration as? KSClassDeclaration)?.superTypes?.toList()?.map {
             env.wrap(
-                ksType = it.resolve(),
+                ksType = resolveTypeArguments(it.resolve(), resolvedTypeArguments),
                 allowPrimitives = false
             )
         } ?: emptyList()
+        val (superClasses, superInterfaces) = superTypes.partition {
+            it.typeElement?.isClass() == true
+        }
+        // Per documentation, always return the class before the interfaces.
+        if (superClasses.isEmpty()) {
+            // Return Object when there's no explicit super class specified on the class/interface.
+            // This matches javac's Types#directSupertypes().
+            listOf(env.requireType(TypeName.OBJECT)) + superInterfaces
+        } else {
+            check(superClasses.size == 1)
+            superClasses + superInterfaces
+        }
+    }
+
+    private fun resolveTypeArguments(
+        type: KSType,
+        resolvedTypeArguments: Map<String, KSTypeArgument>
+    ): KSType {
+        return type.replace(
+            type.arguments.map { argument ->
+                val argDeclaration = argument.type?.resolve()?.declaration
+                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
+                ) {
+                    // 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)
+                        ),
+                        variance = Variance.INVARIANT
+                    )
+                } else {
+                    argument
+                }
+            }.toList()
+        )
     }
 
     override val typeElement by lazy {
@@ -136,7 +187,14 @@
     }
 
     override fun isError(): Boolean {
-        return ksType.isError
+        // Avoid returning true if this type represents a java wildcard type, e.g. "? extends Foo"
+        // since in that case the wildcard type is not the error type itself. Instead, the error
+        // type should be on the XType#extendsBound() type, "Foo", instead.
+        return ksType.isError && !isJavaWildcardType()
+    }
+
+    private fun isJavaWildcardType(): Boolean {
+        return asTypeName().java is WildcardTypeName
     }
 
     override fun defaultValue(): String {
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index 75517f7..7674249 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -45,7 +45,6 @@
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
 import com.google.devtools.ksp.symbol.Modifier
 import com.squareup.javapoet.ClassName
-import com.squareup.javapoet.TypeName
 import com.squareup.kotlinpoet.javapoet.JClassName
 import com.squareup.kotlinpoet.javapoet.KClassName
 
@@ -89,17 +88,6 @@
         )
     }
 
-    override val superTypes: List<XType> by lazy {
-        buildList {
-            if (isInterface() && superInterfaces.isEmpty()) {
-                add(env.requireType(TypeName.OBJECT))
-            } else {
-                superClass?.let { add(it) }
-                addAll(superInterfaces)
-            }
-        }
-    }
-
     override val superClass: XType? by lazy {
         if (isInterface()) {
             // interfaces don't have super classes (they do have super types)
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 36836e4..b49b301 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
@@ -145,7 +145,7 @@
                 assertThat(it.superClass).isEqualTo(
                     invocation.processingEnv.requireType("foo.bar.AbstractClass")
                 )
-                assertThat(it.superTypes).containsExactly(
+                assertThat(it.type.superTypes).containsExactly(
                     invocation.processingEnv.requireType("foo.bar.AbstractClass"),
                     invocation.processingEnv.requireType("foo.bar.MyInterface")
                 )
@@ -160,7 +160,7 @@
                 assertThat(it.superClass).isEqualTo(
                     invocation.processingEnv.requireType(JTypeName.OBJECT)
                 )
-                assertThat(it.superTypes).containsExactly(
+                assertThat(it.type.superTypes).containsExactly(
                     invocation.processingEnv.requireType(JTypeName.OBJECT)
                 )
                 assertThat(it.isAbstract()).isTrue()
@@ -171,7 +171,7 @@
             }
             invocation.processingEnv.requireTypeElement("foo.bar.MyInterface").let {
                 assertThat(it.superClass).isNull()
-                assertThat(it.superTypes).containsExactly(
+                assertThat(it.type.superTypes).containsExactly(
                     invocation.processingEnv.requireType(JTypeName.OBJECT)
                 )
                 assertThat(it.isInterface()).isTrue()
@@ -181,7 +181,8 @@
             }
             invocation.processingEnv.requireTypeElement("foo.bar.AnotherInterface").let {
                 assertThat(it.superClass).isNull()
-                assertThat(it.superTypes).containsExactly(
+                assertThat(it.type.superTypes).containsExactly(
+                    invocation.processingEnv.requireType("java.lang.Object"),
                     invocation.processingEnv.requireType("foo.bar.MyInterface")
                 )
                 assertThat(it.isInterface()).isTrue()
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 b42a29c..4e5c8b2 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
@@ -37,6 +37,7 @@
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeVariableName
+import com.squareup.javapoet.WildcardTypeName
 import com.squareup.kotlinpoet.INT
 import com.squareup.kotlinpoet.MUTABLE_SET
 import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
@@ -1037,4 +1038,273 @@
             """.trimIndent()
         ))) { it.checkPrimitiveType() }
     }
+
+    @Test
+    fun setSuperTypeNames() {
+        fun superTypeHierarchy(type: XType, depth: Int = 0): String {
+            val sb: StringBuilder = StringBuilder()
+            sb.append("${"  ".repeat(depth)}> ${type.typeName}")
+            type.superTypes.forEach {
+                sb.append("\n").append(superTypeHierarchy(it, depth + 1))
+            }
+            return sb.toString()
+        }
+
+        fun XTestInvocation.checkType() {
+            val fooElement = processingEnv.requireTypeElement("test.Foo")
+            val method1 = fooElement.getMethodByJvmName("method1")
+            val method2 = fooElement.getMethodByJvmName("method2")
+
+            // Check the return types of the unresolved methods
+            assertThat(method1.returnType.typeName).isEqualTo(TypeVariableName.get("T1"))
+            assertThat(method2.returnType.typeName).isEqualTo(TypeVariableName.get("T2"))
+
+            // Check the return types of the methods resolved into Usage
+            val usageElement = processingEnv.requireTypeElement("test.Usage")
+            assertThat(method1.asMemberOf(usageElement.type).returnType.typeName.toString())
+                .isEqualTo("test.Baz<java.lang.Long, java.lang.Number>")
+            assertThat(method2.asMemberOf(usageElement.type).returnType.typeName.toString())
+                .isEqualTo("java.lang.Integer")
+
+            // Check the supertypes of the unresolved Foo
+            assertThat(superTypeHierarchy(fooElement.type)).isEqualTo(
+                """
+                > test.Foo<V1, V2>
+                  > java.lang.Object
+                  > test.Bar<test.Baz<V1, java.lang.Number>, V2>
+                    > java.lang.Object
+                    > test.Baz<test.Baz<V1, java.lang.Number>, V2>
+                      > java.lang.Object
+                """.trimIndent()
+            )
+
+            // Check the supertypes of Foo<Long, Integer>
+            assertThat(superTypeHierarchy(usageElement.type)).isEqualTo(
+                """
+                > test.Usage
+                  > java.lang.Object
+                  > test.Foo<java.lang.Long, java.lang.Integer>
+                    > java.lang.Object
+                    > test.Bar<test.Baz<java.lang.Long, java.lang.Number>, java.lang.Integer>
+                      > java.lang.Object
+                      > test.Baz<test.Baz<java.lang.Long, java.lang.Number>, java.lang.Integer>
+                        > java.lang.Object
+                """.trimIndent()
+            )
+
+            // Check the supertypes of Foo<String, Integer>
+            val methodFoo = usageElement.getMethodByJvmName("foo")
+            assertThat(superTypeHierarchy(methodFoo.returnType)).isEqualTo(
+                """
+                > test.Foo<java.lang.String, java.lang.Integer>
+                  > java.lang.Object
+                  > test.Bar<test.Baz<java.lang.String, java.lang.Number>, java.lang.Integer>
+                    > java.lang.Object
+                    > test.Baz<test.Baz<java.lang.String, java.lang.Number>, java.lang.Integer>
+                      > java.lang.Object
+                """.trimIndent()
+            )
+
+            // Check the supertypes of Foo<Double, Integer>
+            assertThat(superTypeHierarchy(methodFoo.parameters[0].type)).isEqualTo(
+                """
+                > test.Foo<java.lang.Double, java.lang.Integer>
+                  > java.lang.Object
+                  > test.Bar<test.Baz<java.lang.Double, java.lang.Number>, java.lang.Integer>
+                    > java.lang.Object
+                    > test.Baz<test.Baz<java.lang.Double, java.lang.Number>, java.lang.Integer>
+                      > java.lang.Object
+                """.trimIndent()
+            )
+        }
+
+        runProcessorTest(listOf(Source.java(
+            "test.Usage",
+            """
+            package test;
+            interface Usage extends Foo<Long, Integer> {
+                Foo<String, Integer> foo(Foo<Double, Integer> param);
+            }
+            interface Foo<V1, V2 extends Integer> extends Bar<Baz<V1, Number>, V2> {}
+            interface Bar<U1, U2 extends Integer> extends Baz<U1, U2> {}
+            interface Baz<T1, T2 extends Number> {
+                T1 method1();
+                T2 method2();
+            }
+            """.trimIndent()
+        ))) { it.checkType() }
+
+        runProcessorTest(listOf(Source.kotlin(
+            "test.Usage.kt",
+            """
+            package test
+            interface Usage : Foo<Long, Integer> {
+                fun foo(param: Foo<Double, Integer>): Foo<String, Integer>
+            }
+            interface Foo<V1, V2: Integer> : Bar<Baz<V1, Number>, V2> {}
+            interface Bar<U1, U2: Integer> : Baz<U1, U2> {}
+            interface Baz<T1, T2: Number> {
+                fun method1(): T1
+                fun method2(): T2
+            }
+            """.trimIndent()
+        ))) { it.checkType() }
+    }
+
+    @Test
+    fun typeArgumentMissingType() {
+        class TypeArgumentProcessingStep : XProcessingStep {
+            override fun annotations() = setOf("test.Inspect")
+
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>,
+                isLastRound: Boolean
+            ): Set<XElement> {
+                val barElement = env.requireTypeElement("test.Bar")
+                val missingTypeName = if (
+                    env.backend == XProcessingEnv.Backend.KSP ||
+                    // There's a bug in KAPT that doesn't replace NonExistentClass even when
+                    // correctErrorTypes is enabled, so we account for that here.
+                    // https://youtrack.jetbrains.com/issue/KT-34193/Kapt-CorrectErrorTypes-doesnt-work-for-generics
+                    barElement.hasAnnotation(Metadata::class)
+                ) {
+                    ClassName.get("error", "NonExistentClass")
+                } else {
+                    ClassName.get("", "MissingType")
+                }
+                val barType = barElement.type
+                val fooTypeName = ParameterizedTypeName.get(
+                    ClassName.get("test", "Foo"),
+                    missingTypeName
+                )
+
+                val fooType = barType.superTypes.single()
+                assertThat(fooType.typeName).isEqualTo(fooTypeName)
+                assertThat(fooType.isError()).isFalse()
+
+                val typeArgument = fooType.typeArguments.single()
+                assertThat(typeArgument.typeName).isEqualTo(missingTypeName)
+                assertThat(typeArgument.isError()).isTrue()
+
+                return emptySet()
+            }
+        }
+
+        runProcessorTest(
+            sources = listOf(Source.java(
+                "test.Foo",
+                """
+                package test;
+                @Inspect
+                class Bar extends Foo<MissingType> {}
+                class Foo<T> {}
+                @interface Inspect {}
+                """.trimIndent()
+            )),
+            createProcessingStep = { TypeArgumentProcessingStep() }
+        ) { result ->
+            result.hasError()
+            result.hasErrorCount(1)
+            result.hasErrorContaining("cannot find symbol")
+        }
+
+        runProcessorTest(
+            sources = listOf(Source.kotlin(
+                "test.Foo.kt",
+                """
+            package test
+            class Bar : Foo<MissingType>()
+            open class Foo<T>
+            """.trimIndent()
+            )),
+            kotlincArguments = listOf(
+                "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"
+            ),
+            createProcessingStep = { TypeArgumentProcessingStep() }
+        ) { result ->
+            result.hasError()
+            result.hasErrorCount(1)
+            result.hasErrorContaining("Unresolved reference")
+        }
+    }
+
+    @Test
+    fun wildcardWithMissingType() {
+        class WildcardProcessingStep : XProcessingStep {
+            override fun annotations() = setOf("test.Inspect")
+
+            override fun process(
+                env: XProcessingEnv,
+                elementsByAnnotation: Map<String, Set<XElement>>,
+                isLastRound: Boolean
+            ): Set<XElement> {
+                val missingTypeName = if (env.backend == XProcessingEnv.Backend.KSP) {
+                    ClassName.get("error", "NonExistentClass")
+                } else {
+                    ClassName.get("", "MissingType")
+                }
+                val wildcardTypeName = WildcardTypeName.subtypeOf(missingTypeName)
+                val fooTypeName = ParameterizedTypeName.get(
+                    ClassName.get("test", "Foo"),
+                    wildcardTypeName
+                )
+
+                val fooElement = env.requireTypeElement("test.Foo")
+                val fooType = fooElement.getField("foo").type
+                assertThat(fooType.typeName).isEqualTo(fooTypeName)
+                assertThat(fooType.isError()).isFalse()
+
+                val wildcardType = fooType.typeArguments.single()
+                assertThat(wildcardType.typeName).isEqualTo(wildcardTypeName)
+                assertThat(wildcardType.isError()).isFalse()
+
+                assertThat(wildcardType.extendsBound()).isNotNull()
+                val errorType = wildcardType.extendsBound()!!
+                assertThat(errorType.typeName).isEqualTo(missingTypeName)
+                assertThat(errorType.isError()).isTrue()
+
+                return emptySet()
+            }
+        }
+
+        runProcessorTest(
+            sources = listOf(Source.java(
+                "test.Foo",
+                """
+                package test;
+                @Inspect
+                class Foo<T> {
+                  Foo<? extends MissingType> foo;
+                }
+                @interface Inspect {}
+                """.trimIndent()
+            )),
+            createProcessingStep = { WildcardProcessingStep() }
+        ) { result ->
+            result.hasError()
+            result.hasErrorCount(1)
+            result.hasErrorContaining("cannot find symbol")
+        }
+
+        runProcessorTest(
+            sources = listOf(Source.kotlin(
+                "test.Foo.kt",
+                """
+            package test
+            class Foo<T> {
+              val foo: Foo<out MissingType> = TODO()
+            }
+            """.trimIndent()
+            )),
+            kotlincArguments = listOf(
+                "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"
+            ),
+            createProcessingStep = { WildcardProcessingStep() }
+        ) { result ->
+            result.hasError()
+            result.hasErrorCount(1)
+            result.hasErrorContaining("Unresolved reference")
+        }
+    }
 }
diff --git a/settings.gradle b/settings.gradle
index 66f7240..3d2ec6a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -578,6 +578,8 @@
 includeProject(":concurrent:concurrent-futures-ktx", [BuildType.MAIN, BuildType.CAMERA])
 includeProject(":constraintlayout:constraintlayout-compose", [BuildType.COMPOSE])
 includeProject(":constraintlayout:constraintlayout-compose:integration-tests:constraintlayout-compose-demos", [BuildType.COMPOSE])
+includeProject(":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark", [BuildType.COMPOSE])
+includeProject(":constraintlayout:constraintlayout-compose:integration-tests:macrobenchmark-target", [BuildType.COMPOSE])
 includeProject(":constraintlayout:constraintlayout", [BuildType.MAIN])
 includeProject(":constraintlayout:constraintlayout-core", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":contentpager:contentpager", [BuildType.MAIN])
@@ -657,6 +659,8 @@
 includeProject(":glance:glance-appwidget-preview", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget-proto", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:integration-tests:demos", [BuildType.GLANCE])
+includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark", [BuildType.GLANCE])
+includeProject(":glance:glance-appwidget:integration-tests:macrobenchmark-target", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:integration-tests:template-demos", [BuildType.GLANCE])
 includeProject(":glance:glance-appwidget:glance-layout-generator", [BuildType.GLANCE])
 includeProject(":glance:glance-preview", [BuildType.GLANCE])
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiCollection.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiCollection.java
index 40b8b2a..5322d2a 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiCollection.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiCollection.java
@@ -50,7 +50,6 @@
     @NonNull
     public UiObject getChildByDescription(@NonNull UiSelector childPattern, @NonNull String text)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text);
         if (text != null) {
             int count = getChildCount(childPattern);
             for (int x = 0; x < count; x++) {
@@ -84,7 +83,6 @@
     @NonNull
     public UiObject getChildByInstance(@NonNull UiSelector childPattern, int instance)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, instance);
         UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
                 UiSelector.patternBuilder(childPattern).instance(instance));
         return new UiObject(patternSelector);
@@ -108,7 +106,6 @@
     @NonNull
     public UiObject getChildByText(@NonNull UiSelector childPattern, @NonNull String text)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text);
         if (text != null) {
             int count = getChildCount(childPattern);
             for (int x = 0; x < count; x++) {
@@ -137,7 +134,6 @@
      * @return the number of matched childPattern under the current {@link UiCollection}
      */
     public int getChildCount(@NonNull UiSelector childPattern) {
-        Tracer.trace(childPattern);
         UiSelector patternSelector =
                 UiSelector.patternBuilder(getSelector(), UiSelector.patternBuilder(childPattern));
         return getQueryController().getPatternCount(patternSelector);
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiDevice.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiDevice.java
index 18177fe..e1c2e70 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiDevice.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiDevice.java
@@ -56,6 +56,7 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -69,8 +70,7 @@
  * such as pressing the d-pad or pressing the Home and Menu buttons.
  */
 public class UiDevice implements Searchable {
-
-    private static final String LOG_TAG = UiDevice.class.getSimpleName();
+    private static final String TAG = UiDevice.class.getSimpleName();
 
     // Use a short timeout after HOME or BACK key presses, as no events might be generated if
     // already on the home page or if there is nothing to go back to.
@@ -165,6 +165,7 @@
      * was not met before the {@code timeout}.
      */
     public <U> U wait(@NonNull SearchCondition<U> condition, long timeout) {
+        Log.d(TAG, String.format("Waiting %dms for condition %s.", timeout, condition));
         return mWaitMixin.wait(condition, timeout);
     }
 
@@ -179,11 +180,14 @@
     public <U> U performActionAndWait(@NonNull Runnable action,
             @NonNull EventCondition<U> condition, long timeout) {
         AccessibilityEvent event = null;
+        Log.d(TAG, String.format("Performing action %s and waiting %dms for condition %s.",
+                action, timeout, condition));
         try {
             event = getUiAutomation().executeAndWaitForEvent(
                 action, new EventForwardingFilter(condition), timeout);
         } catch (TimeoutException e) {
             // Ignore
+            Log.w(TAG, String.format("Timed out waiting %dms on the condition.", timeout));
         }
 
         if (event != null) {
@@ -263,7 +267,6 @@
      */
     @NonNull
     public Point getDisplaySizeDp() {
-        Tracer.trace();
         Display display = getDefaultDisplay();
         Point p = new Point();
         display.getRealSize(p);
@@ -286,7 +289,6 @@
      */
     @NonNull
     public String getProductName() {
-        Tracer.trace();
         return Build.PRODUCT;
     }
 
@@ -306,7 +308,6 @@
      */
     @SuppressLint("UnknownNullness") // Avoid unnecessary null checks from nullable testing APIs.
     public String getLastTraversedText() {
-        Tracer.trace();
         return getQueryController().getLastTraversedText();
     }
 
@@ -315,7 +316,7 @@
      * See {@link #getLastTraversedText()}.
      */
     public void clearLastTraversedText() {
-        Tracer.trace();
+        Log.d(TAG, "Clearing last traversed text.");
         getQueryController().clearLastTraversedText();
     }
 
@@ -324,8 +325,8 @@
      * @return true if successful, else return false
      */
     public boolean pressMenu() {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Pressing menu button.");
         return getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_MENU, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
@@ -336,8 +337,8 @@
      * @return true if successful, else return false
      */
     public boolean pressBack() {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Pressing back button.");
         return getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_BACK, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
@@ -348,8 +349,8 @@
      * @return true if successful, else return false
      */
     public boolean pressHome() {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Pressing home button.");
         return getInteractionController().sendKeyAndWaitForEvent(
                 KeyEvent.KEYCODE_HOME, 0, AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED,
                 KEY_PRESS_EVENT_TIMEOUT);
@@ -360,7 +361,6 @@
      * @return true if successful, else return false
      */
     public boolean pressSearch() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_SEARCH);
     }
 
@@ -369,7 +369,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDPadCenter() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DPAD_CENTER);
     }
 
@@ -378,7 +377,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDPadDown() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DPAD_DOWN);
     }
 
@@ -387,7 +385,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDPadUp() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DPAD_UP);
     }
 
@@ -396,7 +393,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDPadLeft() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DPAD_LEFT);
     }
 
@@ -405,7 +401,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDPadRight() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DPAD_RIGHT);
     }
 
@@ -414,7 +409,6 @@
      * @return true if successful, else return false
      */
     public boolean pressDelete() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_DEL);
     }
 
@@ -423,7 +417,6 @@
      * @return true if successful, else return false
      */
     public boolean pressEnter() {
-        Tracer.trace();
         return pressKeyCode(KeyEvent.KEYCODE_ENTER);
     }
 
@@ -434,8 +427,8 @@
      * @return true if successful, else return false
      */
     public boolean pressKeyCode(int keyCode) {
-        Tracer.trace(keyCode);
         waitForIdle();
+        Log.d(TAG, String.format("Pressing keycode %d.", keyCode));
         return getInteractionController().sendKey(keyCode, 0);
     }
 
@@ -448,8 +441,9 @@
      * @return true if successful, else return false
      */
     public boolean pressKeyCode(int keyCode, int metaState) {
-        Tracer.trace(keyCode, metaState);
         waitForIdle();
+        Log.d(TAG, String.format("Pressing keycode %d with modifier %d.", keyCode,
+                metaState));
         return getInteractionController().sendKey(keyCode, metaState);
     }
 
@@ -460,8 +454,8 @@
      * @throws RemoteException
      */
     public boolean pressRecentApps() throws RemoteException {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Pressing recent apps button.");
         return getInteractionController().toggleRecentApps();
     }
 
@@ -471,8 +465,8 @@
      * @return true if successful, else return false
      */
     public boolean openNotification() {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Opening notification.");
         return  getInteractionController().openNotification();
     }
 
@@ -482,8 +476,8 @@
      * @return true if successful, else return false
      */
     public boolean openQuickSettings() {
-        Tracer.trace();
         waitForIdle();
+        Log.d(TAG, "Opening quick settings.");
         return getInteractionController().openQuickSettings();
     }
 
@@ -493,7 +487,6 @@
      * @return width in pixels or zero on failure
      */
     public int getDisplayWidth() {
-        Tracer.trace();
         Display display = getDefaultDisplay();
         Point p = new Point();
         display.getRealSize(p);
@@ -506,7 +499,6 @@
      * @return height in pixels or zero on failure
      */
     public int getDisplayHeight() {
-        Tracer.trace();
         Display display = getDefaultDisplay();
         Point p = new Point();
         display.getRealSize(p);
@@ -521,10 +513,12 @@
      * @return true if the click succeeded else false
      */
     public boolean click(int x, int y) {
-        Tracer.trace(x, y);
         if (x >= getDisplayWidth() || y >= getDisplayHeight()) {
+            Log.w(TAG, String.format("Cannot click. Point (%d, %d) is outside display (%d, %d).",
+                    x, y, getDisplayWidth(), getDisplayHeight()));
             return false;
         }
+        Log.d(TAG, String.format("Clicking on (%d, %d).", x, y));
         return getInteractionController().clickNoSync(x, y);
     }
 
@@ -541,7 +535,8 @@
      * @return false if the operation fails or the coordinates are invalid
      */
     public boolean swipe(int startX, int startY, int endX, int endY, int steps) {
-        Tracer.trace(startX, startY, endX, endY, steps);
+        Log.d(TAG, String.format("Swiping from (%d, %d) to (%d, %d) in %d steps.", startX, startY,
+                endX, endY, steps));
         return getInteractionController()
                 .swipe(startX, startY, endX, endY, steps);
     }
@@ -561,7 +556,8 @@
      * or the coordinates are invalid
      */
     public boolean drag(int startX, int startY, int endX, int endY, int steps) {
-        Tracer.trace(startX, startY, endX, endY, steps);
+        Log.d(TAG, String.format("Dragging from (%d, %d) to (%d, %d) in %d steps.", startX, startY,
+                endX, endY, steps));
         return getInteractionController()
                 .swipe(startX, startY, endX, endY, steps, true);
     }
@@ -575,7 +571,8 @@
      * @return true on success
      */
     public boolean swipe(@NonNull Point[] segments, int segmentSteps) {
-        Tracer.trace(segments, segmentSteps);
+        Log.d(TAG, String.format("Swiping between %s in %d steps.", Arrays.toString(segments),
+                segmentSteps * (segments.length - 1)));
         return getInteractionController().swipe(segments, segmentSteps);
     }
 
@@ -584,7 +581,6 @@
      * Default wait timeout is 10 seconds
      */
     public void waitForIdle() {
-        Tracer.trace();
         getQueryController().waitForIdle();
     }
 
@@ -593,7 +589,6 @@
      * @param timeout in milliseconds
      */
     public void waitForIdle(long timeout) {
-        Tracer.trace(timeout);
         getQueryController().waitForIdle(timeout);
     }
 
@@ -605,7 +600,6 @@
     @Deprecated
     @SuppressLint("UnknownNullness") // Avoid unnecessary null checks from nullable testing APIs.
     public String getCurrentActivityName() {
-        Tracer.trace();
         return getQueryController().getCurrentActivityName();
     }
 
@@ -615,7 +609,6 @@
      */
     @SuppressLint("UnknownNullness") // Avoid unnecessary null checks from nullable testing APIs.
     public String getCurrentPackageName() {
-        Tracer.trace();
         return getQueryController().getCurrentPackageName();
     }
 
@@ -627,7 +620,7 @@
      * @param watcher {@link UiWatcher}
      */
     public void registerWatcher(@Nullable String name, @Nullable UiWatcher watcher) {
-        Tracer.trace(name, watcher);
+        Log.d(TAG, String.format("Registering watcher %s.", name));
         if (mInWatcherContext) {
             throw new IllegalStateException("Cannot register new watcher from within another");
         }
@@ -641,7 +634,7 @@
      * @param name used to register the UiWatcher
      */
     public void removeWatcher(@Nullable String name) {
-        Tracer.trace(name);
+        Log.d(TAG, String.format("Removing watcher %s.", name));
         if (mInWatcherContext) {
             throw new IllegalStateException("Cannot remove a watcher from within another");
         }
@@ -653,7 +646,6 @@
      * See {@link #registerWatcher(String, UiWatcher)}
      */
     public void runWatchers() {
-        Tracer.trace();
         if (mInWatcherContext) {
             return;
         }
@@ -667,7 +659,7 @@
                         setWatcherTriggered(watcherName);
                     }
                 } catch (Exception e) {
-                    Log.e(LOG_TAG, "Exceuting watcher: " + watcherName, e);
+                    Log.e(TAG, String.format("Failed to execute watcher %s.", watcherName), e);
                 } finally {
                     mInWatcherContext = false;
                 }
@@ -682,7 +674,7 @@
      * See {@link #registerWatcher(String, UiWatcher)}
      */
     public void resetWatcherTriggers() {
-        Tracer.trace();
+        Log.d(TAG, "Resetting all watchers.");
         mWatchersTriggers.clear();
     }
 
@@ -697,7 +689,6 @@
      * @return true if triggered else false
      */
     public boolean hasWatcherTriggered(@Nullable String watcherName) {
-        Tracer.trace(watcherName);
         return mWatchersTriggers.contains(watcherName);
     }
 
@@ -708,7 +699,6 @@
      * See {@link #hasWatcherTriggered(String)}
      */
     public boolean hasAnyWatcherTriggered() {
-        Tracer.trace();
         return mWatchersTriggers.size() > 0;
     }
 
@@ -717,7 +707,6 @@
      * @param watcherName
      */
     private void setWatcherTriggered(String watcherName) {
-        Tracer.trace(watcherName);
         if (!hasWatcherTriggered(watcherName)) {
             mWatchersTriggers.add(watcherName);
         }
@@ -729,7 +718,6 @@
      * @return true if it is in natural orientation
      */
     public boolean isNaturalOrientation() {
-        Tracer.trace();
         waitForIdle();
         int ret = getDisplayRotation();
         return ret == UiAutomation.ROTATION_FREEZE_0 ||
@@ -740,7 +728,6 @@
      * Returns the current rotation of the display, as defined in {@link Surface}
      */
     public int getDisplayRotation() {
-        Tracer.trace();
         waitForIdle();
         return getDefaultDisplay().getRotation();
     }
@@ -751,7 +738,7 @@
      * @throws RemoteException
      */
     public void freezeRotation() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Freezing rotation.");
         getInteractionController().freezeRotation();
     }
 
@@ -762,7 +749,7 @@
      * @throws RemoteException
      */
     public void unfreezeRotation() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Unfreezing rotation.");
         getInteractionController().unfreezeRotation();
     }
 
@@ -775,7 +762,7 @@
      * @throws RemoteException
      */
     public void setOrientationLeft() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Setting orientation to left.");
         getInteractionController().setRotationLeft();
         waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
     }
@@ -789,7 +776,7 @@
      * @throws RemoteException
      */
     public void setOrientationRight() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Setting orientation to right.");
         getInteractionController().setRotationRight();
         waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
     }
@@ -803,7 +790,7 @@
      * @throws RemoteException
      */
     public void setOrientationNatural() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Setting orientation to natural.");
         getInteractionController().setRotationNatural();
         waitForIdle(); // we don't need to check for idle on entry for this. We'll sync on exit
     }
@@ -817,7 +804,7 @@
      * @throws RemoteException
      */
     public void wakeUp() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Turning on screen.");
         if(getInteractionController().wakeDevice()) {
             // sync delay to allow the window manager to start accepting input
             // after the device is awakened.
@@ -832,7 +819,6 @@
      * @throws RemoteException
      */
     public boolean isScreenOn() throws RemoteException {
-        Tracer.trace();
         return getInteractionController().isScreenOn();
     }
 
@@ -843,7 +829,7 @@
      * @throws RemoteException
      */
     public void sleep() throws RemoteException {
-        Tracer.trace();
+        Log.d(TAG, "Turning off screen.");
         getInteractionController().sleepDevice();
     }
 
@@ -857,7 +843,6 @@
      */
     @Deprecated
     public void dumpWindowHierarchy(@NonNull String fileName) {
-        Tracer.trace(fileName);
 
         File dumpFile = new File(fileName);
         if (!dumpFile.isAbsolute()) {
@@ -906,9 +891,10 @@
      *         window does not have the specified package name
      */
     public boolean waitForWindowUpdate(@Nullable String packageName, long timeout) {
-        Tracer.trace(packageName, timeout);
         if (packageName != null) {
             if (!packageName.equals(getCurrentPackageName())) {
+                Log.w(TAG, String.format("Skipping wait as package %s does not match current "
+                        + "window %s.", packageName, getCurrentPackageName()));
                 return false;
             }
         }
@@ -927,12 +913,15 @@
                 return false;
             }
         };
+        Log.d(TAG, String.format("Waiting %dms for window update of package %s.", timeout,
+                packageName));
         try {
             getUiAutomation().executeAndWaitForEvent(emptyRunnable, checkWindowUpdate, timeout);
         } catch (TimeoutException e) {
+            Log.w(TAG, String.format("Timed out waiting %dms on window update.", timeout));
             return false;
         } catch (Exception e) {
-            Log.e(LOG_TAG, "waitForWindowUpdate: general exception from bridge", e);
+            Log.e(TAG, "Failed to wait for window update.", e);
             return false;
         }
         return true;
@@ -948,7 +937,6 @@
      * @return true if screen shot is created successfully, false otherwise
      */
     public boolean takeScreenshot(@NonNull File storePath) {
-        Tracer.trace(storePath);
         return takeScreenshot(storePath, 1.0f, 90);
     }
 
@@ -963,9 +951,11 @@
      * @return true if screen shot is created successfully, false otherwise
      */
     public boolean takeScreenshot(@NonNull File storePath, float scale, int quality) {
-        Tracer.trace(storePath, scale, quality);
+        Log.d(TAG, String.format("Taking screenshot (scale=%f, quality=%d) and storing at %s.",
+                scale, quality, storePath));
         Bitmap screenshot = getUiAutomation().takeScreenshot();
         if (screenshot == null) {
+            Log.w(TAG, "Failed to take screenshot.");
             return false;
         }
         try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(storePath))) {
@@ -976,7 +966,7 @@
             bos.flush();
             return true;
         } catch (IOException ioe) {
-            Log.e(LOG_TAG, "failed to save screen shot to file", ioe);
+            Log.e(TAG, "Failed to save screenshot.", ioe);
             return false;
         } finally {
             screenshot.recycle();
@@ -1022,6 +1012,7 @@
     @RequiresApi(21)
     @NonNull
     public String executeShellCommand(@NonNull String cmd) throws IOException {
+        Log.d(TAG, String.format("Executing shell command: %s", cmd));
         try (ParcelFileDescriptor pfd = Api21Impl.executeShellCommand(getUiAutomation(), cmd);
              FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
             byte[] buf = new byte[512];
@@ -1073,7 +1064,7 @@
             for (final AccessibilityWindowInfo window : getWindows()) {
                 final AccessibilityNodeInfo root = Api21Impl.getRoot(window);
                 if (root == null) {
-                    Log.w(LOG_TAG, "Skipping null root node for window: " + window);
+                    Log.w(TAG, "Skipping null root node for window: " + window);
                     continue;
                 }
                 roots.add(root);
@@ -1107,7 +1098,7 @@
             uiAutomation = Api24Impl.getUiAutomation(getInstrumentation(), flags);
         } else {
             if (flags != Configurator.DEFAULT_UIAUTOMATION_FLAGS) {
-                Log.w(LOG_TAG, "UiAutomation flags not supported prior to API 24");
+                Log.w(TAG, "UiAutomation flags not supported prior to API 24");
             }
             uiAutomation = getInstrumentation().getUiAutomation();
         }
@@ -1126,7 +1117,7 @@
             } else {
                 serviceInfo.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
             }
-            Log.d(LOG_TAG,
+            Log.d(TAG,
                     String.format("Setting accessibility service flags: %d", serviceInfo.flags));
             uiAutomation.setServiceInfo(serviceInfo);
             mCachedServiceFlags = serviceInfo.flags;
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject.java
index db7e3d3..974fb8f 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject.java
@@ -1121,7 +1121,7 @@
      *         <code>false</code> otherwise
      */
     public boolean performMultiPointerGesture(@NonNull PointerCoords[]... touches) {
-        Log.d(TAG, String.format("Performing multi-point gesture %s", touchesToString(touches)));
+        Log.d(TAG, String.format("Performing multi-point gesture %s.", touchesToString(touches)));
         return getInteractionController().performMultiPointerGesture(touches);
     }
 
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
index 54dd5e5..cb83ac0ab 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiObject2.java
@@ -153,6 +153,7 @@
      * condition} was not met before the {@code timeout}.
      */
     public <U> U wait(@NonNull UiObject2Condition<U> condition, long timeout) {
+        Log.d(TAG, String.format("Waiting %dms for condition %s.", timeout, condition));
         return mWaitMixin.wait(condition, timeout);
     }
 
@@ -165,6 +166,7 @@
      * condition} was not met before the {@code timeout}.
      */
     public <U> U wait(@NonNull SearchCondition<U> condition, long timeout) {
+        Log.d(TAG, String.format("Waiting %dms for condition %s.", timeout, condition));
         return mWaitMixin.wait(condition, timeout);
     }
 
@@ -450,7 +452,7 @@
     /** Clicks on this object's center. */
     public void click() {
         Point center = getVisibleCenter();
-        Log.v(TAG, String.format("click(center=%s)", center));
+        Log.d(TAG, String.format("Clicking on (%d, %d).", center.x, center.y));
         mGestureController.performGesture(Gestures.click(center, getDisplayId()));
     }
 
@@ -461,14 +463,14 @@
      */
     public void click(@NonNull Point point) {
         clipToGestureBounds(point);
-        Log.v(TAG, String.format("click(point=%s)", point));
+        Log.d(TAG, String.format("Clicking on (%d, %d).", point.x, point.y));
         mGestureController.performGesture(Gestures.click(point, getDisplayId()));
     }
 
     /** Clicks on this object's center for {@code duration} milliseconds. */
     public void click(long duration) {
         Point center = getVisibleCenter();
-        Log.v(TAG, String.format("click(center=%s,duration=%d)", center, duration));
+        Log.d(TAG, String.format("Clicking on (%d, %d) for %dms.", center.x, center.y, duration));
         mGestureController.performGesture(Gestures.click(center, duration, getDisplayId()));
     }
 
@@ -480,7 +482,7 @@
      */
     public void click(@NonNull Point point, long duration) {
         clipToGestureBounds(point);
-        Log.v(TAG, String.format("click(point=%s,duration=%d)", point, duration));
+        Log.d(TAG, String.format("Clicking on (%d, %d) for %dms.", point.x, point.y, duration));
         mGestureController.performGesture(Gestures.click(point, duration, getDisplayId()));
     }
 
@@ -492,7 +494,8 @@
      */
     public <U> U clickAndWait(@NonNull EventCondition<U> condition, long timeout) {
         Point center = getVisibleCenter();
-        Log.v(TAG, String.format("clickAndWait(center=%s,timeout=%d)", center, timeout));
+        Log.d(TAG, String.format("Clicking on (%d, %d) and waiting %dms for condition %s.",
+                center.x, center.y, timeout, condition));
         return mGestureController.performGestureAndWait(condition, timeout,
                 Gestures.click(center, getDisplayId()));
     }
@@ -508,7 +511,8 @@
     public <U> U clickAndWait(@NonNull Point point, @NonNull EventCondition<U> condition,
             long timeout) {
         clipToGestureBounds(point);
-        Log.v(TAG, String.format("clickAndWait(point=%s,timeout=%d)", point, timeout));
+        Log.d(TAG, String.format("Clicking on (%d, %d) and waiting %dms for condition %s.",
+                point.x, point.y, timeout, condition));
         return mGestureController.performGestureAndWait(
                 condition, timeout, Gestures.click(point, getDisplayId()));
     }
@@ -533,14 +537,15 @@
             throw new IllegalArgumentException("Speed cannot be negative");
         }
         Point center = getVisibleCenter();
-        Log.v(TAG, String.format("drag(start=%s,dest=%s,speed=%d)", center, dest, speed));
+        Log.d(TAG, String.format("Dragging from (%d, %d) to (%d, %d) at %dpx/s.", center.x,
+                center.y, dest.x, dest.y, speed));
         mGestureController.performGesture(Gestures.drag(center, dest, speed, getDisplayId()));
     }
 
     /** Performs a long click on this object's center. */
     public void longClick() {
         Point center = getVisibleCenter();
-        Log.v(TAG, String.format("longClick(center=%s)", center));
+        Log.d(TAG, String.format("Long-clicking on (%d, %d).", center.x, center.y));
         mGestureController.performGesture(Gestures.longClick(center, getDisplayId()));
     }
 
@@ -567,8 +572,8 @@
             throw new IllegalArgumentException("Speed cannot be negative");
         }
         Rect bounds = getVisibleBoundsForGestures();
-        Log.v(TAG, String.format("pinchClose(bounds=%s,percent=%f,speed=%d)",
-                bounds, percent, speed));
+        Log.d(TAG, String.format("Pinching close (bounds=%s, percent=%f) at %dpx/s.", bounds,
+                percent, speed));
         mGestureController.performGesture(
                 Gestures.pinchClose(bounds, percent, speed, getDisplayId()));
     }
@@ -596,8 +601,8 @@
             throw new IllegalArgumentException("Speed cannot be negative");
         }
         Rect bounds = getVisibleBoundsForGestures();
-        Log.v(TAG, String.format("pinchOpen(bounds=%s,percent=%f,speed=%d)",
-                bounds, percent, speed));
+        Log.d(TAG, String.format("Pinching open (bounds=%s, percent=%f) at %dpx/s.", bounds,
+                percent, speed));
         mGestureController.performGesture(
                 Gestures.pinchOpen(bounds, percent, speed, getDisplayId()));
     }
@@ -627,8 +632,8 @@
             throw new IllegalArgumentException("Speed cannot be negative");
         }
         Rect bounds = getVisibleBoundsForGestures();
-        Log.v(TAG, String.format("swipe(bounds=%s,direction=%s,percent=%f,speed=%d)",
-                bounds, direction, percent, speed));
+        Log.d(TAG, String.format("Swiping %s (bounds=%s, percent=%f) at %dpx/s.",
+                direction.name().toLowerCase(), bounds, percent, speed));
         mGestureController.performGesture(
                 Gestures.swipeRect(bounds, direction, percent, speed, getDisplayId()));
     }
@@ -665,8 +670,8 @@
 
         // Scroll by performing repeated swipes
         Rect bounds = getVisibleBoundsForGestures();
-        Log.v(TAG, String.format("scroll(bounds=%s,direction=%s,percent=%f,speed=%d)",
-                direction, bounds, percent, speed));
+        Log.d(TAG, String.format("Scrolling %s (bounds=%s, percent=%f) at %dpx/s.",
+                direction.name().toLowerCase(), bounds, percent, speed));
         for (; percent > 0.0f; percent -= 1.0f) {
             float segment = Math.min(percent, 1.0f);
             PointerGesture swipe = Gestures.swipeRect(
@@ -709,12 +714,12 @@
         final Direction swipeDirection = Direction.reverse(direction);
 
         Rect bounds = getVisibleBoundsForGestures();
-        Log.v(TAG, String.format("fling(bounds=%s,direction=%s,speed=%d)",
-                bounds, direction, speed));
         PointerGesture swipe = Gestures.swipeRect(
                 bounds, swipeDirection, 1.0f, speed, getDisplayId());
 
         // Perform the gesture and return true if we did not reach the end
+        Log.d(TAG, String.format("Flinging %s (bounds=%s) at %dpx/s.",
+                direction.name().toLowerCase(), bounds, speed));
         return !mGestureController.performGestureAndWait(
                 Until.scrollFinished(direction), FLING_TIMEOUT, swipe);
     }
@@ -732,6 +737,7 @@
             text = "";
         }
 
+        Log.d(TAG, String.format("Setting text to '%s'.", text));
         CharSequence currentText = node.getText();
         if (currentText == null || !text.contentEquals(currentText)) {
             InteractionController ic = getDevice().getInteractionController();
@@ -760,8 +766,8 @@
         if (text == null) {
             text = "";
         }
-        Log.v(TAG, String.format("setText(text=\"%s\")", text));
 
+        Log.d(TAG, String.format("Setting text to '%s'.", text));
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             // ACTION_SET_TEXT is added in API 21.
             Bundle args = new Bundle();
diff --git a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiScrollable.java b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiScrollable.java
index c60e8c0..8dcfbf5 100644
--- a/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiScrollable.java
+++ b/test/uiautomator/uiautomator/src/main/java/androidx/test/uiautomator/UiScrollable.java
@@ -28,7 +28,7 @@
  * horizontally or vertically scrollable controls.
  */
 public class UiScrollable extends UiCollection {
-    private static final String LOG_TAG = UiScrollable.class.getSimpleName();
+    private static final String TAG = UiScrollable.class.getSimpleName();
 
     // More steps slows the swipe and prevents contents from being flung too far
     private static final int SCROLL_STEPS = 55;
@@ -64,7 +64,6 @@
      */
     @NonNull
     public UiScrollable setAsVerticalList() {
-        Tracer.trace();
         mIsVerticalList = true;
         return this;
     }
@@ -75,7 +74,6 @@
      */
     @NonNull
     public UiScrollable setAsHorizontalList() {
-        Tracer.trace();
         mIsVerticalList = false;
         return this;
     }
@@ -115,7 +113,6 @@
     public UiObject getChildByDescription(
             @NonNull UiSelector childPattern, @NonNull String text)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text);
         return getChildByDescription(childPattern, text, true);
     }
 
@@ -137,7 +134,6 @@
     @NonNull
     public UiObject getChildByDescription(@NonNull UiSelector childPattern, @NonNull String text,
             boolean allowScrollSearch) throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text, allowScrollSearch);
         if (text != null) {
             if (allowScrollSearch) {
                 scrollIntoView(new UiSelector().descriptionContains(text));
@@ -161,7 +157,6 @@
     @Override
     public UiObject getChildByInstance(@NonNull UiSelector childPattern, int instance)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, instance);
         UiSelector patternSelector = UiSelector.patternBuilder(getSelector(),
                 UiSelector.patternBuilder(childPattern).instance(instance));
         return new UiObject(patternSelector);
@@ -186,7 +181,6 @@
     @Override
     public UiObject getChildByText(@NonNull UiSelector childPattern, @NonNull String text)
             throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text);
         return getChildByText(childPattern, text, true);
     }
 
@@ -208,7 +202,6 @@
     public UiObject getChildByText(@NonNull UiSelector childPattern,
             @NonNull String text,
             boolean allowScrollSearch) throws UiObjectNotFoundException {
-        Tracer.trace(childPattern, text, allowScrollSearch);
         if (text != null) {
             if (allowScrollSearch) {
                 scrollIntoView(new UiSelector().text(text));
@@ -229,7 +222,6 @@
      */
     public boolean scrollDescriptionIntoView(@NonNull String text)
             throws UiObjectNotFoundException {
-        Tracer.trace(text);
         return scrollIntoView(new UiSelector().description(text));
     }
 
@@ -241,7 +233,6 @@
      * @return true if the item was found and now is in view else false
      */
     public boolean scrollIntoView(@NonNull UiObject obj) throws UiObjectNotFoundException {
-        Tracer.trace(obj.getSelector());
         return scrollIntoView(obj.getSelector());
     }
 
@@ -255,7 +246,7 @@
      * @return true if the item was found and now is in view; else, false
      */
     public boolean scrollIntoView(@NonNull UiSelector selector) throws UiObjectNotFoundException {
-        Tracer.trace(selector);
+        Log.d(TAG, String.format("Scrolling %s into view.", selector));
         // if we happen to be on top of the text we want then return here
         UiSelector childSelector = getSelector().childSelector(selector);
         if (exists(childSelector)) {
@@ -292,6 +283,7 @@
      */
     public boolean ensureFullyVisible(@NonNull UiObject childObject)
             throws UiObjectNotFoundException {
+        Log.d(TAG, String.format("Ensuring %s is fully visible.", childObject.getSelector()));
         Rect actual = childObject.getBounds();
         Rect visible = childObject.getVisibleBounds();
         if (visible.width() * visible.height() == actual.width() * actual.height()) {
@@ -332,7 +324,6 @@
      * @return true if item is found; else, false
      */
     public boolean scrollTextIntoView(@NonNull String text) throws UiObjectNotFoundException {
-        Tracer.trace(text);
         return scrollIntoView(new UiSelector().text(text));
     }
 
@@ -347,7 +338,6 @@
      */
     @NonNull
     public UiScrollable setMaxSearchSwipes(int swipes) {
-        Tracer.trace(swipes);
         mMaxSearchSwipes = swipes;
         return this;
     }
@@ -361,7 +351,6 @@
      * @return max the number of search swipes to perform until giving up
      */
     public int getMaxSearchSwipes() {
-        Tracer.trace();
         return mMaxSearchSwipes;
     }
 
@@ -376,7 +365,6 @@
      * @return true if scrolled, false if can't scroll anymore
      */
     public boolean flingForward() throws UiObjectNotFoundException {
-        Tracer.trace();
         return scrollForward(FLING_STEPS);
     }
 
@@ -391,7 +379,6 @@
      * @return true if scrolled, false if can't scroll anymore
      */
     public boolean scrollForward() throws UiObjectNotFoundException {
-        Tracer.trace();
         return scrollForward(SCROLL_STEPS);
     }
 
@@ -406,8 +393,6 @@
      * @return true if scrolled, false if can't scroll anymore
      */
     public boolean scrollForward(int steps) throws UiObjectNotFoundException {
-        Tracer.trace(steps);
-        Log.d(LOG_TAG, "scrollForward() on selector = " + getSelector());
         AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
         if(node == null) {
             throw new UiObjectNotFoundException(getSelector().toString());
@@ -438,6 +423,8 @@
             upX = rect.left + swipeAreaAdjust;
             upY = rect.centerY();
         }
+        Log.d(TAG, String.format("Scrolling forward from (%d, %d) to (%d, %d) in %d steps.", downX,
+                downY, upX, upY, steps));
         return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
     }
 
@@ -452,7 +439,6 @@
      * @return true if scrolled, and false if can't scroll anymore
      */
     public boolean flingBackward() throws UiObjectNotFoundException {
-        Tracer.trace();
         return scrollBackward(FLING_STEPS);
     }
 
@@ -467,7 +453,6 @@
      * @return true if scrolled, and false if can't scroll anymore
      */
     public boolean scrollBackward() throws UiObjectNotFoundException {
-        Tracer.trace();
         return scrollBackward(SCROLL_STEPS);
     }
 
@@ -482,8 +467,6 @@
      * @return true if scrolled, false if can't scroll anymore
      */
     public boolean scrollBackward(int steps) throws UiObjectNotFoundException {
-        Tracer.trace(steps);
-        Log.d(LOG_TAG, "scrollBackward() on selector = " + getSelector());
         AccessibilityNodeInfo node = findAccessibilityNodeInfo(WAIT_FOR_SELECTOR_TIMEOUT);
         if (node == null) {
             throw new UiObjectNotFoundException(getSelector().toString());
@@ -500,7 +483,6 @@
         // set otherwise by setAsHorizontalContainer()
         if(mIsVerticalList) {
             int swipeAreaAdjust = (int)(rect.height() * getSwipeDeadZonePercentage());
-            Log.d(LOG_TAG, "scrollToBeginning() using vertical scroll");
             // scroll vertically: swipe up -> down
             downX = rect.centerX();
             downY = rect.top + swipeAreaAdjust;
@@ -508,7 +490,6 @@
             upY = rect.bottom - swipeAreaAdjust;
         } else {
             int swipeAreaAdjust = (int)(rect.width() * getSwipeDeadZonePercentage());
-            Log.d(LOG_TAG, "scrollToBeginning() using hotizontal scroll");
             // scroll horizontally: swipe left -> right
             // TODO: Assuming device is not in right to left language
             downX = rect.left + swipeAreaAdjust;
@@ -516,6 +497,8 @@
             upX = rect.right - swipeAreaAdjust;
             upY = rect.centerY();
         }
+        Log.d(TAG, String.format("Scrolling backward from (%d, %d) to (%d, %d) in %d steps.", downX,
+                downY, upX, upY, steps));
         return getInteractionController().scrollSwipe(downX, downY, upX, upY, steps);
     }
 
@@ -529,8 +512,6 @@
      * @return true on scrolled else false
      */
     public boolean scrollToBeginning(int maxSwipes, int steps) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes, steps);
-        Log.d(LOG_TAG, "scrollToBeginning() on selector = " + getSelector());
         // protect against potential hanging and return after preset attempts
         for(int x = 0; x < maxSwipes; x++) {
             if(!scrollBackward(steps)) {
@@ -550,7 +531,6 @@
      * @return true on scrolled else false
      */
     public boolean scrollToBeginning(int maxSwipes) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes);
         return scrollToBeginning(maxSwipes, SCROLL_STEPS);
     }
 
@@ -564,7 +544,6 @@
      * @return true on scrolled else false
      */
     public boolean flingToBeginning(int maxSwipes) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes);
         return scrollToBeginning(maxSwipes, FLING_STEPS);
     }
 
@@ -578,7 +557,6 @@
      * @return true on scrolled else false
      */
     public boolean scrollToEnd(int maxSwipes, int steps) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes, steps);
         // protect against potential hanging and return after preset attempts
         for(int x = 0; x < maxSwipes; x++) {
             if(!scrollForward(steps)) {
@@ -598,7 +576,6 @@
      * @return true on scrolled, else false
      */
     public boolean scrollToEnd(int maxSwipes) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes);
         return scrollToEnd(maxSwipes, SCROLL_STEPS);
     }
 
@@ -612,7 +589,6 @@
      * @return true on scrolled, else false
      */
     public boolean flingToEnd(int maxSwipes) throws UiObjectNotFoundException {
-        Tracer.trace(maxSwipes);
         return scrollToEnd(maxSwipes, FLING_STEPS);
     }
 
@@ -627,7 +603,6 @@
      * @return a value between 0 and 1
      */
     public double getSwipeDeadZonePercentage() {
-        Tracer.trace();
         return mSwipeDeadZonePercentage;
     }
 
@@ -645,7 +620,6 @@
      */
     @NonNull
     public UiScrollable setSwipeDeadZonePercentage(double swipeDeadZonePercentage) {
-        Tracer.trace(swipeDeadZonePercentage);
         mSwipeDeadZonePercentage = swipeDeadZonePercentage;
         return this;
     }
diff --git a/tracing/tracing-perfetto/build.gradle b/tracing/tracing-perfetto/build.gradle
index ca9af2c..f69a48a 100644
--- a/tracing/tracing-perfetto/build.gradle
+++ b/tracing/tracing-perfetto/build.gradle
@@ -67,5 +67,8 @@
 }
 
 android {
+    buildTypes.all {
+        consumerProguardFiles "proguard-rules.pro"
+    }
     namespace "androidx.tracing.perfetto"
 }
diff --git a/tracing/tracing-perfetto/proguard-rules.pro b/tracing/tracing-perfetto/proguard-rules.pro
new file mode 100644
index 0000000..526c4f3
--- /dev/null
+++ b/tracing/tracing-perfetto/proguard-rules.pro
@@ -0,0 +1,7 @@
+# Preserve class methods (that we explicitly register in native code), if the class is preserved
+-keepclassmembers class androidx.tracing.perfetto.jni.PerfettoNative {
+    java.lang.String nativeVersion();
+    void nativeRegisterWithPerfetto();
+    void nativeTraceEventBegin(int, java.lang.String);
+    void nativeTraceEventEnd();
+}
\ No newline at end of file
diff --git a/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.java b/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.java
deleted file mode 100644
index 5c954de..0000000
--- a/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.java
+++ /dev/null
@@ -1,2553 +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 android.support.wearable.complications;
-
-import android.annotation.SuppressLint;
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.os.BadParcelableException;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RestrictTo;
-import androidx.wear.watchface.complications.data.ComplicationDisplayPolicies;
-import androidx.wear.watchface.complications.data.ComplicationDisplayPolicy;
-import androidx.wear.watchface.complications.data.ComplicationPersistencePolicies;
-import androidx.wear.watchface.complications.data.ComplicationPersistencePolicy;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-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.Objects;
-import java.util.Set;
-
-/**
- * Container for complication data of all types.
- *
- * <p>A {@link androidx.wear.watchface.complications.ComplicationProviderService} should create
- * instances of
- * this class using {@link ComplicationData.Builder} and send them to the complication system in
- * response to
- * {@link androidx.wear.watchface.complications.ComplicationProviderService#onComplicationRequest}.
- * Depending on the type of complication data, some fields will be required and some will be
- * optional - see the documentation for each type, and for the builder's set methods, for details.
- *
- * <p>A watch face will receive instances of this class as long as providers are configured.
- *
- * <p>When rendering the complication data for a given time, the watch face should first call {@link
- * #isActiveAt} to determine whether the data is valid at that time. See the documentation for each
- * of the complication types below for details of which fields are expected to be displayed.
- *
- * @hide
- */
-@SuppressLint("BanParcelableUsage")
-@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public final class ComplicationData implements Parcelable, Serializable {
-
-    private static final String TAG = "ComplicationData";
-    public static final String PLACEHOLDER_STRING = "__placeholder__";
-
-    /** @hide */
-    @IntDef({
-            TYPE_EMPTY,
-            TYPE_NOT_CONFIGURED,
-            TYPE_SHORT_TEXT,
-            TYPE_LONG_TEXT,
-            TYPE_RANGED_VALUE,
-            TYPE_ICON,
-            TYPE_SMALL_IMAGE,
-            TYPE_LARGE_IMAGE,
-            TYPE_NO_PERMISSION,
-            TYPE_NO_DATA,
-            TYPE_GOAL_PROGRESS,
-            TYPE_WEIGHTED_ELEMENTS,
-            EXP_TYPE_PROTO_LAYOUT,
-            EXP_TYPE_LIST
-    })
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ComplicationType {
-    }
-
-    /**
-     * Type sent when a complication does not have a provider configured. The system will send data
-     * of this type to watch faces when the user has not chosen a provider for an active
-     * complication, and the watch face has not set a default provider. Providers cannot send data
-     * of this type.
-     *
-     * <p>No fields may be populated for complication data of this type.
-     */
-    public static final int TYPE_NOT_CONFIGURED = 1;
-
-    /**
-     * Type sent when the user has specified that an active complication should have no provider,
-     * i.e. when the user has chosen "Empty" in the provider chooser. Providers cannot send data of
-     * this type.
-     *
-     * <p>No fields may be populated for complication data of this type.
-     */
-    public static final int TYPE_EMPTY = 2;
-
-    /**
-     * Type that can be sent by any provider, regardless of the configured type, when the provider
-     * has no data to be displayed. Watch faces may choose whether to render this in some way or
-     * leave the slot empty.
-     *
-     * <p>No fields may be populated for complication data of this type.
-     */
-    public static final int TYPE_NO_DATA = 10;
-
-    /**
-     * Type used for complications where the primary piece of data is a short piece of text
-     * (expected to be no more than seven characters in length). The short text may be accompanied
-     * by an icon or a short title (or both, but if both are provided then a watch face may choose
-     * to display only one).
-     *
-     * <p>The <i>short text</i> field is required for this type, and is expected to always be
-     * displayed.
-     *
-     * <p>The <i>icon</i> (and <i>burnInProtectionIcon</i>) and <i>short title</i> fields are
-     * optional for this type. If only one of these is provided, it is expected that it will be
-     * displayed. If both are provided, it is expected that one of these will be displayed.
-     */
-    public static final int TYPE_SHORT_TEXT = 3;
-
-    /**
-     * Type used for complications where the primary piece of data is a piece of text. The text may
-     * be accompanied by an icon and/or a title.
-     *
-     * <p>The <i>long text</i> field is required for this type, and is expected to always be
-     * displayed.
-     *
-     * <p>The <i>long title</i> field is optional for this type. If provided, it is expected that
-     * this field will be displayed.
-     *
-     * <p>The <i>icon</i> (and <i>burnInProtectionIcon</i>) and <i>small image</i> fields are also
-     * optional for this type. If provided, at least one of these should be displayed.
-     */
-    public static final int TYPE_LONG_TEXT = 4;
-
-    /**
-     * Type used for complications including a numerical value within a range, such as a percentage.
-     * The value may be accompanied by an icon and/or short text and title.
-     *
-     * <p>The <i>value</i>, <i>min value</i>, and <i>max value</i> fields are required for this
-     * type, and the value within the range is expected to always be displayed.
-     *
-     * <p>The <i>icon</i> (and <i>burnInProtectionIcon</i>), <i>short title</i>, and <i>short
-     * text</i> fields are optional for this type, but at least one must be defined. The watch face
-     * may choose which of these fields to display, if any.
-     */
-    public static final int TYPE_RANGED_VALUE = 5;
-
-    /**
-     * Type used for complications which consist only of a tintable icon.
-     *
-     * <p>The <i>icon</i> field is required for this type, and is expected to always be displayed,
-     * unless the device is in ambient mode with burn-in protection enabled, in which case the
-     * <i>burnInProtectionIcon</i> field should be used instead.
-     *
-     * <p>The contentDescription field is recommended for this type. Use it to describe what data
-     * the icon represents. If the icon is purely stylistic, and does not convey any information to
-     * the user, then enter the empty string as the contentDescription.
-     *
-     * <p>No other fields are valid for this type.
-     */
-    public static final int TYPE_ICON = 6;
-
-    /**
-     * Type used for complications which consist only of a small image.
-     *
-     * <p>The <i>small image</i> field is required for this type, and is expected to always be
-     * displayed, unless the device is in ambient mode, in which case either nothing or the
-     * <i>burnInProtectionSmallImage</i> field may be used instead.
-     *
-     * <p>The contentDescription field is recommended for this type. Use it to describe what data
-     * the image represents. If the image is purely stylistic, and does not convey any information
-     * to the user, then enter the empty string as the contentDescription.
-     *
-     * <p>No other fields are valid for this type.
-     */
-    public static final int TYPE_SMALL_IMAGE = 7;
-
-    /**
-     * Type used for complications which consist only of a large image. A large image here is one
-     * that could be used to fill the watch face, for example as the background.
-     *
-     * <p>The <i>large image</i> field is required for this type, and is expected to always be
-     * displayed, unless the device is in ambient mode.
-     *
-     * <p>The contentDescription field is recommended for this type. Use it to describe what data
-     * the image represents. If the image is purely stylistic, and does not convey any information
-     * to the user, then enter the empty string as the contentDescription.
-     *
-     * <p>No other fields are valid for this type.
-     */
-    public static final int TYPE_LARGE_IMAGE = 8;
-
-    /**
-     * Type sent by the system when the watch face does not have permission to receive complication
-     * data.
-     *
-     * <p>Fields will be populated to allow the data to be rendered as if it were of {@link
-     * #TYPE_SHORT_TEXT} or {@link #TYPE_ICON} for consistency and convenience, but watch faces may
-     * render this as they see fit.
-     *
-     * <p>It is recommended that, where possible, tapping on the complication when in this state
-     * should trigger a permission request.
-     */
-    public static final int TYPE_NO_PERMISSION = 9;
-
-    /**
-     * Type used for complications which indicate progress towards a goal. The value may be
-     * accompanied by an icon and/or short text and title.
-     *
-     * <p>The <i>value</i>, and <i>target value</i> fields are required for this type, and the
-     * value is expected to always be displayed. The value must be >= 0 and may be > target value.
-     * E.g. 15000 out of a target of 10000 steps.
-     *
-     * <p>The <i>icon</i> (and <i>burnInProtectionIcon</i>), <i>short title</i>, and <i>short
-     * text</i> fields are optional for this type, but at least one must be defined. The watch face
-     * may choose which of these fields to display, if any.
-     */
-    public static final int TYPE_GOAL_PROGRESS = 13;
-
-    /**
-     * Type used for complications to display a series of weighted values e.g. in a pie chart. The
-     * weighted values may be accompanied by an icon and/or short text and title.
-     *
-     * <p>The <i>element weights</i> and <i>element colors</i> fields are required for this type,
-     * and the value within the range is expected to always be displayed.
-     *
-     * <p>The <i>icon</i> (and <i>burnInProtectionIcon</i>), <i>short title</i>, and <i>short
-     * text</i> fields are optional for this type, but at least one must be defined. The watch face
-     * may choose which of these fields to display, if any.
-     */
-    public static final int TYPE_WEIGHTED_ELEMENTS = 14;
-
-    // The following types are experimental, and they have negative IDs.
-
-    /** Type that specifies a proto layout based complication. */
-    public static final int EXP_TYPE_PROTO_LAYOUT = -11;
-
-    /** Type that specifies a list of complication values. E.g. to support linear 3. */
-    public static final int EXP_TYPE_LIST = -12;
-
-    /** @hide */
-    @IntDef({IMAGE_STYLE_PHOTO, IMAGE_STYLE_ICON})
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ImageStyle {
-    }
-
-    /**
-     * Style for small images which are photos that are expected to fill the space available. Images
-     * of this style may be cropped to fit the shape of the complication - in particular, the image
-     * may be cropped to a circle. Photos my not be recolored.
-     *
-     * <p>This is the default value.
-     */
-    public static final int IMAGE_STYLE_PHOTO = 1;
-
-    /**
-     * Style for small images that have a transparent background and are expected to be drawn
-     * entirely within the space available, such as a launcher icon. Watch faces may add padding
-     * when drawing these images, but should never crop these images. Icons may be recolored to fit
-     * the complication style.
-     */
-    public static final int IMAGE_STYLE_ICON = 2;
-
-    private static final String FIELD_COLOR_RAMP = "COLOR_RAMP";
-    private static final String FIELD_COLOR_RAMP_INTERPOLATED = "COLOR_RAMP_INTERPOLATED";
-    private static final String FIELD_DATA_SOURCE = "FIELD_DATA_SOURCE";
-    private static final String FIELD_DISPLAY_POLICY = "DISPLAY_POLICY";
-    private static final String FIELD_ELEMENT_BACKGROUND_COLOR = "ELEMENT_BACKGROUND_COLOR";
-    private static final String FIELD_ELEMENT_COLORS = "ELEMENT_COLORS";
-    private static final String FIELD_ELEMENT_WEIGHTS = "ELEMENT_WEIGHTS";
-    private static final String FIELD_END_TIME = "END_TIME";
-    private static final String FIELD_ICON = "ICON";
-    private static final String FIELD_ICON_BURN_IN_PROTECTION = "ICON_BURN_IN_PROTECTION";
-    private static final String FIELD_IMAGE_STYLE = "IMAGE_STYLE";
-    private static final String FIELD_LARGE_IMAGE = "LARGE_IMAGE";
-    private static final String FIELD_LONG_TITLE = "LONG_TITLE";
-    private static final String FIELD_LONG_TEXT = "LONG_TEXT";
-    private static final String FIELD_MAX_VALUE = "MAX_VALUE";
-    private static final String FIELD_MIN_VALUE = "MIN_VALUE";
-    private static final String FIELD_PERSISTENCE_POLICY = "PERSISTENCE_POLICY";
-    private static final String FIELD_PLACEHOLDER_FIELDS = "PLACEHOLDER_FIELDS";
-    private static final String FIELD_PLACEHOLDER_TYPE = "PLACEHOLDER_TYPE";
-    private static final String FIELD_SMALL_IMAGE = "SMALL_IMAGE";
-    private static final String FIELD_SMALL_IMAGE_BURN_IN_PROTECTION =
-            "SMALL_IMAGE_BURN_IN_PROTECTION";
-    private static final String FIELD_SHORT_TITLE = "SHORT_TITLE";
-    private static final String FIELD_SHORT_TEXT = "SHORT_TEXT";
-    private static final String FIELD_START_TIME = "START_TIME";
-    private static final String FIELD_TAP_ACTION = "TAP_ACTION";
-    private static final String FIELD_TAP_ACTION_LOST = "FIELD_TAP_ACTION_LOST";
-    private static final String FIELD_TARGET_VALUE = "TARGET_VALUE";
-    private static final String FIELD_TIMELINE_START_TIME = "TIMELINE_START_TIME";
-    private static final String FIELD_TIMELINE_END_TIME = "TIMELINE_END_TIME";
-    private static final String FIELD_TIMELINE_ENTRIES = "TIMELINE";
-    private static final String FIELD_TIMELINE_ENTRY_TYPE = "TIMELINE_ENTRY_TYPE";
-    private static final String FIELD_VALUE = "VALUE";
-    private static final String FIELD_VALUE_TYPE = "VALUE_TYPE";
-
-    // Experimental fields, these are subject to change without notice.
-    private static final String EXP_FIELD_LIST_ENTRIES = "EXP_LIST_ENTRIES";
-    private static final String EXP_FIELD_LIST_ENTRY_TYPE = "EXP_LIST_ENTRY_TYPE";
-    private static final String EXP_FIELD_LIST_STYLE_HINT = "EXP_LIST_STYLE_HINT";
-    private static final String EXP_FIELD_PROTO_LAYOUT_AMBIENT = "EXP_FIELD_PROTO_LAYOUT_AMBIENT";
-    private static final String EXP_FIELD_PROTO_LAYOUT_INTERACTIVE =
-            "EXP_FIELD_PROTO_LAYOUT_INTERACTIVE";
-    private static final String EXP_FIELD_PROTO_LAYOUT_RESOURCES =
-            "EXP_FIELD_PROTO_LAYOUT_RESOURCES";
-
-    // Originally it was planned to support both content and image content descriptions.
-    private static final String FIELD_CONTENT_DESCRIPTION = "IMAGE_CONTENT_DESCRIPTION";
-
-    // The set of valid types.
-    private static final Set<Integer> VALID_TYPES = validTypes();
-
-    private static Set<Integer> validTypes() {
-        HashSet<Integer> set = new HashSet<>();
-        set.add(TYPE_NOT_CONFIGURED);
-        set.add(TYPE_EMPTY);
-        set.add(TYPE_SHORT_TEXT);
-        set.add(TYPE_LONG_TEXT);
-        set.add(TYPE_RANGED_VALUE);
-        set.add(TYPE_ICON);
-        set.add(TYPE_SMALL_IMAGE);
-        set.add(TYPE_LARGE_IMAGE);
-        set.add(TYPE_NO_PERMISSION);
-        set.add(TYPE_NO_DATA);
-        set.add(EXP_TYPE_PROTO_LAYOUT);
-        set.add(EXP_TYPE_LIST);
-        set.add(TYPE_GOAL_PROGRESS);
-        set.add(TYPE_WEIGHTED_ELEMENTS);
-        return set;
-    }
-
-    // Used for validation. REQUIRED_FIELDS[i] is an array containing all the fields which must be
-    // populated for @ComplicationType i.
-    private static final Map<Integer, String[]> REQUIRED_FIELDS = requiredFieldsMap();
-
-    private static Map<Integer, String[]> requiredFieldsMap() {
-        HashMap<Integer, String[]> map = new HashMap<>();
-        map.put(TYPE_NOT_CONFIGURED, new String[0]);
-        map.put(TYPE_EMPTY, new String[0]);
-        map.put(TYPE_SHORT_TEXT, new String[]{FIELD_SHORT_TEXT});
-        map.put(TYPE_LONG_TEXT, new String[]{FIELD_LONG_TEXT});
-        map.put(TYPE_RANGED_VALUE, new String[]{FIELD_VALUE, FIELD_MIN_VALUE, FIELD_MAX_VALUE});
-        map.put(TYPE_ICON, new String[]{FIELD_ICON});
-        map.put(TYPE_SMALL_IMAGE, new String[]{FIELD_SMALL_IMAGE, FIELD_IMAGE_STYLE});
-        map.put(TYPE_LARGE_IMAGE, new String[]{FIELD_LARGE_IMAGE});
-        map.put(TYPE_NO_PERMISSION, new String[0]);
-        map.put(TYPE_NO_DATA, new String[0]);
-        map.put(EXP_TYPE_PROTO_LAYOUT, new String[]{EXP_FIELD_PROTO_LAYOUT_AMBIENT,
-                EXP_FIELD_PROTO_LAYOUT_INTERACTIVE,
-                EXP_FIELD_PROTO_LAYOUT_RESOURCES});
-        map.put(EXP_TYPE_LIST, new String[]{EXP_FIELD_LIST_ENTRIES});
-        map.put(TYPE_GOAL_PROGRESS, new String[]{FIELD_VALUE, FIELD_TARGET_VALUE});
-        map.put(TYPE_WEIGHTED_ELEMENTS, new String[]{FIELD_ELEMENT_WEIGHTS,
-                FIELD_ELEMENT_COLORS,
-                FIELD_ELEMENT_BACKGROUND_COLOR});
-        return map;
-    }
-
-    // Used for validation. OPTIONAL_FIELDS[i] is an array containing all the fields which are
-    // valid but not required for type i.
-    private static final Map<Integer, String[]> OPTIONAL_FIELDS = optionalFieldsMap();
-
-    private static Map<Integer, String[]> optionalFieldsMap() {
-        HashMap<Integer, String[]> map = new HashMap<>();
-        map.put(TYPE_NOT_CONFIGURED, new String[0]);
-        map.put(TYPE_EMPTY, new String[0]);
-        map.put(TYPE_SHORT_TEXT, new String[]{
-                FIELD_SHORT_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_LONG_TEXT, new String[]{
-                FIELD_LONG_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_RANGED_VALUE, new String[]{
-                FIELD_SHORT_TEXT,
-                FIELD_SHORT_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_COLOR_RAMP,
-                FIELD_COLOR_RAMP_INTERPOLATED,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY,
-                FIELD_VALUE_TYPE});
-        map.put(TYPE_ICON, new String[]{
-                FIELD_TAP_ACTION,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_SMALL_IMAGE, new String[]{
-                FIELD_TAP_ACTION,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_LARGE_IMAGE, new String[]{
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_NO_PERMISSION, new String[]{
-                FIELD_SHORT_TEXT,
-                FIELD_SHORT_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY
-        });
-        map.put(TYPE_NO_DATA, new String[]{
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_LARGE_IMAGE,
-                FIELD_LONG_TEXT,
-                FIELD_LONG_TITLE,
-                FIELD_MAX_VALUE,
-                FIELD_MIN_VALUE,
-                FIELD_PLACEHOLDER_FIELDS,
-                FIELD_PLACEHOLDER_TYPE,
-                FIELD_SHORT_TEXT,
-                FIELD_SHORT_TITLE,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_TAP_ACTION,
-                FIELD_VALUE,
-                FIELD_VALUE_TYPE,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY
-        });
-        map.put(EXP_TYPE_PROTO_LAYOUT, new String[]{
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(EXP_TYPE_LIST, new String[]{
-                FIELD_TAP_ACTION,
-                EXP_FIELD_LIST_STYLE_HINT,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_GOAL_PROGRESS, new String[]{
-                FIELD_SHORT_TEXT,
-                FIELD_SHORT_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_COLOR_RAMP,
-                FIELD_COLOR_RAMP_INTERPOLATED,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        map.put(TYPE_WEIGHTED_ELEMENTS, new String[]{
-                FIELD_SHORT_TEXT,
-                FIELD_SHORT_TITLE,
-                FIELD_ICON,
-                FIELD_ICON_BURN_IN_PROTECTION,
-                FIELD_SMALL_IMAGE,
-                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
-                FIELD_IMAGE_STYLE,
-                FIELD_TAP_ACTION,
-                FIELD_CONTENT_DESCRIPTION,
-                FIELD_DATA_SOURCE,
-                FIELD_PERSISTENCE_POLICY,
-                FIELD_DISPLAY_POLICY});
-        return map;
-    }
-
-    @NonNull
-    public static final Creator<ComplicationData> CREATOR =
-            new Creator<ComplicationData>() {
-                @SuppressLint("SyntheticAccessor")
-                @NonNull
-                @Override
-                public ComplicationData createFromParcel(@NonNull Parcel source) {
-                    return new ComplicationData(source);
-                }
-
-                @NonNull
-                @Override
-                public ComplicationData[] newArray(int size) {
-                    return new ComplicationData[size];
-                }
-            };
-
-    @ComplicationType
-    final int mType;
-    final Bundle mFields;
-
-    ComplicationData(@NonNull Builder builder) {
-        mType = builder.mType;
-        mFields = builder.mFields;
-    }
-
-    ComplicationData(int type, Bundle fields) {
-        mType = type;
-        mFields = fields;
-        mFields.setClassLoader(getClass().getClassLoader());
-    }
-
-    private ComplicationData(@NonNull Parcel in) {
-        mType = in.readInt();
-        mFields = in.readBundle(getClass().getClassLoader());
-    }
-
-    @RequiresApi(api = Build.VERSION_CODES.P)
-    private static class SerializedForm implements Serializable {
-        private static final int VERSION_NUMBER = 19;
-
-        @NonNull
-        ComplicationData mComplicationData;
-
-        SerializedForm() {
-        }
-
-        SerializedForm(@NonNull ComplicationData complicationData) {
-            mComplicationData = complicationData;
-        }
-
-        @SuppressLint("SyntheticAccessor") // For mComplicationData.mFields
-        private void writeObject(ObjectOutputStream oos) throws IOException {
-            oos.writeInt(VERSION_NUMBER);
-            int type = mComplicationData.getType();
-            oos.writeInt(type);
-            oos.writeInt(mComplicationData.getPersistencePolicy());
-            oos.writeInt(mComplicationData.getDisplayPolicy());
-
-            if (isFieldValidForType(FIELD_LONG_TEXT, type)) {
-                oos.writeObject(mComplicationData.getLongText());
-            }
-            if (isFieldValidForType(FIELD_LONG_TITLE, type)) {
-                oos.writeObject(mComplicationData.getLongTitle());
-            }
-            if (isFieldValidForType(FIELD_SHORT_TEXT, type)) {
-                oos.writeObject(mComplicationData.getShortText());
-            }
-            if (isFieldValidForType(FIELD_SHORT_TITLE, type)) {
-                oos.writeObject(mComplicationData.getShortTitle());
-            }
-            if (isFieldValidForType(FIELD_CONTENT_DESCRIPTION, type)) {
-                oos.writeObject(mComplicationData.getContentDescription());
-            }
-            if (isFieldValidForType(FIELD_ICON, type)) {
-                oos.writeObject(IconSerializableHelper.create(mComplicationData.getIcon()));
-            }
-            if (isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, type)) {
-                oos.writeObject(
-                        IconSerializableHelper.create(mComplicationData.getBurnInProtectionIcon()));
-            }
-            if (isFieldValidForType(FIELD_SMALL_IMAGE, type)) {
-                oos.writeObject(IconSerializableHelper.create(mComplicationData.getSmallImage()));
-            }
-            if (isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, type)) {
-                oos.writeObject(IconSerializableHelper.create(
-                        mComplicationData.getBurnInProtectionSmallImage()));
-            }
-            if (isFieldValidForType(FIELD_IMAGE_STYLE, type)) {
-                oos.writeInt(mComplicationData.getSmallImageStyle());
-            }
-            if (isFieldValidForType(FIELD_LARGE_IMAGE, type)) {
-                oos.writeObject(IconSerializableHelper.create(mComplicationData.getLargeImage()));
-            }
-            if (isFieldValidForType(FIELD_VALUE, type)) {
-                oos.writeFloat(mComplicationData.getRangedValue());
-            }
-            if (isFieldValidForType(FIELD_VALUE_TYPE, type)) {
-                oos.writeInt(mComplicationData.getRangedValueType());
-            }
-            if (isFieldValidForType(FIELD_MIN_VALUE, type)) {
-                oos.writeFloat(mComplicationData.getRangedMinValue());
-            }
-            if (isFieldValidForType(FIELD_MAX_VALUE, type)) {
-                oos.writeFloat(mComplicationData.getRangedMaxValue());
-            }
-            if (isFieldValidForType(FIELD_TARGET_VALUE, type)) {
-                oos.writeFloat(mComplicationData.getTargetValue());
-            }
-            if (isFieldValidForType(FIELD_COLOR_RAMP, type)) {
-                int[] colors = mComplicationData.getColorRamp();
-                if (colors != null) {
-                    oos.writeBoolean(true);
-                    oos.writeInt(colors.length);
-                    for (int color : colors) {
-                        oos.writeInt(color);
-                    }
-                } else {
-                    oos.writeBoolean(false);
-                }
-            }
-            if (isFieldValidForType(FIELD_COLOR_RAMP_INTERPOLATED, type)) {
-                Boolean isColorRampSmoothShaded = mComplicationData.isColorRampInterpolated();
-                if (isColorRampSmoothShaded != null) {
-                    oos.writeBoolean(true);
-                    oos.writeBoolean(isColorRampSmoothShaded);
-                } else {
-                    oos.writeBoolean(false);
-                }
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_WEIGHTS, type)) {
-                float[] weights = mComplicationData.getElementWeights();
-                if (weights != null) {
-                    oos.writeBoolean(true);
-                    oos.writeInt(weights.length);
-                    for (float weight : weights) {
-                        oos.writeFloat(weight);
-                    }
-                } else {
-                    oos.writeBoolean(false);
-                }
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_COLORS, type)) {
-                int[] colors = mComplicationData.getElementColors();
-                if (colors != null) {
-                    oos.writeBoolean(true);
-                    oos.writeInt(colors.length);
-                    for (int color : colors) {
-                        oos.writeInt(color);
-                    }
-                } else {
-                    oos.writeBoolean(false);
-                }
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_BACKGROUND_COLOR, type)) {
-                oos.writeInt(mComplicationData.getElementBackgroundColor());
-            }
-            if (isFieldValidForType(FIELD_START_TIME, type)) {
-                oos.writeLong(mComplicationData.getStartDateTimeMillis());
-            }
-            if (isFieldValidForType(FIELD_END_TIME, type)) {
-                oos.writeLong(mComplicationData.getEndDateTimeMillis());
-            }
-            oos.writeInt(mComplicationData.mFields.getInt(EXP_FIELD_LIST_ENTRY_TYPE));
-            if (isFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, type)) {
-                oos.writeInt(mComplicationData.getListStyleHint());
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, type)) {
-                byte[] bytes = mComplicationData.getInteractiveLayout();
-                if (bytes == null) {
-                    oos.writeInt(0);
-                } else {
-                    oos.writeInt(bytes.length);
-                    oos.write(bytes);
-                }
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_AMBIENT, type)) {
-                byte[] bytes = mComplicationData.getAmbientLayout();
-                if (bytes == null) {
-                    oos.writeInt(0);
-                } else {
-                    oos.writeInt(bytes.length);
-                    oos.write(bytes);
-                }
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_RESOURCES, type)) {
-                byte[] bytes = mComplicationData.getLayoutResources();
-                if (bytes == null) {
-                    oos.writeInt(0);
-                } else {
-                    oos.writeInt(bytes.length);
-                    oos.write(bytes);
-                }
-            }
-            if (isFieldValidForType(FIELD_DATA_SOURCE, type)) {
-                ComponentName componentName = mComplicationData.getDataSource();
-                if (componentName == null) {
-                    oos.writeUTF("");
-                } else {
-                    oos.writeUTF(componentName.flattenToString());
-                }
-            }
-
-            // TapAction unfortunately can't be serialized, instead we record if we've lost it.
-            oos.writeBoolean(mComplicationData.hasTapAction()
-                    || mComplicationData.getTapActionLostDueToSerialization());
-            long start = mComplicationData.mFields.getLong(FIELD_TIMELINE_START_TIME, -1);
-            oos.writeLong(start);
-            long end = mComplicationData.mFields.getLong(FIELD_TIMELINE_END_TIME, -1);
-            oos.writeLong(end);
-            oos.writeInt(mComplicationData.mFields.getInt(FIELD_TIMELINE_ENTRY_TYPE));
-
-            List<ComplicationData> listEntries = mComplicationData.getListEntries();
-            int listEntriesLength = (listEntries != null) ? listEntries.size() : 0;
-            oos.writeInt(listEntriesLength);
-            if (listEntries != null) {
-                for (ComplicationData data : listEntries) {
-                    new SerializedForm(data).writeObject(oos);
-                }
-            }
-
-            if (isFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)) {
-                ComplicationData placeholder = mComplicationData.getPlaceholder();
-                if (placeholder == null) {
-                    oos.writeBoolean(false);
-                } else {
-                    oos.writeBoolean(true);
-                    new SerializedForm(placeholder).writeObject(oos);
-                }
-            }
-
-            // This has to be last, since it's recursive.
-            List<ComplicationData> timeline = mComplicationData.getTimelineEntries();
-            int timelineLength = (timeline != null) ? timeline.size() : 0;
-            oos.writeInt(timelineLength);
-            if (timeline != null) {
-                for (ComplicationData data : timeline) {
-                    new SerializedForm(data).writeObject(oos);
-                }
-            }
-        }
-
-        private static void putIfNotNull(Bundle fields, String field, Parcelable value) {
-            if (value != null) {
-                fields.putParcelable(field, value);
-            }
-        }
-
-        @SuppressLint("SyntheticAccessor") // For mComplicationData.mFields
-        private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-            int versionNumber = ois.readInt();
-            if (versionNumber != VERSION_NUMBER) {
-                // Give up if there's a version skew.
-                throw new IOException("Unsupported serialization version number " + versionNumber);
-            }
-            int type = ois.readInt();
-            Bundle fields = new Bundle();
-            fields.putInt(FIELD_PERSISTENCE_POLICY, ois.readInt());
-            fields.putInt(FIELD_DISPLAY_POLICY, ois.readInt());
-
-            if (isFieldValidForType(FIELD_LONG_TEXT, type)) {
-                putIfNotNull(fields, FIELD_LONG_TEXT, (ComplicationText) ois.readObject());
-            }
-            if (isFieldValidForType(FIELD_LONG_TITLE, type)) {
-                putIfNotNull(fields, FIELD_LONG_TITLE, (ComplicationText) ois.readObject());
-            }
-            if (isFieldValidForType(FIELD_SHORT_TEXT, type)) {
-                putIfNotNull(fields, FIELD_SHORT_TEXT, (ComplicationText) ois.readObject());
-            }
-            if (isFieldValidForType(FIELD_SHORT_TITLE, type)) {
-                putIfNotNull(fields, FIELD_SHORT_TITLE, (ComplicationText) ois.readObject());
-            }
-            if (isFieldValidForType(FIELD_CONTENT_DESCRIPTION, type)) {
-                putIfNotNull(fields, FIELD_CONTENT_DESCRIPTION,
-                        (ComplicationText) ois.readObject());
-            }
-            if (isFieldValidForType(FIELD_ICON, type)) {
-                putIfNotNull(fields, FIELD_ICON, IconSerializableHelper.read(ois));
-            }
-            if (isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, type)) {
-                putIfNotNull(fields, FIELD_ICON_BURN_IN_PROTECTION,
-                        IconSerializableHelper.read(ois));
-            }
-            if (isFieldValidForType(FIELD_SMALL_IMAGE, type)) {
-                putIfNotNull(fields, FIELD_SMALL_IMAGE, IconSerializableHelper.read(ois));
-            }
-            if (isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, type)) {
-                putIfNotNull(fields,
-                        FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, IconSerializableHelper.read(ois));
-            }
-            if (isFieldValidForType(FIELD_IMAGE_STYLE, type)) {
-                fields.putInt(FIELD_IMAGE_STYLE, ois.readInt());
-            }
-            if (isFieldValidForType(FIELD_LARGE_IMAGE, type)) {
-                fields.putParcelable(FIELD_LARGE_IMAGE, IconSerializableHelper.read(ois));
-            }
-            if (isFieldValidForType(FIELD_VALUE, type)) {
-                fields.putFloat(FIELD_VALUE, ois.readFloat());
-            }
-            if (isFieldValidForType(FIELD_VALUE_TYPE, type)) {
-                fields.putInt(FIELD_VALUE_TYPE, ois.readInt());
-            }
-            if (isFieldValidForType(FIELD_MIN_VALUE, type)) {
-                fields.putFloat(FIELD_MIN_VALUE, ois.readFloat());
-            }
-            if (isFieldValidForType(FIELD_MAX_VALUE, type)) {
-                fields.putFloat(FIELD_MAX_VALUE, ois.readFloat());
-            }
-            if (isFieldValidForType(FIELD_TARGET_VALUE, type)) {
-                fields.putFloat(FIELD_TARGET_VALUE, ois.readFloat());
-            }
-            if (isFieldValidForType(FIELD_COLOR_RAMP, type) && ois.readBoolean()) {
-                int numColors = ois.readInt();
-                int[] colors = new int[numColors];
-                for (int i = 0; i < numColors; ++i) {
-                    colors[i] = ois.readInt();
-                }
-                fields.putIntArray(FIELD_COLOR_RAMP, colors);
-            }
-            if (isFieldValidForType(FIELD_COLOR_RAMP_INTERPOLATED, type) && ois.readBoolean()) {
-                fields.putBoolean(FIELD_COLOR_RAMP_INTERPOLATED, ois.readBoolean());
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_WEIGHTS, type) && ois.readBoolean()) {
-                int numWeights = ois.readInt();
-                float[] weights = new float[numWeights];
-                for (int i = 0; i < numWeights; ++i) {
-                    weights[i] = ois.readFloat();
-                }
-                fields.putFloatArray(FIELD_ELEMENT_WEIGHTS, weights);
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_COLORS, type) && ois.readBoolean()) {
-                int numColors = ois.readInt();
-                int[] colors = new int[numColors];
-                for (int i = 0; i < numColors; ++i) {
-                    colors[i] = ois.readInt();
-                }
-                fields.putIntArray(FIELD_ELEMENT_COLORS, colors);
-            }
-            if (isFieldValidForType(FIELD_ELEMENT_BACKGROUND_COLOR, type)) {
-                fields.putInt(FIELD_ELEMENT_BACKGROUND_COLOR, ois.readInt());
-            }
-            if (isFieldValidForType(FIELD_START_TIME, type)) {
-                fields.putLong(FIELD_START_TIME, ois.readLong());
-            }
-            if (isFieldValidForType(FIELD_END_TIME, type)) {
-                fields.putLong(FIELD_END_TIME, ois.readLong());
-            }
-            int listEntryType = ois.readInt();
-            if (listEntryType != 0) {
-                fields.putInt(EXP_FIELD_LIST_ENTRY_TYPE, listEntryType);
-            }
-            if (isFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, type)) {
-                fields.putInt(EXP_FIELD_LIST_STYLE_HINT, ois.readInt());
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, type)) {
-                int length = ois.readInt();
-                if (length > 0) {
-                    byte[] protoLayout = new byte[length];
-                    ois.readFully(protoLayout);
-                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, protoLayout);
-                }
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_AMBIENT, type)) {
-                int length = ois.readInt();
-                if (length > 0) {
-                    byte[] ambientProtoLayout = new byte[length];
-                    ois.readFully(ambientProtoLayout);
-                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_AMBIENT, ambientProtoLayout);
-                }
-            }
-            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_RESOURCES, type)) {
-                int length = ois.readInt();
-                if (length > 0) {
-                    byte[] protoLayoutResources = new byte[length];
-                    ois.readFully(protoLayoutResources);
-                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_RESOURCES, protoLayoutResources);
-                }
-            }
-            if (isFieldValidForType(FIELD_DATA_SOURCE, type)) {
-                String componentName = ois.readUTF();
-                if (componentName.isEmpty()) {
-                    fields.remove(FIELD_DATA_SOURCE);
-                } else {
-                    fields.putParcelable(
-                            FIELD_DATA_SOURCE, ComponentName.unflattenFromString(componentName));
-                }
-            }
-            if (ois.readBoolean()) {
-                fields.putBoolean(FIELD_TAP_ACTION_LOST, true);
-            }
-            long start = ois.readLong();
-            if (start != -1) {
-                fields.putLong(FIELD_TIMELINE_START_TIME, start);
-            }
-            long end = ois.readLong();
-            if (end != -1) {
-                fields.putLong(FIELD_TIMELINE_END_TIME, end);
-            }
-            int timelineEntryType = ois.readInt();
-            if (timelineEntryType != 0) {
-                fields.putInt(FIELD_TIMELINE_ENTRY_TYPE, timelineEntryType);
-            }
-
-            int listEntriesLength = ois.readInt();
-            if (listEntriesLength != 0) {
-                Parcelable[] parcels = new Parcelable[listEntriesLength];
-                for (int i = 0; i < listEntriesLength; i++) {
-                    SerializedForm entry = new SerializedForm();
-                    entry.readObject(ois);
-                    parcels[i] = entry.mComplicationData.mFields;
-                }
-                fields.putParcelableArray(EXP_FIELD_LIST_ENTRIES, parcels);
-            }
-
-            if (isFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)) {
-                if (ois.readBoolean()) {
-                    SerializedForm serializedPlaceholder = new SerializedForm();
-                    serializedPlaceholder.readObject(ois);
-                    fields.putInt(FIELD_PLACEHOLDER_TYPE,
-                            serializedPlaceholder.mComplicationData.mType);
-                    fields.putBundle(FIELD_PLACEHOLDER_FIELDS,
-                            serializedPlaceholder.mComplicationData.mFields);
-                }
-            }
-
-            int timelineLength = ois.readInt();
-            if (timelineLength != 0) {
-                Parcelable[] parcels = new Parcelable[timelineLength];
-                for (int i = 0; i < timelineLength; i++) {
-                    SerializedForm entry = new SerializedForm();
-                    entry.readObject(ois);
-                    parcels[i] = entry.mComplicationData.mFields;
-                }
-                fields.putParcelableArray(FIELD_TIMELINE_ENTRIES, parcels);
-            }
-            mComplicationData = new ComplicationData(type, fields);
-        }
-
-        Object readResolve() {
-            return mComplicationData;
-        }
-    }
-
-    @RequiresApi(api = Build.VERSION_CODES.P)
-    Object writeReplace() {
-        return new SerializedForm(this);
-    }
-
-    private void readObject(ObjectInputStream stream) throws InvalidObjectException {
-        throw new InvalidObjectException("Use SerializedForm");
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mType);
-        dest.writeBundle(mFields);
-    }
-
-    /**
-     * Returns the type of this complication data.
-     *
-     * <p>Will be one of {@link #TYPE_SHORT_TEXT}, {@link #TYPE_LONG_TEXT}, {@link
-     * #TYPE_RANGED_VALUE}, {@link #TYPE_ICON}, {@link #TYPE_SMALL_IMAGE}, {@link
-     * #TYPE_LARGE_IMAGE}, {@link #TYPE_NOT_CONFIGURED}, {@link #TYPE_EMPTY}, {@link
-     * #TYPE_NO_PERMISSION}, or {@link #TYPE_NO_DATA}.
-     */
-    @ComplicationType
-    public int getType() {
-        return mType;
-    }
-
-    /**
-     * Returns true if the complication is active and should be displayed at the given time. If this
-     * returns false, the complication should not be displayed.
-     *
-     * <p>This must be checked for any time for which the complication will be displayed.
-     */
-    public boolean isActiveAt(long dateTimeMillis) {
-        return dateTimeMillis >= mFields.getLong(FIELD_START_TIME, 0)
-                && dateTimeMillis <= mFields.getLong(FIELD_END_TIME, Long.MAX_VALUE);
-    }
-
-    /**
-     * TapAction unfortunately can't be serialized. Returns true if tapAction has been lost due to
-     * serialization (e.g. due to being read from the local cache). The next complication update
-     * from the system would replace this with one with a tapAction.
-     */
-    public boolean getTapActionLostDueToSerialization() {
-        return mFields.getBoolean(FIELD_TAP_ACTION_LOST);
-    }
-
-    /**
-     * For timeline entries. Returns the epoch second at which this timeline entry becomes
-     * valid or `null` if it's not set.
-     */
-    @Nullable
-    public Long getTimelineStartEpochSecond() {
-        long expiresAt = mFields.getLong(FIELD_TIMELINE_START_TIME, -1);
-        if (expiresAt == -1) {
-            return null;
-        } else {
-            return expiresAt;
-        }
-    }
-
-    /**
-     * For timeline entries. Sets the epoch second at which this timeline entry becomes invalid
-     * or clears the field if instant is `null`.
-     */
-    public void setTimelineStartEpochSecond(@Nullable Long epochSecond) {
-        if (epochSecond == null) {
-            mFields.remove(FIELD_TIMELINE_START_TIME);
-        } else {
-            mFields.putLong(FIELD_TIMELINE_START_TIME, epochSecond);
-        }
-    }
-
-    /**
-     * For timeline entries. Returns the epoch second at which this timeline entry becomes invalid
-     * or `null` if it's not set.
-     */
-    @Nullable
-    public Long getTimelineEndEpochSecond() {
-        long expiresAt = mFields.getLong(FIELD_TIMELINE_END_TIME, -1);
-        if (expiresAt == -1) {
-            return null;
-        } else {
-            return expiresAt;
-        }
-    }
-
-    /**
-     * For timeline entries. Sets the epoch second at which this timeline entry becomes invalid,
-     * or clears the field if instant is `null`.
-     */
-    public void setTimelineEndEpochSecond(@Nullable Long epochSecond) {
-        if (epochSecond == null) {
-            mFields.remove(FIELD_TIMELINE_END_TIME);
-        } else {
-            mFields.putLong(FIELD_TIMELINE_END_TIME, epochSecond);
-        }
-    }
-
-    /** Returns the list of {@link ComplicationData} timeline entries. */
-    @Nullable
-    @SuppressWarnings("deprecation")
-    public List<ComplicationData> getTimelineEntries() {
-        Parcelable[] bundles = mFields.getParcelableArray(FIELD_TIMELINE_ENTRIES);
-        if (bundles == null) {
-            return null;
-        }
-        ArrayList<ComplicationData> entries = new ArrayList<>();
-        for (Parcelable parcelable : bundles) {
-            Bundle bundle = (Bundle) parcelable;
-            bundle.setClassLoader(getClass().getClassLoader());
-            // Use the serialized FIELD_TIMELINE_ENTRY_TYPE or the outer type if it's not there.
-            // Usually the timeline entry type will be the same as the outer type, unless an entry
-            // contains NoDataComplicationData.
-            int type = bundle.getInt(FIELD_TIMELINE_ENTRY_TYPE, mType);
-            entries.add(new ComplicationData(type, (Bundle) parcelable));
-        }
-        return entries;
-    }
-
-    /** Sets the list of {@link ComplicationData} timeline entries. */
-    public void setTimelineEntryCollection(@Nullable Collection<ComplicationData> timelineEntries) {
-        if (timelineEntries == null) {
-            mFields.remove(FIELD_TIMELINE_ENTRIES);
-        } else {
-            mFields.putParcelableArray(
-                    FIELD_TIMELINE_ENTRIES,
-                    timelineEntries.stream().map(
-                            e -> {
-                                // This supports timeline entry of NoDataComplicationData.
-                                e.mFields.putInt(FIELD_TIMELINE_ENTRY_TYPE, e.mType);
-                                return e.mFields;
-                            }
-                    ).toArray(Parcelable[]::new));
-        }
-    }
-
-    /** Returns the list of {@link ComplicationData} entries for a ListComplicationData. */
-    @Nullable
-    @SuppressWarnings("deprecation")
-    public List<ComplicationData> getListEntries() {
-        Parcelable[] bundles = mFields.getParcelableArray(EXP_FIELD_LIST_ENTRIES);
-        if (bundles == null) {
-            return null;
-        }
-        ArrayList<ComplicationData> entries = new ArrayList<>();
-        for (Parcelable parcelable : bundles) {
-            Bundle bundle = (Bundle) parcelable;
-            bundle.setClassLoader(getClass().getClassLoader());
-            entries.add(new ComplicationData(bundle.getInt(EXP_FIELD_LIST_ENTRY_TYPE), bundle));
-        }
-        return entries;
-    }
-
-    /**
-     * Sets the {@link ComponentName} of the ComplicationDataSourceService that provided this
-     * ComplicationData.
-     */
-    public void setDataSource(@Nullable ComponentName provider) {
-        mFields.putParcelable(FIELD_DATA_SOURCE, provider);
-    }
-
-    /**
-     * Gets the {@link ComponentName} of the ComplicationDataSourceService that provided this
-     * ComplicationData.
-     */
-    @Nullable
-    @SuppressWarnings("deprecation")  // The safer alternative is not available on Wear OS yet.
-    public ComponentName getDataSource() {
-        return (ComponentName) mFields.getParcelable(FIELD_DATA_SOURCE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a ranged max value. I.e. if
-     * {@link #getRangedValue} can succeed.
-     */
-    public boolean hasRangedValue() {
-        try {
-            return isFieldValidForType(FIELD_VALUE, mType);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>value</i> field for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE}.
-     * Otherwise returns zero.
-     */
-    public float getRangedValue() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_VALUE, mType);
-        return mFields.getFloat(FIELD_VALUE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a ranged max type. I.e. if
-     * {@link #getRangedValueType} can succeed.
-     */
-    public boolean hasRangedValueType() {
-        try {
-            return isFieldValidForType(FIELD_VALUE_TYPE, mType);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>value</i> field for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE}.
-     * Otherwise returns zero.
-     */
-    public int getRangedValueType() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_VALUE_TYPE, mType);
-        return mFields.getInt(FIELD_VALUE_TYPE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a ranged max value. I.e. if
-     * {@link #getRangedMinValue} can succeed.
-     */
-    public boolean hasRangedMinValue() {
-        try {
-            return isFieldValidForType(FIELD_MIN_VALUE, mType);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>min value</i> field for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE}.
-     * Otherwise returns zero.
-     */
-    public float getRangedMinValue() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_MIN_VALUE, mType);
-        return mFields.getFloat(FIELD_MIN_VALUE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a ranged max value. I.e. if
-     * {@link #getRangedMaxValue} can succeed.
-     */
-    public boolean hasRangedMaxValue() {
-        try {
-            return isFieldValidForType(FIELD_MAX_VALUE, mType);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>max value</i> field for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE}.
-     * Otherwise returns zero.
-     */
-    public float getRangedMaxValue() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_MAX_VALUE, mType);
-        return mFields.getFloat(FIELD_MAX_VALUE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a ranged max value. I.e. if
-     * {@link #getTargetValue} can succeed.
-     */
-    public boolean hasTargetValue() {
-        try {
-            return isFieldValidForType(FIELD_TARGET_VALUE, mType);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>value</i> field for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_GOAL_PROGRESS}.
-     * Otherwise returns zero.
-     */
-    public float getTargetValue() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_TARGET_VALUE, mType);
-        return mFields.getFloat(FIELD_TARGET_VALUE);
-    }
-
-    /**
-     * Returns the colors for the progress bar.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE} or
-     * {@link #TYPE_GOAL_PROGRESS}.
-     */
-    @ColorInt
-    @Nullable
-    public int[] getColorRamp() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_COLOR_RAMP, mType);
-        if (mFields.containsKey(FIELD_COLOR_RAMP)) {
-            return mFields.getIntArray(FIELD_COLOR_RAMP);
-        }
-        return null;
-    }
-
-    /**
-     * Returns either a boolean where: true means the color ramp colors should be smoothly
-     * interpolatded; false means the color ramp should be rendered in equal sized blocks of
-     * solid color; null means this value wasn't set, i.e. the complication is not of type
-     * {@link #TYPE_RANGED_VALUE} or {@link #TYPE_GOAL_PROGRESS}.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_RANGED_VALUE} or
-     * {@link #TYPE_GOAL_PROGRESS}.
-     */
-    @Nullable
-    public Boolean isColorRampInterpolated() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_COLOR_RAMP_INTERPOLATED, mType);
-        if (mFields.containsKey(FIELD_COLOR_RAMP_INTERPOLATED)) {
-            return mFields.getBoolean(FIELD_COLOR_RAMP_INTERPOLATED);
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a short title. I.e. if {@link #getShortTitle}
-     * can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasShortTitle() {
-        try {
-            return isFieldValidForType(FIELD_SHORT_TITLE, mType)
-                    && (mFields.getParcelable(FIELD_SHORT_TITLE) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>short title</i> field for this complication, or {@code null} if no value was
-     * provided for the field.
-     *
-     * <p>The value is provided as a {@link ComplicationText} object, from which the text to display
-     * can be obtained for a given point in time.
-     *
-     * <p>The length of the text, including any time-dependent values at any valid time, is expected
-     * to not exceed seven characters. When using this text, the watch face should be able to
-     * display any string of up to seven characters (reducing the text size appropriately if the
-     * string is very wide). Although not expected, it is possible that strings of more than seven
-     * characters might be seen, in which case they may be truncated.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_SHORT_TEXT}, {@link
-     * #TYPE_RANGED_VALUE}, or {@link #TYPE_NO_PERMISSION}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public ComplicationText getShortTitle() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_SHORT_TITLE, mType);
-        return getParcelableField(FIELD_SHORT_TITLE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains short text. I.e. if {@link #getShortText} can
-     * succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasShortText() {
-        try {
-            return isFieldValidForType(FIELD_SHORT_TEXT, mType)
-                    && (mFields.getParcelable(FIELD_SHORT_TEXT) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>short text</i> field for this complication, or {@code null} if no value was
-     * provided for the field.
-     *
-     * <p>The value is provided as a {@link ComplicationText} object, from which the text to display
-     * can be obtained for a given point in time.
-     *
-     * <p>The length of the text, including any time-dependent values at any valid time, is expected
-     * to not exceed seven characters. When using this text, the watch face should be able to
-     * display any string of up to seven characters (reducing the text size appropriately if the
-     * string is very wide). Although not expected, it is possible that strings of more than seven
-     * characters might be seen, in which case they may be truncated.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_SHORT_TEXT}, {@link
-     * #TYPE_RANGED_VALUE}, or {@link #TYPE_NO_PERMISSION}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public ComplicationText getShortText() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_SHORT_TEXT, mType);
-        return getParcelableField(FIELD_SHORT_TEXT);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a long title. I.e. if {@link #getLongTitle}
-     * can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasLongTitle() {
-        try {
-            return isFieldValidForType(FIELD_LONG_TITLE, mType)
-                    && (mFields.getParcelable(FIELD_LONG_TITLE) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>long title</i> field for this complication, or {@code null} if no value was
-     * provided for the field.
-     *
-     * <p>The value is provided as a {@link ComplicationText} object, from which the text to display
-     * can be obtained for a given point in time.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_LONG_TEXT}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public ComplicationText getLongTitle() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_LONG_TITLE, mType);
-        return getParcelableField(FIELD_LONG_TITLE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains long text. I.e. if {@link #getLongText} can
-     * succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasLongText() {
-        try {
-            return isFieldValidForType(FIELD_LONG_TEXT, mType)
-                    && (mFields.getParcelable(FIELD_LONG_TEXT) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>long text</i> field for this complication.
-     *
-     * <p>The value is provided as a {@link ComplicationText} object, from which the text to display
-     * can be obtained for a given point in time.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_LONG_TEXT}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public ComplicationText getLongText() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_LONG_TEXT, mType);
-        return getParcelableField(FIELD_LONG_TEXT);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains an Icon. I.e. if {@link #getIcon} can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasIcon() {
-        try {
-            return isFieldValidForType(FIELD_ICON, mType)
-                    && (mFields.getParcelable(FIELD_ICON) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>icon</i> field for this complication, or {@code null} if no value was provided
-     * for the field. The image returned is expected to be single-color and so may be tinted to
-     * whatever color the watch face requires (but note that {@link Drawable#mutate()} should be
-     * called before drawables are tinted).
-     *
-     * <p>If the device is in ambient mode, and utilises burn-in protection, then the result of
-     * {@link #getBurnInProtectionIcon} must be used instead of this.
-     *
-     * <p>Valid for the types {@link #TYPE_SHORT_TEXT}, {@link #TYPE_LONG_TEXT}, {@link
-     * #TYPE_RANGED_VALUE}, {@link #TYPE_ICON}, or {@link #TYPE_NO_PERMISSION}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public Icon getIcon() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_ICON, mType);
-        return getParcelableField(FIELD_ICON);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a burn in protection Icon. I.e. if
-     * {@link #getBurnInProtectionIcon} can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasBurnInProtectionIcon() {
-        try {
-            return isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, mType)
-                    && (mFields.getParcelable(FIELD_ICON_BURN_IN_PROTECTION) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the burn-in protection version of the <i>icon</i> field for this complication, or
-     * {@code null} if no such icon was provided. The image returned is expected to be an outline
-     * image suitable for use in ambient mode on screens with burn-in protection. The image is also
-     * expected to be single-color and so may be tinted to whatever color the watch face requires
-     * (but note that {@link Drawable#mutate()} should be called before drawables are tinted, and
-     * that the color used should be suitable for ambient mode with burn-in protection).
-     *
-     * <p>If the device is in ambient mode, and utilises burn-in protection, then the result of this
-     * method must be used instead of the result of {@link #getIcon}.
-     *
-     * <p>Valid for the types {@link #TYPE_SHORT_TEXT}, {@link #TYPE_LONG_TEXT}, {@link
-     * #TYPE_RANGED_VALUE}, {@link #TYPE_ICON}, or {@link #TYPE_NO_PERMISSION}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public Icon getBurnInProtectionIcon() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_ICON_BURN_IN_PROTECTION, mType);
-        return getParcelableField(FIELD_ICON_BURN_IN_PROTECTION);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a small image. I.e. if {@link #getSmallImage}
-     * can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasSmallImage() {
-        try {
-            return isFieldValidForType(FIELD_SMALL_IMAGE, mType)
-                    && (mFields.getParcelable(FIELD_SMALL_IMAGE) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>small image</i> field for this complication, or {@code null} if no value was
-     * provided for the field.
-     *
-     * <p>This may be either a {@link #IMAGE_STYLE_PHOTO photo style} image, which is expected to
-     * fill the space available, or an {@link #IMAGE_STYLE_ICON icon style} image, which should be
-     * drawn entirely within the space available. Use {@link #getSmallImageStyle} to determine which
-     * of these applies.
-     *
-     * <p>As this may be any image, it is unlikely to be suitable for display in ambient mode when
-     * burn-in protection is enabled, or in low-bit ambient mode, and should not be rendered under
-     * these circumstances.
-     *
-     * <p>Valid for the types {@link #TYPE_LONG_TEXT} and {@link #TYPE_SMALL_IMAGE}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public Icon getSmallImage() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_SMALL_IMAGE, mType);
-        return getParcelableField(FIELD_SMALL_IMAGE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a burn in protection small image. I.e. if
-     * {@link #getBurnInProtectionSmallImage} can succeed.
-     *
-     * @throws IllegalStateException for invalid types
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasBurnInProtectionSmallImage() {
-        try {
-            return isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, mType)
-                    && (mFields.getParcelable(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the burn-in protection version of the <i>small image</i> field for this complication,
-     * or {@code null} if no such icon was provided. The image returned is expected to be an outline
-     * image suitable for use in ambient mode on screens with burn-in protection. The image is also
-     * expected to be single-color and so may be tinted to whatever color the watch face requires
-     * (but note that {@link Drawable#mutate()} should be called before drawables are tinted, and
-     * that the color used should be suitable for ambient mode with burn-in protection).
-     *
-     * <p>If the device is in ambient mode, and utilises burn-in protection, then the result of this
-     * method must be used instead of the result of {@link #getSmallImage()}.
-     *
-     * <p>Valid for the types {@link #TYPE_LONG_TEXT} and {@link #TYPE_SMALL_IMAGE}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public Icon getBurnInProtectionSmallImage() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, mType);
-        return getParcelableField(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION);
-    }
-
-    /**
-     * Returns the <i>small image style</i> field for this complication.
-     *
-     * <p>The result of this method should be taken in to account when drawing a small image
-     * complication.
-     *
-     * <p>Valid only for types that contain small images, i.e. {@link #TYPE_SMALL_IMAGE} and {@link
-     * #TYPE_LONG_TEXT}.
-     * Otherwise returns zero.
-     *
-     * @see #IMAGE_STYLE_PHOTO which can be cropped but not recolored.
-     * @see #IMAGE_STYLE_ICON which can be recolored but not cropped.
-     */
-    @ImageStyle
-    public int getSmallImageStyle() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_IMAGE_STYLE, mType);
-        return mFields.getInt(FIELD_IMAGE_STYLE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a large image. I.e. if {@link #getLargeImage}
-     * can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasLargeImage() {
-        try {
-            return isFieldValidForType(FIELD_LARGE_IMAGE, mType)
-                    && (mFields.getParcelable(FIELD_LARGE_IMAGE) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>large image</i> field for this complication. This image is expected to be of a
-     * suitable size to fill the screen of the watch.
-     *
-     * <p>As this may be any image, it is unlikely to be suitable for display in ambient mode when
-     * burn-in protection is enabled, or in low-bit ambient mode, and should not be rendered under
-     * these circumstances.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_LARGE_IMAGE}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public Icon getLargeImage() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_LARGE_IMAGE, mType);
-        return getParcelableField(FIELD_LARGE_IMAGE);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a tap action. I.e. if {@link #getTapAction}
-     * can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasTapAction() {
-        try {
-            return isFieldValidForType(FIELD_TAP_ACTION, mType)
-                    && (mFields.getParcelable(FIELD_TAP_ACTION) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>tap action</i> field for this complication. The result is a {@link
-     * PendingIntent} that should be fired if the complication is tapped on, assuming the
-     * complication is tappable, or {@code null} if no tap action has been specified.
-     *
-     * <p>Valid for all non-empty types.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public PendingIntent getTapAction() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_TAP_ACTION, mType);
-        return getParcelableField(FIELD_TAP_ACTION);
-    }
-
-    /**
-     * Returns true if the ComplicationData contains a content description. I.e. if
-     * {@link #getContentDescription} can succeed.
-     */
-    @SuppressWarnings("deprecation")
-    public boolean hasContentDescription() {
-        try {
-            return isFieldValidForType(FIELD_CONTENT_DESCRIPTION, mType)
-                    && (mFields.getParcelable(FIELD_CONTENT_DESCRIPTION) != null);
-        } catch (BadParcelableException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns the <i>content description </i> field for this complication, for screen readers. This
-     * usually describes the image, but may also describe the overall complication.
-     *
-     * <p>Valid for all non-empty types.
-     */
-    @Nullable
-    public ComplicationText getContentDescription() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_CONTENT_DESCRIPTION, mType);
-        return getParcelableField(FIELD_CONTENT_DESCRIPTION);
-    }
-
-    /**
-     * Returns the element weights for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_WEIGHTED_ELEMENTS}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public float[] getElementWeights() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_WEIGHTS, mType);
-        return mFields.getFloatArray(FIELD_ELEMENT_WEIGHTS);
-    }
-
-    /**
-     * Returns the element colors for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_WEIGHTED_ELEMENTS}.
-     * Otherwise returns null.
-     */
-    @Nullable
-    public int[] getElementColors() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_COLORS, mType);
-        return mFields.getIntArray(FIELD_ELEMENT_COLORS);
-    }
-
-    /**
-     * Returns the background color to use between elements for this complication.
-     *
-     * <p>Valid only if the type of this complication data is {@link #TYPE_WEIGHTED_ELEMENTS}.
-     * Otherwise returns 0.
-     */
-    @ColorInt
-    public int getElementBackgroundColor() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_BACKGROUND_COLOR, mType);
-        return mFields.getInt(FIELD_ELEMENT_BACKGROUND_COLOR);
-    }
-
-    /**
-     * Returns the placeholder ComplicationData if there is one or `null`.
-     */
-    @Nullable
-    public ComplicationData getPlaceholder() {
-        checkFieldValidForType(FIELD_PLACEHOLDER_FIELDS, mType);
-        checkFieldValidForType(FIELD_PLACEHOLDER_TYPE, mType);
-        if (!mFields.containsKey(FIELD_PLACEHOLDER_FIELDS)
-                || !mFields.containsKey(FIELD_PLACEHOLDER_TYPE)) {
-            return null;
-        }
-        return new ComplicationData(mFields.getInt(FIELD_PLACEHOLDER_TYPE),
-                mFields.getBundle(FIELD_PLACEHOLDER_FIELDS));
-    }
-
-    /** Returns the bytes of the proto layout. */
-    @Nullable
-    public byte[] getInteractiveLayout() {
-        return mFields.getByteArray(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE);
-    }
-
-    /**
-     * Returns the list style hint.
-     *
-     * <p>Valid only if the type of this complication data is {@link #EXP_TYPE_LIST}. Otherwise
-     * returns zero.
-     */
-    public int getListStyleHint() {
-        checkFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, mType);
-        return mFields.getInt(EXP_FIELD_LIST_STYLE_HINT);
-    }
-
-    /** Returns the bytes of the ambient proto layout. */
-    @Nullable
-    public byte[] getAmbientLayout() {
-        return mFields.getByteArray(EXP_FIELD_PROTO_LAYOUT_AMBIENT);
-    }
-
-    /** Returns the bytes of the proto layout resources. */
-    @Nullable
-    public byte[] getLayoutResources() {
-        return mFields.getByteArray(EXP_FIELD_PROTO_LAYOUT_RESOURCES);
-    }
-
-    /** Return's the complication's [ComplicationCachePolicy]. */
-    @ComplicationPersistencePolicy
-    public int getPersistencePolicy() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_PERSISTENCE_POLICY, mType);
-        return mFields.getInt(
-                FIELD_PERSISTENCE_POLICY, ComplicationPersistencePolicies.CACHING_ALLOWED);
-    }
-
-    /** Return's the complication's [ComplicationDisplayPolicy]. */
-    @ComplicationDisplayPolicy
-    public int getDisplayPolicy() {
-        checkFieldValidForTypeWithoutThrowingException(FIELD_DISPLAY_POLICY, mType);
-        return mFields.getInt(FIELD_DISPLAY_POLICY, ComplicationDisplayPolicies.ALWAYS_DISPLAY);
-    }
-
-    /**
-     * Returns the start time for this complication data (i.e. the first time at which it should
-     * be considered active and displayed), this may be 0. See also {@link #isActiveAt(long)}.
-     */
-    public long getStartDateTimeMillis() {
-        return mFields.getLong(FIELD_START_TIME, 0);
-    }
-
-    /**
-     * Returns the end time for this complication data (i.e. the last time at which it should be
-     * considered active and displayed), this may be {@link Long#MAX_VALUE}. See also {@link
-     * #isActiveAt(long)}.
-     */
-    public long getEndDateTimeMillis() {
-        return mFields.getLong(FIELD_END_TIME, Long.MAX_VALUE);
-    }
-
-    /**
-     * Returns true if the complication data contains at least one text field with a value that may
-     * change based on the current time.
-     */
-    public boolean isTimeDependent() {
-        return isTimeDependentField(FIELD_SHORT_TEXT)
-                || isTimeDependentField(FIELD_SHORT_TITLE)
-                || isTimeDependentField(FIELD_LONG_TEXT)
-                || isTimeDependentField(FIELD_LONG_TITLE);
-    }
-
-    private boolean isTimeDependentField(String field) {
-        ComplicationText text = getParcelableField(field);
-
-        return text != null && text.isTimeDependent();
-    }
-
-    static boolean isFieldValidForType(String field, @ComplicationType int type) {
-        String[] requiredFields = REQUIRED_FIELDS.get(type);
-        if (requiredFields == null) {
-            return false;
-        }
-        for (String requiredField : requiredFields) {
-            if (requiredField.equals(field)) {
-                return true;
-            }
-        }
-        for (String optionalField : Objects.requireNonNull(OPTIONAL_FIELDS.get(type))) {
-            if (optionalField.equals(field)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static boolean isTypeSupported(int type) {
-        return VALID_TYPES.contains(type);
-    }
-
-    /**
-     * The unparceling logic needs to remain backward compatible.
-     */
-    private static void checkFieldValidForTypeWithoutThrowingException(
-            String field, @ComplicationType int type) {
-        if (!isTypeSupported(type)) {
-            Log.w(TAG, "Type " + type + " can not be recognized");
-            return;
-        }
-        if (!isFieldValidForType(field, type)) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Field " + field + " is not supported for type " + type);
-            }
-        }
-    }
-
-    private static void checkFieldValidForType(String field, @ComplicationType int type) {
-        if (!isTypeSupported(type)) {
-            throw new IllegalStateException("Type " + type + " can not be recognized");
-        }
-        if (!isFieldValidForType(field, type)) {
-            throw new IllegalStateException(
-                    "Field " + field + " is not supported for type " + type);
-        }
-    }
-
-    @SuppressWarnings({"TypeParameterUnusedInFormals", "deprecation"})
-    private <T extends Parcelable> T getParcelableField(String field) {
-        try {
-            return mFields.getParcelable(field);
-        } catch (BadParcelableException e) {
-            Log.w(
-                    TAG,
-                    "Could not unparcel ComplicationData. Provider apps must exclude wearable "
-                            + "support complication classes from proguard.",
-                    e);
-            return null;
-        }
-    }
-
-    @NonNull
-    @Override
-    public String toString() {
-        if (shouldRedact()) {
-            return "ComplicationData{" + "mType=" + mType + ", mFields=REDACTED}";
-        }
-        return toStringNoRedaction();
-    }
-
-    /** @hide */
-    @NonNull
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public String toStringNoRedaction() {
-        return "ComplicationData{" + "mType=" + mType + ", mFields=" + mFields + '}';
-    }
-
-    /** Builder class for {@link ComplicationData}. */
-    public static final class Builder {
-        @ComplicationType
-        final int mType;
-        final Bundle mFields;
-
-        /** Creates a builder from given {@link ComplicationData}, copying its type and data. */
-        @SuppressLint("SyntheticAccessor")
-        public Builder(@NonNull ComplicationData data) {
-            mType = data.getType();
-            mFields = (Bundle) data.mFields.clone();
-        }
-
-        public Builder(@ComplicationType int type) {
-            mType = type;
-            mFields = new Bundle();
-            if (type == TYPE_SMALL_IMAGE || type == TYPE_LONG_TEXT) {
-                setSmallImageStyle(IMAGE_STYLE_PHOTO);
-            }
-        }
-
-        /** Sets the complication's [ComplicationCachePolicy]. */
-        @NonNull
-        public Builder setPersistencePolicy(@ComplicationPersistencePolicy int cachePolicy) {
-            mFields.putInt(FIELD_PERSISTENCE_POLICY, cachePolicy);
-            return this;
-        }
-
-        /** Sets the complication's [ComplicationDisplayPolicy]. */
-        @NonNull
-        public Builder setDisplayPolicy(@ComplicationDisplayPolicy int displayPolicy) {
-            mFields.putInt(FIELD_DISPLAY_POLICY, displayPolicy);
-            return this;
-        }
-
-        /**
-         * Sets the start time for this complication data. This is optional for any type.
-         *
-         * <p>The complication data will be considered inactive (i.e. should not be displayed) if
-         * the current time is less than the start time. If not specified, the data is considered
-         * active for all time up to the end time (or always active if end time is also not
-         * specified).
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setStartDateTimeMillis(long startDateTimeMillis) {
-            mFields.putLong(FIELD_START_TIME, startDateTimeMillis);
-            return this;
-        }
-
-        /**
-         * Removes the start time for this complication data.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder clearStartDateTime() {
-            mFields.remove(FIELD_START_TIME);
-            return this;
-        }
-
-        /**
-         * Sets the end time for this complication data. This is optional for any type.
-         *
-         * <p>The complication data will be considered inactive (i.e. should not be displayed) if
-         * the current time is greater than the end time. If not specified, the data is considered
-         * active for all time after the start time (or always active if start time is also not
-         * specified).
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setEndDateTimeMillis(long endDateTimeMillis) {
-            mFields.putLong(FIELD_END_TIME, endDateTimeMillis);
-            return this;
-        }
-
-        /**
-         * Removes the end time for this complication data.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder clearEndDateTime() {
-            mFields.remove(FIELD_END_TIME);
-            return this;
-        }
-
-        /**
-         * Sets the <i>value</i> field. This is required for the {@link #TYPE_RANGED_VALUE} type,
-         * and the {@link #TYPE_GOAL_PROGRESS} type. For {@link #TYPE_RANGED_VALUE} value must
-         * be in the range [min .. max] for {@link #TYPE_GOAL_PROGRESS} value must be >= and may
-         * be greater than target value.
-         *
-         * <p>Both the {@link #TYPE_RANGED_VALUE} complication and the
-         * {@link #TYPE_GOAL_PROGRESS} complication visually present a single value, which is
-         * usually a percentage. E.g. you have completed 70% of today's  target of 10000 steps.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setRangedValue(float value) {
-            putFloatField(FIELD_VALUE, value);
-            return this;
-        }
-
-        /**
-         * Sets the <i>value type</i> field which provides meta data about the value. This is
-         * optional for the {@link #TYPE_RANGED_VALUE} type.
-         */
-        @NonNull
-        public Builder setRangedValueType(int valueType) {
-            putIntField(FIELD_VALUE_TYPE, valueType);
-            return this;
-        }
-
-        /**
-         * Sets the <i>min value</i> field. This is required for the {@link #TYPE_RANGED_VALUE}
-         * type, and is not valid for any other type. A {@link #TYPE_RANGED_VALUE} complication
-         * visually presents a single value, which is usually a percentage. E.g. you have
-         * completed 70% of today's target of 10000 steps.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setRangedMinValue(float minValue) {
-            putFloatField(FIELD_MIN_VALUE, minValue);
-            return this;
-        }
-
-        /**
-         * Sets the <i>max value</i> field. This is required for the {@link #TYPE_RANGED_VALUE}
-         * type, and is not valid for any other type.A {@link #TYPE_RANGED_VALUE} complication
-         * visually presents a single value, which is usually a percentage. E.g. you have
-         * completed 70% of today's target of 10000 steps.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setRangedMaxValue(float maxValue) {
-            putFloatField(FIELD_MAX_VALUE, maxValue);
-            return this;
-        }
-
-        /**
-         * Sets the <i>targetValue</i> field. This is required for the
-         * {@link #TYPE_GOAL_PROGRESS} type, and is not valid for any other type. A
-         * {@link #TYPE_GOAL_PROGRESS} complication visually presents a single value, which
-         * is usually a percentage. E.g. you have completed 70% of today's target of 10000 steps.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setTargetValue(float targetValue) {
-            putFloatField(FIELD_TARGET_VALUE, targetValue);
-            return this;
-        }
-
-        /**
-         * Sets the <i>long title</i> field. This is optional for the {@link #TYPE_LONG_TEXT} type,
-         * and is not valid for any other type.
-         *
-         * <p>The value must be provided as a {@link ComplicationText} object, so that
-         * time-dependent values may be included.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setLongTitle(@Nullable ComplicationText longTitle) {
-            putOrRemoveField(FIELD_LONG_TITLE, longTitle);
-            return this;
-        }
-
-        /**
-         * Sets the <i>long text</i> field. This is required for the {@link #TYPE_LONG_TEXT} type,
-         * and is not valid for any other type.
-         *
-         * <p>The value must be provided as a {@link ComplicationText} object, so that
-         * time-dependent values may be included.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setLongText(@Nullable ComplicationText longText) {
-            putOrRemoveField(FIELD_LONG_TEXT, longText);
-            return this;
-        }
-
-        /**
-         * Sets the <i>short title</i> field. This is valid for the {@link #TYPE_SHORT_TEXT}, {@link
-         * #TYPE_RANGED_VALUE}, and {@link #TYPE_NO_PERMISSION} types, and is not valid for any
-         * other type.
-         *
-         * <p>The value must be provided as a {@link ComplicationText} object, so that
-         * time-dependent values may be included.
-         *
-         * <p>The length of the text, including any time-dependent values, should not exceed seven
-         * characters. If it does, the text may be truncated by the watch face or might not fit in
-         * the complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setShortTitle(@Nullable ComplicationText shortTitle) {
-            putOrRemoveField(FIELD_SHORT_TITLE, shortTitle);
-            return this;
-        }
-
-        /**
-         * Sets the <i>short text</i> field. This is required for the {@link #TYPE_SHORT_TEXT} type,
-         * is optional for the {@link #TYPE_RANGED_VALUE} and {@link #TYPE_NO_PERMISSION} types, and
-         * is not valid for any other type.
-         *
-         * <p>The value must be provided as a {@link ComplicationText} object, so that
-         * time-dependent values may be included.
-         *
-         * <p>The length of the text, including any time-dependent values, should not exceed seven
-         * characters. If it does, the text may be truncated by the watch face or might not fit in
-         * the complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setShortText(@Nullable ComplicationText shortText) {
-            putOrRemoveField(FIELD_SHORT_TEXT, shortText);
-            return this;
-        }
-
-        /**
-         * Sets the <i>icon</i> field. This is required for the {@link #TYPE_ICON} type, and is
-         * optional for the {@link #TYPE_SHORT_TEXT}, {@link #TYPE_LONG_TEXT}, {@link
-         * #TYPE_RANGED_VALUE}, and {@link #TYPE_NO_PERMISSION} types.
-         *
-         * <p>The provided image must be single-color, so that watch faces can tint it as required.
-         *
-         * <p>If the icon provided here is not suitable for display in ambient mode with burn-in
-         * protection (e.g. if it includes solid blocks of pixels), then a burn-in safe version of
-         * the icon must be provided via {@link #setBurnInProtectionIcon}.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setIcon(@Nullable Icon icon) {
-            putOrRemoveField(FIELD_ICON, icon);
-            return this;
-        }
-
-        /**
-         * Sets the burn-in protection version of the <i>icon</i> field. This should be provided if
-         * the <i>icon</i> field is provided, unless the main icon is already safe for use with
-         * burn-in protection.  This icon should have fewer lit pixels, and should use darker
-         * colors to prevent LCD burn in issues.
-         *
-         * <p>The provided image must be single-color, so that watch faces can tint it as required.
-         *
-         * <p>The provided image must not contain solid blocks of pixels - it should instead be
-         * composed of outlines or lines only.
-         *
-         * <p>If this field is set, the <i>icon</i> field must also be set.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setBurnInProtectionIcon(@Nullable Icon icon) {
-            putOrRemoveField(FIELD_ICON_BURN_IN_PROTECTION, icon);
-            return this;
-        }
-
-        /**
-         * Sets the <i>small image</i> field. This is required for the {@link #TYPE_SMALL_IMAGE}
-         * type, and is optional for the {@link #TYPE_LONG_TEXT} type.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setSmallImage(@Nullable Icon smallImage) {
-            putOrRemoveField(FIELD_SMALL_IMAGE, smallImage);
-            return this;
-        }
-
-        /**
-         * Sets the burn-in protection version of the <i>small image</i> field. This should be
-         * provided if the <i>small image</i> field is provided, unless the main small image is
-         * already safe for use with burn-in protection.
-         *
-         * <p>The provided image must not contain solid blocks of pixels - it should instead be
-         * composed of outlines or lines only.
-         *
-         * <p>If this field is set, the <i>small image</i> field must also be set.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setBurnInProtectionSmallImage(@Nullable Icon smallImage) {
-            putOrRemoveField(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, smallImage);
-            return this;
-        }
-
-        /**
-         * Sets the display style for this complication data. This is valid only for types that
-         * contain small images, i.e. {@link #TYPE_SMALL_IMAGE} and {@link #TYPE_LONG_TEXT}.
-         *
-         * <p>This affects how watch faces will draw the image in the complication.
-         *
-         * <p>If not specified, the default is {@link #IMAGE_STYLE_PHOTO}.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         * @see #IMAGE_STYLE_PHOTO which can be cropped but not recolored.
-         * @see #IMAGE_STYLE_ICON which can be recolored but not cropped.
-         */
-        @NonNull
-        public Builder setSmallImageStyle(@ImageStyle int imageStyle) {
-            putIntField(FIELD_IMAGE_STYLE, imageStyle);
-            return this;
-        }
-
-        /**
-         * Sets the <i>large image</i> field. This is required for the {@link #TYPE_LARGE_IMAGE}
-         * type, and is not valid for any other type.
-         *
-         * <p>The provided image should be suitably sized to fill the screen of the watch.
-         *
-         * <p>Returns this Builder to allow chaining.
-         *
-         * @throws IllegalStateException if this field is not valid for the complication type
-         */
-        @NonNull
-        public Builder setLargeImage(@Nullable Icon largeImage) {
-            putOrRemoveField(FIELD_LARGE_IMAGE, largeImage);
-            return this;
-        }
-
-        /**
-         * Sets the list style hint
-         *
-         * <p>Valid only if the type of this complication data is {@link #EXP_TYPE_LIST}. Otherwise
-         * returns
-         * zero.
-         */
-        @NonNull
-        public Builder setListStyleHint(int listStyleHint) {
-            putIntField(EXP_FIELD_LIST_STYLE_HINT, listStyleHint);
-            return this;
-        }
-
-        /**
-         * Sets the <i>tap action</i> field. This is optional for any non-empty type.
-         *
-         * <p>The provided {@link PendingIntent} may be fired if the complication is tapped on. Note
-         * that some complications might not be tappable, in which case this field will be ignored.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setTapAction(@Nullable PendingIntent pendingIntent) {
-            putOrRemoveField(FIELD_TAP_ACTION, pendingIntent);
-            return this;
-        }
-
-        /**
-         * Sets the <i>content description</i> field for accessibility. This is optional for any
-         * non-empty type. It is recommended to provide a content description whenever the
-         * data includes an image.
-         *
-         * <p>The provided text will be read aloud by a Text-to-speech converter for users who may
-         * be vision-impaired. It will be read aloud in addition to any long, short, or range text
-         * in the complication.
-         *
-         * <p>If using to describe an image/icon that is purely stylistic and doesn't convey any
-         * information to the user, you may set the image content description to an empty string
-         * ("").
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setContentDescription(@Nullable ComplicationText description) {
-            putOrRemoveField(FIELD_CONTENT_DESCRIPTION, description);
-            return this;
-        }
-
-        /**
-         * Sets whether or not this ComplicationData has been serialized.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setTapActionLostDueToSerialization(boolean tapActionLostDueToSerialization) {
-            if (tapActionLostDueToSerialization) {
-                mFields.putBoolean(FIELD_TAP_ACTION_LOST, tapActionLostDueToSerialization);
-            }
-            return this;
-        }
-
-        /**
-         * Sets the placeholder.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @SuppressLint("SyntheticAccessor")
-        @NonNull
-        public Builder setPlaceholder(@Nullable ComplicationData placeholder) {
-            if (placeholder == null) {
-                mFields.remove(FIELD_PLACEHOLDER_FIELDS);
-                mFields.remove(FIELD_PLACEHOLDER_TYPE);
-            } else {
-                ComplicationData.checkFieldValidForType(FIELD_PLACEHOLDER_FIELDS, mType);
-                mFields.putBundle(FIELD_PLACEHOLDER_FIELDS, placeholder.mFields);
-                putIntField(FIELD_PLACEHOLDER_TYPE, placeholder.mType);
-            }
-            return this;
-        }
-
-        /**
-         * Sets the {@link ComponentName} of the ComplicationDataSourceService that provided this
-         * ComplicationData. Generally this field should be set and is only nullable for backwards
-         * compatibility.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setDataSource(@Nullable ComponentName provider) {
-            putOrRemoveField(FIELD_DATA_SOURCE, provider);
-            return this;
-        }
-
-        /**
-         * Sets the ambient proto layout associated with this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setAmbientLayout(@NonNull byte[] ambientProtoLayout) {
-            putByteArrayField(EXP_FIELD_PROTO_LAYOUT_AMBIENT, ambientProtoLayout);
-            return this;
-        }
-
-        /**
-         * Sets the proto layout associated with this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setInteractiveLayout(@NonNull byte[] protoLayout) {
-            putByteArrayField(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, protoLayout);
-            return this;
-        }
-
-        /**
-         * Sets the proto layout resources associated with this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setLayoutResources(@NonNull byte[] resources) {
-            putByteArrayField(EXP_FIELD_PROTO_LAYOUT_RESOURCES, resources);
-            return this;
-        }
-
-        /**
-         * Optional. Sets the color the color ramp should be drawn with.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setColorRamp(@Nullable int[] colorRamp) {
-            putOrRemoveField(FIELD_COLOR_RAMP, colorRamp);
-            return this;
-        }
-
-        /**
-         * Optional. Sets whether or not the color ramp should be smootly shaded or drawn with
-         * steps.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setColorRampIsSmoothShaded(@Nullable Boolean isSmoothShaded) {
-            putOrRemoveField(FIELD_COLOR_RAMP_INTERPOLATED, isSmoothShaded);
-            return this;
-        }
-
-        /**
-         * Sets the list of {@link ComplicationData} timeline entries.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setListEntryCollection(
-                @Nullable Collection<ComplicationData> timelineEntries) {
-            if (timelineEntries == null) {
-                mFields.remove(EXP_FIELD_LIST_ENTRIES);
-            } else {
-                mFields.putParcelableArray(
-                        EXP_FIELD_LIST_ENTRIES,
-                        timelineEntries.stream()
-                                .map(
-                                        e -> {
-                                            e.mFields.putInt(EXP_FIELD_LIST_ENTRY_TYPE, e.mType);
-                                            return e.mFields;
-                                        })
-                                .toArray(Parcelable[]::new));
-            }
-            return this;
-        }
-
-        /**
-         * Sets the element weights for this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setElementWeights(@Nullable float[] elementWeights) {
-            putOrRemoveField(FIELD_ELEMENT_WEIGHTS, elementWeights);
-            return this;
-        }
-
-        /**
-         * Sets the element colors for this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setElementColors(@Nullable int[] elementColors) {
-            putOrRemoveField(FIELD_ELEMENT_COLORS, elementColors);
-            return this;
-        }
-
-        /**
-         * Sets the background color to use between elements for this complication.
-         *
-         * <p>Returns this Builder to allow chaining.
-         */
-        @NonNull
-        public Builder setElementBackgroundColor(@ColorInt int elementBackgroundColor) {
-            putOrRemoveField(FIELD_ELEMENT_BACKGROUND_COLOR, elementBackgroundColor);
-            return this;
-        }
-
-        /**
-         * Constructs and returns {@link ComplicationData} with the provided fields. All required
-         * fields must be populated before this method is called.
-         *
-         * @throws IllegalStateException if the required fields have not been populated
-         */
-        @NonNull
-        @SuppressLint("SyntheticAccessor")
-        public ComplicationData build() {
-            // Validate.
-            for (String requiredField : Objects.requireNonNull(REQUIRED_FIELDS.get(mType))) {
-                if (!mFields.containsKey(requiredField)) {
-                    throw new IllegalStateException(
-                            "Field " + requiredField + " is required for type " + mType);
-                }
-
-                if (mFields.containsKey(FIELD_ICON_BURN_IN_PROTECTION)
-                        && !mFields.containsKey(FIELD_ICON)) {
-                    throw new IllegalStateException(
-                            "Field ICON must be provided when field ICON_BURN_IN_PROTECTION is"
-                                    + " provided.");
-                }
-
-                if (mFields.containsKey(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION)
-                        && !mFields.containsKey(FIELD_SMALL_IMAGE)) {
-                    throw new IllegalStateException(
-                            "Field SMALL_IMAGE must be provided when field"
-                                    + " SMALL_IMAGE_BURN_IN_PROTECTION is provided.");
-                }
-            }
-
-            return new ComplicationData(this);
-        }
-
-        @SuppressLint("SyntheticAccessor")
-        private void putIntField(@NonNull String field, int value) {
-            ComplicationData.checkFieldValidForType(field, mType);
-            mFields.putInt(field, value);
-        }
-
-        @SuppressLint("SyntheticAccessor")
-        private void putFloatField(@NonNull String field, float value) {
-            ComplicationData.checkFieldValidForType(field, mType);
-            mFields.putFloat(field, value);
-        }
-
-        @SuppressLint("SyntheticAccessor")
-        private void putByteArrayField(@NonNull String field, @NonNull byte[] value) {
-            ComplicationData.checkFieldValidForType(field, mType);
-            mFields.putByteArray(field, value);
-        }
-
-        /** Sets the field with obj or removes it if null. */
-        @SuppressLint("SyntheticAccessor")
-        private void putOrRemoveField(@NonNull String field, @Nullable Object obj) {
-            ComplicationData.checkFieldValidForType(field, mType);
-            if (obj == null) {
-                mFields.remove(field);
-                return;
-            }
-            if (obj instanceof Boolean) {
-                mFields.putBoolean(field, (Boolean) obj);
-            } else if (obj instanceof Integer) {
-                mFields.putInt(field, (Integer) obj);
-            } else if (obj instanceof String) {
-                mFields.putString(field, (String) obj);
-            } else if (obj instanceof Parcelable) {
-                mFields.putParcelable(field, (Parcelable) obj);
-            } else if (obj instanceof int[]) {
-                mFields.putIntArray(field, (int[]) obj);
-            } else if (obj instanceof float[]) {
-                mFields.putFloatArray(field, (float[]) obj);
-            } else {
-                throw new IllegalArgumentException("Unexpected object type: " + obj.getClass());
-            }
-        }
-    }
-
-    /** Returns whether or not we should redact complication data in toString(). */
-    public static boolean shouldRedact() {
-        return !Log.isLoggable(TAG, Log.DEBUG);
-    }
-
-    @NonNull
-    static String maybeRedact(@Nullable CharSequence unredacted) {
-        if (unredacted == null) {
-            return "(null)";
-        }
-        return maybeRedact(unredacted.toString());
-    }
-
-    @NonNull
-    static String maybeRedact(@NonNull String unredacted) {
-        if (!shouldRedact() || unredacted.equals(PLACEHOLDER_STRING)) {
-            return unredacted;
-        }
-        return "REDACTED";
-    }
-}
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
new file mode 100644
index 0000000..02dc741
--- /dev/null
+++ b/wear/watchface/watchface-complications-data/src/main/java/android/support/wearable/complications/ComplicationData.kt
@@ -0,0 +1,2235 @@
+/*
+ * 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 android.support.wearable.complications
+
+import android.annotation.SuppressLint
+import android.app.PendingIntent
+import android.content.ComponentName
+import android.graphics.drawable.Icon
+import android.os.BadParcelableException
+import android.os.Build
+import android.os.Bundle
+import android.os.Parcel
+import android.os.Parcelable
+import android.util.Log
+import androidx.annotation.ColorInt
+import androidx.annotation.IntDef
+import androidx.annotation.RequiresApi
+import androidx.annotation.RestrictTo
+import androidx.wear.watchface.complications.data.ComplicationDisplayPolicies
+import androidx.wear.watchface.complications.data.ComplicationDisplayPolicy
+import androidx.wear.watchface.complications.data.ComplicationPersistencePolicies
+import androidx.wear.watchface.complications.data.ComplicationPersistencePolicy
+import java.io.IOException
+import java.io.InvalidObjectException
+import java.io.ObjectInputStream
+import java.io.ObjectOutputStream
+import java.io.Serializable
+
+/**
+ * Container for complication data of all types.
+ *
+ * A [androidx.wear.watchface.complications.ComplicationProviderService] should create
+ * instances of
+ * this class using [ComplicationData.Builder] and send them to the complication system in
+ * response to
+ * [androidx.wear.watchface.complications.ComplicationProviderService.onComplicationRequest].
+ * Depending on the type of complication data, some fields will be required and some will be
+ * optional - see the documentation for each type, and for the builder's set methods, for details.
+ *
+ * A watch face will receive instances of this class as long as providers are configured.
+ *
+ * When rendering the complication data for a given time, the watch face should first call
+ * [isActiveAt] to determine whether the data is valid at that time. See the documentation for each
+ * of the complication types below for details of which fields are expected to be displayed.
+ *
+ * @hide
+ */
+@SuppressLint("BanParcelableUsage")
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+class ComplicationData : Parcelable, Serializable {
+    /** @hide */
+    @IntDef(
+        TYPE_EMPTY,
+        TYPE_NOT_CONFIGURED,
+        TYPE_SHORT_TEXT,
+        TYPE_LONG_TEXT,
+        TYPE_RANGED_VALUE,
+        TYPE_ICON,
+        TYPE_SMALL_IMAGE,
+        TYPE_LARGE_IMAGE,
+        TYPE_NO_PERMISSION,
+        TYPE_NO_DATA,
+        TYPE_GOAL_PROGRESS,
+        TYPE_WEIGHTED_ELEMENTS,
+        EXP_TYPE_PROTO_LAYOUT,
+        EXP_TYPE_LIST
+    )
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class ComplicationType
+
+    /** @hide */
+    @IntDef(IMAGE_STYLE_PHOTO, IMAGE_STYLE_ICON)
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @Retention(AnnotationRetention.SOURCE)
+    annotation class ImageStyle
+
+    /** Returns the type of this complication data. */
+    @ComplicationType
+    val type: Int
+
+    private val fields: Bundle
+
+    internal constructor(builder: Builder) {
+        type = builder.type
+        fields = builder.fields
+    }
+
+    internal constructor(type: Int, fields: Bundle) {
+        this.type = type
+        this.fields = fields
+        this.fields.classLoader = javaClass.classLoader
+    }
+
+    internal constructor(input: Parcel) {
+        type = input.readInt()
+        fields = input.readBundle(javaClass.classLoader) ?: run {
+            Log.w(TAG, "ComplicationData parcel input has null bundle.")
+            Bundle()
+        }
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.P)
+    private class SerializedForm
+    @JvmOverloads
+    constructor(
+        private var complicationData: ComplicationData? = null
+    ) : Serializable {
+
+        @Throws(IOException::class)
+        private fun writeObject(oos: ObjectOutputStream) {
+            // Get a copy because it could technically change to null in another thread.
+            val complicationData = this.complicationData!!
+            oos.writeInt(VERSION_NUMBER)
+            val type = complicationData.type
+            oos.writeInt(type)
+            oos.writeInt(complicationData.persistencePolicy)
+            oos.writeInt(complicationData.displayPolicy)
+            if (isFieldValidForType(FIELD_LONG_TEXT, type)) {
+                oos.writeObject(complicationData.longText)
+            }
+            if (isFieldValidForType(FIELD_LONG_TITLE, type)) {
+                oos.writeObject(complicationData.longTitle)
+            }
+            if (isFieldValidForType(FIELD_SHORT_TEXT, type)) {
+                oos.writeObject(complicationData.shortText)
+            }
+            if (isFieldValidForType(FIELD_SHORT_TITLE, type)) {
+                oos.writeObject(complicationData.shortTitle)
+            }
+            if (isFieldValidForType(FIELD_CONTENT_DESCRIPTION, type)) {
+                oos.writeObject(complicationData.contentDescription)
+            }
+            if (isFieldValidForType(FIELD_ICON, type)) {
+                oos.writeObject(IconSerializableHelper.create(complicationData.icon))
+            }
+            if (isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, type)) {
+                oos.writeObject(
+                    IconSerializableHelper.create(complicationData.burnInProtectionIcon)
+                )
+            }
+            if (isFieldValidForType(FIELD_SMALL_IMAGE, type)) {
+                oos.writeObject(IconSerializableHelper.create(complicationData.smallImage))
+            }
+            if (isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, type)) {
+                oos.writeObject(
+                    IconSerializableHelper.create(
+                        complicationData.burnInProtectionSmallImage
+                    )
+                )
+            }
+            if (isFieldValidForType(FIELD_IMAGE_STYLE, type)) {
+                oos.writeInt(complicationData.smallImageStyle)
+            }
+            if (isFieldValidForType(FIELD_LARGE_IMAGE, type)) {
+                oos.writeObject(IconSerializableHelper.create(complicationData.largeImage))
+            }
+            if (isFieldValidForType(FIELD_VALUE, type)) {
+                oos.writeFloat(complicationData.rangedValue)
+            }
+            if (isFieldValidForType(FIELD_VALUE_TYPE, type)) {
+                oos.writeInt(complicationData.rangedValueType)
+            }
+            if (isFieldValidForType(FIELD_MIN_VALUE, type)) {
+                oos.writeFloat(complicationData.rangedMinValue)
+            }
+            if (isFieldValidForType(FIELD_MAX_VALUE, type)) {
+                oos.writeFloat(complicationData.rangedMaxValue)
+            }
+            if (isFieldValidForType(FIELD_TARGET_VALUE, type)) {
+                oos.writeFloat(complicationData.targetValue)
+            }
+            if (isFieldValidForType(FIELD_COLOR_RAMP, type)) {
+                val colors = complicationData.colorRamp
+                if (colors != null) {
+                    oos.writeBoolean(true)
+                    oos.writeInt(colors.size)
+                    for (color in colors) {
+                        oos.writeInt(color)
+                    }
+                } else {
+                    oos.writeBoolean(false)
+                }
+            }
+            if (isFieldValidForType(FIELD_COLOR_RAMP_INTERPOLATED, type)) {
+                val isColorRampSmoothShaded = complicationData.isColorRampInterpolated
+                if (isColorRampSmoothShaded != null) {
+                    oos.writeBoolean(true)
+                    oos.writeBoolean(isColorRampSmoothShaded)
+                } else {
+                    oos.writeBoolean(false)
+                }
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_WEIGHTS, type)) {
+                val weights = complicationData.elementWeights
+                if (weights != null) {
+                    oos.writeBoolean(true)
+                    oos.writeInt(weights.size)
+                    for (weight in weights) {
+                        oos.writeFloat(weight)
+                    }
+                } else {
+                    oos.writeBoolean(false)
+                }
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_COLORS, type)) {
+                val colors = complicationData.elementColors
+                if (colors != null) {
+                    oos.writeBoolean(true)
+                    oos.writeInt(colors.size)
+                    for (color in colors) {
+                        oos.writeInt(color)
+                    }
+                } else {
+                    oos.writeBoolean(false)
+                }
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_BACKGROUND_COLOR, type)) {
+                oos.writeInt(complicationData.elementBackgroundColor)
+            }
+            if (isFieldValidForType(FIELD_START_TIME, type)) {
+                oos.writeLong(complicationData.startDateTimeMillis)
+            }
+            if (isFieldValidForType(FIELD_END_TIME, type)) {
+                oos.writeLong(complicationData.endDateTimeMillis)
+            }
+            oos.writeInt(complicationData.fields.getInt(EXP_FIELD_LIST_ENTRY_TYPE))
+            if (isFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, type)) {
+                oos.writeInt(complicationData.listStyleHint)
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, type)) {
+                val bytes = complicationData.interactiveLayout
+                if (bytes == null) {
+                    oos.writeInt(0)
+                } else {
+                    oos.writeInt(bytes.size)
+                    oos.write(bytes)
+                }
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_AMBIENT, type)) {
+                val bytes = complicationData.ambientLayout
+                if (bytes == null) {
+                    oos.writeInt(0)
+                } else {
+                    oos.writeInt(bytes.size)
+                    oos.write(bytes)
+                }
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_RESOURCES, type)) {
+                val bytes = complicationData.layoutResources
+                if (bytes == null) {
+                    oos.writeInt(0)
+                } else {
+                    oos.writeInt(bytes.size)
+                    oos.write(bytes)
+                }
+            }
+            if (isFieldValidForType(FIELD_DATA_SOURCE, type)) {
+                val componentName = complicationData.dataSource
+                if (componentName == null) {
+                    oos.writeUTF("")
+                } else {
+                    oos.writeUTF(componentName.flattenToString())
+                }
+            }
+
+            // TapAction unfortunately can't be serialized, instead we record if we've lost it.
+            oos.writeBoolean(
+                complicationData.hasTapAction() || complicationData.tapActionLostDueToSerialization
+            )
+            val start = complicationData.fields.getLong(FIELD_TIMELINE_START_TIME, -1)
+            oos.writeLong(start)
+            val end = complicationData.fields.getLong(FIELD_TIMELINE_END_TIME, -1)
+            oos.writeLong(end)
+            oos.writeInt(complicationData.fields.getInt(FIELD_TIMELINE_ENTRY_TYPE))
+            val listEntries = complicationData.listEntries
+            val listEntriesLength = listEntries?.size ?: 0
+            oos.writeInt(listEntriesLength)
+            if (listEntries != null) {
+                for (data in listEntries) {
+                    SerializedForm(data).writeObject(oos)
+                }
+            }
+            if (isFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)) {
+                val placeholder = complicationData.placeholder
+                if (placeholder == null) {
+                    oos.writeBoolean(false)
+                } else {
+                    oos.writeBoolean(true)
+                    SerializedForm(placeholder).writeObject(oos)
+                }
+            }
+
+            // This has to be last, since it's recursive.
+            val timeline = complicationData.timelineEntries
+            val timelineLength = timeline?.size ?: 0
+            oos.writeInt(timelineLength)
+            if (timeline != null) {
+                for (data in timeline) {
+                    SerializedForm(data).writeObject(oos)
+                }
+            }
+        }
+
+        @Throws(IOException::class, ClassNotFoundException::class)
+        private fun readObject(ois: ObjectInputStream) {
+            val versionNumber = ois.readInt()
+            if (versionNumber != VERSION_NUMBER) {
+                // Give up if there's a version skew.
+                throw IOException("Unsupported serialization version number $versionNumber")
+            }
+            val type = ois.readInt()
+            val fields = Bundle()
+            fields.putInt(FIELD_PERSISTENCE_POLICY, ois.readInt())
+            fields.putInt(FIELD_DISPLAY_POLICY, ois.readInt())
+            if (isFieldValidForType(FIELD_LONG_TEXT, type)) {
+                putIfNotNull(fields, FIELD_LONG_TEXT, ois.readObject() as ComplicationText?)
+            }
+            if (isFieldValidForType(FIELD_LONG_TITLE, type)) {
+                putIfNotNull(fields, FIELD_LONG_TITLE, ois.readObject() as ComplicationText?)
+            }
+            if (isFieldValidForType(FIELD_SHORT_TEXT, type)) {
+                putIfNotNull(fields, FIELD_SHORT_TEXT, ois.readObject() as ComplicationText?)
+            }
+            if (isFieldValidForType(FIELD_SHORT_TITLE, type)) {
+                putIfNotNull(fields, FIELD_SHORT_TITLE, ois.readObject() as ComplicationText?)
+            }
+            if (isFieldValidForType(FIELD_CONTENT_DESCRIPTION, type)) {
+                putIfNotNull(
+                    fields, FIELD_CONTENT_DESCRIPTION,
+                    ois.readObject() as ComplicationText?
+                )
+            }
+            if (isFieldValidForType(FIELD_ICON, type)) {
+                putIfNotNull(fields, FIELD_ICON, IconSerializableHelper.read(ois))
+            }
+            if (isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, type)) {
+                putIfNotNull(
+                    fields, FIELD_ICON_BURN_IN_PROTECTION,
+                    IconSerializableHelper.read(ois)
+                )
+            }
+            if (isFieldValidForType(FIELD_SMALL_IMAGE, type)) {
+                putIfNotNull(fields, FIELD_SMALL_IMAGE, IconSerializableHelper.read(ois))
+            }
+            if (isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, type)) {
+                putIfNotNull(
+                    fields,
+                    FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, IconSerializableHelper.read(ois)
+                )
+            }
+            if (isFieldValidForType(FIELD_IMAGE_STYLE, type)) {
+                fields.putInt(FIELD_IMAGE_STYLE, ois.readInt())
+            }
+            if (isFieldValidForType(FIELD_LARGE_IMAGE, type)) {
+                fields.putParcelable(FIELD_LARGE_IMAGE, IconSerializableHelper.read(ois))
+            }
+            if (isFieldValidForType(FIELD_VALUE, type)) {
+                fields.putFloat(FIELD_VALUE, ois.readFloat())
+            }
+            if (isFieldValidForType(FIELD_VALUE_TYPE, type)) {
+                fields.putInt(FIELD_VALUE_TYPE, ois.readInt())
+            }
+            if (isFieldValidForType(FIELD_MIN_VALUE, type)) {
+                fields.putFloat(FIELD_MIN_VALUE, ois.readFloat())
+            }
+            if (isFieldValidForType(FIELD_MAX_VALUE, type)) {
+                fields.putFloat(FIELD_MAX_VALUE, ois.readFloat())
+            }
+            if (isFieldValidForType(FIELD_TARGET_VALUE, type)) {
+                fields.putFloat(FIELD_TARGET_VALUE, ois.readFloat())
+            }
+            if (isFieldValidForType(FIELD_COLOR_RAMP, type) && ois.readBoolean()) {
+                val numColors = ois.readInt()
+                val colors = IntArray(numColors)
+                for (i in 0 until numColors) {
+                    colors[i] = ois.readInt()
+                }
+                fields.putIntArray(FIELD_COLOR_RAMP, colors)
+            }
+            if (isFieldValidForType(FIELD_COLOR_RAMP_INTERPOLATED, type) && ois.readBoolean()) {
+                fields.putBoolean(FIELD_COLOR_RAMP_INTERPOLATED, ois.readBoolean())
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_WEIGHTS, type) && ois.readBoolean()) {
+                val numWeights = ois.readInt()
+                val weights = FloatArray(numWeights)
+                for (i in 0 until numWeights) {
+                    weights[i] = ois.readFloat()
+                }
+                fields.putFloatArray(FIELD_ELEMENT_WEIGHTS, weights)
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_COLORS, type) && ois.readBoolean()) {
+                val numColors = ois.readInt()
+                val colors = IntArray(numColors)
+                for (i in 0 until numColors) {
+                    colors[i] = ois.readInt()
+                }
+                fields.putIntArray(FIELD_ELEMENT_COLORS, colors)
+            }
+            if (isFieldValidForType(FIELD_ELEMENT_BACKGROUND_COLOR, type)) {
+                fields.putInt(FIELD_ELEMENT_BACKGROUND_COLOR, ois.readInt())
+            }
+            if (isFieldValidForType(FIELD_START_TIME, type)) {
+                fields.putLong(FIELD_START_TIME, ois.readLong())
+            }
+            if (isFieldValidForType(FIELD_END_TIME, type)) {
+                fields.putLong(FIELD_END_TIME, ois.readLong())
+            }
+            val listEntryType = ois.readInt()
+            if (listEntryType != 0) {
+                fields.putInt(EXP_FIELD_LIST_ENTRY_TYPE, listEntryType)
+            }
+            if (isFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, type)) {
+                fields.putInt(EXP_FIELD_LIST_STYLE_HINT, ois.readInt())
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, type)) {
+                val length = ois.readInt()
+                if (length > 0) {
+                    val protoLayout = ByteArray(length)
+                    ois.readFully(protoLayout)
+                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, protoLayout)
+                }
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_AMBIENT, type)) {
+                val length = ois.readInt()
+                if (length > 0) {
+                    val ambientProtoLayout = ByteArray(length)
+                    ois.readFully(ambientProtoLayout)
+                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_AMBIENT, ambientProtoLayout)
+                }
+            }
+            if (isFieldValidForType(EXP_FIELD_PROTO_LAYOUT_RESOURCES, type)) {
+                val length = ois.readInt()
+                if (length > 0) {
+                    val protoLayoutResources = ByteArray(length)
+                    ois.readFully(protoLayoutResources)
+                    fields.putByteArray(EXP_FIELD_PROTO_LAYOUT_RESOURCES, protoLayoutResources)
+                }
+            }
+            if (isFieldValidForType(FIELD_DATA_SOURCE, type)) {
+                val componentName = ois.readUTF()
+                if (componentName.isEmpty()) {
+                    fields.remove(FIELD_DATA_SOURCE)
+                } else {
+                    fields.putParcelable(
+                        FIELD_DATA_SOURCE, ComponentName.unflattenFromString(componentName)
+                    )
+                }
+            }
+            if (ois.readBoolean()) {
+                fields.putBoolean(FIELD_TAP_ACTION_LOST, true)
+            }
+            val start = ois.readLong()
+            if (start != -1L) {
+                fields.putLong(FIELD_TIMELINE_START_TIME, start)
+            }
+            val end = ois.readLong()
+            if (end != -1L) {
+                fields.putLong(FIELD_TIMELINE_END_TIME, end)
+            }
+            val timelineEntryType = ois.readInt()
+            if (timelineEntryType != 0) {
+                fields.putInt(FIELD_TIMELINE_ENTRY_TYPE, timelineEntryType)
+            }
+            val listEntriesLength = ois.readInt()
+            if (listEntriesLength != 0) {
+                val parcels = arrayOfNulls<Parcelable>(listEntriesLength)
+                for (i in 0 until listEntriesLength) {
+                    val entry = SerializedForm()
+                    entry.readObject(ois)
+                    parcels[i] = entry.complicationData!!.fields
+                }
+                fields.putParcelableArray(EXP_FIELD_LIST_ENTRIES, parcels)
+            }
+            if (isFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)) {
+                if (ois.readBoolean()) {
+                    val serializedPlaceholder = SerializedForm()
+                    serializedPlaceholder.readObject(ois)
+                    fields.putInt(
+                        FIELD_PLACEHOLDER_TYPE,
+                        serializedPlaceholder.complicationData!!.type
+                    )
+                    fields.putBundle(
+                        FIELD_PLACEHOLDER_FIELDS,
+                        serializedPlaceholder.complicationData!!.fields
+                    )
+                }
+            }
+            val timelineLength = ois.readInt()
+            if (timelineLength != 0) {
+                val parcels = arrayOfNulls<Parcelable>(timelineLength)
+                for (i in 0 until timelineLength) {
+                    val entry = SerializedForm()
+                    entry.readObject(ois)
+                    parcels[i] = entry.complicationData!!.fields
+                }
+                fields.putParcelableArray(FIELD_TIMELINE_ENTRIES, parcels)
+            }
+            complicationData = ComplicationData(type, fields)
+        }
+
+        fun readResolve(): Any = complicationData!!
+
+        companion object {
+            private const val VERSION_NUMBER = 19
+            internal fun putIfNotNull(fields: Bundle, field: String, value: Parcelable?) {
+                if (value != null) {
+                    fields.putParcelable(field, value)
+                }
+            }
+        }
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.P)
+    fun writeReplace(): Any = SerializedForm(this)
+
+    @Throws(InvalidObjectException::class)
+    private fun readObject(@Suppress("UNUSED_PARAMETER") stream: ObjectInputStream) {
+        throw InvalidObjectException("Use SerializedForm")
+    }
+
+    override fun describeContents() = 0
+
+    override fun writeToParcel(dest: Parcel, flags: Int) {
+        dest.writeInt(type)
+        dest.writeBundle(fields)
+    }
+
+    /**
+     * Returns true if the complication is active and should be displayed at the given time. If this
+     * returns false, the complication should not be displayed.
+     *
+     * This must be checked for any time for which the complication will be displayed.
+     */
+    fun isActiveAt(dateTimeMillis: Long) =
+        (dateTimeMillis >= fields.getLong(FIELD_START_TIME, 0) &&
+            dateTimeMillis <= fields.getLong(FIELD_END_TIME, Long.MAX_VALUE))
+
+    /**
+     * TapAction unfortunately can't be serialized. Returns true if tapAction has been lost due to
+     * serialization (e.g. due to being read from the local cache). The next complication update
+     * from the system would replace this with one with a tapAction.
+     */
+    val tapActionLostDueToSerialization: Boolean
+        get() = fields.getBoolean(FIELD_TAP_ACTION_LOST)
+
+    /**
+     * For timeline entries. The epoch second at which this timeline entry becomes * valid or `null`
+     * if it's not set.
+     */
+    var timelineStartEpochSecond: Long?
+        get() {
+            val expiresAt = fields.getLong(FIELD_TIMELINE_START_TIME, -1)
+            return if (expiresAt == -1L) {
+                null
+            } else {
+                expiresAt
+            }
+        }
+        set(epochSecond) {
+            if (epochSecond == null) {
+                fields.remove(FIELD_TIMELINE_START_TIME)
+            } else {
+                fields.putLong(FIELD_TIMELINE_START_TIME, epochSecond)
+            }
+        }
+
+    /**
+     * For timeline entries. The epoch second at which this timeline entry becomes invalid or `null`
+     * if it's not set.
+     */
+    var timelineEndEpochSecond: Long?
+        get() {
+            val expiresAt = fields.getLong(FIELD_TIMELINE_END_TIME, -1)
+            return if (expiresAt == -1L) {
+                null
+            } else {
+                expiresAt
+            }
+        }
+        set(epochSecond) {
+            if (epochSecond == null) {
+                fields.remove(FIELD_TIMELINE_END_TIME)
+            } else {
+                fields.putLong(FIELD_TIMELINE_END_TIME, epochSecond)
+            }
+        }
+
+    /** The list of [ComplicationData] timeline entries. */
+    val timelineEntries: List<ComplicationData>?
+        @Suppress("DEPRECATION")
+        get() = fields.getParcelableArray(FIELD_TIMELINE_ENTRIES)
+            ?.map { parcelable ->
+                val bundle = parcelable as Bundle
+                bundle.classLoader = javaClass.classLoader
+                // Use the serialized FIELD_TIMELINE_ENTRY_TYPE or the outer type if it's not there.
+                // Usually the timeline entry type will be the same as the outer type, unless an
+                // entry contains NoDataComplicationData.
+                val type = bundle.getInt(FIELD_TIMELINE_ENTRY_TYPE, type)
+                ComplicationData(type, parcelable)
+            }
+
+    /** Sets the list of [ComplicationData] timeline entries. */
+    fun setTimelineEntryCollection(timelineEntries: Collection<ComplicationData>?) {
+        if (timelineEntries == null) {
+            fields.remove(FIELD_TIMELINE_ENTRIES)
+        } else {
+            fields.putParcelableArray(
+                FIELD_TIMELINE_ENTRIES,
+                timelineEntries.map {
+                    // This supports timeline entry of NoDataComplicationData.
+                    it.fields.putInt(FIELD_TIMELINE_ENTRY_TYPE, it.type)
+                    it.fields
+                }.toTypedArray()
+            )
+        }
+    }
+
+    /** The list of [ComplicationData] entries for a ListComplicationData. */
+    val listEntries: List<ComplicationData>?
+        @Suppress("deprecation")
+        get() = fields.getParcelableArray(EXP_FIELD_LIST_ENTRIES)
+            ?.map { parcelable ->
+                val bundle = parcelable as Bundle
+                bundle.classLoader = javaClass.classLoader
+                ComplicationData(bundle.getInt(EXP_FIELD_LIST_ENTRY_TYPE), bundle)
+            }
+
+    /**
+     * The [ComponentName] of the ComplicationDataSourceService that provided this ComplicationData.
+     */
+    var dataSource: ComponentName?
+        // The safer alternative is not available on Wear OS yet.
+        get() = getParcelableField(FIELD_DATA_SOURCE)
+        set(provider) {
+            fields.putParcelable(FIELD_DATA_SOURCE, provider)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a ranged max value. I.e. if [rangedValue] can
+     * succeed.
+     */
+    fun hasRangedValue(): Boolean = isFieldValidForType(FIELD_VALUE, type)
+
+    /**
+     * Returns the *value* field for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE], otherwise returns
+     * zero.
+     */
+    val rangedValue: Float
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_VALUE, type)
+            return fields.getFloat(FIELD_VALUE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a ranged max type. I.e. if [rangedValueType]
+     * can succeed.
+     */
+    fun hasRangedValueType(): Boolean = isFieldValidForType(FIELD_VALUE_TYPE, type)
+
+    /**
+     * Returns the *value* field for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE], otherwise returns
+     * zero.
+     */
+    val rangedValueType: Int
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_VALUE_TYPE, type)
+            return fields.getInt(FIELD_VALUE_TYPE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a ranged max value. I.e. if [rangedMinValue]
+     * can succeed.
+     */
+    fun hasRangedMinValue(): Boolean = isFieldValidForType(FIELD_MIN_VALUE, type)
+
+    /**
+     * Returns the *min value* field for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE], otherwise returns
+     * zero.
+     */
+    val rangedMinValue: Float
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_MIN_VALUE, type)
+            return fields.getFloat(FIELD_MIN_VALUE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a ranged max value. I.e. if [rangedMaxValue]
+     * can succeed.
+     */
+    fun hasRangedMaxValue(): Boolean = isFieldValidForType(FIELD_MAX_VALUE, type)
+
+    /**
+     * Returns the *max value* field for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE], otherwise returns
+     * zero.
+     */
+    val rangedMaxValue: Float
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_MAX_VALUE, type)
+            return fields.getFloat(FIELD_MAX_VALUE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a ranged max value. I.e. if [targetValue] can
+     * succeed.
+     */
+    fun hasTargetValue(): Boolean = isFieldValidForType(FIELD_TARGET_VALUE, type)
+
+    /**
+     * Returns the *value* field for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_GOAL_PROGRESS], otherwise returns
+     * zero.
+     */
+    val targetValue: Float
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_TARGET_VALUE, type)
+            return fields.getFloat(FIELD_TARGET_VALUE)
+        }
+
+    /**
+     * Returns the colors for the progress bar.
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE] or
+     * [TYPE_GOAL_PROGRESS].
+     */
+    @get:ColorInt
+    val colorRamp: IntArray?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_COLOR_RAMP, type)
+            return if (fields.containsKey(FIELD_COLOR_RAMP)) {
+                fields.getIntArray(FIELD_COLOR_RAMP)
+            } else {
+                null
+            }
+        }
+
+    /**
+     * Returns either a boolean where: true means the color ramp colors should be smoothly
+     * interpolated; false means the color ramp should be rendered in equal sized blocks of
+     * solid color; null means this value wasn't set, i.e. the complication is not of type
+     * [TYPE_RANGED_VALUE] or [TYPE_GOAL_PROGRESS].
+     *
+     * Valid only if the type of this complication data is [TYPE_RANGED_VALUE] or
+     * [TYPE_GOAL_PROGRESS].
+     */
+    val isColorRampInterpolated: Boolean?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_COLOR_RAMP_INTERPOLATED, type)
+            return if (fields.containsKey(FIELD_COLOR_RAMP_INTERPOLATED)) {
+                fields.getBoolean(FIELD_COLOR_RAMP_INTERPOLATED)
+            } else {
+                null
+            }
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a short title. I.e. if [shortTitle]
+     * can succeed.
+     */
+    fun hasShortTitle(): Boolean =
+        isFieldValidForType(FIELD_SHORT_TITLE, type) && hasParcelableField(FIELD_SHORT_TITLE)
+
+    /**
+     * Returns the *short title* field for this complication, or `null` if no value was
+     * provided for the field.
+     *
+     * The value is provided as a [ComplicationText] object, from which the text to display
+     * can be obtained for a given point in time.
+     *
+     * The length of the text, including any time-dependent values at any valid time, is expected
+     * to not exceed seven characters. When using this text, the watch face should be able to
+     * display any string of up to seven characters (reducing the text size appropriately if the
+     * string is very wide). Although not expected, it is possible that strings of more than seven
+     * characters might be seen, in which case they may be truncated.
+     *
+     * Valid only if the type of this complication data is [TYPE_SHORT_TEXT], [TYPE_RANGED_VALUE],
+     * or [TYPE_NO_PERMISSION], otherwise returns null.
+     */
+    val shortTitle: ComplicationText?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_SHORT_TITLE, type)
+            return getParcelableFieldOrWarn<ComplicationText>(FIELD_SHORT_TITLE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains short text. I.e. if [shortText] can succeed.
+     */
+    fun hasShortText(): Boolean =
+        isFieldValidForType(FIELD_SHORT_TEXT, type) && hasParcelableField(FIELD_SHORT_TEXT)
+
+    /**
+     * Returns the *short text* field for this complication, or `null` if no value was
+     * provided for the field.
+     *
+     * The value is provided as a [ComplicationText] object, from which the text to display
+     * can be obtained for a given point in time.
+     *
+     * The length of the text, including any time-dependent values at any valid time, is expected
+     * to not exceed seven characters. When using this text, the watch face should be able to
+     * display any string of up to seven characters (reducing the text size appropriately if the
+     * string is very wide). Although not expected, it is possible that strings of more than seven
+     * characters might be seen, in which case they may be truncated.
+     *
+     * Valid only if the type of this complication data is [TYPE_SHORT_TEXT], [TYPE_RANGED_VALUE],
+     * or [TYPE_NO_PERMISSION], otherwise returns null.
+     */
+    val shortText: ComplicationText?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_SHORT_TEXT, type)
+            return getParcelableFieldOrWarn<ComplicationText>(FIELD_SHORT_TEXT)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a long title. I.e. if [longTitle]
+     * can succeed.
+     */
+    fun hasLongTitle(): Boolean =
+        isFieldValidForType(FIELD_LONG_TITLE, type) && hasParcelableField(FIELD_LONG_TITLE)
+
+    /**
+     * Returns the *long title* field for this complication, or `null` if no value was
+     * provided for the field.
+     *
+     * The value is provided as a [ComplicationText] object, from which the text to display
+     * can be obtained for a given point in time.
+     *
+     * Valid only if the type of this complication data is [TYPE_LONG_TEXT], otherwise returns null.
+     */
+    val longTitle: ComplicationText?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_LONG_TITLE, type)
+            return getParcelableFieldOrWarn<ComplicationText>(FIELD_LONG_TITLE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains long text. I.e. if [longText] can
+     * succeed.
+     */
+    fun hasLongText(): Boolean =
+        isFieldValidForType(FIELD_LONG_TEXT, type) && hasParcelableField(FIELD_LONG_TEXT)
+
+    /**
+     * Returns the *long text* field for this complication.
+     *
+     * The value is provided as a [ComplicationText] object, from which the text to display
+     * can be obtained for a given point in time.
+     *
+     * Valid only if the type of this complication data is [TYPE_LONG_TEXT], otherwise returns null.
+     */
+    val longText: ComplicationText?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_LONG_TEXT, type)
+            return getParcelableFieldOrWarn<ComplicationText>(FIELD_LONG_TEXT)
+        }
+
+    /** Returns true if the ComplicationData contains an Icon. I.e. if [icon] can succeed. */
+    fun hasIcon(): Boolean =
+        isFieldValidForType(FIELD_ICON, type) && hasParcelableField(FIELD_ICON)
+
+    /**
+     * Returns the *icon* field for this complication, or `null` if no value was provided
+     * for the field. The image returned is expected to be single-color and so may be tinted to
+     * whatever color the watch face requires (but note that
+     * [android.graphics.drawable.Drawable.mutate] should be called before drawables are tinted).
+     *
+     * If the device is in ambient mode, and utilises burn-in protection, then the result of
+     * [burnInProtectionIcon] must be used instead of this.
+     *
+     * Valid for the types [TYPE_SHORT_TEXT], [TYPE_LONG_TEXT], [TYPE_RANGED_VALUE], [TYPE_ICON], or
+     * [TYPE_NO_PERMISSION], otherwise returns null.
+     */
+    val icon: Icon?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_ICON, type)
+            return getParcelableFieldOrWarn<Icon>(FIELD_ICON)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a burn in protection Icon. I.e. if
+     * [burnInProtectionIcon] can succeed.
+     */
+    fun hasBurnInProtectionIcon(): Boolean =
+        isFieldValidForType(FIELD_ICON_BURN_IN_PROTECTION, type) &&
+            hasParcelableField(FIELD_ICON_BURN_IN_PROTECTION)
+
+    /**
+     * Returns the burn-in protection version of the *icon* field for this complication, or
+     * `null` if no such icon was provided. The image returned is expected to be an outline
+     * image suitable for use in ambient mode on screens with burn-in protection. The image is also
+     * expected to be single-color and so may be tinted to whatever color the watch face requires
+     * (but note that [android.graphics.drawable.Drawable.mutate] should be called before drawables
+     * are tinted, and that the color used should be suitable for ambient mode with burn-in
+     * protection).
+     *
+     * If the device is in ambient mode, and utilises burn-in protection, then the result of this
+     * method must be used instead of the result of [icon].
+     *
+     * Valid for the types [TYPE_SHORT_TEXT], [TYPE_LONG_TEXT], [TYPE_RANGED_VALUE], [TYPE_ICON], or
+     * [TYPE_NO_PERMISSION], otherwise returns null.
+     */
+    val burnInProtectionIcon: Icon?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_ICON_BURN_IN_PROTECTION, type)
+            return getParcelableFieldOrWarn<Icon>(FIELD_ICON_BURN_IN_PROTECTION)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a small image. I.e. if [smallImage]
+     * can succeed.
+     */
+    fun hasSmallImage(): Boolean =
+        isFieldValidForType(FIELD_SMALL_IMAGE, type) && hasParcelableField(FIELD_SMALL_IMAGE)
+
+    /**
+     * Returns the *small image* field for this complication, or `null` if no value was
+     * provided for the field.
+     *
+     * This may be either a [IMAGE_STYLE_PHOTO] image, which is expected to
+     * fill the space available, or an [IMAGE_STYLE_ICON] image, which should be
+     * drawn entirely within the space available. Use [smallImageStyle] to determine which
+     * of these applies.
+     *
+     * As this may be any image, it is unlikely to be suitable for display in ambient mode when
+     * burn-in protection is enabled, or in low-bit ambient mode, and should not be rendered under
+     * these circumstances.
+     *
+     * Valid for the types [TYPE_LONG_TEXT] and [TYPE_SMALL_IMAGE].
+     * Otherwise returns null.
+     */
+    val smallImage: Icon?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_SMALL_IMAGE, type)
+            return getParcelableFieldOrWarn<Icon>(FIELD_SMALL_IMAGE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a burn in protection small image. I.e. if
+     * [burnInProtectionSmallImage] can succeed.
+     *
+     * @throws IllegalStateException for invalid types
+     */
+    fun hasBurnInProtectionSmallImage(): Boolean =
+        isFieldValidForType(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, type) &&
+            hasParcelableField(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION)
+
+    /**
+     * Returns the burn-in protection version of the *small image* field for this complication,
+     * or `null` if no such icon was provided. The image returned is expected to be an outline
+     * image suitable for use in ambient mode on screens with burn-in protection. The image is also
+     * expected to be single-color and so may be tinted to whatever color the watch face requires
+     * (but note that [android.graphics.drawable.Drawable.mutate] should be called before drawables
+     * are tinted, and that the color used should be suitable for ambient mode with burn-in
+     * protection).
+     *
+     * If the device is in ambient mode, and utilises burn-in protection, then the result of this
+     * method must be used instead of the result of [smallImage].
+     *
+     * Valid for the types [TYPE_LONG_TEXT] and [TYPE_SMALL_IMAGE].
+     * Otherwise returns null.
+     */
+    val burnInProtectionSmallImage: Icon?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                type
+            )
+            return getParcelableFieldOrWarn<Icon>(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION)
+        }
+
+    /**
+     * Returns the *small image style* field for this complication.
+     *
+     * The result of this method should be taken in to account when drawing a small image
+     * complication.
+     *
+     * Valid only for types that contain small images, i.e. [TYPE_SMALL_IMAGE] and [TYPE_LONG_TEXT].
+     * Otherwise returns zero.
+     *
+     * @see IMAGE_STYLE_PHOTO which can be cropped but not recolored.
+     * @see IMAGE_STYLE_ICON which can be recolored but not cropped.
+     */
+    @ImageStyle
+    val smallImageStyle: Int
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_IMAGE_STYLE, type)
+            return fields.getInt(FIELD_IMAGE_STYLE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a large image. I.e. if [largeImage]
+     * can succeed.
+     */
+    fun hasLargeImage(): Boolean =
+        isFieldValidForType(FIELD_LARGE_IMAGE, type) && hasParcelableField(FIELD_LARGE_IMAGE)
+
+    /**
+     * Returns the *large image* field for this complication. This image is expected to be of a
+     * suitable size to fill the screen of the watch.
+     *
+     * As this may be any image, it is unlikely to be suitable for display in ambient mode when
+     * burn-in protection is enabled, or in low-bit ambient mode, and should not be rendered under
+     * these circumstances.
+     *
+     * Valid only if the type of this complication data is [TYPE_LARGE_IMAGE].
+     * Otherwise returns null.
+     */
+    val largeImage: Icon?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_LARGE_IMAGE, type)
+            return getParcelableFieldOrWarn<Icon>(FIELD_LARGE_IMAGE)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a tap action. I.e. if [tapAction]
+     * can succeed.
+     */
+    fun hasTapAction(): Boolean =
+        isFieldValidForType(FIELD_TAP_ACTION, type) && hasParcelableField(FIELD_TAP_ACTION)
+
+    /**
+     * Returns the *tap action* field for this complication. The result is a [PendingIntent] that
+     * should be fired if the complication is tapped on, assuming the complication is tappable, or
+     * `null` if no tap action has been specified.
+     *
+     * Valid for all non-empty types, otherwise returns null.
+     */
+    val tapAction: PendingIntent?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_TAP_ACTION, type)
+            return getParcelableFieldOrWarn<PendingIntent>(FIELD_TAP_ACTION)
+        }
+
+    /**
+     * Returns true if the ComplicationData contains a content description. I.e. if
+     * [contentDescription] can succeed.
+     */
+    fun hasContentDescription(): Boolean =
+        isFieldValidForType(FIELD_CONTENT_DESCRIPTION, type) &&
+            hasParcelableField(FIELD_CONTENT_DESCRIPTION)
+
+    /**
+     * Returns the *content description * field for this complication, for screen readers. This
+     * usually describes the image, but may also describe the overall complication.
+     *
+     * Valid for all non-empty types.
+     */
+    val contentDescription: ComplicationText?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_CONTENT_DESCRIPTION, type)
+            return getParcelableFieldOrWarn<ComplicationText>(FIELD_CONTENT_DESCRIPTION)
+        }
+
+    /**
+     * Returns the element weights for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_WEIGHTED_ELEMENTS].
+     * Otherwise returns null.
+     */
+    val elementWeights: FloatArray?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_WEIGHTS, type)
+            return fields.getFloatArray(FIELD_ELEMENT_WEIGHTS)
+        }
+
+    /**
+     * Returns the element colors for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_WEIGHTED_ELEMENTS].
+     * Otherwise returns null.
+     */
+    val elementColors: IntArray?
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_COLORS, type)
+            return fields.getIntArray(FIELD_ELEMENT_COLORS)
+        }
+
+    /**
+     * Returns the background color to use between elements for this complication.
+     *
+     * Valid only if the type of this complication data is [TYPE_WEIGHTED_ELEMENTS].
+     * Otherwise returns 0.
+     */
+    @get:ColorInt
+    val elementBackgroundColor: Int
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_ELEMENT_BACKGROUND_COLOR, type)
+            return fields.getInt(FIELD_ELEMENT_BACKGROUND_COLOR)
+        }
+
+    /** Returns the placeholder ComplicationData if there is one or `null`. */
+    val placeholder: ComplicationData?
+        get() {
+            checkFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)
+            checkFieldValidForType(FIELD_PLACEHOLDER_TYPE, type)
+            return if (
+                !fields.containsKey(FIELD_PLACEHOLDER_FIELDS) ||
+                !fields.containsKey(FIELD_PLACEHOLDER_TYPE)
+            ) {
+                null
+            } else ComplicationData(
+                fields.getInt(FIELD_PLACEHOLDER_TYPE),
+                fields.getBundle(FIELD_PLACEHOLDER_FIELDS)!!
+            )
+        }
+
+    /** Returns the bytes of the proto layout. */
+    val interactiveLayout: ByteArray?
+        get() = fields.getByteArray(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE)
+
+    /**
+     * Returns the list style hint.
+     *
+     * Valid only if the type of this complication data is [EXP_TYPE_LIST]. Otherwise
+     * returns zero.
+     */
+    val listStyleHint: Int
+        get() {
+            checkFieldValidForType(EXP_FIELD_LIST_STYLE_HINT, type)
+            return fields.getInt(EXP_FIELD_LIST_STYLE_HINT)
+        }
+
+    /** Returns the bytes of the ambient proto layout. */
+    val ambientLayout: ByteArray?
+        get() = fields.getByteArray(EXP_FIELD_PROTO_LAYOUT_AMBIENT)
+
+    /** Returns the bytes of the proto layout resources. */
+    val layoutResources: ByteArray?
+        get() = fields.getByteArray(EXP_FIELD_PROTO_LAYOUT_RESOURCES)
+
+    /** Return's the complication's [ComplicationPersistencePolicies]. */
+    @ComplicationPersistencePolicy
+    val persistencePolicy: Int
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_PERSISTENCE_POLICY, type)
+            return fields.getInt(
+                FIELD_PERSISTENCE_POLICY, ComplicationPersistencePolicies.CACHING_ALLOWED
+            )
+        }
+
+    /** Return's the complication's [ComplicationDisplayPolicy]. */
+    @ComplicationDisplayPolicy
+    val displayPolicy: Int
+        get() {
+            checkFieldValidForTypeWithoutThrowingException(FIELD_DISPLAY_POLICY, type)
+            return fields.getInt(FIELD_DISPLAY_POLICY, ComplicationDisplayPolicies.ALWAYS_DISPLAY)
+        }
+
+    /**
+     * Returns the start time for this complication data (i.e. the first time at which it should
+     * be considered active and displayed), this may be 0. See also [isActiveAt].
+     */
+    val startDateTimeMillis: Long
+        get() = fields.getLong(FIELD_START_TIME, 0)
+
+    /**
+     * Returns the end time for this complication data (i.e. the last time at which it should be
+     * considered active and displayed), this may be [Long.MAX_VALUE]. See also [isActiveAt].
+     */
+    val endDateTimeMillis: Long
+        get() = fields.getLong(FIELD_END_TIME, Long.MAX_VALUE)
+
+    /**
+     * Returns true if the complication data contains at least one text field with a value that may
+     * change based on the current time.
+     */
+    val isTimeDependent: Boolean
+        get() = isTimeDependentField(FIELD_SHORT_TEXT) ||
+            isTimeDependentField(FIELD_SHORT_TITLE) ||
+            isTimeDependentField(FIELD_LONG_TEXT) ||
+            isTimeDependentField(FIELD_LONG_TITLE)
+
+    private fun isTimeDependentField(field: String): Boolean {
+        val text = getParcelableFieldOrWarn<ComplicationText>(field)
+        return text != null && text.isTimeDependent
+    }
+
+    private fun <T : Parcelable?> getParcelableField(field: String): T? =
+        try {
+            @Suppress("deprecation")
+            fields.getParcelable<T>(field)
+        } catch (e: BadParcelableException) {
+            null
+        }
+
+    private fun hasParcelableField(field: String) = getParcelableField<Parcelable>(field) != null
+
+    private fun <T : Parcelable?> getParcelableFieldOrWarn(field: String): T? =
+        try {
+            @Suppress("deprecation")
+            fields.getParcelable<T>(field)
+        } catch (e: BadParcelableException) {
+            Log.w(
+                TAG,
+                "Could not unparcel ComplicationData. Provider apps must exclude wearable " +
+                    "support complication classes from proguard.",
+                e
+            )
+            null
+        }
+
+    override fun toString() =
+        if (shouldRedact()) {
+            "ComplicationData{mType=$type, mFields=REDACTED}"
+        } else {
+            toStringNoRedaction()
+        }
+
+    /** @hide
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun toStringNoRedaction() = "ComplicationData{mType=$type, mFields=$fields}"
+
+    /** Builder class for [ComplicationData]. */
+    class Builder {
+        @ComplicationType
+        internal val type: Int
+
+        internal val fields: Bundle
+
+        /** Creates a builder from given [ComplicationData], copying its type and data. */
+        constructor(data: ComplicationData) {
+            type = data.type
+            fields = data.fields.clone() as Bundle
+        }
+
+        constructor(@ComplicationType type: Int) {
+            this.type = type
+            fields = Bundle()
+            if (type == TYPE_SMALL_IMAGE || type == TYPE_LONG_TEXT) {
+                setSmallImageStyle(IMAGE_STYLE_PHOTO)
+            }
+        }
+
+        /** Sets the complication's [ComplicationPersistencePolicy]. */
+        fun setPersistencePolicy(@ComplicationPersistencePolicy cachePolicy: Int) =
+            apply { fields.putInt(FIELD_PERSISTENCE_POLICY, cachePolicy) }
+
+        /** Sets the complication's [ComplicationDisplayPolicy]. */
+        fun setDisplayPolicy(@ComplicationDisplayPolicy displayPolicy: Int) =
+            apply { fields.putInt(FIELD_DISPLAY_POLICY, displayPolicy) }
+
+        /**
+         * Sets the start time for this complication data. This is optional for any type.
+         *
+         * The complication data will be considered inactive (i.e. should not be displayed) if
+         * the current time is less than the start time. If not specified, the data is considered
+         * active for all time up to the end time (or always active if end time is also not
+         * specified).
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setStartDateTimeMillis(startDateTimeMillis: Long) =
+            apply { fields.putLong(FIELD_START_TIME, startDateTimeMillis) }
+
+        /**
+         * Removes the start time for this complication data.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun clearStartDateTime() = apply { fields.remove(FIELD_START_TIME) }
+
+        /**
+         * Sets the end time for this complication data. This is optional for any type.
+         *
+         * The complication data will be considered inactive (i.e. should not be displayed) if
+         * the current time is greater than the end time. If not specified, the data is considered
+         * active for all time after the start time (or always active if start time is also not
+         * specified).
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setEndDateTimeMillis(endDateTimeMillis: Long) =
+            apply { fields.putLong(FIELD_END_TIME, endDateTimeMillis) }
+
+        /**
+         * Removes the end time for this complication data.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun clearEndDateTime() = apply { fields.remove(FIELD_END_TIME) }
+
+        /**
+         * Sets the *value* field. This is required for the [TYPE_RANGED_VALUE] type,
+         * and the [TYPE_GOAL_PROGRESS] type. For [TYPE_RANGED_VALUE] value must
+         * be in the range [min .. max] for [TYPE_GOAL_PROGRESS] value must be >= and may
+         * be greater than target value.
+         *
+         * Both the [TYPE_RANGED_VALUE] complication and the
+         * [TYPE_GOAL_PROGRESS] complication visually present a single value, which is
+         * usually a percentage. E.g. you have completed 70% of today's  target of 10000 steps.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setRangedValue(value: Float) = apply { putFloatField(FIELD_VALUE, value) }
+
+        /**
+         * Sets the *value type* field which provides meta data about the value. This is
+         * optional for the [TYPE_RANGED_VALUE] type.
+         */
+        fun setRangedValueType(valueType: Int) = apply { putIntField(FIELD_VALUE_TYPE, valueType) }
+
+        /**
+         * Sets the *min value* field. This is required for the [TYPE_RANGED_VALUE]
+         * type, and is not valid for any other type. A [TYPE_RANGED_VALUE] complication
+         * visually presents a single value, which is usually a percentage. E.g. you have
+         * completed 70% of today's target of 10000 steps.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setRangedMinValue(minValue: Float) = apply { putFloatField(FIELD_MIN_VALUE, minValue) }
+
+        /**
+         * Sets the *max value* field. This is required for the [TYPE_RANGED_VALUE]
+         * type, and is not valid for any other type. A [TYPE_RANGED_VALUE] complication
+         * visually presents a single value, which is usually a percentage. E.g. you have
+         * completed 70% of today's target of 10000 steps.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setRangedMaxValue(maxValue: Float) = apply { putFloatField(FIELD_MAX_VALUE, maxValue) }
+
+        /**
+         * Sets the *targetValue* field. This is required for the
+         * [TYPE_GOAL_PROGRESS] type, and is not valid for any other type. A
+         * [TYPE_GOAL_PROGRESS] complication visually presents a single value, which
+         * is usually a percentage. E.g. you have completed 70% of today's target of 10000 steps.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setTargetValue(targetValue: Float) =
+            apply { putFloatField(FIELD_TARGET_VALUE, targetValue) }
+
+        /**
+         * Sets the *long title* field. This is optional for the [TYPE_LONG_TEXT] type,
+         * and is not valid for any other type.
+         *
+         * The value must be provided as a [ComplicationText] object, so that
+         * time-dependent values may be included.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setLongTitle(longTitle: ComplicationText?) =
+            apply { putOrRemoveField(FIELD_LONG_TITLE, longTitle) }
+
+        /**
+         * Sets the *long text* field. This is required for the [TYPE_LONG_TEXT] type,
+         * and is not valid for any other type.
+         *
+         * The value must be provided as a [ComplicationText] object, so that
+         * time-dependent values may be included.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setLongText(longText: ComplicationText?) =
+            apply { putOrRemoveField(FIELD_LONG_TEXT, longText) }
+
+        /**
+         * Sets the *short title* field. This is valid for the [TYPE_SHORT_TEXT],
+         * [TYPE_RANGED_VALUE], and [TYPE_NO_PERMISSION] types, and is not valid for any other type.
+         *
+         * The value must be provided as a [ComplicationText] object, so that
+         * time-dependent values may be included.
+         *
+         * The length of the text, including any time-dependent values, should not exceed seven
+         * characters. If it does, the text may be truncated by the watch face or might not fit in
+         * the complication.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setShortTitle(shortTitle: ComplicationText?) =
+            apply { putOrRemoveField(FIELD_SHORT_TITLE, shortTitle) }
+
+        /**
+         * Sets the *short text* field. This is required for the [TYPE_SHORT_TEXT] type,
+         * is optional for the [TYPE_RANGED_VALUE] and [TYPE_NO_PERMISSION] types, and
+         * is not valid for any other type.
+         *
+         * The value must be provided as a [ComplicationText] object, so that
+         * time-dependent values may be included.
+         *
+         * The length of the text, including any time-dependent values, should not exceed seven
+         * characters. If it does, the text may be truncated by the watch face or might not fit in
+         * the complication.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setShortText(shortText: ComplicationText?) =
+            apply { putOrRemoveField(FIELD_SHORT_TEXT, shortText) }
+
+        /**
+         * Sets the *icon* field. This is required for the [TYPE_ICON] type, and is
+         * optional for the [TYPE_SHORT_TEXT], [TYPE_LONG_TEXT], [TYPE_RANGED_VALUE], and
+         * [TYPE_NO_PERMISSION] types.
+         *
+         * The provided image must be single-color, so that watch faces can tint it as required.
+         *
+         * If the icon provided here is not suitable for display in ambient mode with burn-in
+         * protection (e.g. if it includes solid blocks of pixels), then a burn-in safe version of
+         * the icon must be provided via [setBurnInProtectionIcon].
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setIcon(icon: Icon?) = apply { putOrRemoveField(FIELD_ICON, icon) }
+
+        /**
+         * Sets the burn-in protection version of the *icon* field. This should be provided if
+         * the *icon* field is provided, unless the main icon is already safe for use with
+         * burn-in protection.  This icon should have fewer lit pixels, and should use darker
+         * colors to prevent LCD burn in issues.
+         *
+         * The provided image must be single-color, so that watch faces can tint it as required.
+         *
+         * The provided image must not contain solid blocks of pixels - it should instead be
+         * composed of outlines or lines only.
+         *
+         * If this field is set, the *icon* field must also be set.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setBurnInProtectionIcon(icon: Icon?) =
+            apply { putOrRemoveField(FIELD_ICON_BURN_IN_PROTECTION, icon) }
+
+        /**
+         * Sets the *small image* field. This is required for the [TYPE_SMALL_IMAGE]
+         * type, and is optional for the [TYPE_LONG_TEXT] type.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setSmallImage(smallImage: Icon?) =
+            apply { putOrRemoveField(FIELD_SMALL_IMAGE, smallImage) }
+
+        /**
+         * Sets the burn-in protection version of the *small image* field. This should be
+         * provided if the *small image* field is provided, unless the main small image is
+         * already safe for use with burn-in protection.
+         *
+         * The provided image must not contain solid blocks of pixels - it should instead be
+         * composed of outlines or lines only.
+         *
+         * If this field is set, the *small image* field must also be set.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setBurnInProtectionSmallImage(smallImage: Icon?) =
+            apply { putOrRemoveField(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION, smallImage) }
+
+        /**
+         * Sets the display style for this complication data. This is valid only for types that
+         * contain small images, i.e. [TYPE_SMALL_IMAGE] and [TYPE_LONG_TEXT].
+         *
+         * This affects how watch faces will draw the image in the complication.
+         *
+         * If not specified, the default is [IMAGE_STYLE_PHOTO].
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         * @see .IMAGE_STYLE_PHOTO which can be cropped but not recolored.
+         *
+         * @see .IMAGE_STYLE_ICON which can be recolored but not cropped.
+         */
+        fun setSmallImageStyle(@ImageStyle imageStyle: Int) =
+            apply { putIntField(FIELD_IMAGE_STYLE, imageStyle) }
+
+        /**
+         * Sets the *large image* field. This is required for the [TYPE_LARGE_IMAGE]
+         * type, and is not valid for any other type.
+         *
+         * The provided image should be suitably sized to fill the screen of the watch.
+         *
+         * Returns this Builder to allow chaining.
+         *
+         * @throws IllegalStateException if this field is not valid for the complication type
+         */
+        fun setLargeImage(largeImage: Icon?) =
+            apply { putOrRemoveField(FIELD_LARGE_IMAGE, largeImage) }
+
+        /**
+         * Sets the list style hint
+         *
+         * Valid only if the type of this complication data is [EXP_TYPE_LIST]. Otherwise
+         * returns
+         * zero.
+         */
+        fun setListStyleHint(listStyleHint: Int) =
+            apply { putIntField(EXP_FIELD_LIST_STYLE_HINT, listStyleHint) }
+
+        /**
+         * Sets the *tap action* field. This is optional for any non-empty type.
+         *
+         * The provided [PendingIntent] may be fired if the complication is tapped on. Note
+         * that some complications might not be tappable, in which case this field will be ignored.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setTapAction(pendingIntent: PendingIntent?) =
+            apply { putOrRemoveField(FIELD_TAP_ACTION, pendingIntent) }
+
+        /**
+         * Sets the *content description* field for accessibility. This is optional for any
+         * non-empty type. It is recommended to provide a content description whenever the
+         * data includes an image.
+         *
+         * The provided text will be read aloud by a Text-to-speech converter for users who may
+         * be vision-impaired. It will be read aloud in addition to any long, short, or range text
+         * in the complication.
+         *
+         * If using to describe an image/icon that is purely stylistic and doesn't convey any
+         * information to the user, you may set the image content description to an empty string
+         * ("").
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setContentDescription(description: ComplicationText?) =
+            apply { putOrRemoveField(FIELD_CONTENT_DESCRIPTION, description) }
+
+        /**
+         * Sets whether or not this ComplicationData has been serialized.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setTapActionLostDueToSerialization(tapActionLostDueToSerialization: Boolean) = apply {
+            if (tapActionLostDueToSerialization) {
+                fields.putBoolean(FIELD_TAP_ACTION_LOST, tapActionLostDueToSerialization)
+            }
+        }
+
+        /**
+         * Sets the placeholder.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setPlaceholder(placeholder: ComplicationData?) = apply {
+            if (placeholder == null) {
+                fields.remove(FIELD_PLACEHOLDER_FIELDS)
+                fields.remove(FIELD_PLACEHOLDER_TYPE)
+            } else {
+                checkFieldValidForType(FIELD_PLACEHOLDER_FIELDS, type)
+                fields.putBundle(FIELD_PLACEHOLDER_FIELDS, placeholder.fields)
+                putIntField(FIELD_PLACEHOLDER_TYPE, placeholder.type)
+            }
+        }
+
+        /**
+         * Sets the [ComponentName] of the ComplicationDataSourceService that provided this
+         * ComplicationData. Generally this field should be set and is only nullable for backwards
+         * compatibility.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setDataSource(provider: ComponentName?) =
+            apply { putOrRemoveField(FIELD_DATA_SOURCE, provider) }
+
+        /**
+         * Sets the ambient proto layout associated with this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setAmbientLayout(ambientProtoLayout: ByteArray) =
+            apply { putByteArrayField(EXP_FIELD_PROTO_LAYOUT_AMBIENT, ambientProtoLayout) }
+
+        /**
+         * Sets the proto layout associated with this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setInteractiveLayout(protoLayout: ByteArray) =
+            apply { putByteArrayField(EXP_FIELD_PROTO_LAYOUT_INTERACTIVE, protoLayout) }
+
+        /**
+         * Sets the proto layout resources associated with this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setLayoutResources(resources: ByteArray) =
+            apply { putByteArrayField(EXP_FIELD_PROTO_LAYOUT_RESOURCES, resources) }
+
+        /**
+         * Optional. Sets the color the color ramp should be drawn with.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setColorRamp(colorRamp: IntArray?) =
+            apply { putOrRemoveField(FIELD_COLOR_RAMP, colorRamp) }
+
+        /**
+         * Optional. Sets whether or not the color ramp should be smoothly shaded or drawn with
+         * steps.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setColorRampIsSmoothShaded(isSmoothShaded: Boolean?) =
+            apply { putOrRemoveField(FIELD_COLOR_RAMP_INTERPOLATED, isSmoothShaded) }
+
+        /**
+         * Sets the list of [ComplicationData] timeline entries.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setListEntryCollection(
+            timelineEntries: Collection<ComplicationData>?
+        ) = apply {
+            if (timelineEntries == null) {
+                fields.remove(EXP_FIELD_LIST_ENTRIES)
+            } else {
+                fields.putParcelableArray(
+                    EXP_FIELD_LIST_ENTRIES,
+                    timelineEntries.map { data ->
+                        data.fields.putInt(EXP_FIELD_LIST_ENTRY_TYPE, data.type)
+                        data.fields
+                    }.toTypedArray()
+                )
+            }
+        }
+
+        /**
+         * Sets the element weights for this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setElementWeights(elementWeights: FloatArray?) =
+            apply { putOrRemoveField(FIELD_ELEMENT_WEIGHTS, elementWeights) }
+
+        /**
+         * Sets the element colors for this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setElementColors(elementColors: IntArray?) =
+            apply { putOrRemoveField(FIELD_ELEMENT_COLORS, elementColors) }
+
+        /**
+         * Sets the background color to use between elements for this complication.
+         *
+         * Returns this Builder to allow chaining.
+         */
+        fun setElementBackgroundColor(@ColorInt elementBackgroundColor: Int) =
+            apply { putOrRemoveField(FIELD_ELEMENT_BACKGROUND_COLOR, elementBackgroundColor) }
+
+        /**
+         * Constructs and returns [ComplicationData] with the provided fields. All required
+         * fields must be populated before this method is called.
+         *
+         * @throws IllegalStateException if the required fields have not been populated
+         */
+        fun build(): ComplicationData {
+            // Validate.
+            for (requiredField in REQUIRED_FIELDS[type]!!) {
+                check(fields.containsKey(requiredField)) {
+                    "Field $requiredField is required for type $type"
+                }
+                check(
+                    !(fields.containsKey(FIELD_ICON_BURN_IN_PROTECTION) &&
+                        !fields.containsKey(FIELD_ICON))
+                ) {
+                    "Field ICON must be provided when field ICON_BURN_IN_PROTECTION is provided."
+                }
+                check(
+                    !(fields.containsKey(FIELD_SMALL_IMAGE_BURN_IN_PROTECTION) &&
+                        !fields.containsKey(FIELD_SMALL_IMAGE))
+                ) {
+                    "Field SMALL_IMAGE must be provided when field SMALL_IMAGE_BURN_IN_PROTECTION" +
+                        " is provided."
+                }
+            }
+            return ComplicationData(this)
+        }
+
+        private fun putIntField(field: String, value: Int) {
+            checkFieldValidForType(field, type)
+            fields.putInt(field, value)
+        }
+
+        private fun putFloatField(field: String, value: Float) {
+            checkFieldValidForType(field, type)
+            fields.putFloat(field, value)
+        }
+
+        private fun putByteArrayField(field: String, value: ByteArray) {
+            checkFieldValidForType(field, type)
+            fields.putByteArray(field, value)
+        }
+
+        /** Sets the field with obj or removes it if null. */
+        private fun putOrRemoveField(field: String, obj: Any?) {
+            checkFieldValidForType(field, type)
+            if (obj == null) {
+                fields.remove(field)
+                return
+            }
+            when (obj) {
+                is Boolean -> fields.putBoolean(field, obj)
+                is Int -> fields.putInt(field, obj)
+                is String -> fields.putString(field, obj)
+                is Parcelable -> fields.putParcelable(field, obj)
+                is IntArray -> fields.putIntArray(field, obj)
+                is FloatArray -> fields.putFloatArray(field, obj)
+                else -> throw IllegalArgumentException("Unexpected object type: " + obj.javaClass)
+            }
+        }
+    }
+
+    companion object {
+        private const val TAG = "ComplicationData"
+        const val PLACEHOLDER_STRING = "__placeholder__"
+
+        /**
+         * Type sent when a complication does not have a provider configured. The system will send
+         * data of this type to watch faces when the user has not chosen a provider for an active
+         * complication, and the watch face has not set a default provider. Providers cannot send
+         * data of this type.
+         *
+         * No fields may be populated for complication data of this type.
+         */
+        const val TYPE_NOT_CONFIGURED = 1
+
+        /**
+         * Type sent when the user has specified that an active complication should have no
+         * provider, i.e. when the user has chosen "Empty" in the provider chooser. Providers cannot
+         * send data of this type.
+         *
+         * No fields may be populated for complication data of this type.
+         */
+        const val TYPE_EMPTY = 2
+
+        /**
+         * Type that can be sent by any provider, regardless of the configured type, when the
+         * provider has no data to be displayed. Watch faces may choose whether to render this in
+         * some way or leave the slot empty.
+         *
+         * No fields may be populated for complication data of this type.
+         */
+        const val TYPE_NO_DATA = 10
+
+        /**
+         * Type used for complications where the primary piece of data is a short piece of text
+         * (expected to be no more than seven characters in length). The short text may be
+         * accompanied by an icon or a short title (or both, but if both are provided then a watch
+         * face may choose to display only one).
+         *
+         * The *short text* field is required for this type, and is expected to always be
+         * displayed.
+         *
+         * The *icon* (and *burnInProtectionIcon*) and *short title* fields are
+         * optional for this type. If only one of these is provided, it is expected that it will be
+         * displayed. If both are provided, it is expected that one of these will be displayed.
+         */
+        const val TYPE_SHORT_TEXT = 3
+
+        /**
+         * Type used for complications where the primary piece of data is a piece of text. The text
+         * may be accompanied by an icon and/or a title.
+         *
+         * The *long text* field is required for this type, and is expected to always be
+         * displayed.
+         *
+         * The *long title* field is optional for this type. If provided, it is expected that
+         * this field will be displayed.
+         *
+         * The *icon* (and *burnInProtectionIcon*) and *small image* fields are also
+         * optional for this type. If provided, at least one of these should be displayed.
+         */
+        const val TYPE_LONG_TEXT = 4
+
+        /**
+         * Type used for complications including a numerical value within a range, such as a
+         * percentage. The value may be accompanied by an icon and/or short text and title.
+         *
+         * The *value*, *min value*, and *max value* fields are required for this
+         * type, and the value within the range is expected to always be displayed.
+         *
+         * The *icon* (and *burnInProtectionIcon*), *short title*, and *short
+         * text* fields are optional for this type, but at least one must be defined. The watch face
+         * may choose which of these fields to display, if any.
+         */
+        const val TYPE_RANGED_VALUE = 5
+
+        /**
+         * Type used for complications which consist only of a tintable icon.
+         *
+         * The *icon* field is required for this type, and is expected to always be displayed,
+         * unless the device is in ambient mode with burn-in protection enabled, in which case the
+         * *burnInProtectionIcon* field should be used instead.
+         *
+         * The contentDescription field is recommended for this type. Use it to describe what data
+         * the icon represents. If the icon is purely stylistic, and does not convey any information
+         * to the user, then enter the empty string as the contentDescription.
+         *
+         * No other fields are valid for this type.
+         */
+        const val TYPE_ICON = 6
+
+        /**
+         * Type used for complications which consist only of a small image.
+         *
+         * The *small image* field is required for this type, and is expected to always be
+         * displayed, unless the device is in ambient mode, in which case either nothing or the
+         * *burnInProtectionSmallImage* field may be used instead.
+         *
+         * The contentDescription field is recommended for this type. Use it to describe what data
+         * the image represents. If the image is purely stylistic, and does not convey any
+         * information to the user, then enter the empty string as the contentDescription.
+         *
+         * No other fields are valid for this type.
+         */
+        const val TYPE_SMALL_IMAGE = 7
+
+        /**
+         * Type used for complications which consist only of a large image. A large image here is
+         * one that could be used to fill the watch face, for example as the background.
+         *
+         * The *large image* field is required for this type, and is expected to always be
+         * displayed, unless the device is in ambient mode.
+         *
+         * The contentDescription field is recommended for this type. Use it to describe what data
+         * the image represents. If the image is purely stylistic, and does not convey any
+         * information to the user, then enter the empty string as the contentDescription.
+         *
+         * No other fields are valid for this type.
+         */
+        const val TYPE_LARGE_IMAGE = 8
+
+        /**
+         * Type sent by the system when the watch face does not have permission to receive
+         * complication data.
+         *
+         * Fields will be populated to allow the data to be rendered as if it were of
+         * [TYPE_SHORT_TEXT] or [TYPE_ICON] for consistency and convenience, but watch faces may
+         * render this as they see fit.
+         *
+         * It is recommended that, where possible, tapping on the complication when in this state
+         * should trigger a permission request.
+         */
+        const val TYPE_NO_PERMISSION = 9
+
+        /**
+         * Type used for complications which indicate progress towards a goal. The value may be
+         * accompanied by an icon and/or short text and title.
+         *
+         * The *value*, and *target value* fields are required for this type, and the
+         * value is expected to always be displayed. The value must be >= 0 and may be > target
+         * value. E.g. 15000 out of a target of 10000 steps.
+         *
+         * The *icon* (and *burnInProtectionIcon*), *short title*, and *short
+         * text* fields are optional for this type, but at least one must be defined. The watch face
+         * may choose which of these fields to display, if any.
+         */
+        const val TYPE_GOAL_PROGRESS = 13
+
+        /**
+         * Type used for complications to display a series of weighted values e.g. in a pie chart.
+         * The weighted values may be accompanied by an icon and/or short text and title.
+         *
+         * The *element weights* and *element colors* fields are required for this type,
+         * and the value within the range is expected to always be displayed.
+         *
+         * The *icon* (and *burnInProtectionIcon*), *short title*, and *short
+         * text* fields are optional for this type, but at least one must be defined. The watch face
+         * may choose which of these fields to display, if any.
+         */
+        const val TYPE_WEIGHTED_ELEMENTS = 14
+
+        // The following types are experimental, and they have negative IDs.
+        /** Type that specifies a proto layout based complication. */
+        const val EXP_TYPE_PROTO_LAYOUT = -11
+
+        /** Type that specifies a list of complication values. E.g. to support linear 3. */
+        const val EXP_TYPE_LIST = -12
+
+        /**
+         * Style for small images which are photos that are expected to fill the space available.
+         * Images of this style may be cropped to fit the shape of the complication - in particular,
+         * the image may be cropped to a circle. Photos my not be recolored.
+         *
+         * This is the default value.
+         */
+        const val IMAGE_STYLE_PHOTO = 1
+
+        /**
+         * Style for small images that have a transparent background and are expected to be drawn
+         * entirely within the space available, such as a launcher icon. Watch faces may add padding
+         * when drawing these images, but should never crop these images. Icons may be recolored to
+         * fit the complication style.
+         */
+        const val IMAGE_STYLE_ICON = 2
+        private const val FIELD_COLOR_RAMP = "COLOR_RAMP"
+        private const val FIELD_COLOR_RAMP_INTERPOLATED = "COLOR_RAMP_INTERPOLATED"
+        private const val FIELD_DATA_SOURCE = "FIELD_DATA_SOURCE"
+        private const val FIELD_DISPLAY_POLICY = "DISPLAY_POLICY"
+        private const val FIELD_ELEMENT_BACKGROUND_COLOR = "ELEMENT_BACKGROUND_COLOR"
+        private const val FIELD_ELEMENT_COLORS = "ELEMENT_COLORS"
+        private const val FIELD_ELEMENT_WEIGHTS = "ELEMENT_WEIGHTS"
+        private const val FIELD_END_TIME = "END_TIME"
+        private const val FIELD_ICON = "ICON"
+        private const val FIELD_ICON_BURN_IN_PROTECTION = "ICON_BURN_IN_PROTECTION"
+        private const val FIELD_IMAGE_STYLE = "IMAGE_STYLE"
+        private const val FIELD_LARGE_IMAGE = "LARGE_IMAGE"
+        private const val FIELD_LONG_TITLE = "LONG_TITLE"
+        private const val FIELD_LONG_TEXT = "LONG_TEXT"
+        private const val FIELD_MAX_VALUE = "MAX_VALUE"
+        private const val FIELD_MIN_VALUE = "MIN_VALUE"
+        private const val FIELD_PERSISTENCE_POLICY = "PERSISTENCE_POLICY"
+        private const val FIELD_PLACEHOLDER_FIELDS = "PLACEHOLDER_FIELDS"
+        private const val FIELD_PLACEHOLDER_TYPE = "PLACEHOLDER_TYPE"
+        private const val FIELD_SMALL_IMAGE = "SMALL_IMAGE"
+        private const val FIELD_SMALL_IMAGE_BURN_IN_PROTECTION = "SMALL_IMAGE_BURN_IN_PROTECTION"
+        private const val FIELD_SHORT_TITLE = "SHORT_TITLE"
+        private const val FIELD_SHORT_TEXT = "SHORT_TEXT"
+        private const val FIELD_START_TIME = "START_TIME"
+        private const val FIELD_TAP_ACTION = "TAP_ACTION"
+        private const val FIELD_TAP_ACTION_LOST = "FIELD_TAP_ACTION_LOST"
+        private const val FIELD_TARGET_VALUE = "TARGET_VALUE"
+        private const val FIELD_TIMELINE_START_TIME = "TIMELINE_START_TIME"
+        private const val FIELD_TIMELINE_END_TIME = "TIMELINE_END_TIME"
+        private const val FIELD_TIMELINE_ENTRIES = "TIMELINE"
+        private const val FIELD_TIMELINE_ENTRY_TYPE = "TIMELINE_ENTRY_TYPE"
+        private const val FIELD_VALUE = "VALUE"
+        private const val FIELD_VALUE_TYPE = "VALUE_TYPE"
+
+        // Experimental fields, these are subject to change without notice.
+        private const val EXP_FIELD_LIST_ENTRIES = "EXP_LIST_ENTRIES"
+        private const val EXP_FIELD_LIST_ENTRY_TYPE = "EXP_LIST_ENTRY_TYPE"
+        private const val EXP_FIELD_LIST_STYLE_HINT = "EXP_LIST_STYLE_HINT"
+        private const val EXP_FIELD_PROTO_LAYOUT_AMBIENT = "EXP_FIELD_PROTO_LAYOUT_AMBIENT"
+        private const val EXP_FIELD_PROTO_LAYOUT_INTERACTIVE = "EXP_FIELD_PROTO_LAYOUT_INTERACTIVE"
+        private const val EXP_FIELD_PROTO_LAYOUT_RESOURCES = "EXP_FIELD_PROTO_LAYOUT_RESOURCES"
+
+        // Originally it was planned to support both content and image content descriptions.
+        private const val FIELD_CONTENT_DESCRIPTION = "IMAGE_CONTENT_DESCRIPTION"
+
+        // The set of valid types.
+        private val VALID_TYPES: Set<Int> = setOf(
+            TYPE_NOT_CONFIGURED,
+            TYPE_EMPTY,
+            TYPE_SHORT_TEXT,
+            TYPE_LONG_TEXT,
+            TYPE_RANGED_VALUE,
+            TYPE_ICON,
+            TYPE_SMALL_IMAGE,
+            TYPE_LARGE_IMAGE,
+            TYPE_NO_PERMISSION,
+            TYPE_NO_DATA,
+            EXP_TYPE_PROTO_LAYOUT,
+            EXP_TYPE_LIST,
+            TYPE_GOAL_PROGRESS,
+            TYPE_WEIGHTED_ELEMENTS,
+        )
+
+        // Used for validation. REQUIRED_FIELDS[i] is a list containing all the fields which must be
+        // populated for @ComplicationType i.
+        private val REQUIRED_FIELDS: Map<Int, Set<String>> = mapOf(
+            TYPE_NOT_CONFIGURED to setOf(),
+            TYPE_EMPTY to setOf(),
+            TYPE_SHORT_TEXT to setOf(FIELD_SHORT_TEXT),
+            TYPE_LONG_TEXT to setOf(FIELD_LONG_TEXT),
+            TYPE_RANGED_VALUE to setOf(FIELD_VALUE, FIELD_MIN_VALUE, FIELD_MAX_VALUE),
+            TYPE_ICON to setOf(FIELD_ICON),
+            TYPE_SMALL_IMAGE to setOf(FIELD_SMALL_IMAGE, FIELD_IMAGE_STYLE),
+            TYPE_LARGE_IMAGE to setOf(FIELD_LARGE_IMAGE),
+            TYPE_NO_PERMISSION to setOf(),
+            TYPE_NO_DATA to setOf(),
+            EXP_TYPE_PROTO_LAYOUT to setOf(
+                EXP_FIELD_PROTO_LAYOUT_AMBIENT,
+                EXP_FIELD_PROTO_LAYOUT_INTERACTIVE,
+                EXP_FIELD_PROTO_LAYOUT_RESOURCES
+            ),
+            EXP_TYPE_LIST to setOf(EXP_FIELD_LIST_ENTRIES),
+            TYPE_GOAL_PROGRESS to setOf(FIELD_VALUE, FIELD_TARGET_VALUE),
+            TYPE_WEIGHTED_ELEMENTS to setOf(
+                FIELD_ELEMENT_WEIGHTS,
+                FIELD_ELEMENT_COLORS,
+                FIELD_ELEMENT_BACKGROUND_COLOR
+            ),
+        )
+
+        // Used for validation. OPTIONAL_FIELDS[i] is an array containing all the fields which are
+        // valid but not required for type i.
+        private val OPTIONAL_FIELDS: Map<Int, Set<String>> = mapOf(
+            TYPE_NOT_CONFIGURED to setOf(),
+            TYPE_EMPTY to setOf(),
+            TYPE_SHORT_TEXT to setOf(
+                FIELD_SHORT_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_LONG_TEXT to setOf(
+                FIELD_LONG_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_RANGED_VALUE to setOf(
+                FIELD_SHORT_TEXT,
+                FIELD_SHORT_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_COLOR_RAMP,
+                FIELD_COLOR_RAMP_INTERPOLATED,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY,
+                FIELD_VALUE_TYPE
+            ),
+            TYPE_ICON to setOf(
+                FIELD_TAP_ACTION,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_SMALL_IMAGE to setOf(
+                FIELD_TAP_ACTION,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_LARGE_IMAGE to setOf(
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_NO_PERMISSION to setOf(
+                FIELD_SHORT_TEXT,
+                FIELD_SHORT_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_NO_DATA to setOf(
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_LARGE_IMAGE,
+                FIELD_LONG_TEXT,
+                FIELD_LONG_TITLE,
+                FIELD_MAX_VALUE,
+                FIELD_MIN_VALUE,
+                FIELD_PLACEHOLDER_FIELDS,
+                FIELD_PLACEHOLDER_TYPE,
+                FIELD_SHORT_TEXT,
+                FIELD_SHORT_TITLE,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_TAP_ACTION,
+                FIELD_VALUE,
+                FIELD_VALUE_TYPE,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            EXP_TYPE_PROTO_LAYOUT to setOf(
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            EXP_TYPE_LIST to setOf(
+                FIELD_TAP_ACTION,
+                EXP_FIELD_LIST_STYLE_HINT,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_GOAL_PROGRESS to setOf(
+                FIELD_SHORT_TEXT,
+                FIELD_SHORT_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_COLOR_RAMP,
+                FIELD_COLOR_RAMP_INTERPOLATED,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+            TYPE_WEIGHTED_ELEMENTS to setOf(
+                FIELD_SHORT_TEXT,
+                FIELD_SHORT_TITLE,
+                FIELD_ICON,
+                FIELD_ICON_BURN_IN_PROTECTION,
+                FIELD_SMALL_IMAGE,
+                FIELD_SMALL_IMAGE_BURN_IN_PROTECTION,
+                FIELD_IMAGE_STYLE,
+                FIELD_TAP_ACTION,
+                FIELD_CONTENT_DESCRIPTION,
+                FIELD_DATA_SOURCE,
+                FIELD_PERSISTENCE_POLICY,
+                FIELD_DISPLAY_POLICY
+            ),
+        )
+
+        @JvmField
+        val CREATOR = object : Parcelable.Creator<ComplicationData> {
+            override fun createFromParcel(source: Parcel) = ComplicationData(source)
+
+            override fun newArray(size: Int): Array<ComplicationData?> = Array(size) { null }
+        }
+
+        fun isFieldValidForType(field: String, @ComplicationType type: Int): Boolean {
+            val requiredFields = REQUIRED_FIELDS[type] ?: return false
+            for (requiredField in requiredFields) {
+                if (requiredField == field) {
+                    return true
+                }
+            }
+            for (optionalField in OPTIONAL_FIELDS[type]!!) {
+                if (optionalField == field) {
+                    return true
+                }
+            }
+            return false
+        }
+
+        private fun isTypeSupported(type: Int) = type in VALID_TYPES
+
+        /** The unparceling logic needs to remain backward compatible. */
+        internal fun checkFieldValidForTypeWithoutThrowingException(
+            field: String,
+            @ComplicationType type: Int,
+        ) {
+            if (!isTypeSupported(type)) {
+                Log.w(TAG, "Type $type can not be recognized")
+                return
+            }
+            if (!isFieldValidForType(field, type)) {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "Field $field is not supported for type $type")
+                }
+            }
+        }
+
+        internal fun checkFieldValidForType(field: String, @ComplicationType type: Int) {
+            check(isTypeSupported(type)) { "Type $type can not be recognized" }
+            check(isFieldValidForType(field, type)) {
+                "Field $field is not supported for type $type"
+            }
+        }
+
+        /** Returns whether or not we should redact complication data in toString(). */
+        @JvmStatic
+        fun shouldRedact() = !Log.isLoggable(TAG, Log.DEBUG)
+
+        @JvmStatic
+        fun maybeRedact(unredacted: CharSequence?): String =
+            if (unredacted == null) "(null)"
+            else maybeRedact(unredacted.toString())
+
+        @JvmSynthetic
+        private fun maybeRedact(unredacted: String): String =
+            if (!shouldRedact() || unredacted == PLACEHOLDER_STRING) unredacted
+            else "REDACTED"
+    }
+}
\ No newline at end of file
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Image.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Image.kt
index c5463bf..5558fca 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Image.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/Image.kt
@@ -194,7 +194,7 @@
     internal fun addToWireComplicationData(builder: WireComplicationDataBuilder) = builder.apply {
         setSmallImage(image)
         setSmallImageStyle(
-            when (type) {
+            when (this@SmallImage.type) {
                 SmallImageType.ICON -> WireComplicationData.IMAGE_STYLE_ICON
                 SmallImageType.PHOTO -> WireComplicationData.IMAGE_STYLE_PHOTO
             }
diff --git a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/PlaceholderTest.kt b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/PlaceholderTest.kt
index c70e7a6..513af6b 100644
--- a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/PlaceholderTest.kt
+++ b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/PlaceholderTest.kt
@@ -21,7 +21,7 @@
 import android.graphics.Color
 import android.graphics.drawable.Icon
 import android.support.wearable.complications.ComplicationData
-import android.support.wearable.complications.ComplicationData.IMAGE_STYLE_ICON
+import android.support.wearable.complications.ComplicationData.Companion.IMAGE_STYLE_ICON
 import androidx.test.core.app.ApplicationProvider
 import com.google.common.truth.Truth.assertThat
 import java.time.Instant