Merge "Update Material3 to collections kmp structure" into androidx-main
diff --git a/activity/activity-compose/samples/build.gradle b/activity/activity-compose/samples/build.gradle
index e76d4bc..3190107 100644
--- a/activity/activity-compose/samples/build.gradle
+++ b/activity/activity-compose/samples/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Activity Integration Samples"
+    name = "Compose UI Activity Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
     description = "Samples for Compose integration with Activity"
diff --git a/activity/activity-lint/build.gradle b/activity/activity-lint/build.gradle
index 704ee58..554da78 100644
--- a/activity/activity-lint/build.gradle
+++ b/activity/activity-lint/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Android Activity Lint Checks"
+    name = "Activity Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2020"
     description = "Android Activity Lint Checks"
diff --git a/annotation/annotation/build.gradle b/annotation/annotation/build.gradle
index e821397..769ac65 100644
--- a/annotation/annotation/build.gradle
+++ b/annotation/annotation/build.gradle
@@ -66,10 +66,10 @@
 }
 
 androidx {
-    name = "Android Support Library Annotations"
+    name = "Annotation"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.ANNOTATION
     mavenMultiplatformVersion = LibraryVersions.ANNOTATION_KMP
     inceptionYear = "2013"
-    description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs."
+    description = "Provides source annotations for tooling and readability."
 }
diff --git a/appactions/builtintypes/builtintypes-core/build.gradle b/appactions/builtintypes/builtintypes-core/build.gradle
index 9d98eb3..828e4de 100644
--- a/appactions/builtintypes/builtintypes-core/build.gradle
+++ b/appactions/builtintypes/builtintypes-core/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "androidx.appactions.builtintypes:builtintypes-core"
+    name = "AppActions Builtin Types Core"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2023"
     description = "This library exposes a core set of data types based on schema.org definitions."
diff --git a/appcompat/appcompat-resources/build.gradle b/appcompat/appcompat-resources/build.gradle
index cd96606..7686cb1 100644
--- a/appcompat/appcompat-resources/build.gradle
+++ b/appcompat/appcompat-resources/build.gradle
@@ -59,8 +59,9 @@
 }
 
 androidx {
-    name = "Android Resources Library"
+    name = "AppCompat Resources"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
-    description = "The Resources Library is a static library that you can add to your Android application in order to use resource APIs that backport the latest APIs to older versions of the platform. Compatible on devices running API 14 or later."
+    description = "Provides backward-compatible implementations of resource-related Android SDK" +
+            "functionality, including color state list theming."
 }
diff --git a/appcompat/appcompat/build.gradle b/appcompat/appcompat/build.gradle
index 614c612..22296ee 100644
--- a/appcompat/appcompat/build.gradle
+++ b/appcompat/appcompat/build.gradle
@@ -104,9 +104,10 @@
 }
 
 androidx {
-    name = "Android AppCompat Library"
+    name = "AppCompat"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2011"
-    description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    description = "Provides backwards-compatible implementations of UI-related Android SDK " +
+            "functionality, including dark mode and Material theming."
     failOnDeprecationWarnings = false
 }
diff --git a/appsearch/appsearch-builtin-types/build.gradle b/appsearch/appsearch-builtin-types/build.gradle
index 892b427..369bdb7 100644
--- a/appsearch/appsearch-builtin-types/build.gradle
+++ b/appsearch/appsearch-builtin-types/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = 'AppSearch Builtin Types'
+    name = "AppSearch Builtin Types"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = '2021'
     description = 'Contains AppSearch Document classes and builders for a variety of common ' +
diff --git a/appsearch/appsearch-debug-view/build.gradle b/appsearch/appsearch-debug-view/build.gradle
index 1b0c3f2..91cc056 100644
--- a/appsearch/appsearch-debug-view/build.gradle
+++ b/appsearch/appsearch-debug-view/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "AndroidX AppSearch Debug View"
+    name = "AppSearch Debug View"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "A support library for AndroidX AppSearch that contains activities and views " +
diff --git a/appsearch/appsearch-debug-view/samples/build.gradle b/appsearch/appsearch-debug-view/samples/build.gradle
index 6724661..532b284 100644
--- a/appsearch/appsearch-debug-view/samples/build.gradle
+++ b/appsearch/appsearch-debug-view/samples/build.gradle
@@ -46,7 +46,7 @@
 }
 
 androidx {
-    name = "AndroidX AppSearch Debug View Sample App"
+    name = "AppSearch Debug View Sample App"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains a sample app for integrating the Androidx AppSearch Debug View"
diff --git a/appsearch/appsearch-ktx/build.gradle b/appsearch/appsearch-ktx/build.gradle
index fd812db..7b75083 100644
--- a/appsearch/appsearch-ktx/build.gradle
+++ b/appsearch/appsearch-ktx/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = 'AndroidX AppSearch - Kotlin Extensions'
+    name = "AppSearch - Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = '2021'
     description = 'AndroidX AppSearch - Kotlin Extensions'
diff --git a/appsearch/appsearch/build.gradle b/appsearch/appsearch/build.gradle
index 7c0365c..f991e23 100644
--- a/appsearch/appsearch/build.gradle
+++ b/appsearch/appsearch/build.gradle
@@ -55,7 +55,7 @@
 }
 
 androidx {
-    name = 'AndroidX AppSearch'
+    name = "AppSearch"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = '2019'
     description = 'AndroidX AppSearch - App Indexing'
diff --git a/appsearch/compiler/build.gradle b/appsearch/compiler/build.gradle
index f2c72b7..cb9caf4 100644
--- a/appsearch/compiler/build.gradle
+++ b/appsearch/compiler/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = 'AndroidX AppSearch Compiler'
+    name = "AppSearch Compiler"
     type = LibraryType.ANNOTATION_PROCESSOR
     inceptionYear = '2019'
     description = 'Compiler for classes annotated with @androidx.appsearch.annotation.Document'
diff --git a/arch/core/core-common/build.gradle b/arch/core/core-common/build.gradle
index 8a60844..f8d646f7 100644
--- a/arch/core/core-common/build.gradle
+++ b/arch/core/core-common/build.gradle
@@ -29,7 +29,7 @@
 }
 
 androidx {
-    name = "Android Arch-Common"
+    name = "Arch-Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Arch-Common"
diff --git a/arch/core/core-runtime/build.gradle b/arch/core/core-runtime/build.gradle
index 6652bdf..f1d60e1 100644
--- a/arch/core/core-runtime/build.gradle
+++ b/arch/core/core-runtime/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "Android Arch-Runtime"
+    name = "Arch-Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Arch-Runtime"
diff --git a/arch/core/core-testing/build.gradle b/arch/core/core-testing/build.gradle
index 0476e53..4b071ea 100644
--- a/arch/core/core-testing/build.gradle
+++ b/arch/core/core-testing/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Core-Testing"
+    name = "Core-Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Core-Testing"
diff --git a/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle b/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
index 8f08e8c..a6034b9 100644
--- a/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
+++ b/asynclayoutinflater/asynclayoutinflater-appcompat/build.gradle
@@ -13,10 +13,11 @@
 }
 
 androidx {
-    name = "AsyncLayoutInflater integration for AppCompat"
+    name = "AsyncLayoutInflater AppCompat"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2022"
-    description = "A thread-safe LayoutInflater Factory that provides compatibility between AsyncLayoutInflater and AppCompat."
+    description = "A thread-safe LayoutInflater Factory that provides compatibility between " +
+            "AsyncLayoutInflater and AppCompat."
 }
 
 android {
diff --git a/asynclayoutinflater/asynclayoutinflater/build.gradle b/asynclayoutinflater/asynclayoutinflater/build.gradle
index 713ec8e..44ec7c0 100644
--- a/asynclayoutinflater/asynclayoutinflater/build.gradle
+++ b/asynclayoutinflater/asynclayoutinflater/build.gradle
@@ -19,10 +19,10 @@
 }
 
 androidx {
-    name = "Android Support Library Async Layout Inflater"
+    name = "AsyncLayoutInflater"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
-    description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
+    description = "Provides support for inflating layouts off the UI thread."
 }
 
 android {
diff --git a/autofill/autofill/build.gradle b/autofill/autofill/build.gradle
index c4a5853..e5bbb65 100644
--- a/autofill/autofill/build.gradle
+++ b/autofill/autofill/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Autofill"
+    name = "Autofill"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "AndroidX Autofill"
diff --git a/benchmark/baseline-profile-gradle-plugin/build.gradle b/benchmark/baseline-profile-gradle-plugin/build.gradle
index 9038336..e4884b6 100644
--- a/benchmark/baseline-profile-gradle-plugin/build.gradle
+++ b/benchmark/baseline-profile-gradle-plugin/build.gradle
@@ -72,7 +72,7 @@
 }
 
 androidx {
-    name = "Android Baseline Profile Gradle Plugin"
+    name = "Baseline Profile Gradle Plugin"
     publish = Publish.SNAPSHOT_AND_RELEASE
     type = LibraryType.GRADLE_PLUGIN
     inceptionYear = "2022"
diff --git a/benchmark/benchmark-common/build.gradle b/benchmark/benchmark-common/build.gradle
index e8f2eca..b66a11b 100644
--- a/benchmark/benchmark-common/build.gradle
+++ b/benchmark/benchmark-common/build.gradle
@@ -66,7 +66,7 @@
 }
 
 androidx {
-    name = "Android Benchmark - Common"
+    name = "Benchmark - Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Benchmark - Common"
diff --git a/benchmark/benchmark-darwin-core/build.gradle b/benchmark/benchmark-darwin-core/build.gradle
index ac9243d..12b8a6b 100644
--- a/benchmark/benchmark-darwin-core/build.gradle
+++ b/benchmark/benchmark-darwin-core/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "AndroidX Benchmarks - Darwin Core"
+    name = "Benchmarks - Darwin Core"
     inceptionYear = "2022"
     description = "AndroidX Benchmarks - Darwin Core"
 }
diff --git a/benchmark/benchmark-darwin-gradle-plugin/build.gradle b/benchmark/benchmark-darwin-gradle-plugin/build.gradle
index 7a16cf9..5c3aa31 100644
--- a/benchmark/benchmark-darwin-gradle-plugin/build.gradle
+++ b/benchmark/benchmark-darwin-gradle-plugin/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "AndroidX Benchmarks - Darwin Gradle Plugin"
+    name = "Benchmarks - Darwin Gradle Plugin"
     publish = Publish.SNAPSHOT_ONLY
     type = LibraryType.GRADLE_PLUGIN
     inceptionYear = "2022"
diff --git a/benchmark/benchmark-darwin-samples/build.gradle b/benchmark/benchmark-darwin-samples/build.gradle
index c297722..3684119 100644
--- a/benchmark/benchmark-darwin-samples/build.gradle
+++ b/benchmark/benchmark-darwin-samples/build.gradle
@@ -60,7 +60,7 @@
 }
 
 androidx {
-    name = "AndroidX Benchmarks - Darwin Samples"
+    name = "Benchmarks - Darwin Samples"
     inceptionYear = "2022"
     description = "AndroidX Benchmarks - Darwin Samples"
 }
diff --git a/benchmark/benchmark-darwin/build.gradle b/benchmark/benchmark-darwin/build.gradle
index 473a5c3..e192b8f 100644
--- a/benchmark/benchmark-darwin/build.gradle
+++ b/benchmark/benchmark-darwin/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "AndroidX Benchmarks - Darwin"
+    name = "Benchmarks - Darwin"
     inceptionYear = "2022"
     description = "AndroidX Benchmarks - Darwin"
 }
diff --git a/benchmark/benchmark-junit4/build.gradle b/benchmark/benchmark-junit4/build.gradle
index 4db5a73..cfb08c2 100644
--- a/benchmark/benchmark-junit4/build.gradle
+++ b/benchmark/benchmark-junit4/build.gradle
@@ -47,7 +47,7 @@
 }
 
 androidx {
-    name = "Android Benchmark - JUnit4"
+    name = "Benchmark - JUnit4"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android Benchmark - JUnit4"
diff --git a/benchmark/benchmark-macro-junit4/build.gradle b/benchmark/benchmark-macro-junit4/build.gradle
index cd4804f..5fa8211 100644
--- a/benchmark/benchmark-macro-junit4/build.gradle
+++ b/benchmark/benchmark-macro-junit4/build.gradle
@@ -53,7 +53,7 @@
 }
 
 androidx {
-    name = "Android Benchmark - Macrobenchmark JUnit4"
+    name = "Benchmark - Macrobenchmark JUnit4"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Benchmark - Macrobenchmark JUnit4"
diff --git a/benchmark/benchmark-macro/build.gradle b/benchmark/benchmark-macro/build.gradle
index 538d68d..bc6c8e3 100644
--- a/benchmark/benchmark-macro/build.gradle
+++ b/benchmark/benchmark-macro/build.gradle
@@ -80,7 +80,7 @@
 }
 
 androidx {
-    name = "Android Benchmark - Macrobenchmark"
+    name = "Benchmark - Macrobenchmark"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Benchmark - Macrobenchmark"
diff --git a/benchmark/gradle-plugin/build.gradle b/benchmark/gradle-plugin/build.gradle
index fdf95af..11bf133 100644
--- a/benchmark/gradle-plugin/build.gradle
+++ b/benchmark/gradle-plugin/build.gradle
@@ -58,7 +58,7 @@
 }
 
 androidx {
-    name = "Android Benchmark Gradle Plugin"
+    name = "Benchmark Gradle Plugin"
     type = LibraryType.GRADLE_PLUGIN
     inceptionYear = "2019"
     description = "Android Benchmark Gradle Plugin"
diff --git a/biometric/biometric-ktx/samples/build.gradle b/biometric/biometric-ktx/samples/build.gradle
index 0f995ee..5d20e55 100644
--- a/biometric/biometric-ktx/samples/build.gradle
+++ b/biometric/biometric-ktx/samples/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "AndroidX Biometric Samples"
+    name = "Biometric Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the AndroidX Biometric library"
diff --git a/bluetooth/bluetooth-testing/build.gradle b/bluetooth/bluetooth-testing/build.gradle
index a9ac8a5..e0f587c 100644
--- a/bluetooth/bluetooth-testing/build.gradle
+++ b/bluetooth/bluetooth-testing/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "AndroidX Bluetooth Testing"
+    name = "Bluetooth Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2022"
     description = "Test utilities for AndroidX Bluetooth"
diff --git a/bluetooth/bluetooth/build.gradle b/bluetooth/bluetooth/build.gradle
index c455f0b..8e7f695 100644
--- a/bluetooth/bluetooth/build.gradle
+++ b/bluetooth/bluetooth/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "AndroidX Bluetooth"
+    name = "Bluetooth"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2022"
     description = "AndroidX Bluetooth Library"
diff --git a/browser/browser/build.gradle b/browser/browser/build.gradle
index de7fa00..195ec5c 100644
--- a/browser/browser/build.gradle
+++ b/browser/browser/build.gradle
@@ -51,8 +51,8 @@
 }
 
 androidx {
-    name = "Android Support Custom Tabs"
+    name = "Browser"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2015"
-    description = "Android Support Custom Tabs"
+    description = "Provides support for embedding Custom Tabs in an app."
 }
diff --git a/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle b/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
index 06e9e6e..eae2213 100644
--- a/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
+++ b/buildSrc-tests/max-dep-versions/buildSrc-tests-max-dep-versions-dep/build.gradle
@@ -11,7 +11,7 @@
 }
 
 androidx {
-    name = "Sample Library"
+    name = "Sample"
     publish = Publish.SNAPSHOT_AND_RELEASE
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index d5f73f51..bb7940d 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -586,6 +586,7 @@
                 extension.type == LibraryType.UNSET
             if (mavenGroup != null && isProbablyPublished && extension.shouldPublish()) {
                 validateProjectStructure(mavenGroup.group)
+                validateProjectMavenName(extension.name.get(), mavenGroup.group)
             }
         }
     }
@@ -1135,46 +1136,6 @@
     return false
 }
 
-private const val GROUP_PREFIX = "androidx."
-
-/**
- * Validates the project structure against Jetpack guidelines.
- */
-fun Project.validateProjectStructure(groupId: String) {
-    if (!project.isValidateProjectStructureEnabled()) {
-        return
-    }
-
-    val shortGroupId = if (groupId.startsWith(GROUP_PREFIX)) {
-        groupId.substring(GROUP_PREFIX.length)
-    } else {
-        groupId
-    }
-
-    // Fully-qualified Gradle project name should match the Maven coordinate.
-    val expectName = ":${shortGroupId.replace(".",":")}:${project.name}"
-    val actualName = project.path
-    if (expectName != actualName) {
-        throw GradleException(
-            "Invalid project structure! Expected $expectName as project name, found $actualName"
-        )
-    }
-
-    // Project directory should match the Maven coordinate.
-    val expectDir = shortGroupId.replace(".", File.separator) +
-        "${File.separator}${project.name}"
-    // Canonical projectDir is needed because sometimes, at least in tests, on OSX, supportRoot
-    // starts with /var, and projectDir starts with /private/var (which are the same thing)
-    val canonicalProjectDir = project.projectDir.canonicalFile
-    val actualDir =
-        canonicalProjectDir.toRelativeString(project.getSupportRootFolder().canonicalFile)
-    if (expectDir != actualDir) {
-        throw GradleException(
-            "Invalid project structure! Expected $expectDir as project directory, found $actualDir"
-        )
-    }
-}
-
 fun Project.validateMultiplatformPluginHasNotBeenApplied() {
     if (plugins.hasPlugin(KotlinMultiplatformPluginWrapper::class.java)) {
         throw GradleException(
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt b/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt
new file mode 100644
index 0000000..bbe7f2a
--- /dev/null
+++ b/buildSrc/private/src/main/kotlin/androidx/build/ProjectConfigValidators.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.build
+
+import java.io.File
+import org.gradle.api.GradleException
+import org.gradle.api.Project
+
+// Translate common phrases and marketing names into Maven name component equivalents.
+private val mavenNameMap = mapOf(
+    "android for cars" to "car",
+    "android wear" to "wear",
+    "internationalization" to "i18n",
+    "kotlin extensions" to "ktx",
+    "lint checks" to "lint",
+    "material components" to "material",
+    "material3 components" to "material3",
+    "workmanager" to "work",
+    "windowmanager" to "window",
+)
+
+// Allow a small set of common Maven name components that don't need to appear in the project name.
+private val mavenNameAllowlist = setOf(
+    "extension",
+    "extensions",
+    "for",
+    "integration",
+    "with",
+)
+
+/**
+ * Validates the project's Maven name against Jetpack guidelines.
+ */
+fun Project.validateProjectMavenName(mavenName: String?, groupId: String) {
+    if (mavenName == null) return
+
+    // Tokenize the Maven name into components. This is *very* permissive regarding separators, and
+    // we may want to revisit that policy in the future.
+    val nameComponents = mavenName.lowercase().let { name ->
+        mavenNameMap.entries.fold(name) { newName, entry ->
+            newName.replace(entry.key, entry.value)
+        }
+    }.split(" ", ",", ":", "-").toMutableList() - mavenNameAllowlist
+
+    // Remaining components *must* appear in the Maven coordinate. Shortening long (>10 char) words
+    // to five letters or more is allowed, as is changing the pluralization of words.
+    nameComponents.find { nameComponent ->
+        !name.contains(nameComponent) && !groupId.contains(nameComponent) &&
+            !(nameComponent.length > 10 && name.contains(nameComponent.substring(0, 5))) &&
+            !(nameComponent.endsWith("s") && name.contains(nameComponent.dropLast(1)))
+    }?.let { missingComponent ->
+        throw GradleException(
+            "Invalid Maven name! Found \"$missingComponent\" in Maven name for $displayName, but " +
+                "not project name.\n\nConsider removing \"$missingComponent\" from \"$mavenName\"."
+        )
+    }
+}
+
+private const val GROUP_PREFIX = "androidx."
+
+/**
+ * Validates the project structure against Jetpack guidelines.
+ */
+fun Project.validateProjectStructure(groupId: String) {
+    if (!project.isValidateProjectStructureEnabled()) {
+        return
+    }
+
+    val shortGroupId = if (groupId.startsWith(GROUP_PREFIX)) {
+        groupId.substring(GROUP_PREFIX.length)
+    } else {
+        groupId
+    }
+
+    // Fully-qualified Gradle project name should match the Maven coordinate.
+    val expectName = ":${shortGroupId.replace(".",":")}:${project.name}"
+    val actualName = project.path
+    if (expectName != actualName) {
+        throw GradleException(
+            "Invalid project structure! Expected $expectName as project name, found $actualName"
+        )
+    }
+
+    // Project directory should match the Maven coordinate.
+    val expectDir = shortGroupId.replace(".", File.separator) +
+        "${File.separator}${project.name}"
+    // Canonical projectDir is needed because sometimes, at least in tests, on OSX, supportRoot
+    // starts with /var, and projectDir starts with /private/var (which are the same thing)
+    val canonicalProjectDir = project.projectDir.canonicalFile
+    val actualDir =
+        canonicalProjectDir.toRelativeString(project.getSupportRootFolder().canonicalFile)
+    if (expectDir != actualDir) {
+        throw GradleException(
+            "Invalid project structure! Expected $expectDir as project directory, found $actualDir"
+        )
+    }
+}
diff --git a/camera/camera-camera2-pipe-integration/build.gradle b/camera/camera-camera2-pipe-integration/build.gradle
index 5ba8cb5..3a1f95e 100644
--- a/camera/camera-camera2-pipe-integration/build.gradle
+++ b/camera/camera-camera2-pipe-integration/build.gradle
@@ -115,11 +115,11 @@
 }
 
 androidx {
-    name = "Jetpack Camera Camera Pipe Integration Library"
+    name = "Camera2 Pipe Integration"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CAMERA_PIPE
     inceptionYear = "2020"
-    description = "A CameraPipe implementation of CameraX, a library providing a consistent and " +
-            "reliable camera foundation that enables great camera driven experiences across all " +
-            "of Android."
+    description = "A Camera2 Pipe implementation of CameraX, a library providing a consistent " +
+            "and reliable camera foundation that enables great camera driven experiences across " +
+            "all of Android."
 }
diff --git a/camera/camera-camera2-pipe-testing/build.gradle b/camera/camera-camera2-pipe-testing/build.gradle
index fcf6f79..1d31206 100644
--- a/camera/camera-camera2-pipe-testing/build.gradle
+++ b/camera/camera-camera2-pipe-testing/build.gradle
@@ -60,12 +60,12 @@
 }
 
 androidx {
-    name = "Jetpack Camera Camera Pipe Testing Library"
+    name = "Camera2 Pipe Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CAMERA_PIPE
     runApiTasks = new RunApiTasks.No("CameraPipe is an implementation detail of other libraries.")
     inceptionYear = "2020"
-    description = "Testing components for the Jetpack CameraPipe Library, a library providing a " +
+    description = "Testing components for the Camera2 Pipe Library, a library providing a " +
             "consistent and reliable camera foundation that enables great camera driven " +
             "experiences across all of Android."
 }
diff --git a/camera/camera-camera2-pipe/build.gradle b/camera/camera-camera2-pipe/build.gradle
index f339499..e2a6054 100644
--- a/camera/camera-camera2-pipe/build.gradle
+++ b/camera/camera-camera2-pipe/build.gradle
@@ -71,7 +71,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Pipe"
+    name = "Camera2 Pipe"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CAMERA_PIPE
     runApiTasks = new RunApiTasks.No("CameraPipe is an implementation detail of other libraries.")
diff --git a/camera/camera-camera2/build.gradle b/camera/camera-camera2/build.gradle
index 8c0100e..b4ad3b0 100644
--- a/camera/camera-camera2/build.gradle
+++ b/camera/camera-camera2/build.gradle
@@ -88,7 +88,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Library Camera2 Implementation/Extensions"
+    name = "Camera2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Camera2 implementation and extensions for the Jetpack Camera Library, a " +
diff --git a/camera/camera-core/build.gradle b/camera/camera-core/build.gradle
index c789d6d..90360e1 100644
--- a/camera/camera-core/build.gradle
+++ b/camera/camera-core/build.gradle
@@ -111,7 +111,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Core Library"
+    name = "Camera Core"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Core components for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-effects-still-portrait/build.gradle b/camera/camera-effects-still-portrait/build.gradle
index e6d14aa..647567c 100644
--- a/camera/camera-effects-still-portrait/build.gradle
+++ b/camera/camera-effects-still-portrait/build.gradle
@@ -32,7 +32,7 @@
     namespace "androidx.camera.effects.stillportrait"
 }
 androidx {
-    name = "Jetpack Camera Portrait Still Effect Library"
+    name = "Camera Effects: Still Portrait"
     publish = Publish.SNAPSHOT_ONLY
     inceptionYear = "2022"
     runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-effects/build.gradle b/camera/camera-effects/build.gradle
index d6fc08d..858866e 100644
--- a/camera/camera-effects/build.gradle
+++ b/camera/camera-effects/build.gradle
@@ -32,7 +32,7 @@
     namespace "androidx.camera.effects"
 }
 androidx {
-    name = "Jetpack Camera Effects Library"
+    name = "Camera Effects"
     publish = Publish.NONE
     inceptionYear = "2022"
     runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-extensions-stub/build.gradle b/camera/camera-extensions-stub/build.gradle
index de2b943..efca9c0 100644
--- a/camera/camera-extensions-stub/build.gradle
+++ b/camera/camera-extensions-stub/build.gradle
@@ -25,7 +25,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Library OEM Extensions Stub"
+    name = "Camera OEM Extensions Stub"
     publish = Publish.NONE
 
     inceptionYear = "2019"
diff --git a/camera/camera-extensions/build.gradle b/camera/camera-extensions/build.gradle
index 1627bec..4cb5a01 100644
--- a/camera/camera-extensions/build.gradle
+++ b/camera/camera-extensions/build.gradle
@@ -81,7 +81,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Library OEM Extensions"
+    name = "Camera Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
 
     inceptionYear = "2019"
diff --git a/camera/camera-lifecycle/build.gradle b/camera/camera-lifecycle/build.gradle
index 7d0119c..4f7b607 100644
--- a/camera/camera-lifecycle/build.gradle
+++ b/camera/camera-lifecycle/build.gradle
@@ -61,7 +61,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Lifecycle Library"
+    name = "Camera Lifecycle"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Lifecycle components for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-mlkit-vision/build.gradle b/camera/camera-mlkit-vision/build.gradle
index f0f3bad..e569d1f 100644
--- a/camera/camera-mlkit-vision/build.gradle
+++ b/camera/camera-mlkit-vision/build.gradle
@@ -58,7 +58,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera MLKit Vision Library"
+    name = "Camera MLKit Vision"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2022"
     runApiTasks = new RunApiTasks.Yes()
diff --git a/camera/camera-testing/build.gradle b/camera/camera-testing/build.gradle
index 177e3db..3c9f0b7 100644
--- a/camera/camera-testing/build.gradle
+++ b/camera/camera-testing/build.gradle
@@ -91,7 +91,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Testing Library"
+    name = "Camera Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     runApiTasks = new RunApiTasks.No("Internal testing library without any release plan yet.")
     inceptionYear = "2019"
diff --git a/camera/camera-testlib-extensions/build.gradle b/camera/camera-testlib-extensions/build.gradle
index 886b875..849e115 100644
--- a/camera/camera-testlib-extensions/build.gradle
+++ b/camera/camera-testlib-extensions/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Extensions Example Library"
+    name = "Camera Extensions Example"
     publish = Publish.NONE
     inceptionYear = "2019"
     description = "Example extension implementation for the Jetpack Camera Library, a library providing a " +
diff --git a/camera/camera-video/build.gradle b/camera/camera-video/build.gradle
index ff70608..d62ee62 100644
--- a/camera/camera-video/build.gradle
+++ b/camera/camera-video/build.gradle
@@ -87,7 +87,7 @@
 }
 
 androidx {
-    name = "Jetpack Camera Video Library"
+    name = "Camera Video"
     publish = Publish.SNAPSHOT_AND_RELEASE
     runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
     inceptionYear = "2020"
diff --git a/camera/camera-view/build.gradle b/camera/camera-view/build.gradle
index fe34a08..2476a37 100644
--- a/camera/camera-view/build.gradle
+++ b/camera/camera-view/build.gradle
@@ -80,7 +80,7 @@
     namespace "androidx.camera.view"
 }
 androidx {
-    name = "Jetpack Camera View Library"
+    name = "Camera View"
     publish = Publish.SNAPSHOT_AND_RELEASE
 
     inceptionYear = "2019"
diff --git a/camera/camera-viewfinder-core/build.gradle b/camera/camera-viewfinder-core/build.gradle
index f2a2a9e..840c124 100644
--- a/camera/camera-viewfinder-core/build.gradle
+++ b/camera/camera-viewfinder-core/build.gradle
@@ -33,9 +33,9 @@
 }
 
 androidx {
-    name = "androidx.camera:camera-viewfinder-core"
+    name = "Camera ViewFinder Core"
     type = LibraryType.PUBLISHED_LIBRARY
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2023"
-    description = "core dependencies for viewfinder"
+    description = "Core dependencies for ViewFinder"
 }
diff --git a/camera/camera-viewfinder/build.gradle b/camera/camera-viewfinder/build.gradle
index 39c752c..e77d559 100644
--- a/camera/camera-viewfinder/build.gradle
+++ b/camera/camera-viewfinder/build.gradle
@@ -80,7 +80,7 @@
 }
 
 androidx {
-    name = "androidx.camera:camera-viewfinder"
+    name = "Camera ViewFinder"
     publish = Publish.SNAPSHOT_AND_RELEASE
     runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
     inceptionYear = "2022"
diff --git a/car/app/app-automotive/build.gradle b/car/app/app-automotive/build.gradle
index a496e2d..7361f0e 100644
--- a/car/app/app-automotive/build.gradle
+++ b/car/app/app-automotive/build.gradle
@@ -72,7 +72,7 @@
 }
 
 androidx {
-    name = "Android for Cars App Library Automotive Extension"
+    name = "Android for Cars App Automotive Extension"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Automotive OS specific functionality to build navigation, parking, and charging apps for cars"
diff --git a/car/app/app-projected/build.gradle b/car/app/app-projected/build.gradle
index 5754a49..454cbec 100644
--- a/car/app/app-projected/build.gradle
+++ b/car/app/app-projected/build.gradle
@@ -60,7 +60,7 @@
 }
 
 androidx {
-    name = "Android for Cars App Library Projected Extension"
+    name = "Android for Cars App Projected Extension"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Android Auto Projected specific funationaltiy to build navigation, parking, and charging apps for cars"
diff --git a/car/app/app/build.gradle b/car/app/app/build.gradle
index 43d2789..e31bbf1 100644
--- a/car/app/app/build.gradle
+++ b/car/app/app/build.gradle
@@ -100,7 +100,7 @@
 }
 
 androidx {
-    name = "Android for Cars App Library"
+    name = "Android for Cars App"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     description = "Build navigation, parking, and charging apps for Android Auto"
diff --git a/cardview/cardview/build.gradle b/cardview/cardview/build.gradle
index 239abf1..13cc235 100644
--- a/cardview/cardview/build.gradle
+++ b/cardview/cardview/build.gradle
@@ -11,7 +11,7 @@
 }
 
 androidx {
-    name = "Android Support CardView"
+    name = "CardView"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2011"
     description = "Android Support CardView"
diff --git a/collection/collection-benchmark/build.gradle b/collection/collection-benchmark/build.gradle
index dc0cf11..931098c 100644
--- a/collection/collection-benchmark/build.gradle
+++ b/collection/collection-benchmark/build.gradle
@@ -105,7 +105,7 @@
 }
 
 androidx {
-    name = "AndroidX Collections Benchmarks (Android / iOS)"
+    name = "Collections Benchmarks (Android / iOS)"
     inceptionYear = "2022"
     description = "AndroidX Collections Benchmarks (Android / iOS)"
 }
diff --git a/collection/collection/build.gradle b/collection/collection/build.gradle
index 0ac4f14..47b1d5e 100644
--- a/collection/collection/build.gradle
+++ b/collection/collection/build.gradle
@@ -136,7 +136,7 @@
 }
 
 androidx {
-    name = "Android Support Library collections"
+    name = "collections"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2018"
     description = "Standalone efficient collections."
diff --git a/collection/integration-tests/testapp/build.gradle b/collection/integration-tests/testapp/build.gradle
index a8d529f..67a0ce6 100644
--- a/collection/integration-tests/testapp/build.gradle
+++ b/collection/integration-tests/testapp/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "AndroidX Collection Integration Tests"
+    name = "Collection Integration Tests"
     publish = Publish.NONE
     inceptionYear = "2021"
     description = "AndroidX Collection Integration Tests"
diff --git a/compose/animation/animation-core/samples/build.gradle b/compose/animation/animation-core/samples/build.gradle
index 160f365..735da8e 100644
--- a/compose/animation/animation-core/samples/build.gradle
+++ b/compose/animation/animation-core/samples/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Animation Library Core Classes Samples"
+    name = "Compose UI Animation Core Classes Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Animation Core Classes"
diff --git a/compose/animation/animation-graphics/samples/build.gradle b/compose/animation/animation-graphics/samples/build.gradle
index 2b0e793..c317288 100644
--- a/compose/animation/animation-graphics/samples/build.gradle
+++ b/compose/animation/animation-graphics/samples/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Animation Graphics Library Samples"
+    name = "Compose UI Animation Graphics Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the Androidx Compose UI Animation Graphics Library"
diff --git a/compose/animation/animation/samples/build.gradle b/compose/animation/animation/samples/build.gradle
index d355cdf..9fd59da 100644
--- a/compose/animation/animation/samples/build.gradle
+++ b/compose/animation/animation/samples/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Animation Library Samples"
+    name = "Compose UI Animation Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Animation Library"
diff --git a/compose/compiler/compiler-daemon/integration-tests/build.gradle b/compose/compiler/compiler-daemon/integration-tests/build.gradle
index afda48a..5416516 100644
--- a/compose/compiler/compiler-daemon/integration-tests/build.gradle
+++ b/compose/compiler/compiler-daemon/integration-tests/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "AndroidX Compiler Daemon CLI Tests"
+    name = "Compiler Daemon CLI Tests"
     type = LibraryType.COMPILER_DAEMON_TEST
     inceptionYear = "2021"
     description = "Contains test for the compose compiler daemon"
diff --git a/compose/compiler/compiler-hosted/build.gradle b/compose/compiler/compiler-hosted/build.gradle
index fb76744..e4ce28e 100644
--- a/compose/compiler/compiler-hosted/build.gradle
+++ b/compose/compiler/compiler-hosted/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Hosted Compiler Plugin"
+    name = "Compose Hosted Compiler Plugin"
     // This is only published because that is required when exporting it to g3.
     // Nobody should ever get this artifact from maven; just from studio or from source
     type = LibraryType.COMPILER_PLUGIN
diff --git a/compose/compiler/compiler-hosted/integration-tests/build.gradle b/compose/compiler/compiler-hosted/integration-tests/build.gradle
index b874154..00a111c 100644
--- a/compose/compiler/compiler-hosted/integration-tests/build.gradle
+++ b/compose/compiler/compiler-hosted/integration-tests/build.gradle
@@ -82,7 +82,7 @@
 }
 
 androidx {
-    name = "AndroidX Compiler CLI Tests"
+    name = "Compiler CLI Tests"
     publish = Publish.NONE
     inceptionYear = "2019"
     description = "Contains test for the compose compiler plugin"
diff --git a/compose/desktop/desktop/build.gradle b/compose/desktop/desktop/build.gradle
index 46e9c83..2ff1640 100644
--- a/compose/desktop/desktop/build.gradle
+++ b/compose/desktop/desktop/build.gradle
@@ -98,7 +98,7 @@
 }
 
 androidx {
-    name = "Jetpack Compose desktop implementation"
+    name = "Compose Desktop"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     legacyDisableKotlinStrictApiMode = true
diff --git a/compose/foundation/foundation-layout/samples/build.gradle b/compose/foundation/foundation-layout/samples/build.gradle
index dd396a9..3e07527 100644
--- a/compose/foundation/foundation-layout/samples/build.gradle
+++ b/compose/foundation/foundation-layout/samples/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Core Layout Classes Samples"
+    name = "Compose UI Core Layout Classes Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Core Layout Classes"
diff --git a/compose/foundation/foundation/samples/build.gradle b/compose/foundation/foundation/samples/build.gradle
index 38d57ca..d6871de 100644
--- a/compose/foundation/foundation/samples/build.gradle
+++ b/compose/foundation/foundation/samples/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Foundational Component Samples"
+    name = "Compose UI Foundational Component Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Foundational Components"
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
index 39f045c..af3679b 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyGridSnapFlingBehaviorTest.kt
@@ -24,7 +24,10 @@
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
 import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion.CenterToCenter
 import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
+import androidx.compose.foundation.gestures.snapping.offsetOnMainAxis
 import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.singleAxisViewportSize
+import androidx.compose.foundation.gestures.snapping.sizeOnMainAxis
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
@@ -469,11 +472,16 @@
         var itemIndex = -1
         if (state == null) return -1
         var minDistance = Float.POSITIVE_INFINITY
+        val layoutInfo = state.layoutInfo
         (state.layoutInfo.visibleItemsInfo).forEach {
             val distance = calculateDistanceToDesiredSnapPosition(
-                state.layoutInfo,
-                it,
-                CenterToCenter
+                mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+                beforeContentPadding = layoutInfo.beforeContentPadding,
+                afterContentPadding = layoutInfo.afterContentPadding,
+                itemSize = it.sizeOnMainAxis(orientation = layoutInfo.orientation),
+                itemOffset = it.offsetOnMainAxis(orientation = layoutInfo.orientation),
+                itemIndex = it.index,
+                snapPositionInLayout = CenterToCenter
             )
             if (abs(distance) < minDistance) {
                 minDistance = abs(distance)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
index 3153d92..603bbf7 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/gesture/snapping/LazyListSnapFlingBehaviorTest.kt
@@ -26,6 +26,7 @@
 import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout.Companion.CenterToCenter
 import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
+import androidx.compose.foundation.gestures.snapping.singleAxisViewportSize
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
@@ -457,11 +458,16 @@
         var itemIndex = -1
         if (state == null) return -1
         var minDistance = Float.POSITIVE_INFINITY
+        val layoutInfo = state.layoutInfo
         (state.layoutInfo.visibleItemsInfo).forEach {
             val distance = calculateDistanceToDesiredSnapPosition(
-                state.layoutInfo,
-                it,
-                CenterToCenter
+                mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+                beforeContentPadding = layoutInfo.beforeContentPadding,
+                afterContentPadding = layoutInfo.afterContentPadding,
+                itemSize = it.size,
+                itemOffset = it.offset,
+                itemIndex = it.index,
+                snapPositionInLayout = CenterToCenter
             )
             if (abs(distance) < minDistance) {
                 minDistance = abs(distance)
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
index 030e1d7..5885114 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/grid/LazyGridAnimateItemPlacementTest.kt
@@ -18,6 +18,8 @@
 
 import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.scrollBy
@@ -28,6 +30,8 @@
 import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.layout.requiredWidthIn
+import androidx.compose.foundation.lazy.list.getValueAtFrame
+import androidx.compose.foundation.lazy.list.getVelocityAtFrame
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
@@ -2254,6 +2258,70 @@
         }
     }
 
+    @Test
+    fun interruptedSizeChange() {
+        var item0Size by mutableStateOf(itemSizeDp)
+        val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+        rule.setContent {
+            LazyGrid(cells = 1) {
+                items(2, key = { it }) {
+                    Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = itemSize2Dp
+        }
+
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, itemSize)
+                )
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterOneFrame =
+                    animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, valueAfterOneFrame)
+                )
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = 0.dp
+        }
+
+        rule.waitForIdle()
+        val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+        val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, startValue)
+                )
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterThreeFrames = animSpec.getValueAtFrame(
+                    1,
+                    from = startValue,
+                    to = 0f,
+                    initialVelocity = startVelocity
+                )
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, valueAfterThreeFrames)
+                )
+            }
+        }
+    }
+
     private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
         if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
 
@@ -2337,9 +2405,11 @@
         for (i in 0..duration step FrameDuration) {
             val fraction = i / duration.toFloat()
             onFrame(fraction)
-            rule.mainClock.advanceTimeBy(FrameDuration)
-            expectedTime += FrameDuration
-            assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            if (i < duration) {
+                rule.mainClock.advanceTimeBy(FrameDuration)
+                expectedTime += FrameDuration
+                assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            }
         }
     }
 
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
index 74ca4f1..2763637 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/list/LazyListAnimateItemPlacementTest.kt
@@ -18,6 +18,10 @@
 
 import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.SpringSpec
+import androidx.compose.animation.core.VectorConverter
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.scrollBy
@@ -65,6 +69,7 @@
 import androidx.test.filters.LargeTest
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import java.util.concurrent.TimeUnit
 import kotlin.math.roundToInt
 import kotlinx.coroutines.runBlocking
 import org.junit.Assume.assumeTrue
@@ -1703,6 +1708,58 @@
         }
     }
 
+    @Test
+    fun interruptedSizeChange() {
+        var item0Size by mutableStateOf(itemSizeDp)
+        val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+        rule.setContent {
+            LazyList {
+                items(2, key = { it }) {
+                    Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = itemSize2Dp
+        }
+
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(0 to 0f, 1 to itemSize)
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterOneFrame =
+                    animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+                assertPositions(0 to 0f, 1 to valueAfterOneFrame, fraction = fraction)
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = 0.dp
+        }
+
+        rule.waitForIdle()
+        val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+        val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(0 to 0f, 1 to startValue)
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterThreeFrames = animSpec.getValueAtFrame(
+                    1,
+                    from = startValue,
+                    to = 0f,
+                    initialVelocity = startVelocity
+                )
+                assertPositions(0 to 0f, 1 to valueAfterThreeFrames)
+            }
+        }
+    }
+
     private fun assertPositions(
         vararg expected: Pair<Any, Float>,
         crossAxis: List<Pair<Any, Float>>? = null,
@@ -1777,9 +1834,11 @@
         for (i in 0..duration step FrameDuration) {
             val fraction = i / duration.toFloat()
             onFrame(fraction)
-            rule.mainClock.advanceTimeBy(FrameDuration)
-            expectedTime += FrameDuration
-            assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            if (i < duration) {
+                rule.mainClock.advanceTimeBy(FrameDuration)
+                expectedTime += FrameDuration
+                assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            }
         }
     }
 
@@ -1923,3 +1982,51 @@
     End,
     Center
 }
+
+internal fun SpringSpec<IntOffset>.getValueAtFrame(
+    frameCount: Int,
+    from: Float,
+    to: Float,
+    initialVelocity: IntOffset = IntOffset.Zero
+): Float {
+    val frameInNanos = TimeUnit.MILLISECONDS.toNanos(FrameDuration)
+    val vectorized = vectorize(converter = IntOffset.VectorConverter)
+    return IntOffset.VectorConverter.convertFromVector(
+        vectorized.getValueFromNanos(
+            playTimeNanos = frameInNanos * frameCount,
+            initialValue = IntOffset.VectorConverter.convertToVector(
+                IntOffset(0, from.toInt())
+            ),
+            targetValue = IntOffset.VectorConverter.convertToVector(
+                IntOffset(0, to.toInt())
+            ),
+            initialVelocity = IntOffset.VectorConverter.convertToVector(
+                initialVelocity
+            )
+        )
+    ).y.toFloat()
+}
+
+internal fun SpringSpec<IntOffset>.getVelocityAtFrame(
+    frameCount: Int,
+    from: Float,
+    to: Float,
+    initialVelocity: IntOffset = IntOffset.Zero
+): IntOffset {
+    val frameInNanos = TimeUnit.MILLISECONDS.toNanos(FrameDuration)
+    val vectorized = vectorize(converter = IntOffset.VectorConverter)
+    return IntOffset.VectorConverter.convertFromVector(
+        vectorized.getVelocityFromNanos(
+            playTimeNanos = frameInNanos * frameCount,
+            initialValue = IntOffset.VectorConverter.convertToVector(
+                IntOffset(0, from.toInt())
+            ),
+            targetValue = IntOffset.VectorConverter.convertToVector(
+                IntOffset(0, to.toInt())
+            ),
+            initialVelocity = IntOffset.VectorConverter.convertToVector(
+                initialVelocity
+            )
+        )
+    )
+}
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
index 984c7d4..41f1c73f 100644
--- a/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
+++ b/compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/staggeredgrid/LazyStaggeredGridAnimateItemPlacementTest.kt
@@ -18,6 +18,8 @@
 
 import androidx.compose.animation.core.FiniteAnimationSpec
 import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.VisibilityThreshold
+import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.scrollBy
@@ -27,6 +29,8 @@
 import androidx.compose.foundation.layout.requiredHeightIn
 import androidx.compose.foundation.layout.requiredWidth
 import androidx.compose.foundation.layout.requiredWidthIn
+import androidx.compose.foundation.lazy.list.getValueAtFrame
+import androidx.compose.foundation.lazy.list.getVelocityAtFrame
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
@@ -1992,6 +1996,70 @@
         }
     }
 
+    @Test
+    fun interruptedSizeChange() {
+        var item0Size by mutableStateOf(itemSizeDp)
+        val animSpec = spring(visibilityThreshold = IntOffset.VisibilityThreshold)
+        rule.setContent {
+            LazyStaggeredGrid(cells = 1) {
+                items(2, key = { it }) {
+                    Item(it, if (it == 0) item0Size else itemSizeDp, animSpec = animSpec)
+                }
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = itemSize2Dp
+        }
+
+        rule.waitForIdle()
+        rule.mainClock.advanceTimeByFrame()
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, itemSize)
+                )
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterOneFrame =
+                    animSpec.getValueAtFrame(1, from = itemSize, to = itemSize2)
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, valueAfterOneFrame)
+                )
+            }
+        }
+
+        rule.runOnUiThread {
+            item0Size = 0.dp
+        }
+
+        rule.waitForIdle()
+        val startValue = animSpec.getValueAtFrame(2, from = itemSize, to = itemSize2)
+        val startVelocity = animSpec.getVelocityAtFrame(2, from = itemSize, to = itemSize2)
+        onAnimationFrame(duration = FrameDuration) { fraction ->
+            if (fraction == 0f) {
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, startValue)
+                )
+            } else {
+                assertThat(fraction).isEqualTo(1f)
+                val valueAfterThreeFrames = animSpec.getValueAtFrame(
+                    1,
+                    from = startValue,
+                    to = 0f,
+                    initialVelocity = startVelocity
+                )
+                assertPositions(
+                    0 to AxisOffset(0f, 0f),
+                    1 to AxisOffset(0f, valueAfterThreeFrames)
+                )
+            }
+        }
+    }
+
     private fun AxisOffset(crossAxis: Float, mainAxis: Float) =
         if (isVertical) Offset(crossAxis, mainAxis) else Offset(mainAxis, crossAxis)
 
@@ -2075,9 +2143,11 @@
         for (i in 0..duration step FrameDuration) {
             val fraction = i / duration.toFloat()
             onFrame(fraction)
-            rule.mainClock.advanceTimeBy(FrameDuration)
-            expectedTime += FrameDuration
-            assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            if (i < duration) {
+                rule.mainClock.advanceTimeBy(FrameDuration)
+                expectedTime += FrameDuration
+                assertThat(expectedTime).isEqualTo(rule.mainClock.currentTime)
+            }
         }
     }
 
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
index 515dfc3..962b9d9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyGridSnapLayoutInfoProvider.kt
@@ -78,7 +78,15 @@
 
         layoutInfo.visibleItemsInfo.fastForEach { item ->
             val distance =
-                calculateDistanceToDesiredSnapPosition(layoutInfo, item, positionInLayout)
+                calculateDistanceToDesiredSnapPosition(
+                    mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+                    beforeContentPadding = layoutInfo.beforeContentPadding,
+                    afterContentPadding = layoutInfo.afterContentPadding,
+                    itemSize = item.sizeOnMainAxis(orientation = layoutInfo.orientation),
+                    itemOffset = item.offsetOnMainAxis(orientation = layoutInfo.orientation),
+                    itemIndex = item.index,
+                    snapPositionInLayout = positionInLayout
+                )
 
             // Find item that is closest to the center
             if (distance <= 0 && distance > distanceFromItemBeforeTarget) {
@@ -112,32 +120,14 @@
     }
 }
 
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
-    layoutInfo: LazyGridLayoutInfo,
-    item: LazyGridItemInfo,
-    positionInLayout: SnapPositionInLayout = SnapPositionInLayout.CenterToCenter
-): Float {
-
-    val containerSize =
-        with(layoutInfo) { singleAxisViewportSize - beforeContentPadding - afterContentPadding }
-
-    val desiredDistance = with(positionInLayout) {
-        position(containerSize, item.sizeOnMainAxis(layoutInfo.orientation), item.index)
-    }
-
-    val itemCurrentPosition = item.offsetOnMainAxis(layoutInfo.orientation)
-    return itemCurrentPosition - desiredDistance.toFloat()
-}
-
-private val LazyGridLayoutInfo.singleAxisViewportSize: Int
+internal val LazyGridLayoutInfo.singleAxisViewportSize: Int
     get() = if (orientation == Orientation.Vertical) {
         viewportSize.height
     } else {
         viewportSize.width
     }
 
-private fun LazyGridItemInfo.sizeOnMainAxis(orientation: Orientation): Int {
+internal fun LazyGridItemInfo.sizeOnMainAxis(orientation: Orientation): Int {
     return if (orientation == Orientation.Vertical) {
         size.height
     } else {
@@ -145,7 +135,7 @@
     }
 }
 
-private fun LazyGridItemInfo.offsetOnMainAxis(orientation: Orientation): Int {
+internal fun LazyGridItemInfo.offsetOnMainAxis(orientation: Orientation): Int {
     return if (orientation == Orientation.Vertical) {
         offset.y
     } else {
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
index fece172..5df071b 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/LazyListSnapLayoutInfoProvider.kt
@@ -22,7 +22,6 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.FlingBehavior
 import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.lazy.LazyListItemInfo
 import androidx.compose.foundation.lazy.LazyListLayoutInfo
 import androidx.compose.foundation.lazy.LazyListState
 import androidx.compose.runtime.Composable
@@ -71,7 +70,15 @@
 
         layoutInfo.visibleItemsInfo.fastForEach { item ->
             val offset =
-                calculateDistanceToDesiredSnapPosition(layoutInfo, item, positionInLayout)
+                calculateDistanceToDesiredSnapPosition(
+                    mainAxisViewPortSize = layoutInfo.singleAxisViewportSize,
+                    beforeContentPadding = layoutInfo.beforeContentPadding,
+                    afterContentPadding = layoutInfo.afterContentPadding,
+                    itemSize = item.size,
+                    itemOffset = item.offset,
+                    itemIndex = item.index,
+                    snapPositionInLayout = positionInLayout
+                )
 
             // Find item that is closest to the center
             if (offset <= 0 && offset > lowerBoundOffset) {
@@ -110,22 +117,5 @@
     return rememberSnapFlingBehavior(snappingLayout)
 }
 
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
-    layoutInfo: LazyListLayoutInfo,
-    item: LazyListItemInfo,
-    positionInLayout: SnapPositionInLayout
-): Float {
-    val containerSize =
-        with(layoutInfo) { singleAxisViewportSize - beforeContentPadding - afterContentPadding }
-
-    val desiredDistance = with(positionInLayout) {
-        position(containerSize, item.size, item.index)
-    }.toFloat()
-
-    val itemCurrentPosition = item.offset
-    return itemCurrentPosition - desiredDistance
-}
-
-private val LazyListLayoutInfo.singleAxisViewportSize: Int
+internal val LazyListLayoutInfo.singleAxisViewportSize: Int
     get() = if (orientation == Orientation.Vertical) viewportSize.height else viewportSize.width
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
index 3b3f94f..6a16ff9 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/snapping/SnapPositionInLayout.kt
@@ -39,4 +39,23 @@
         val CenterToCenter =
             SnapPositionInLayout { layoutSize, itemSize, _ -> layoutSize / 2 - itemSize / 2 }
     }
+}
+
+@OptIn(ExperimentalFoundationApi::class)
+internal fun Density.calculateDistanceToDesiredSnapPosition(
+    mainAxisViewPortSize: Int,
+    beforeContentPadding: Int,
+    afterContentPadding: Int,
+    itemSize: Int,
+    itemOffset: Int,
+    itemIndex: Int,
+    snapPositionInLayout: SnapPositionInLayout
+): Float {
+    val containerSize = mainAxisViewPortSize - beforeContentPadding - afterContentPadding
+
+    val desiredDistance = with(snapPositionInLayout) {
+        position(containerSize, itemSize, itemIndex)
+    }.toFloat()
+
+    return itemOffset - desiredDistance
 }
\ No newline at end of file
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
index 5623db2..dc2161f 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/layout/LazyLayoutAnimateItemModifierNode.kt
@@ -92,10 +92,17 @@
                 } else {
                     placementAnimationSpec
                 }
-                val startVelocity = placementDeltaAnimation.velocity
-                placementDeltaAnimation.snapTo(totalDelta)
-                placementDeltaAnimation.animateTo(IntOffset.Zero, spec, startVelocity) {
-                    placementDelta = value
+                if (!placementDeltaAnimation.isRunning) {
+                    // if not running we can snap to the initial value and animate to zero
+                    placementDeltaAnimation.snapTo(totalDelta)
+                }
+                // if animation is not currently running the target will be zero, otherwise
+                // we have to continue the animation from the current value, but keep the needed
+                // total delta for the new animation.
+                val animationTarget = placementDeltaAnimation.value - totalDelta
+                placementDeltaAnimation.animateTo(animationTarget, spec) {
+                    // placementDelta is calculated as if we always animate to target equal to zero
+                    placementDelta = value - animationTarget
                 }
 
                 isAnimationInProgress = false
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
index 9d070c4..96e93f6 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt
@@ -31,6 +31,7 @@
 import androidx.compose.foundation.gestures.snapping.MinFlingVelocityDp
 import androidx.compose.foundation.gestures.snapping.SnapFlingBehavior
 import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Stable
@@ -673,13 +674,13 @@
 
             layoutInfo.visiblePagesInfo.fastForEach { page ->
                 val offset = calculateDistanceToDesiredSnapPosition(
-                    axisViewPortSize = layoutInfo.mainAxisViewportSize,
+                    mainAxisViewPortSize = layoutInfo.mainAxisViewportSize,
                     beforeContentPadding = layoutInfo.beforeContentPadding,
                     afterContentPadding = layoutInfo.afterContentPadding,
-                    pageSize = layoutInfo.pageSize,
-                    pageOffset = page.offset,
-                    pageIndex = page.index,
-                    positionInLayout = SnapAlignmentStartToStart
+                    itemSize = layoutInfo.pageSize,
+                    itemOffset = page.offset,
+                    itemIndex = page.index,
+                    snapPositionInLayout = SnapAlignmentStartToStart
                 )
 
                 // Find page that is closest to the snap position, but before it
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
index d758bf2..2cc255c 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerMeasure.kt
@@ -19,7 +19,7 @@
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.fastFilter
 import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.layout.Arrangement.Absolute.spacedBy
 import androidx.compose.foundation.lazy.layout.LazyLayoutMeasureScope
 import androidx.compose.ui.Alignment
@@ -350,6 +350,7 @@
                 else
                     currentMainAxisOffset
             )
+
         val layoutHeight = constraints
             .constrainHeight(
                 if (orientation == Orientation.Vertical)
@@ -382,13 +383,13 @@
         val closestPageToSnapPosition = visiblePagesInfo.fastMaxBy {
             -abs(
                 calculateDistanceToDesiredSnapPosition(
-                    viewPortSize,
-                    beforeContentPadding,
-                    afterContentPadding,
-                    pageAvailableSize,
-                    it.offset,
-                    it.index,
-                    SnapAlignmentStartToStart
+                    mainAxisViewPortSize = viewPortSize,
+                    beforeContentPadding = beforeContentPadding,
+                    afterContentPadding = afterContentPadding,
+                    itemSize = pageAvailableSize,
+                    itemOffset = it.offset,
+                    itemIndex = it.index,
+                    snapPositionInLayout = SnapAlignmentStartToStart
                 )
             )
         }
@@ -417,25 +418,6 @@
     }
 }
 
-@OptIn(ExperimentalFoundationApi::class)
-internal fun Density.calculateDistanceToDesiredSnapPosition(
-    axisViewPortSize: Int,
-    beforeContentPadding: Int,
-    afterContentPadding: Int,
-    pageSize: Int,
-    pageOffset: Int,
-    pageIndex: Int,
-    positionInLayout: SnapPositionInLayout
-): Float {
-    val containerSize = axisViewPortSize - beforeContentPadding - afterContentPadding
-
-    val desiredDistance = with(positionInLayout) {
-        position(containerSize, pageSize, pageIndex)
-    }.toFloat()
-
-    return pageOffset - desiredDistance
-}
-
 private fun createPagesAfterList(
     currentLastPage: Int,
     pagesCount: Int,
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
index 61592a5..ea799c2 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt
@@ -26,6 +26,7 @@
 import androidx.compose.foundation.gestures.ScrollableState
 import androidx.compose.foundation.gestures.animateScrollBy
 import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout
+import androidx.compose.foundation.gestures.snapping.calculateDistanceToDesiredSnapPosition
 import androidx.compose.foundation.interaction.InteractionSource
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier
@@ -260,13 +261,13 @@
     private val distanceToSnapPosition: Float
         get() = layoutInfo.closestPageToSnapPosition?.let {
             density.calculateDistanceToDesiredSnapPosition(
-                layoutInfo.mainAxisViewportSize,
-                layoutInfo.beforeContentPadding,
-                layoutInfo.afterContentPadding,
-                layoutInfo.pageSize,
-                it.offset,
-                it.index,
-                SnapAlignmentStartToStart
+                mainAxisViewPortSize = layoutInfo.mainAxisViewportSize,
+                beforeContentPadding = layoutInfo.beforeContentPadding,
+                afterContentPadding = layoutInfo.afterContentPadding,
+                itemSize = layoutInfo.pageSize,
+                itemOffset = it.offset,
+                itemIndex = it.index,
+                snapPositionInLayout = SnapAlignmentStartToStart
             )
         } ?: 0f
 
diff --git a/compose/material/material-icons-core/samples/build.gradle b/compose/material/material-icons-core/samples/build.gradle
index 040d910..0977215 100644
--- a/compose/material/material-icons-core/samples/build.gradle
+++ b/compose/material/material-icons-core/samples/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Core Material Icons Samples"
+    name = "Compose UI Core Material Icons Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Core Material Icons"
diff --git a/compose/material/material/samples/build.gradle b/compose/material/material/samples/build.gradle
index 0b5f612..73cef10 100644
--- a/compose/material/material/samples/build.gradle
+++ b/compose/material/material/samples/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Material Components Samples"
+    name = "Compose Material Components Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the AndroidX Compose Material components."
diff --git a/compose/material3/material3-window-size-class/samples/build.gradle b/compose/material3/material3-window-size-class/samples/build.gradle
index 4dc7891..71ffc63d1 100644
--- a/compose/material3/material3-window-size-class/samples/build.gradle
+++ b/compose/material3/material3-window-size-class/samples/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Material 3 Window Size Class Samples"
+    name = "Compose Material 3 Window Size Class Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2022"
     description = "Contains the sample code for the Material 3 Window Size Class APIs"
diff --git a/compose/material3/material3/integration-tests/material3-demos/build.gradle b/compose/material3/material3/integration-tests/material3-demos/build.gradle
index fc83ff8..76ba389 100644
--- a/compose/material3/material3/integration-tests/material3-demos/build.gradle
+++ b/compose/material3/material3/integration-tests/material3-demos/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Material3 Components Demos"
+    name = "Compose Material3 Components Demos"
     publish = Publish.NONE
     inceptionYear = "2022"
     description = "Contains the demo code for the AndroidX Compose Material 3 components."
diff --git a/compose/material3/material3/samples/build.gradle b/compose/material3/material3/samples/build.gradle
index 075b5f4..eb9d9a3 100644
--- a/compose/material3/material3/samples/build.gradle
+++ b/compose/material3/material3/samples/build.gradle
@@ -47,7 +47,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Material3 Components Samples"
+    name = "Compose Material3 Components Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the AndroidX Compose Material You components."
diff --git a/compose/runtime/runtime-livedata/samples/build.gradle b/compose/runtime/runtime-livedata/samples/build.gradle
index 78130f2..436d6e9 100644
--- a/compose/runtime/runtime-livedata/samples/build.gradle
+++ b/compose/runtime/runtime-livedata/samples/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Livedata Interop Samples"
+    name = "Compose UI Livedata Interop Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Livedata Interop System"
diff --git a/compose/runtime/runtime-rxjava2/samples/build.gradle b/compose/runtime/runtime-rxjava2/samples/build.gradle
index d73b254..5c9082f4 100644
--- a/compose/runtime/runtime-rxjava2/samples/build.gradle
+++ b/compose/runtime/runtime-rxjava2/samples/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose RxJava 2 Integration Samples"
+    name = "Compose RxJava 2 Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose RxJava 2 Integration System"
diff --git a/compose/runtime/runtime-rxjava3/samples/build.gradle b/compose/runtime/runtime-rxjava3/samples/build.gradle
index aa111a0..9da055d 100644
--- a/compose/runtime/runtime-rxjava3/samples/build.gradle
+++ b/compose/runtime/runtime-rxjava3/samples/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose RxJava 3 Integration Samples"
+    name = "Compose RxJava 3 Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
     description = "Contains the sample code for the Androidx Compose RxJava 3 Integration System"
diff --git a/compose/runtime/runtime-saveable/samples/build.gradle b/compose/runtime/runtime-saveable/samples/build.gradle
index 8483522..c69d961 100644
--- a/compose/runtime/runtime-saveable/samples/build.gradle
+++ b/compose/runtime/runtime-saveable/samples/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Saved Instance State System Samples"
+    name = "Compose Saved Instance State System Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose Saved Instance State System"
diff --git a/compose/runtime/runtime/samples/build.gradle b/compose/runtime/runtime/samples/build.gradle
index 376b851..a8c279f 100644
--- a/compose/runtime/runtime/samples/build.gradle
+++ b/compose/runtime/runtime/samples/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Runtime Samples"
+    name = "Compose Runtime Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Compose runtime"
diff --git a/compose/ui/ui-graphics/samples/build.gradle b/compose/ui/ui-graphics/samples/build.gradle
index b255806..15643a9 100644
--- a/compose/ui/ui-graphics/samples/build.gradle
+++ b/compose/ui/ui-graphics/samples/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Graphics Components Samples"
+    name = "Compose UI Graphics Components Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Graphics Components"
diff --git a/compose/ui/ui-inspection/build.gradle b/compose/ui/ui-inspection/build.gradle
index d7db14f..9ee96cd9 100644
--- a/compose/ui/ui-inspection/build.gradle
+++ b/compose/ui/ui-inspection/build.gradle
@@ -62,7 +62,7 @@
 }
 
 androidx {
-    name = "Android Compose Layout Inspector"
+    name = "Compose Layout Inspector"
     type = LibraryType.IDE_PLUGIN
     inceptionYear = "2021"
     description = "Compose layout inspector. Exposes information to our tools for better IDE support."
diff --git a/compose/ui/ui-test/samples/build.gradle b/compose/ui/ui-test/samples/build.gradle
index 668bb91..0845c78 100644
--- a/compose/ui/ui-test/samples/build.gradle
+++ b/compose/ui/ui-test/samples/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Testing Samples"
+    name = "Compose Testing Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2022"
     description = "Contains samples for AndroidX Compose Testing."
diff --git a/compose/ui/ui-text-google-fonts/build.gradle b/compose/ui/ui-text-google-fonts/build.gradle
index d8c49be..f557000 100644
--- a/compose/ui/ui-text-google-fonts/build.gradle
+++ b/compose/ui/ui-text-google-fonts/build.gradle
@@ -42,7 +42,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose Google Fonts integration"
+    name = "Compose Google Fonts integration"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Compose Downloadable Fonts integration for Google Fonts"
diff --git a/compose/ui/ui-text/samples/build.gradle b/compose/ui/ui-text/samples/build.gradle
index 507a2ddb..a6d5aa4 100644
--- a/compose/ui/ui-text/samples/build.gradle
+++ b/compose/ui/ui-text/samples/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Text Core Samples"
+    name = "Compose UI Text Core Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains sample code for the Androidx Compose UI Text Core APIs and Utilities"
diff --git a/compose/ui/ui-tooling-preview/build.gradle b/compose/ui/ui-tooling-preview/build.gradle
index d6d3a42..a2aa077 100644
--- a/compose/ui/ui-tooling-preview/build.gradle
+++ b/compose/ui/ui-tooling-preview/build.gradle
@@ -109,7 +109,7 @@
 }
 
 androidx {
-    name = "Compose Tooling API"
+    name = "Compose UI Preview Tooling"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Compose tooling library API. This library provides the API required to declare" +
diff --git a/compose/ui/ui-unit/samples/build.gradle b/compose/ui/ui-unit/samples/build.gradle
index a1409de..45bec6c 100644
--- a/compose/ui/ui-unit/samples/build.gradle
+++ b/compose/ui/ui-unit/samples/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Simple Unit Classes Samples"
+    name = "Compose UI Simple Unit Classes Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Simple Unit Classes"
diff --git a/compose/ui/ui-viewbinding/samples/build.gradle b/compose/ui/ui-viewbinding/samples/build.gradle
index 29fab3b..88219c6 100644
--- a/compose/ui/ui-viewbinding/samples/build.gradle
+++ b/compose/ui/ui-viewbinding/samples/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Simple Unit Classes Samples"
+    name = "Compose UI Simple Unit Classes Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Simple Unit Classes"
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 3beea81..caff544 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -217,7 +217,7 @@
 }
 
 androidx {
-    name = "Compose UI primitives"
+    name = "Compose UI"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2019"
     description = "Compose UI primitives. This library contains the primitives that form the Compose UI Toolkit, such as drawing, measurement and layout."
diff --git a/compose/ui/ui/samples/build.gradle b/compose/ui/ui/samples/build.gradle
index f2675f6..d201f40 100644
--- a/compose/ui/ui/samples/build.gradle
+++ b/compose/ui/ui/samples/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Core Classes Samples"
+    name = "Compose UI Core Classes Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Compose UI Core Classes"
diff --git a/concurrent/concurrent-futures-ktx/build.gradle b/concurrent/concurrent-futures-ktx/build.gradle
index 1c2ee74..3aee3a0 100644
--- a/concurrent/concurrent-futures-ktx/build.gradle
+++ b/concurrent/concurrent-futures-ktx/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Futures Kotlin Extensions"
+    name = "Futures Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Kotlin Extensions for Androidx implementation of Guava's ListenableFuture"
diff --git a/concurrent/concurrent-futures/build.gradle b/concurrent/concurrent-futures/build.gradle
index 2f134c0..94a63aa 100644
--- a/concurrent/concurrent-futures/build.gradle
+++ b/concurrent/concurrent-futures/build.gradle
@@ -29,7 +29,7 @@
 }
 
 androidx {
-    name = "AndroidX Futures"
+    name = "Futures"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Androidx implementation of Guava's ListenableFuture"
diff --git a/constraintlayout/constraintlayout-compose/build.gradle b/constraintlayout/constraintlayout-compose/build.gradle
index 51a3271..207692f 100644
--- a/constraintlayout/constraintlayout-compose/build.gradle
+++ b/constraintlayout/constraintlayout-compose/build.gradle
@@ -99,7 +99,7 @@
 }
 
 androidx {
-    name = "Android ConstraintLayout Compose Library"
+    name = "ConstraintLayout Compose"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CONSTRAINTLAYOUT_COMPOSE
     inceptionYear = "2022"
diff --git a/constraintlayout/constraintlayout-core/build.gradle b/constraintlayout/constraintlayout-core/build.gradle
index ce816fb..a466adb 100644
--- a/constraintlayout/constraintlayout-core/build.gradle
+++ b/constraintlayout/constraintlayout-core/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "Android ConstraintLayout Core Library"
+    name = "ConstraintLayout Core"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CONSTRAINTLAYOUT_CORE
     inceptionYear = "2022"
diff --git a/constraintlayout/constraintlayout/build.gradle b/constraintlayout/constraintlayout/build.gradle
index 060d756..52a3d6e 100644
--- a/constraintlayout/constraintlayout/build.gradle
+++ b/constraintlayout/constraintlayout/build.gradle
@@ -54,7 +54,7 @@
 }
 
 androidx {
-    name = "Android ConstraintLayout Library"
+    name = "ConstraintLayout"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CONSTRAINTLAYOUT
     inceptionYear = "2022"
diff --git a/contentpager/contentpager/build.gradle b/contentpager/contentpager/build.gradle
index d2624f7..81252bf 100644
--- a/contentpager/contentpager/build.gradle
+++ b/contentpager/contentpager/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "Android Support Content"
+    name = "Content"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Library providing support for paging across content exposed via a ContentProvider. Use of this library allows a client to avoid expensive interprocess \"cursor window swaps\" on the UI thread."
diff --git a/coordinatorlayout/coordinatorlayout/build.gradle b/coordinatorlayout/coordinatorlayout/build.gradle
index bc110f8..9578993 100644
--- a/coordinatorlayout/coordinatorlayout/build.gradle
+++ b/coordinatorlayout/coordinatorlayout/build.gradle
@@ -48,7 +48,7 @@
 }
 
 androidx {
-    name = "Android Support Library Coordinator Layout"
+    name = "Coordinator Layout"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/core/core-animation-testing/build.gradle b/core/core-animation-testing/build.gradle
index 046bc43..78bb2e4 100644
--- a/core/core-animation-testing/build.gradle
+++ b/core/core-animation-testing/build.gradle
@@ -29,7 +29,7 @@
 }
 
 androidx {
-    name = "Android Support Animator Testing"
+    name = "Animation Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CORE_ANIMATION_TESTING
     inceptionYear = "2018"
diff --git a/core/core-animation/build.gradle b/core/core-animation/build.gradle
index fb7cc95..940504b 100644
--- a/core/core-animation/build.gradle
+++ b/core/core-animation/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Support Animation"
+    name = "Animation"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CORE_ANIMATION
     inceptionYear = "2018"
diff --git a/core/core-appdigest/build.gradle b/core/core-appdigest/build.gradle
index a0d4af2..7dadc10 100644
--- a/core/core-appdigest/build.gradle
+++ b/core/core-appdigest/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "AndroidX AppDigest Library"
+    name = "AppDigest"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CORE_APPDIGEST
     inceptionYear = "2020"
diff --git a/core/core-google-shortcuts/build.gradle b/core/core-google-shortcuts/build.gradle
index 3071a80..615be8f 100644
--- a/core/core-google-shortcuts/build.gradle
+++ b/core/core-google-shortcuts/build.gradle
@@ -54,7 +54,7 @@
 }
 
 androidx {
-    name = "Google Shortcuts Integration Library"
+    name = "Google Shortcuts Integration"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CORE_GOOGLE_SHORTCUTS
     inceptionYear = "2021"
diff --git a/core/core-graphics-integration-tests/testapp/build.gradle b/core/core-graphics-integration-tests/testapp/build.gradle
index 59d5bb3..768d7b4 100644
--- a/core/core-graphics-integration-tests/testapp/build.gradle
+++ b/core/core-graphics-integration-tests/testapp/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "AndroidX bitmap scaling Sample"
+    name = "bitmap scaling Sample"
     inceptionYear = "2021"
     description = "Sample for the AndoridX graphics bitmap compatibility"
 }
diff --git a/core/core-location-altitude/build.gradle b/core/core-location-altitude/build.gradle
index 6f5e108..ccee9b7 100644
--- a/core/core-location-altitude/build.gradle
+++ b/core/core-location-altitude/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "Location Altitude Compatibility Library"
+    name = "Location Altitude"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CORE_LOCATION_ALTITUDE
     inceptionYear = "2022"
diff --git a/core/core-remoteviews/build.gradle b/core/core-remoteviews/build.gradle
index eb33cc1..78adb5b 100644
--- a/core/core-remoteviews/build.gradle
+++ b/core/core-remoteviews/build.gradle
@@ -58,7 +58,7 @@
 }
 
 androidx {
-    name = "AndroidX RemoteViews Support"
+    name = "RemoteViews"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CORE_REMOTEVIEWS
     inceptionYear = "2021"
diff --git a/core/core-role/build.gradle b/core/core-role/build.gradle
index e2f2c0a..f820a13 100644
--- a/core/core-role/build.gradle
+++ b/core/core-role/build.gradle
@@ -14,7 +14,7 @@
 }
 
 androidx {
-    name = "Android Support Library Role"
+    name = "Role"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CORE_ROLE
     inceptionYear = "2019"
diff --git a/core/core-splashscreen/samples/build.gradle b/core/core-splashscreen/samples/build.gradle
index 3c59a31..ae1d810 100644
--- a/core/core-splashscreen/samples/build.gradle
+++ b/core/core-splashscreen/samples/build.gradle
@@ -42,7 +42,7 @@
 }
 
 androidx {
-    name = "AndroidX Splashscreen Samples"
+    name = "Splashscreen Samples"
     type = LibraryType.SAMPLES
     mavenVersion = LibraryVersions.CORE_SPLASHSCREEN
     inceptionYear = "2021"
diff --git a/core/core-testing/build.gradle b/core/core-testing/build.gradle
index fdc6f76..1708420 100644
--- a/core/core-testing/build.gradle
+++ b/core/core-testing/build.gradle
@@ -41,9 +41,9 @@
 }
 
 androidx {
-    name = "androidx.core:core-testing"
+    name = "Core Testing"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CORE
     inceptionYear = "2023"
-    description = "Write tests using core APIs."
+    description = "Provides extensions for tests using Core APIs."
 }
diff --git a/core/core/build.gradle b/core/core/build.gradle
index fa351a1..832085f 100644
--- a/core/core/build.gradle
+++ b/core/core/build.gradle
@@ -90,10 +90,11 @@
 }
 
 androidx {
-    name = "Android Support Library compat"
+    name = "Core"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CORE
     inceptionYear = "2015"
-    description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
+    description = "Provides backward-compatible implementations of Android platform APIs and " +
+            "features."
     failOnDeprecationWarnings = false
 }
diff --git a/credentials/credentials-play-services-auth/build.gradle b/credentials/credentials-play-services-auth/build.gradle
index 4558801..dab1da2 100644
--- a/credentials/credentials-play-services-auth/build.gradle
+++ b/credentials/credentials-play-services-auth/build.gradle
@@ -68,7 +68,7 @@
 }
 
 androidx {
-    name = "Credentials Play Services Auth Library"
+    name = "Credentials Play Services Auth"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "sign into apps using play-services-auth library"
diff --git a/credentials/credentials-provider/build.gradle b/credentials/credentials-provider/build.gradle
index 0f5fb6d..a2d506c 100644
--- a/credentials/credentials-provider/build.gradle
+++ b/credentials/credentials-provider/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Credentials Provider Library"
+    name = "Credentials Provider"
     publish = Publish.NONE
     inceptionYear = "2022"
     description = "use utility APIs to process requests from, and return responses to the android" +
diff --git a/credentials/credentials/build.gradle b/credentials/credentials/build.gradle
index 0c8c3fb..c548aa0 100644
--- a/credentials/credentials/build.gradle
+++ b/credentials/credentials/build.gradle
@@ -47,7 +47,7 @@
 }
 
 androidx {
-    name = "Credentials Core Library"
+    name = "Credentials"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Android Credentials Library"
diff --git a/cursoradapter/cursoradapter/build.gradle b/cursoradapter/cursoradapter/build.gradle
index 486beb8..05db38f 100644
--- a/cursoradapter/cursoradapter/build.gradle
+++ b/cursoradapter/cursoradapter/build.gradle
@@ -10,7 +10,7 @@
 }
 
 androidx {
-    name = "Android Support Library Cursor Adapter"
+    name = "Cursor Adapter"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/customview/customview-poolingcontainer/build.gradle b/customview/customview-poolingcontainer/build.gradle
index 49ae408..524083d 100644
--- a/customview/customview-poolingcontainer/build.gradle
+++ b/customview/customview-poolingcontainer/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "androidx.customview:poolingcontainer"
+    name = "CustomView Pooling Container"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.CUSTOMVIEW_POOLINGCONTAINER
     inceptionYear = "2021"
diff --git a/customview/customview/build.gradle b/customview/customview/build.gradle
index 041da7f..e184a65 100644
--- a/customview/customview/build.gradle
+++ b/customview/customview/build.gradle
@@ -20,7 +20,7 @@
 }
 
 androidx {
-    name = "Android Support Library Custom View"
+    name = "Custom View"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.CUSTOMVIEW
     inceptionYear = "2018"
diff --git a/datastore/datastore-core-okio/build.gradle b/datastore/datastore-core-okio/build.gradle
index d1c5ba1..99bb8ec 100644
--- a/datastore/datastore-core-okio/build.gradle
+++ b/datastore/datastore-core-okio/build.gradle
@@ -97,7 +97,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core Okio"
+    name = "DataStore Core Okio"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     description = "Android DataStore Core Okio- contains APIs to use datastore-core in multiplatform via okio"
diff --git a/datastore/datastore-core/build.gradle b/datastore/datastore-core/build.gradle
index da45ae9..67e6e17 100644
--- a/datastore/datastore-core/build.gradle
+++ b/datastore/datastore-core/build.gradle
@@ -156,7 +156,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core"
+    name = "DataStore Core"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     description = "Android DataStore Core - contains the underlying store used by each serialization method"
diff --git a/datastore/datastore-preferences-core/build.gradle b/datastore/datastore-preferences-core/build.gradle
index a9112b0..9567f6b 100644
--- a/datastore/datastore-preferences-core/build.gradle
+++ b/datastore/datastore-preferences-core/build.gradle
@@ -119,7 +119,7 @@
 }
 
 androidx {
-    name = "Android Preferences DataStore Core"
+    name = "Preferences DataStore Core"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     description = "Android Preferences DataStore without the Android Dependencies"
diff --git a/datastore/datastore-preferences-proto/build.gradle b/datastore/datastore-preferences-proto/build.gradle
index 258630b..f599a23 100644
--- a/datastore/datastore-preferences-proto/build.gradle
+++ b/datastore/datastore-preferences-proto/build.gradle
@@ -73,7 +73,7 @@
 artifacts.add(jarjarConf.name, preferencesProtoJarJarTask.flatMap { it.archiveFile })
 
 androidx {
-    name = "Android Preferences DataStore Proto"
+    name = "Preferences DataStore Proto"
     publish = Publish.NONE
     inceptionYear = "2020"
     description = "Jarjar the generated proto and proto-lite dependency for use by " +
diff --git a/datastore/datastore-preferences-rxjava2/build.gradle b/datastore/datastore-preferences-rxjava2/build.gradle
index d58618b..f80ea3d 100644
--- a/datastore/datastore-preferences-rxjava2/build.gradle
+++ b/datastore/datastore-preferences-rxjava2/build.gradle
@@ -56,7 +56,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core RxJava2 Wrappers"
+    name = "DataStore Preferences RxJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-preferences-rxjava3/build.gradle b/datastore/datastore-preferences-rxjava3/build.gradle
index 8461448..7a06c51 100644
--- a/datastore/datastore-preferences-rxjava3/build.gradle
+++ b/datastore/datastore-preferences-rxjava3/build.gradle
@@ -56,7 +56,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core RxJava2 Wrappers"
+    name = "DataStore Preferences RxJava3"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-preferences/build.gradle b/datastore/datastore-preferences/build.gradle
index 37dfd741e..0bbbbe6 100644
--- a/datastore/datastore-preferences/build.gradle
+++ b/datastore/datastore-preferences/build.gradle
@@ -77,7 +77,7 @@
 
 
 androidx {
-    name = "Android Preferences DataStore"
+    name = "Preferences DataStore"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Preferences DataStore"
diff --git a/datastore/datastore-proto/build.gradle b/datastore/datastore-proto/build.gradle
index a3680b0..658823c 100644
--- a/datastore/datastore-proto/build.gradle
+++ b/datastore/datastore-proto/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "Android Proto DataStore"
+    name = "Proto DataStore"
     publish = Publish.NONE
     inceptionYear = "2020"
     description = "Android Proto DataStore"
diff --git a/datastore/datastore-rxjava2/build.gradle b/datastore/datastore-rxjava2/build.gradle
index 20edf8fb..f2354c5 100644
--- a/datastore/datastore-rxjava2/build.gradle
+++ b/datastore/datastore-rxjava2/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core RxJava2 Wrappers"
+    name = "DataStore RxJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore-rxjava3/build.gradle b/datastore/datastore-rxjava3/build.gradle
index c9bfe85..8de1572 100644
--- a/datastore/datastore-rxjava3/build.gradle
+++ b/datastore/datastore-rxjava3/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "Android DataStore Core RxJava2 Wrappers"
+    name = "DataStore RxJava3"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android DataStore Core - contains wrappers for using DataStore using RxJava2"
diff --git a/datastore/datastore/build.gradle b/datastore/datastore/build.gradle
index d450a9b..8b4451d 100644
--- a/datastore/datastore/build.gradle
+++ b/datastore/datastore/build.gradle
@@ -106,7 +106,7 @@
 }
 
 androidx {
-    name = "Android DataStore"
+    name = "DataStore"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2020"
     description = "Android DataStore - contains the underlying store used by each serialization " +
diff --git a/documentfile/documentfile/build.gradle b/documentfile/documentfile/build.gradle
index 4993c26..f9ab3ec 100644
--- a/documentfile/documentfile/build.gradle
+++ b/documentfile/documentfile/build.gradle
@@ -17,7 +17,7 @@
 }
 
 androidx {
-    name = "Android Support Library Document File"
+    name = "Document File"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/draganddrop/draganddrop/build.gradle b/draganddrop/draganddrop/build.gradle
index 37b0365..41c3462 100644
--- a/draganddrop/draganddrop/build.gradle
+++ b/draganddrop/draganddrop/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "AndroidX Drag and Drop Library"
+    name = "Drag and Drop"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "This library makes it easy for developers to accept data dragged-and-dropped from another app, and show a consistent affordance."
diff --git a/drawerlayout/drawerlayout/build.gradle b/drawerlayout/drawerlayout/build.gradle
index 6405b31..2e717e7 100644
--- a/drawerlayout/drawerlayout/build.gradle
+++ b/drawerlayout/drawerlayout/build.gradle
@@ -22,7 +22,7 @@
 }
 
 androidx {
-    name = "Android Support Library Drawer Layout"
+    name = "Drawer Layout"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/dynamicanimation/dynamicanimation/build.gradle b/dynamicanimation/dynamicanimation/build.gradle
index b3a6d81..29f51a5 100644
--- a/dynamicanimation/dynamicanimation/build.gradle
+++ b/dynamicanimation/dynamicanimation/build.gradle
@@ -19,7 +19,7 @@
 }
 
 androidx {
-    name = "Android Support DynamicAnimation"
+    name = "DynamicAnimation"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.DYNAMICANIMATION
     inceptionYear = "2017"
diff --git a/emoji/emoji-appcompat/build.gradle b/emoji/emoji-appcompat/build.gradle
index df0af37..b0e39af 100644
--- a/emoji/emoji-appcompat/build.gradle
+++ b/emoji/emoji-appcompat/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "Android Emoji AppCompat"
+    name = "Emoji AppCompat"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.EMOJI
     inceptionYear = "2017"
diff --git a/emoji/emoji-bundled/build.gradle b/emoji/emoji-bundled/build.gradle
index d757fb1..3414c36 100644
--- a/emoji/emoji-bundled/build.gradle
+++ b/emoji/emoji-bundled/build.gradle
@@ -21,7 +21,7 @@
 }
 
 androidx {
-    name = "Android Emoji Compat"
+    name = "Emoji Bundled"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.EMOJI
     inceptionYear = "2017"
diff --git a/emoji/emoji/build.gradle b/emoji/emoji/build.gradle
index 5e135b6..cfb14e4 100644
--- a/emoji/emoji/build.gradle
+++ b/emoji/emoji/build.gradle
@@ -54,7 +54,7 @@
 }
 
 androidx {
-    name = "Android Emoji Compat"
+    name = "Emoji"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.EMOJI
     inceptionYear = "2017"
diff --git a/emoji2/emoji2-bundled/build.gradle b/emoji2/emoji2-bundled/build.gradle
index 5be609e..da5a158 100644
--- a/emoji2/emoji2-bundled/build.gradle
+++ b/emoji2/emoji2-bundled/build.gradle
@@ -46,7 +46,7 @@
 }
 
 androidx {
-    name = "Android Emoji2 Compat"
+    name = "Emoji2 Bundled"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Library bundled with assets to enable emoji compatibility in Kitkat and newer " +
diff --git a/emoji2/emoji2-emojipicker/build.gradle b/emoji2/emoji2-emojipicker/build.gradle
index 2ab0c6a..0761e00 100644
--- a/emoji2/emoji2-emojipicker/build.gradle
+++ b/emoji2/emoji2-emojipicker/build.gradle
@@ -57,7 +57,7 @@
 }
 
 androidx {
-    name = "androidx.emoji2:emoji2-emojipicker"
+    name = "Emoji2 Emoji Picker"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "This library provides the latest emoji support and emoji picker UI to input " +
diff --git a/emoji2/emoji2-views-helper/build.gradle b/emoji2/emoji2-views-helper/build.gradle
index ed51ab7..62b7b69 100644
--- a/emoji2/emoji2-views-helper/build.gradle
+++ b/emoji2/emoji2-views-helper/build.gradle
@@ -27,8 +27,8 @@
 }
 
 androidx {
-    name = "Android Emoji2 Compat view helpers"
+    name = "Emoji2 Views Helper"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
-    description = "View helpers for Emoji2"
+    description = "Provide helper classes for Emoji2 views."
 }
diff --git a/emoji2/emoji2-views/build.gradle b/emoji2/emoji2-views/build.gradle
index 597d3b1..eae7eb2 100644
--- a/emoji2/emoji2-views/build.gradle
+++ b/emoji2/emoji2-views/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "Android Emoji2 Compat Views"
+    name = "Emoji2 Views"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Support for using emoji2 directly with Android Views, for use in apps without " +
diff --git a/emoji2/emoji2/build.gradle b/emoji2/emoji2/build.gradle
index f1a2cdd..3ab8724 100644
--- a/emoji2/emoji2/build.gradle
+++ b/emoji2/emoji2/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Emoji2 Compat"
+    name = "Emoji2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Core library to enable emoji compatibility in Kitkat and newer devices to avoid the empty emoji characters."
diff --git a/exifinterface/exifinterface/build.gradle b/exifinterface/exifinterface/build.gradle
index b6bcaab..12e623a 100644
--- a/exifinterface/exifinterface/build.gradle
+++ b/exifinterface/exifinterface/build.gradle
@@ -16,7 +16,7 @@
 }
 
 androidx {
-    name = "Android Support ExifInterface"
+    name = "ExifInterface"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2016"
     description = "Android Support ExifInterface"
diff --git a/fragment/fragment-lint/build.gradle b/fragment/fragment-lint/build.gradle
index 9a091e2..b4f8162 100644
--- a/fragment/fragment-lint/build.gradle
+++ b/fragment/fragment-lint/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Android Fragment Lint Checks"
+    name = "Fragment Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2019"
     description = "Android Fragment Lint Checks"
diff --git a/fragment/fragment-testing-lint/build.gradle b/fragment/fragment-testing-lint/build.gradle
index 91a6a84..a9641c7 100644
--- a/fragment/fragment-testing-lint/build.gradle
+++ b/fragment/fragment-testing-lint/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "Android Fragment-Testing Lint Checks"
+    name = "Fragment-Testing Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2019"
     description = "Lint Checks for the Fragment Testing module"
diff --git a/fragment/fragment-testing-manifest-lint/build.gradle b/fragment/fragment-testing-manifest-lint/build.gradle
index 3f8af05..9b4b9f4 100644
--- a/fragment/fragment-testing-manifest-lint/build.gradle
+++ b/fragment/fragment-testing-manifest-lint/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "Android Fragment-Testing-Manifest Lint Checks"
+    name = "Fragment-Testing-Manifest Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2022"
     description = "Lint Checks for the Fragment Testing Manifest module"
diff --git a/fragment/fragment-testing/build.gradle b/fragment/fragment-testing/build.gradle
index 4ef2ed4..0230108 100644
--- a/fragment/fragment-testing/build.gradle
+++ b/fragment/fragment-testing/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "Fragment Test Extensions"
+    name = "Fragment Testing Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Extensions for testing 'fragment' artifact"
diff --git a/fragment/fragment/build.gradle b/fragment/fragment/build.gradle
index 91b6c0f..e2863b8 100644
--- a/fragment/fragment/build.gradle
+++ b/fragment/fragment/build.gradle
@@ -71,7 +71,7 @@
 }
 
 androidx {
-    name = "Android Support Library fragment"
+    name = "fragment"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/glance/glance-appwidget-preview/build.gradle b/glance/glance-appwidget-preview/build.gradle
index 07567f5..20fd21c 100644
--- a/glance/glance-appwidget-preview/build.gradle
+++ b/glance/glance-appwidget-preview/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "Android Glance AppWidget Preview"
+    name = "Glance AppWidget Preview"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GLANCE_PREVIEW
     inceptionYear = "2022"
diff --git a/glance/glance-material/build.gradle b/glance/glance-material/build.gradle
index 5a02590..17a787b 100644
--- a/glance/glance-material/build.gradle
+++ b/glance/glance-material/build.gradle
@@ -26,7 +26,7 @@
 }
 
 androidx {
-    name = "Android Glance Material"
+    name = "Glance Material"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Glance Material 2 integration library." +
diff --git a/glance/glance-material3/build.gradle b/glance/glance-material3/build.gradle
index 4177903..9439749 100644
--- a/glance/glance-material3/build.gradle
+++ b/glance/glance-material3/build.gradle
@@ -26,7 +26,7 @@
 }
 
 androidx {
-    name = "Android Glance Material"
+    name = "Glance Material"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Glance Material integration library." +
diff --git a/glance/glance-preview/build.gradle b/glance/glance-preview/build.gradle
index 844dcee..0857b2ee 100644
--- a/glance/glance-preview/build.gradle
+++ b/glance/glance-preview/build.gradle
@@ -24,7 +24,7 @@
 }
 
 androidx {
-    name = "Android Glance Preview"
+    name = "Glance Preview"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GLANCE_PREVIEW
     inceptionYear = "2022"
diff --git a/glance/glance-template/build.gradle b/glance/glance-template/build.gradle
index a74f078..331d3e2 100644
--- a/glance/glance-template/build.gradle
+++ b/glance/glance-template/build.gradle
@@ -73,7 +73,7 @@
 }
 
 androidx {
-    name = "Glance Templates Library"
+    name = "Glance Templates"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GLANCE_TEMPLATE
     inceptionYear = "2021"
diff --git a/glance/glance-wear-tiles-preview/build.gradle b/glance/glance-wear-tiles-preview/build.gradle
index a5836b4..9314528 100644
--- a/glance/glance-wear-tiles-preview/build.gradle
+++ b/glance/glance-wear-tiles-preview/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Glance Wear Tiles Preview"
+    name = "Glance Wear Tiles Preview"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GLANCE_WEAR_TILES
     inceptionYear = "2022"
diff --git a/glance/glance/build.gradle b/glance/glance/build.gradle
index 68ec157..1d44a68 100644
--- a/glance/glance/build.gradle
+++ b/glance/glance/build.gradle
@@ -88,7 +88,7 @@
 }
 
 androidx {
-    name = "Glance Core Library"
+    name = "Glance"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Glance allows developers to build layouts for remote surfaces using a Jetpack " +
diff --git a/graphics/graphics-core/build.gradle b/graphics/graphics-core/build.gradle
index f20971b..b99b3c8 100644
--- a/graphics/graphics-core/build.gradle
+++ b/graphics/graphics-core/build.gradle
@@ -61,7 +61,7 @@
 }
 
 androidx {
-    name = "Android Graphics Core"
+    name = "Graphics Core"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GRAPHICS_CORE
     inceptionYear = "2021"
diff --git a/graphics/graphics-shapes/build.gradle b/graphics/graphics-shapes/build.gradle
index f04e619..5e5dfc1 100644
--- a/graphics/graphics-shapes/build.gradle
+++ b/graphics/graphics-shapes/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Graphics Shapes"
+    name = "Graphics Shapes"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.GRAPHICS_SHAPES
     inceptionYear = "2022"
diff --git a/gridlayout/gridlayout/build.gradle b/gridlayout/gridlayout/build.gradle
index 44db995..9fdbcdb 100644
--- a/gridlayout/gridlayout/build.gradle
+++ b/gridlayout/gridlayout/build.gradle
@@ -17,7 +17,7 @@
 }
 
 androidx {
-    name = "Android Support Grid Layout"
+    name = "Grid Layout"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2013"
     description = "Android Support Grid Layout"
diff --git a/health/connect/connect-client-proto/build.gradle b/health/connect/connect-client-proto/build.gradle
index 0458446..0ed136e 100644
--- a/health/connect/connect-client-proto/build.gradle
+++ b/health/connect/connect-client-proto/build.gradle
@@ -78,7 +78,7 @@
 artifacts.add(jarjarConf.name, preferencesProtoJarJarTask.flatMap { it.archiveFile })
 
 androidx {
-    name = "AndroidX Health Connect Client Proto"
+    name = "Health Connect Client Proto"
     publish = Publish.NONE
     inceptionYear = "2022"
     description = "Proto files for health-connect-client"
diff --git a/health/connect/connect-client/api/current.txt b/health/connect/connect-client/api/current.txt
index 0a8378c..a5bd664 100644
--- a/health/connect/connect-client/api/current.txt
+++ b/health/connect/connect-client/api/current.txt
@@ -421,21 +421,119 @@
   public static final class ElevationGainedRecord.Companion {
   }
 
+  public final class ExerciseLap {
+    ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+    method public java.time.Instant getEndTime();
+    method public androidx.health.connect.client.units.Length? getLength();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final androidx.health.connect.client.units.Length? length;
+    property public final java.time.Instant startTime;
+  }
+
+  public final class ExerciseSegment {
+    ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+    method public java.time.Instant getEndTime();
+    method public int getRepetitions();
+    method public int getSegmentType();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int repetitions;
+    property public final int segmentType;
+    property public final java.time.Instant startTime;
+    field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+    field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+    field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+    field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+    field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+    field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+    field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+    field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+    field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+    field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+    field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+    field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+    field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+    field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+    field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+    field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+    field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+    field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+    field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+    field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+    field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+    field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+    field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+    field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+    field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+    field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+    field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+    field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+    field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+    field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+    field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+    field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+    field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+    field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+    field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+    field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+    field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+    field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+  }
+
+  public static final class ExerciseSegment.Companion {
+  }
+
   public final class ExerciseSessionRecord implements androidx.health.connect.client.records.Record {
-    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public int getExerciseType();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
     property public java.time.Instant endTime;
     property public java.time.ZoneOffset? endZoneOffset;
     property public final int exerciseType;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
@@ -944,11 +1042,12 @@
   }
 
   public final class SleepSessionRecord implements androidx.health.connect.client.records.Record {
-    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
@@ -956,32 +1055,14 @@
     property public java.time.ZoneOffset? endZoneOffset;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
     field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
     field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
-  }
-
-  public static final class SleepSessionRecord.Companion {
-  }
-
-  public final class SleepStageRecord implements androidx.health.connect.client.records.Record {
-    ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
-    method public java.time.Instant getEndTime();
-    method public java.time.ZoneOffset? getEndZoneOffset();
-    method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
-    method public int getStage();
-    method public java.time.Instant getStartTime();
-    method public java.time.ZoneOffset? getStartZoneOffset();
-    property public java.time.Instant endTime;
-    property public java.time.ZoneOffset? endZoneOffset;
-    property public androidx.health.connect.client.records.metadata.Metadata metadata;
-    property public final int stage;
-    property public java.time.Instant startTime;
-    property public java.time.ZoneOffset? startZoneOffset;
-    field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
     field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+    field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
     field public static final int STAGE_TYPE_DEEP = 5; // 0x5
     field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
     field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -990,7 +1071,17 @@
     field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public static final class SleepStageRecord.Companion {
+  public static final class SleepSessionRecord.Companion {
+  }
+
+  public static final class SleepSessionRecord.Stage {
+    ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+    method public java.time.Instant getEndTime();
+    method public int getStage();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int stage;
+    property public final java.time.Instant startTime;
   }
 
   public final class SpeedRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/public_plus_experimental_current.txt b/health/connect/connect-client/api/public_plus_experimental_current.txt
index 0a8378c..a5bd664 100644
--- a/health/connect/connect-client/api/public_plus_experimental_current.txt
+++ b/health/connect/connect-client/api/public_plus_experimental_current.txt
@@ -421,21 +421,119 @@
   public static final class ElevationGainedRecord.Companion {
   }
 
+  public final class ExerciseLap {
+    ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+    method public java.time.Instant getEndTime();
+    method public androidx.health.connect.client.units.Length? getLength();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final androidx.health.connect.client.units.Length? length;
+    property public final java.time.Instant startTime;
+  }
+
+  public final class ExerciseSegment {
+    ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+    method public java.time.Instant getEndTime();
+    method public int getRepetitions();
+    method public int getSegmentType();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int repetitions;
+    property public final int segmentType;
+    property public final java.time.Instant startTime;
+    field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+    field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+    field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+    field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+    field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+    field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+    field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+    field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+    field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+    field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+    field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+    field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+    field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+    field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+    field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+    field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+    field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+    field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+    field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+    field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+    field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+    field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+    field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+    field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+    field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+    field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+    field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+    field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+    field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+    field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+    field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+    field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+    field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+    field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+    field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+    field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+    field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+    field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+  }
+
+  public static final class ExerciseSegment.Companion {
+  }
+
   public final class ExerciseSessionRecord implements androidx.health.connect.client.records.Record {
-    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public int getExerciseType();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
     property public java.time.Instant endTime;
     property public java.time.ZoneOffset? endZoneOffset;
     property public final int exerciseType;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
@@ -944,11 +1042,12 @@
   }
 
   public final class SleepSessionRecord implements androidx.health.connect.client.records.Record {
-    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
@@ -956,32 +1055,14 @@
     property public java.time.ZoneOffset? endZoneOffset;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
     field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
     field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
-  }
-
-  public static final class SleepSessionRecord.Companion {
-  }
-
-  public final class SleepStageRecord implements androidx.health.connect.client.records.Record {
-    ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
-    method public java.time.Instant getEndTime();
-    method public java.time.ZoneOffset? getEndZoneOffset();
-    method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
-    method public int getStage();
-    method public java.time.Instant getStartTime();
-    method public java.time.ZoneOffset? getStartZoneOffset();
-    property public java.time.Instant endTime;
-    property public java.time.ZoneOffset? endZoneOffset;
-    property public androidx.health.connect.client.records.metadata.Metadata metadata;
-    property public final int stage;
-    property public java.time.Instant startTime;
-    property public java.time.ZoneOffset? startZoneOffset;
-    field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
     field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+    field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
     field public static final int STAGE_TYPE_DEEP = 5; // 0x5
     field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
     field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -990,7 +1071,17 @@
     field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public static final class SleepStageRecord.Companion {
+  public static final class SleepSessionRecord.Companion {
+  }
+
+  public static final class SleepSessionRecord.Stage {
+    ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+    method public java.time.Instant getEndTime();
+    method public int getStage();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int stage;
+    property public final java.time.Instant startTime;
   }
 
   public final class SpeedRecord implements androidx.health.connect.client.records.Record {
diff --git a/health/connect/connect-client/api/restricted_current.txt b/health/connect/connect-client/api/restricted_current.txt
index 970eb61..fbce104 100644
--- a/health/connect/connect-client/api/restricted_current.txt
+++ b/health/connect/connect-client/api/restricted_current.txt
@@ -421,21 +421,119 @@
   public static final class ElevationGainedRecord.Companion {
   }
 
+  public final class ExerciseLap {
+    ctor public ExerciseLap(java.time.Instant startTime, java.time.Instant endTime, optional androidx.health.connect.client.units.Length? length);
+    method public java.time.Instant getEndTime();
+    method public androidx.health.connect.client.units.Length? getLength();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final androidx.health.connect.client.units.Length? length;
+    property public final java.time.Instant startTime;
+  }
+
+  public final class ExerciseSegment {
+    ctor public ExerciseSegment(java.time.Instant startTime, java.time.Instant endTime, int segmentType, optional int repetitions);
+    method public java.time.Instant getEndTime();
+    method public int getRepetitions();
+    method public int getSegmentType();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int repetitions;
+    property public final int segmentType;
+    property public final java.time.Instant startTime;
+    field public static final androidx.health.connect.client.records.ExerciseSegment.Companion Companion;
+    field public static final int EXERCISE_SEGMENT_TYPE_ARM_CURL = 1; // 0x1
+    field public static final int EXERCISE_SEGMENT_TYPE_BACK_EXTENSION = 2; // 0x2
+    field public static final int EXERCISE_SEGMENT_TYPE_BALL_SLAM = 3; // 0x3
+    field public static final int EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS = 4; // 0x4
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_PRESS = 5; // 0x5
+    field public static final int EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP = 6; // 0x6
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING = 7; // 0x7
+    field public static final int EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY = 8; // 0x8
+    field public static final int EXERCISE_SEGMENT_TYPE_BURPEE = 9; // 0x9
+    field public static final int EXERCISE_SEGMENT_TYPE_CRUNCH = 10; // 0xa
+    field public static final int EXERCISE_SEGMENT_TYPE_DEADLIFT = 11; // 0xb
+    field public static final int EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION = 12; // 0xc
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM = 13; // 0xd
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM = 14; // 0xe
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE = 15; // 0xf
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE = 16; // 0x10
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW = 17; // 0x11
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM = 18; // 0x12
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM = 19; // 0x13
+    field public static final int EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM = 20; // 0x14
+    field public static final int EXERCISE_SEGMENT_TYPE_ELLIPTICAL = 21; // 0x15
+    field public static final int EXERCISE_SEGMENT_TYPE_FORWARD_TWIST = 22; // 0x16
+    field public static final int EXERCISE_SEGMENT_TYPE_FRONT_RAISE = 23; // 0x17
+    field public static final int EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING = 24; // 0x18
+    field public static final int EXERCISE_SEGMENT_TYPE_HIP_THRUST = 25; // 0x19
+    field public static final int EXERCISE_SEGMENT_TYPE_HULA_HOOP = 26; // 0x1a
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMPING_JACK = 27; // 0x1b
+    field public static final int EXERCISE_SEGMENT_TYPE_JUMP_ROPE = 28; // 0x1c
+    field public static final int EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING = 29; // 0x1d
+    field public static final int EXERCISE_SEGMENT_TYPE_LATERAL_RAISE = 30; // 0x1e
+    field public static final int EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN = 31; // 0x1f
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_CURL = 32; // 0x20
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_EXTENSION = 33; // 0x21
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_PRESS = 34; // 0x22
+    field public static final int EXERCISE_SEGMENT_TYPE_LEG_RAISE = 35; // 0x23
+    field public static final int EXERCISE_SEGMENT_TYPE_LUNGE = 36; // 0x24
+    field public static final int EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER = 37; // 0x25
+    field public static final int EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT = 38; // 0x26
+    field public static final int EXERCISE_SEGMENT_TYPE_PAUSE = 39; // 0x27
+    field public static final int EXERCISE_SEGMENT_TYPE_PILATES = 40; // 0x28
+    field public static final int EXERCISE_SEGMENT_TYPE_PLANK = 41; // 0x29
+    field public static final int EXERCISE_SEGMENT_TYPE_PULL_UP = 42; // 0x2a
+    field public static final int EXERCISE_SEGMENT_TYPE_PUNCH = 43; // 0x2b
+    field public static final int EXERCISE_SEGMENT_TYPE_REST = 44; // 0x2c
+    field public static final int EXERCISE_SEGMENT_TYPE_ROWING_MACHINE = 45; // 0x2d
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING = 46; // 0x2e
+    field public static final int EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL = 47; // 0x2f
+    field public static final int EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS = 48; // 0x30
+    field public static final int EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION = 49; // 0x31
+    field public static final int EXERCISE_SEGMENT_TYPE_SIT_UP = 50; // 0x32
+    field public static final int EXERCISE_SEGMENT_TYPE_SQUAT = 51; // 0x33
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING = 52; // 0x34
+    field public static final int EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE = 53; // 0x35
+    field public static final int EXERCISE_SEGMENT_TYPE_STRETCHING = 54; // 0x36
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE = 55; // 0x37
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE = 56; // 0x38
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY = 57; // 0x39
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE = 58; // 0x3a
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED = 59; // 0x3b
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER = 60; // 0x3c
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER = 61; // 0x3d
+    field public static final int EXERCISE_SEGMENT_TYPE_SWIMMING_POOL = 62; // 0x3e
+    field public static final int EXERCISE_SEGMENT_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int EXERCISE_SEGMENT_TYPE_UPPER_TWIST = 63; // 0x3f
+    field public static final int EXERCISE_SEGMENT_TYPE_WALKING = 64; // 0x40
+    field public static final int EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING = 65; // 0x41
+    field public static final int EXERCISE_SEGMENT_TYPE_WHEELCHAIR = 66; // 0x42
+    field public static final int EXERCISE_SEGMENT_TYPE_YOGA = 67; // 0x43
+  }
+
+  public static final class ExerciseSegment.Companion {
+  }
+
   public final class ExerciseSessionRecord implements androidx.health.connect.client.records.IntervalRecord {
-    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public ExerciseSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int exerciseType, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata, optional java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments, optional java.util.List<androidx.health.connect.client.records.ExerciseLap> laps);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public int getExerciseType();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseLap> getLaps();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.ExerciseSegment> getSegments();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
     property public java.time.Instant endTime;
     property public java.time.ZoneOffset? endZoneOffset;
     property public final int exerciseType;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseLap> laps;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.ExerciseSegment> segments;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
@@ -967,11 +1065,12 @@
   }
 
   public final class SleepSessionRecord implements androidx.health.connect.client.records.IntervalRecord {
-    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional androidx.health.connect.client.records.metadata.Metadata metadata);
+    ctor public SleepSessionRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, optional String? title, optional String? notes, optional java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages, optional androidx.health.connect.client.records.metadata.Metadata metadata);
     method public java.time.Instant getEndTime();
     method public java.time.ZoneOffset? getEndZoneOffset();
     method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
     method public String? getNotes();
+    method public java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> getStages();
     method public java.time.Instant getStartTime();
     method public java.time.ZoneOffset? getStartZoneOffset();
     method public String? getTitle();
@@ -979,32 +1078,14 @@
     property public java.time.ZoneOffset? endZoneOffset;
     property public androidx.health.connect.client.records.metadata.Metadata metadata;
     property public final String? notes;
+    property public final java.util.List<androidx.health.connect.client.records.SleepSessionRecord.Stage> stages;
     property public java.time.Instant startTime;
     property public java.time.ZoneOffset? startZoneOffset;
     property public final String? title;
     field public static final androidx.health.connect.client.records.SleepSessionRecord.Companion Companion;
     field public static final androidx.health.connect.client.aggregate.AggregateMetric<java.time.Duration> SLEEP_DURATION_TOTAL;
-  }
-
-  public static final class SleepSessionRecord.Companion {
-  }
-
-  public final class SleepStageRecord implements androidx.health.connect.client.records.IntervalRecord {
-    ctor public SleepStageRecord(java.time.Instant startTime, java.time.ZoneOffset? startZoneOffset, java.time.Instant endTime, java.time.ZoneOffset? endZoneOffset, int stage, optional androidx.health.connect.client.records.metadata.Metadata metadata);
-    method public java.time.Instant getEndTime();
-    method public java.time.ZoneOffset? getEndZoneOffset();
-    method public androidx.health.connect.client.records.metadata.Metadata getMetadata();
-    method public int getStage();
-    method public java.time.Instant getStartTime();
-    method public java.time.ZoneOffset? getStartZoneOffset();
-    property public java.time.Instant endTime;
-    property public java.time.ZoneOffset? endZoneOffset;
-    property public androidx.health.connect.client.records.metadata.Metadata metadata;
-    property public final int stage;
-    property public java.time.Instant startTime;
-    property public java.time.ZoneOffset? startZoneOffset;
-    field public static final androidx.health.connect.client.records.SleepStageRecord.Companion Companion;
     field public static final int STAGE_TYPE_AWAKE = 1; // 0x1
+    field public static final int STAGE_TYPE_AWAKE_IN_BED = 7; // 0x7
     field public static final int STAGE_TYPE_DEEP = 5; // 0x5
     field public static final int STAGE_TYPE_LIGHT = 4; // 0x4
     field public static final int STAGE_TYPE_OUT_OF_BED = 3; // 0x3
@@ -1013,7 +1094,17 @@
     field public static final int STAGE_TYPE_UNKNOWN = 0; // 0x0
   }
 
-  public static final class SleepStageRecord.Companion {
+  public static final class SleepSessionRecord.Companion {
+  }
+
+  public static final class SleepSessionRecord.Stage {
+    ctor public SleepSessionRecord.Stage(java.time.Instant startTime, java.time.Instant endTime, int stage);
+    method public java.time.Instant getEndTime();
+    method public int getStage();
+    method public java.time.Instant getStartTime();
+    property public final java.time.Instant endTime;
+    property public final int stage;
+    property public final java.time.Instant startTime;
   }
 
   public final class SpeedRecord implements androidx.health.connect.client.records.SeriesRecord<androidx.health.connect.client.records.SpeedRecord.Sample> {
diff --git a/health/connect/connect-client/build.gradle b/health/connect/connect-client/build.gradle
index 06b657b..f3b4530 100644
--- a/health/connect/connect-client/build.gradle
+++ b/health/connect/connect-client/build.gradle
@@ -73,7 +73,7 @@
 }
 
 androidx {
-    name = "AndroidX Health Connect Client Library"
+    name = "Health Connect Client"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "read or write user's health and fitness records."
diff --git a/health/connect/connect-client/samples/build.gradle b/health/connect/connect-client/samples/build.gradle
index 2d8bd45..b1b2388 100644
--- a/health/connect/connect-client/samples/build.gradle
+++ b/health/connect/connect-client/samples/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Health Connect Library Samples"
+    name = "Health Connect Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2022"
     description = "Contains the sample code for the Androidx Health Connect Library"
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
index 08aa1fc..290feb0 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseLap.kt
@@ -16,21 +16,19 @@
 
 package androidx.health.connect.client.records
 
-import androidx.annotation.RestrictTo
 import androidx.health.connect.client.units.Length
 import java.time.Instant
 
 /**
  * Captures the time of a lap within an exercise session.
  *
- * <p>Each lap contains the start and end time and optional [Length] of the lap (e.g. pool
- * length while swimming or a track lap while running). There may or may not be direct correlation
- * with [ExerciseSegment] start and end times, e.g. [ExerciseSessionRecord] of type
- * running without any segments can be divided into laps of different lengths.
+ * <p>Each lap contains the start and end time and optional [Length] of the lap (e.g. pool length
+ * while swimming or a track lap while running). There may or may not be direct correlation with
+ * [ExerciseSegment] start and end times, e.g. [ExerciseSessionRecord] of type running without any
+ * segments can be divided into laps of different lengths.
  *
  * @see ExerciseSessionRecord
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
 public class ExerciseLap(
     public val startTime: Instant,
     public val endTime: Instant,
@@ -62,4 +60,4 @@
         result = 31 * result + length.hashCode()
         return result
     }
-}
\ No newline at end of file
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
index 67cf876..6afd2ee 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSegment.kt
@@ -28,7 +28,6 @@
  *
  * @see ExerciseSessionRecord
  */
-@RestrictTo(RestrictTo.Scope.LIBRARY)
 public class ExerciseSegment(
     public val startTime: Instant,
     public val endTime: Instant,
@@ -70,10 +69,7 @@
         if (UNIVERSAL_SEGMENTS.contains(segmentType)) {
             return true
         }
-        if (!SESSION_TO_SEGMENTS_MAPPING.contains(sessionType)) {
-            return false
-        }
-        return SESSION_TO_SEGMENTS_MAPPING[sessionType]!!.contains(segmentType)
+        return SESSION_TO_SEGMENTS_MAPPING[sessionType]?.contains(segmentType) ?: false
     }
 
     companion object {
@@ -280,179 +276,48 @@
         /** Use this type for yoga. */
         const val EXERCISE_SEGMENT_TYPE_YOGA = 67
 
-        internal val UNIVERSAL_SESSION_TYPES = setOf(
-            ExerciseSessionRecord.EXERCISE_TYPE_BOOT_CAMP,
-            ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
-            ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT,
-        )
+        internal val UNIVERSAL_SESSION_TYPES =
+            setOf(
+                ExerciseSessionRecord.EXERCISE_TYPE_BOOT_CAMP,
+                ExerciseSessionRecord.EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+                ExerciseSessionRecord.EXERCISE_TYPE_OTHER_WORKOUT,
+            )
 
-        internal val UNIVERSAL_SEGMENTS = setOf(
-            EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
-            EXERCISE_SEGMENT_TYPE_PAUSE,
-            EXERCISE_SEGMENT_TYPE_REST,
-            EXERCISE_SEGMENT_TYPE_STRETCHING,
-            EXERCISE_SEGMENT_TYPE_UNKNOWN,
-        )
-
-        internal val EXERCISE_SEGMENTS = setOf(
-            EXERCISE_SEGMENT_TYPE_ARM_CURL,
-            EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
-            EXERCISE_SEGMENT_TYPE_BALL_SLAM,
-            EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
-            EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
-            EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
-            EXERCISE_SEGMENT_TYPE_BURPEE,
-            EXERCISE_SEGMENT_TYPE_CRUNCH,
-            EXERCISE_SEGMENT_TYPE_DEADLIFT,
-            EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
-            EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
-            EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
-            EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
-            EXERCISE_SEGMENT_TYPE_HIP_THRUST,
-            EXERCISE_SEGMENT_TYPE_HULA_HOOP,
-            EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
-            EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
-            EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
-            EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
-            EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
-            EXERCISE_SEGMENT_TYPE_LEG_CURL,
-            EXERCISE_SEGMENT_TYPE_LEG_EXTENSION,
-            EXERCISE_SEGMENT_TYPE_LEG_PRESS,
-            EXERCISE_SEGMENT_TYPE_LEG_RAISE,
-            EXERCISE_SEGMENT_TYPE_LUNGE,
-            EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER,
-            EXERCISE_SEGMENT_TYPE_PLANK,
-            EXERCISE_SEGMENT_TYPE_PULL_UP,
-            EXERCISE_SEGMENT_TYPE_PUNCH,
-            EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS,
-            EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
-            EXERCISE_SEGMENT_TYPE_SIT_UP,
-            EXERCISE_SEGMENT_TYPE_SQUAT,
-            EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
-            EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING
-        )
-        internal val SWIMMING_SEGMENTS = setOf(
-            EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
-            EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
-            EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
-            EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
-            EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
-            EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER
-        )
-
-        private val SESSION_TO_SEGMENTS_MAPPING = mapOf(
-            ExerciseSessionRecord.EXERCISE_TYPE_BIKING to setOf(EXERCISE_SEGMENT_TYPE_BIKING),
-            ExerciseSessionRecord.EXERCISE_TYPE_BIKING_STATIONARY to setOf(
-                EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS to EXERCISE_SEGMENTS,
-            ExerciseSessionRecord.EXERCISE_TYPE_ELLIPTICAL
-                to setOf(EXERCISE_SEGMENT_TYPE_ELLIPTICAL),
-            ExerciseSessionRecord.EXERCISE_TYPE_EXERCISE_CLASS to setOf(
-                EXERCISE_SEGMENT_TYPE_YOGA,
-                EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
-                EXERCISE_SEGMENT_TYPE_PILATES,
-                EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_GYMNASTICS to EXERCISE_SEGMENTS,
-            ExerciseSessionRecord.EXERCISE_TYPE_HIKING to setOf(
-                EXERCISE_SEGMENT_TYPE_WALKING,
-                EXERCISE_SEGMENT_TYPE_WHEELCHAIR
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_PILATES to setOf(EXERCISE_SEGMENT_TYPE_PILATES),
-            ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE to setOf(
-                EXERCISE_SEGMENT_TYPE_ROWING_MACHINE
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_RUNNING to setOf(
-                EXERCISE_SEGMENT_TYPE_RUNNING,
-                EXERCISE_SEGMENT_TYPE_WALKING
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_RUNNING_TREADMILL to setOf(
-                EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING to EXERCISE_SEGMENTS,
-            ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING to setOf(
-                EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING_MACHINE to setOf(
-                EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE
-            ),
-            ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER to buildSet {
-                add(EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER)
-                addAll(SWIMMING_SEGMENTS)
-            },
-            ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL to buildSet {
-                add(EXERCISE_SEGMENT_TYPE_SWIMMING_POOL)
-                addAll(SWIMMING_SEGMENTS)
-            },
-            ExerciseSessionRecord.EXERCISE_TYPE_WALKING to setOf(EXERCISE_SEGMENT_TYPE_WALKING),
-            ExerciseSessionRecord.EXERCISE_TYPE_WHEELCHAIR
-                to setOf(EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
-            ExerciseSessionRecord.EXERCISE_TYPE_WEIGHTLIFTING to EXERCISE_SEGMENTS,
-            ExerciseSessionRecord.EXERCISE_TYPE_YOGA to setOf(EXERCISE_SEGMENT_TYPE_YOGA),
-        )
-
-        /**
-         * List of supported segment types on Health Platform.
-         *
-         * @suppress
-         */
-        @Retention(AnnotationRetention.SOURCE)
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
-        @IntDef(
-            value =
-            [
-                EXERCISE_SEGMENT_TYPE_UNKNOWN,
-                EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
-                EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
-                EXERCISE_SEGMENT_TYPE_BIKING,
-                EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
-                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
-                EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
-                EXERCISE_SEGMENT_TYPE_ELLIPTICAL,
-                EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
-                EXERCISE_SEGMENT_TYPE_PILATES,
-                EXERCISE_SEGMENT_TYPE_ROWING_MACHINE,
-                EXERCISE_SEGMENT_TYPE_RUNNING,
-                EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL,
-                EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING,
-                EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE,
-                EXERCISE_SEGMENT_TYPE_STRETCHING,
-                EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER,
-                EXERCISE_SEGMENT_TYPE_SWIMMING_POOL,
-                EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
-                EXERCISE_SEGMENT_TYPE_WALKING,
-                EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING,
-                EXERCISE_SEGMENT_TYPE_WHEELCHAIR,
+        internal val UNIVERSAL_SEGMENTS =
+            setOf(
                 EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
-                EXERCISE_SEGMENT_TYPE_YOGA,
+                EXERCISE_SEGMENT_TYPE_PAUSE,
+                EXERCISE_SEGMENT_TYPE_REST,
+                EXERCISE_SEGMENT_TYPE_STRETCHING,
+                EXERCISE_SEGMENT_TYPE_UNKNOWN,
+            )
+
+        internal val EXERCISE_SEGMENTS =
+            setOf(
                 EXERCISE_SEGMENT_TYPE_ARM_CURL,
                 EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
                 EXERCISE_SEGMENT_TYPE_BALL_SLAM,
+                EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
                 EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
+                EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
                 EXERCISE_SEGMENT_TYPE_BURPEE,
                 EXERCISE_SEGMENT_TYPE_CRUNCH,
                 EXERCISE_SEGMENT_TYPE_DEADLIFT,
                 EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
                 EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
+                EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
+                EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
                 EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
                 EXERCISE_SEGMENT_TYPE_HIP_THRUST,
                 EXERCISE_SEGMENT_TYPE_HULA_HOOP,
-                EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
                 EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
+                EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
                 EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
                 EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
                 EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
@@ -469,16 +334,146 @@
                 EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
                 EXERCISE_SEGMENT_TYPE_SIT_UP,
                 EXERCISE_SEGMENT_TYPE_SQUAT,
-                EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
+                EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
+                EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING
+            )
+        internal val SWIMMING_SEGMENTS =
+            setOf(
                 EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
                 EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
+                EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
                 EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
                 EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
-                EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER,
-                EXERCISE_SEGMENT_TYPE_REST,
-                EXERCISE_SEGMENT_TYPE_PAUSE,
-            ]
+                EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER
+            )
+
+        private val SESSION_TO_SEGMENTS_MAPPING =
+            mapOf(
+                ExerciseSessionRecord.EXERCISE_TYPE_BIKING to setOf(EXERCISE_SEGMENT_TYPE_BIKING),
+                ExerciseSessionRecord.EXERCISE_TYPE_BIKING_STATIONARY to
+                    setOf(EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY),
+                ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS to EXERCISE_SEGMENTS,
+                ExerciseSessionRecord.EXERCISE_TYPE_ELLIPTICAL to
+                    setOf(EXERCISE_SEGMENT_TYPE_ELLIPTICAL),
+                ExerciseSessionRecord.EXERCISE_TYPE_EXERCISE_CLASS to
+                    setOf(
+                        EXERCISE_SEGMENT_TYPE_YOGA,
+                        EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
+                        EXERCISE_SEGMENT_TYPE_PILATES,
+                        EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING
+                    ),
+                ExerciseSessionRecord.EXERCISE_TYPE_GYMNASTICS to EXERCISE_SEGMENTS,
+                ExerciseSessionRecord.EXERCISE_TYPE_HIKING to
+                    setOf(EXERCISE_SEGMENT_TYPE_WALKING, EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
+                ExerciseSessionRecord.EXERCISE_TYPE_PILATES to setOf(EXERCISE_SEGMENT_TYPE_PILATES),
+                ExerciseSessionRecord.EXERCISE_TYPE_ROWING_MACHINE to
+                    setOf(EXERCISE_SEGMENT_TYPE_ROWING_MACHINE),
+                ExerciseSessionRecord.EXERCISE_TYPE_RUNNING to
+                    setOf(EXERCISE_SEGMENT_TYPE_RUNNING, EXERCISE_SEGMENT_TYPE_WALKING),
+                ExerciseSessionRecord.EXERCISE_TYPE_RUNNING_TREADMILL to
+                    setOf(EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL),
+                ExerciseSessionRecord.EXERCISE_TYPE_STRENGTH_TRAINING to EXERCISE_SEGMENTS,
+                ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING to
+                    setOf(EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING),
+                ExerciseSessionRecord.EXERCISE_TYPE_STAIR_CLIMBING_MACHINE to
+                    setOf(EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE),
+                ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER to
+                    buildSet {
+                        add(EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER)
+                        addAll(SWIMMING_SEGMENTS)
+                    },
+                ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_POOL to
+                    buildSet {
+                        add(EXERCISE_SEGMENT_TYPE_SWIMMING_POOL)
+                        addAll(SWIMMING_SEGMENTS)
+                    },
+                ExerciseSessionRecord.EXERCISE_TYPE_WALKING to setOf(EXERCISE_SEGMENT_TYPE_WALKING),
+                ExerciseSessionRecord.EXERCISE_TYPE_WHEELCHAIR to
+                    setOf(EXERCISE_SEGMENT_TYPE_WHEELCHAIR),
+                ExerciseSessionRecord.EXERCISE_TYPE_WEIGHTLIFTING to EXERCISE_SEGMENTS,
+                ExerciseSessionRecord.EXERCISE_TYPE_YOGA to setOf(EXERCISE_SEGMENT_TYPE_YOGA),
+            )
+
+        /**
+         * List of supported segment types on Health Platform.
+         *
+         * @suppress
+         */
+        @Retention(AnnotationRetention.SOURCE)
+        @RestrictTo(RestrictTo.Scope.LIBRARY)
+        @IntDef(
+            value =
+                [
+                    EXERCISE_SEGMENT_TYPE_UNKNOWN,
+                    EXERCISE_SEGMENT_TYPE_BARBELL_SHOULDER_PRESS,
+                    EXERCISE_SEGMENT_TYPE_BENCH_SIT_UP,
+                    EXERCISE_SEGMENT_TYPE_BIKING,
+                    EXERCISE_SEGMENT_TYPE_BIKING_STATIONARY,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_LEFT_ARM,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_CURL_RIGHT_ARM,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_FRONT_RAISE,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_LATERAL_RAISE,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_LEFT_ARM,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_RIGHT_ARM,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_TRICEPS_EXTENSION_TWO_ARM,
+                    EXERCISE_SEGMENT_TYPE_FORWARD_TWIST,
+                    EXERCISE_SEGMENT_TYPE_ELLIPTICAL,
+                    EXERCISE_SEGMENT_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+                    EXERCISE_SEGMENT_TYPE_PILATES,
+                    EXERCISE_SEGMENT_TYPE_ROWING_MACHINE,
+                    EXERCISE_SEGMENT_TYPE_RUNNING,
+                    EXERCISE_SEGMENT_TYPE_RUNNING_TREADMILL,
+                    EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING,
+                    EXERCISE_SEGMENT_TYPE_STAIR_CLIMBING_MACHINE,
+                    EXERCISE_SEGMENT_TYPE_STRETCHING,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_OPEN_WATER,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_POOL,
+                    EXERCISE_SEGMENT_TYPE_UPPER_TWIST,
+                    EXERCISE_SEGMENT_TYPE_WALKING,
+                    EXERCISE_SEGMENT_TYPE_WEIGHTLIFTING,
+                    EXERCISE_SEGMENT_TYPE_WHEELCHAIR,
+                    EXERCISE_SEGMENT_TYPE_OTHER_WORKOUT,
+                    EXERCISE_SEGMENT_TYPE_YOGA,
+                    EXERCISE_SEGMENT_TYPE_ARM_CURL,
+                    EXERCISE_SEGMENT_TYPE_BACK_EXTENSION,
+                    EXERCISE_SEGMENT_TYPE_BALL_SLAM,
+                    EXERCISE_SEGMENT_TYPE_BENCH_PRESS,
+                    EXERCISE_SEGMENT_TYPE_BURPEE,
+                    EXERCISE_SEGMENT_TYPE_CRUNCH,
+                    EXERCISE_SEGMENT_TYPE_DEADLIFT,
+                    EXERCISE_SEGMENT_TYPE_DOUBLE_ARM_TRICEPS_EXTENSION,
+                    EXERCISE_SEGMENT_TYPE_DUMBBELL_ROW,
+                    EXERCISE_SEGMENT_TYPE_FRONT_RAISE,
+                    EXERCISE_SEGMENT_TYPE_HIP_THRUST,
+                    EXERCISE_SEGMENT_TYPE_HULA_HOOP,
+                    EXERCISE_SEGMENT_TYPE_JUMPING_JACK,
+                    EXERCISE_SEGMENT_TYPE_JUMP_ROPE,
+                    EXERCISE_SEGMENT_TYPE_KETTLEBELL_SWING,
+                    EXERCISE_SEGMENT_TYPE_LATERAL_RAISE,
+                    EXERCISE_SEGMENT_TYPE_LAT_PULL_DOWN,
+                    EXERCISE_SEGMENT_TYPE_LEG_CURL,
+                    EXERCISE_SEGMENT_TYPE_LEG_EXTENSION,
+                    EXERCISE_SEGMENT_TYPE_LEG_PRESS,
+                    EXERCISE_SEGMENT_TYPE_LEG_RAISE,
+                    EXERCISE_SEGMENT_TYPE_LUNGE,
+                    EXERCISE_SEGMENT_TYPE_MOUNTAIN_CLIMBER,
+                    EXERCISE_SEGMENT_TYPE_PLANK,
+                    EXERCISE_SEGMENT_TYPE_PULL_UP,
+                    EXERCISE_SEGMENT_TYPE_PUNCH,
+                    EXERCISE_SEGMENT_TYPE_SHOULDER_PRESS,
+                    EXERCISE_SEGMENT_TYPE_SINGLE_ARM_TRICEPS_EXTENSION,
+                    EXERCISE_SEGMENT_TYPE_SIT_UP,
+                    EXERCISE_SEGMENT_TYPE_SQUAT,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_FREESTYLE,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_BACKSTROKE,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_BREASTSTROKE,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_BUTTERFLY,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_MIXED,
+                    EXERCISE_SEGMENT_TYPE_SWIMMING_OTHER,
+                    EXERCISE_SEGMENT_TYPE_REST,
+                    EXERCISE_SEGMENT_TYPE_PAUSE,
+                ]
         )
         annotation class ExerciseSegmentTypes
     }
-}
\ No newline at end of file
+}
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
index 4c9cb06..1709165 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/ExerciseSessionRecord.kt
@@ -34,7 +34,9 @@
  *
  * @sample androidx.health.connect.client.samples.ReadExerciseSessions
  */
-public class ExerciseSessionRecord @RestrictTo(RestrictTo.Scope.LIBRARY) constructor(
+public class ExerciseSessionRecord
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+constructor(
     override val startTime: Instant,
     override val startZoneOffset: ZoneOffset?,
     override val endTime: Instant,
@@ -46,22 +48,23 @@
     /** Additional notes for the session. Optional field. */
     public val notes: String? = null,
     override val metadata: Metadata = Metadata.EMPTY,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY)
-    /** [ExerciseSegment]s of the session. Optional field.
-     * Time in segments should be within the parent session, and should not overlap with each other.
+    /**
+     * [ExerciseSegment]s of the session. Optional field. Time in segments should be within the
+     * parent session, and should not overlap with each other.
      */
     public val segments: List<ExerciseSegment> = emptyList(),
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY)
-    /** [ExerciseLap]s of the session. Optional field.
-     * Time in laps should be within the parent session, and should not overlap with each other.
+    /**
+     * [ExerciseLap]s of the session. Optional field. Time in laps should be within the parent
+     * session, and should not overlap with each other.
      */
     public val laps: List<ExerciseLap> = emptyList(),
     @get:RestrictTo(RestrictTo.Scope.LIBRARY)
     /** [ExerciseRoute]s of the session. Optional field. */
     public val route: ExerciseRoute? = null,
     @get:RestrictTo(RestrictTo.Scope.LIBRARY)
-    /** Indicates whether or not the underlying [ExerciseSessionRecord] has a route, even it's not
-     *  present because lack of permission.
+    /**
+     * Indicates whether or not the underlying [ExerciseSessionRecord] has a route, even it's not
+     * present because lack of permission.
      */
     public val hasRoute: Boolean = false,
 ) : IntervalRecord {
@@ -78,6 +81,8 @@
         /** Additional notes for the session. Optional field. */
         notes: String? = null,
         metadata: Metadata = Metadata.EMPTY,
+        segments: List<ExerciseSegment> = emptyList(),
+        laps: List<ExerciseLap> = emptyList(),
     ) : this(
         startTime,
         startZoneOffset,
@@ -87,10 +92,9 @@
         title,
         notes,
         metadata,
-        emptyList(),
-        emptyList(),
-        null,
-        false
+        segments,
+        laps,
+        null
     )
 
     @RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -163,12 +167,9 @@
         }
         require(route == null || hasRoute) { "hasRoute must be true if the route is not null" }
         if (route != null) {
-            require(
-                route.isWithin(
-                    startTime,
-                    endTime
-                )
-            ) { "route can not be out of parent time range." }
+            require(route.isWithin(startTime, endTime)) {
+                "route can not be out of parent time range."
+            }
         }
     }
 
@@ -396,69 +397,69 @@
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     @IntDef(
         value =
-        [
-            EXERCISE_TYPE_BADMINTON,
-            EXERCISE_TYPE_BASEBALL,
-            EXERCISE_TYPE_BASKETBALL,
-            EXERCISE_TYPE_BIKING,
-            EXERCISE_TYPE_BIKING_STATIONARY,
-            EXERCISE_TYPE_BOOT_CAMP,
-            EXERCISE_TYPE_BOXING,
-            EXERCISE_TYPE_CALISTHENICS,
-            EXERCISE_TYPE_CRICKET,
-            EXERCISE_TYPE_DANCING,
-            EXERCISE_TYPE_ELLIPTICAL,
-            EXERCISE_TYPE_EXERCISE_CLASS,
-            EXERCISE_TYPE_FENCING,
-            EXERCISE_TYPE_FOOTBALL_AMERICAN,
-            EXERCISE_TYPE_FOOTBALL_AUSTRALIAN,
-            EXERCISE_TYPE_FRISBEE_DISC,
-            EXERCISE_TYPE_GOLF,
-            EXERCISE_TYPE_GUIDED_BREATHING,
-            EXERCISE_TYPE_GYMNASTICS,
-            EXERCISE_TYPE_HANDBALL,
-            EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
-            EXERCISE_TYPE_HIKING,
-            EXERCISE_TYPE_ICE_HOCKEY,
-            EXERCISE_TYPE_ICE_SKATING,
-            EXERCISE_TYPE_MARTIAL_ARTS,
-            EXERCISE_TYPE_PADDLING,
-            EXERCISE_TYPE_PARAGLIDING,
-            EXERCISE_TYPE_PILATES,
-            EXERCISE_TYPE_RACQUETBALL,
-            EXERCISE_TYPE_ROCK_CLIMBING,
-            EXERCISE_TYPE_ROLLER_HOCKEY,
-            EXERCISE_TYPE_ROWING,
-            EXERCISE_TYPE_ROWING_MACHINE,
-            EXERCISE_TYPE_RUGBY,
-            EXERCISE_TYPE_RUNNING,
-            EXERCISE_TYPE_RUNNING_TREADMILL,
-            EXERCISE_TYPE_SAILING,
-            EXERCISE_TYPE_SCUBA_DIVING,
-            EXERCISE_TYPE_SKATING,
-            EXERCISE_TYPE_SKIING,
-            EXERCISE_TYPE_SNOWBOARDING,
-            EXERCISE_TYPE_SNOWSHOEING,
-            EXERCISE_TYPE_SOCCER,
-            EXERCISE_TYPE_SOFTBALL,
-            EXERCISE_TYPE_SQUASH,
-            EXERCISE_TYPE_STAIR_CLIMBING,
-            EXERCISE_TYPE_STAIR_CLIMBING_MACHINE,
-            EXERCISE_TYPE_STRENGTH_TRAINING,
-            EXERCISE_TYPE_STRETCHING,
-            EXERCISE_TYPE_SURFING,
-            EXERCISE_TYPE_SWIMMING_OPEN_WATER,
-            EXERCISE_TYPE_SWIMMING_POOL,
-            EXERCISE_TYPE_TABLE_TENNIS,
-            EXERCISE_TYPE_TENNIS,
-            EXERCISE_TYPE_VOLLEYBALL,
-            EXERCISE_TYPE_WALKING,
-            EXERCISE_TYPE_WATER_POLO,
-            EXERCISE_TYPE_WEIGHTLIFTING,
-            EXERCISE_TYPE_WHEELCHAIR,
-            EXERCISE_TYPE_OTHER_WORKOUT,
-            EXERCISE_TYPE_YOGA,
-        ]
+            [
+                EXERCISE_TYPE_BADMINTON,
+                EXERCISE_TYPE_BASEBALL,
+                EXERCISE_TYPE_BASKETBALL,
+                EXERCISE_TYPE_BIKING,
+                EXERCISE_TYPE_BIKING_STATIONARY,
+                EXERCISE_TYPE_BOOT_CAMP,
+                EXERCISE_TYPE_BOXING,
+                EXERCISE_TYPE_CALISTHENICS,
+                EXERCISE_TYPE_CRICKET,
+                EXERCISE_TYPE_DANCING,
+                EXERCISE_TYPE_ELLIPTICAL,
+                EXERCISE_TYPE_EXERCISE_CLASS,
+                EXERCISE_TYPE_FENCING,
+                EXERCISE_TYPE_FOOTBALL_AMERICAN,
+                EXERCISE_TYPE_FOOTBALL_AUSTRALIAN,
+                EXERCISE_TYPE_FRISBEE_DISC,
+                EXERCISE_TYPE_GOLF,
+                EXERCISE_TYPE_GUIDED_BREATHING,
+                EXERCISE_TYPE_GYMNASTICS,
+                EXERCISE_TYPE_HANDBALL,
+                EXERCISE_TYPE_HIGH_INTENSITY_INTERVAL_TRAINING,
+                EXERCISE_TYPE_HIKING,
+                EXERCISE_TYPE_ICE_HOCKEY,
+                EXERCISE_TYPE_ICE_SKATING,
+                EXERCISE_TYPE_MARTIAL_ARTS,
+                EXERCISE_TYPE_PADDLING,
+                EXERCISE_TYPE_PARAGLIDING,
+                EXERCISE_TYPE_PILATES,
+                EXERCISE_TYPE_RACQUETBALL,
+                EXERCISE_TYPE_ROCK_CLIMBING,
+                EXERCISE_TYPE_ROLLER_HOCKEY,
+                EXERCISE_TYPE_ROWING,
+                EXERCISE_TYPE_ROWING_MACHINE,
+                EXERCISE_TYPE_RUGBY,
+                EXERCISE_TYPE_RUNNING,
+                EXERCISE_TYPE_RUNNING_TREADMILL,
+                EXERCISE_TYPE_SAILING,
+                EXERCISE_TYPE_SCUBA_DIVING,
+                EXERCISE_TYPE_SKATING,
+                EXERCISE_TYPE_SKIING,
+                EXERCISE_TYPE_SNOWBOARDING,
+                EXERCISE_TYPE_SNOWSHOEING,
+                EXERCISE_TYPE_SOCCER,
+                EXERCISE_TYPE_SOFTBALL,
+                EXERCISE_TYPE_SQUASH,
+                EXERCISE_TYPE_STAIR_CLIMBING,
+                EXERCISE_TYPE_STAIR_CLIMBING_MACHINE,
+                EXERCISE_TYPE_STRENGTH_TRAINING,
+                EXERCISE_TYPE_STRETCHING,
+                EXERCISE_TYPE_SURFING,
+                EXERCISE_TYPE_SWIMMING_OPEN_WATER,
+                EXERCISE_TYPE_SWIMMING_POOL,
+                EXERCISE_TYPE_TABLE_TENNIS,
+                EXERCISE_TYPE_TENNIS,
+                EXERCISE_TYPE_VOLLEYBALL,
+                EXERCISE_TYPE_WALKING,
+                EXERCISE_TYPE_WATER_POLO,
+                EXERCISE_TYPE_WEIGHTLIFTING,
+                EXERCISE_TYPE_WHEELCHAIR,
+                EXERCISE_TYPE_OTHER_WORKOUT,
+                EXERCISE_TYPE_YOGA,
+            ]
     )
     annotation class ExerciseTypes
 }
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
index 2337212..4aafec9 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepSessionRecord.kt
@@ -32,14 +32,15 @@
  * continuous but shouldn't overlap.
  *
  * Example code demonstrate how to read sleep session with stages:
+ *
  * @sample androidx.health.connect.client.samples.ReadSleepSessions
  *
  * When deleting a session, associated sleep stage records need to be deleted separately:
- * @sample androidx.health.connect.client.samples.DeleteSleepSession
  *
+ * @sample androidx.health.connect.client.samples.DeleteSleepSession
  * @see SleepStageRecord
  */
-public class SleepSessionRecord @RestrictTo(RestrictTo.Scope.LIBRARY) constructor(
+public class SleepSessionRecord(
     override val startTime: Instant,
     override val startZoneOffset: ZoneOffset?,
     override val endTime: Instant,
@@ -48,30 +49,9 @@
     public val title: String? = null,
     /** Additional notes for the session. Optional field. */
     public val notes: String? = null,
-    @get:RestrictTo(RestrictTo.Scope.LIBRARY)
     public val stages: List<Stage> = emptyList(),
     override val metadata: Metadata = Metadata.EMPTY,
 ) : IntervalRecord {
-    public constructor(
-        startTime: Instant,
-        startZoneOffset: ZoneOffset?,
-        endTime: Instant,
-        endZoneOffset: ZoneOffset?,
-        /** Title of the session. Optional field. */
-        title: String? = null,
-        /** Additional notes for the session. Optional field. */
-        notes: String? = null,
-        metadata: Metadata = Metadata.EMPTY,
-    ) : this(
-        startTime,
-        startZoneOffset,
-        endTime,
-        endZoneOffset,
-        title,
-        notes,
-        emptyList(),
-        metadata
-    )
 
     init {
         require(startTime.isBefore(endTime)) { "startTime must be before endTime." }
@@ -124,38 +104,30 @@
             AggregateMetric.durationMetric("SleepSession")
 
         /** Use this type if the stage of sleep is unknown. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_UNKNOWN = 0
 
         /**
          * The user is awake and either known to be in bed, or it is unknown whether they are in bed
          * or not.
          */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_AWAKE = 1
 
         /** The user is asleep but the particular stage of sleep (light, deep or REM) is unknown. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_SLEEPING = 2
 
         /** The user is out of bed and assumed to be awake. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_OUT_OF_BED = 3
 
         /** The user is in a light sleep stage. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_LIGHT = 4
 
         /** The user is in a deep sleep stage. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_DEEP = 5
 
         /** The user is in a REM sleep stage. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_REM = 6
 
         /** The user is awake and in bed. */
-        @RestrictTo(RestrictTo.Scope.LIBRARY)
         const val STAGE_TYPE_AWAKE_IN_BED = 7
 
         @RestrictTo(RestrictTo.Scope.LIBRARY)
@@ -180,21 +152,22 @@
 
     /**
      * Type of sleep stage.
+     *
      * @suppress
      */
     @Retention(AnnotationRetention.SOURCE)
     @IntDef(
         value =
-        [
-            STAGE_TYPE_UNKNOWN,
-            STAGE_TYPE_AWAKE,
-            STAGE_TYPE_SLEEPING,
-            STAGE_TYPE_OUT_OF_BED,
-            STAGE_TYPE_LIGHT,
-            STAGE_TYPE_DEEP,
-            STAGE_TYPE_REM,
-            STAGE_TYPE_AWAKE_IN_BED,
-        ]
+            [
+                STAGE_TYPE_UNKNOWN,
+                STAGE_TYPE_AWAKE,
+                STAGE_TYPE_SLEEPING,
+                STAGE_TYPE_OUT_OF_BED,
+                STAGE_TYPE_LIGHT,
+                STAGE_TYPE_DEEP,
+                STAGE_TYPE_REM,
+                STAGE_TYPE_AWAKE_IN_BED,
+            ]
     )
     @RestrictTo(RestrictTo.Scope.LIBRARY)
     annotation class StageTypes
@@ -204,7 +177,6 @@
      *
      * @see SleepSessionRecord
      */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
     public class Stage(
         val startTime: Instant,
         val endTime: Instant,
diff --git a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
index 1a566d9..f1af1da 100644
--- a/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
+++ b/health/connect/connect-client/src/main/java/androidx/health/connect/client/records/SleepStageRecord.kt
@@ -26,6 +26,7 @@
  *
  * @see SleepSessionRecord
  */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
 public class SleepStageRecord(
     override val startTime: Instant,
     override val startZoneOffset: ZoneOffset?,
@@ -94,6 +95,7 @@
 
     /**
      * Type of sleep stage.
+     *
      * @suppress
      */
     @Retention(AnnotationRetention.SOURCE)
diff --git a/health/health-services-client/build.gradle b/health/health-services-client/build.gradle
index 65a44a0..a0df417 100644
--- a/health/health-services-client/build.gradle
+++ b/health/health-services-client/build.gradle
@@ -79,7 +79,7 @@
 }
 
 androidx {
-    name = "AndroidX Health Services Client Library"
+    name = "Health Services Client"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.HEALTH_SERVICES_CLIENT
     inceptionYear = "2021"
diff --git a/heifwriter/heifwriter/build.gradle b/heifwriter/heifwriter/build.gradle
index 7bffa1a..3e8ff02 100644
--- a/heifwriter/heifwriter/build.gradle
+++ b/heifwriter/heifwriter/build.gradle
@@ -23,7 +23,7 @@
 }
 
 androidx {
-    name = "Android Support HeifWriter"
+    name = "HeifWriter"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Support HeifWriter for writing HEIF still images"
diff --git a/hilt/hilt-common/build.gradle b/hilt/hilt-common/build.gradle
index 24537d9..4737307 100644
--- a/hilt/hilt-common/build.gradle
+++ b/hilt/hilt-common/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "AndroidX Hilt Extension Annotations"
+    name = "Hilt Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.HILT
     inceptionYear = "2020"
diff --git a/hilt/hilt-compiler/build.gradle b/hilt/hilt-compiler/build.gradle
index eb22d1c..e6b2f0e 100644
--- a/hilt/hilt-compiler/build.gradle
+++ b/hilt/hilt-compiler/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "AndroidX Hilt Extension Compiler"
+    name = "Hilt Extension Compiler"
     type = LibraryType.ANNOTATION_PROCESSOR
     mavenVersion = LibraryVersions.HILT
     inceptionYear = "2020"
diff --git a/hilt/hilt-navigation-fragment/build.gradle b/hilt/hilt-navigation-fragment/build.gradle
index 22eea96..814229f 100644
--- a/hilt/hilt-navigation-fragment/build.gradle
+++ b/hilt/hilt-navigation-fragment/build.gradle
@@ -56,7 +56,7 @@
 }
 
 androidx {
-    name = "Android Navigation Fragment Hilt Extension"
+    name = "Navigation Fragment Hilt Extension"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.HILT
     inceptionYear = "2021"
diff --git a/hilt/hilt-navigation/build.gradle b/hilt/hilt-navigation/build.gradle
index ad4e41a..6539c86 100644
--- a/hilt/hilt-navigation/build.gradle
+++ b/hilt/hilt-navigation/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Navigation Hilt Extension"
+    name = "Navigation Hilt Extension"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.HILT
     inceptionYear = "2021"
diff --git a/hilt/hilt-work/build.gradle b/hilt/hilt-work/build.gradle
index 46f258b..abe1186 100644
--- a/hilt/hilt-work/build.gradle
+++ b/hilt/hilt-work/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle WorkManager Hilt Extension"
+    name = "WorkManager Hilt Extension"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.HILT
     inceptionYear = "2020"
diff --git a/input/input-motionprediction/build.gradle b/input/input-motionprediction/build.gradle
index c630796..e5e6f105 100644
--- a/input/input-motionprediction/build.gradle
+++ b/input/input-motionprediction/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "Android Motion Prediction"
+    name = "Motion Prediction"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.INPUT_MOTIONPREDICTION
     inceptionYear = "2022"
diff --git a/inspection/inspection-gradle-plugin/build.gradle b/inspection/inspection-gradle-plugin/build.gradle
index 4589093..bddd9ff 100644
--- a/inspection/inspection-gradle-plugin/build.gradle
+++ b/inspection/inspection-gradle-plugin/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "Android Inspection Gradle Plugin"
+    name = "Inspection Gradle Plugin"
     type = LibraryType.GRADLE_PLUGIN
     publish = Publish.NONE
     inceptionYear = "2019"
diff --git a/inspection/inspection-testing/build.gradle b/inspection/inspection-testing/build.gradle
index 7f51b57..f7b000e 100644
--- a/inspection/inspection-testing/build.gradle
+++ b/inspection/inspection-testing/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Inspection Testing"
+    name = "Inspection Testing"
     type = LibraryType.INTERNAL_TEST_LIBRARY
     publish = Publish.NONE
     inceptionYear = "2019"
diff --git a/inspection/inspection/build.gradle b/inspection/inspection/build.gradle
index 5c35b71..a142722 100644
--- a/inspection/inspection/build.gradle
+++ b/inspection/inspection/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Inspection"
+    name = "Inspection"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Experimental AndroidX Inspection Project"
diff --git a/interpolator/interpolator/build.gradle b/interpolator/interpolator/build.gradle
index 524e14e..00cd919 100644
--- a/interpolator/interpolator/build.gradle
+++ b/interpolator/interpolator/build.gradle
@@ -10,7 +10,7 @@
 }
 
 androidx {
-    name = "Android Support Library Interpolators"
+    name = "Interpolators"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/leanback/leanback-grid/build.gradle b/leanback/leanback-grid/build.gradle
index 36a1965..b6171c8 100644
--- a/leanback/leanback-grid/build.gradle
+++ b/leanback/leanback-grid/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "AndroidX Leanback Grid"
+    name = "Leanback Grid"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.LEANBACK_GRID
     inceptionYear = "2021"
diff --git a/leanback/leanback-paging/build.gradle b/leanback/leanback-paging/build.gradle
index 6c51eec..0b19679 100644
--- a/leanback/leanback-paging/build.gradle
+++ b/leanback/leanback-paging/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "AndroidX Leanback Paging"
+    name = "Leanback Paging"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.LEANBACK_PAGING
     inceptionYear = "2020"
diff --git a/leanback/leanback-preference/build.gradle b/leanback/leanback-preference/build.gradle
index d64a337..8af0e9d 100644
--- a/leanback/leanback-preference/build.gradle
+++ b/leanback/leanback-preference/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "AndroidX Leanback Preference"
+    name = "Leanback Preference"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.LEANBACK_PREFERENCE
     inceptionYear = "2015"
diff --git a/leanback/leanback-tab/build.gradle b/leanback/leanback-tab/build.gradle
index 1c0b1cb..b38819a 100644
--- a/leanback/leanback-tab/build.gradle
+++ b/leanback/leanback-tab/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "AndroidX Leanback Tab"
+    name = "Leanback Tab"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.LEANBACK_TAB
     inceptionYear = "2020"
diff --git a/leanback/leanback/build.gradle b/leanback/leanback/build.gradle
index 1a3152a..d22458a 100644
--- a/leanback/leanback/build.gradle
+++ b/leanback/leanback/build.gradle
@@ -55,7 +55,7 @@
 }
 
 androidx {
-    name = "Android Support Leanback v17"
+    name = "Leanback"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.LEANBACK
     inceptionYear = "2014"
diff --git a/lifecycle/lifecycle-common-java8/build.gradle b/lifecycle/lifecycle-common-java8/build.gradle
index cbab42e..88e4bc1 100644
--- a/lifecycle/lifecycle-common-java8/build.gradle
+++ b/lifecycle/lifecycle-common-java8/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle-Common for Java 8 Language"
+    name = "Lifecycle-Common for Java 8"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle-Common for Java 8 Language"
diff --git a/lifecycle/lifecycle-common/build.gradle b/lifecycle/lifecycle-common/build.gradle
index fcd8ba4..1aeacc3 100644
--- a/lifecycle/lifecycle-common/build.gradle
+++ b/lifecycle/lifecycle-common/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle-Common"
+    name = "Lifecycle-Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle-Common"
diff --git a/lifecycle/lifecycle-compiler/build.gradle b/lifecycle/lifecycle-compiler/build.gradle
index 60945b2..b5ac1f6 100644
--- a/lifecycle/lifecycle-compiler/build.gradle
+++ b/lifecycle/lifecycle-compiler/build.gradle
@@ -53,7 +53,7 @@
 }
 
 androidx {
-    name = "Android Lifecycles Compiler"
+    name = "Lifecycles Compiler"
     type = LibraryType.ANNOTATION_PROCESSOR
     inceptionYear = "2017"
     description = "Android Lifecycles annotation processor"
diff --git a/lifecycle/lifecycle-extensions/build.gradle b/lifecycle/lifecycle-extensions/build.gradle
index b729d31..b8c4e04 100644
--- a/lifecycle/lifecycle-extensions/build.gradle
+++ b/lifecycle/lifecycle-extensions/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Extensions"
+    name = "Lifecycle Extensions"
     publish = Publish.NONE
     runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
     inceptionYear = "2017"
diff --git a/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle b/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
index 6bb81f4..59c894a 100644
--- a/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
+++ b/lifecycle/lifecycle-livedata-core-ktx-lint/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "Android LiveData Kotlin Lint Checks"
+    name = "LiveData Kotlin Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2019"
     description = "Lint Checks for LiveData Kotlin Extensions"
diff --git a/lifecycle/lifecycle-livedata-core/build.gradle b/lifecycle/lifecycle-livedata-core/build.gradle
index 1947720d..58101b7 100644
--- a/lifecycle/lifecycle-livedata-core/build.gradle
+++ b/lifecycle/lifecycle-livedata-core/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle LiveData Core"
+    name = "Lifecycle LiveData Core"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle LiveData Core"
diff --git a/lifecycle/lifecycle-livedata/build.gradle b/lifecycle/lifecycle-livedata/build.gradle
index 824c7f0..898e7b1 100644
--- a/lifecycle/lifecycle-livedata/build.gradle
+++ b/lifecycle/lifecycle-livedata/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle LiveData"
+    name = "Lifecycle LiveData"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle LiveData"
diff --git a/lifecycle/lifecycle-process/build.gradle b/lifecycle/lifecycle-process/build.gradle
index 09a4076..2c59ba1f5 100644
--- a/lifecycle/lifecycle-process/build.gradle
+++ b/lifecycle/lifecycle-process/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Process"
+    name = "Lifecycle Process"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Lifecycle Process"
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
index 79856f6..2fef830 100644
--- a/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams-ktx/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-  name = "Android Lifecycle ReactiveStreams KTX"
+  name = "Lifecycle ReactiveStreams KTX"
   publish = Publish.SNAPSHOT_AND_RELEASE
   inceptionYear = "2018"
   description = "Kotlin extensions for Lifecycle ReactiveStreams"
diff --git a/lifecycle/lifecycle-reactivestreams/build.gradle b/lifecycle/lifecycle-reactivestreams/build.gradle
index e47bb63..e73e520b 100644
--- a/lifecycle/lifecycle-reactivestreams/build.gradle
+++ b/lifecycle/lifecycle-reactivestreams/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Reactivestreams"
+    name = "Lifecycle Reactivestreams"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle Reactivestreams"
diff --git a/lifecycle/lifecycle-runtime-compose/samples/build.gradle b/lifecycle/lifecycle-runtime-compose/samples/build.gradle
index b1f8730..334768e 100644
--- a/lifecycle/lifecycle-runtime-compose/samples/build.gradle
+++ b/lifecycle/lifecycle-runtime-compose/samples/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "AndroidX Lifecycle Runtime Compose Integration Samples"
+    name = "Lifecycle Runtime Compose Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Samples for Compose integration with Lifecycle Runtime"
diff --git a/lifecycle/lifecycle-runtime-ktx-lint/build.gradle b/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
index 3761f26..e10aea4 100644
--- a/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
+++ b/lifecycle/lifecycle-runtime-ktx-lint/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "Android Lifecycles Lint Checks"
+    name = "Lifecycles Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2019"
     description = "Android Lifecycles Lint Checks"
diff --git a/lifecycle/lifecycle-runtime-ktx/build.gradle b/lifecycle/lifecycle-runtime-ktx/build.gradle
index e394b0b..554d287 100644
--- a/lifecycle/lifecycle-runtime-ktx/build.gradle
+++ b/lifecycle/lifecycle-runtime-ktx/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Kotlin Extensions"
+    name = "Lifecycle Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Kotlin extensions for 'lifecycle' artifact"
diff --git a/lifecycle/lifecycle-runtime-testing/build.gradle b/lifecycle/lifecycle-runtime-testing/build.gradle
index 4e59db92..3c7aca3 100644
--- a/lifecycle/lifecycle-runtime-testing/build.gradle
+++ b/lifecycle/lifecycle-runtime-testing/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Runtime Testing"
+    name = "Lifecycle Runtime Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Testing utilities for 'lifecycle' artifact"
diff --git a/lifecycle/lifecycle-runtime/build.gradle b/lifecycle/lifecycle-runtime/build.gradle
index 5199df9..3e06c78 100644
--- a/lifecycle/lifecycle-runtime/build.gradle
+++ b/lifecycle/lifecycle-runtime/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name "Android Lifecycle Runtime"
+    name = "Lifecycle Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear "2017"
     description "Android Lifecycle Runtime"
diff --git a/lifecycle/lifecycle-service/build.gradle b/lifecycle/lifecycle-service/build.gradle
index 690553f..7ab4fc2 100644
--- a/lifecycle/lifecycle-service/build.gradle
+++ b/lifecycle/lifecycle-service/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle Service"
+    name = "Lifecycle Service"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Lifecycle Service"
diff --git a/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle b/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
index 195fb57..f812410 100644
--- a/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-compose/samples/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "AndroidX Lifecycle ViewModel Compose Integration Samples"
+    name = "Lifecycle ViewModel Compose Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Samples for Compose integration with Lifecycle ViewModel"
diff --git a/lifecycle/lifecycle-viewmodel-ktx/build.gradle b/lifecycle/lifecycle-viewmodel-ktx/build.gradle
index efaa638..dfb7838 100644
--- a/lifecycle/lifecycle-viewmodel-ktx/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-ktx/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle ViewModel Kotlin Extensions"
+    name = "Lifecycle ViewModel Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for 'viewmodel' artifact"
diff --git a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
index ec45470..c2144f0 100644
--- a/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-savedstate/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle ViewModel with SavedState"
+    name = "Lifecycle ViewModel with SavedState"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Lifecycle ViewModel"
diff --git a/lifecycle/lifecycle-viewmodel/build.gradle b/lifecycle/lifecycle-viewmodel/build.gradle
index 125c988..4c2db52 100644
--- a/lifecycle/lifecycle-viewmodel/build.gradle
+++ b/lifecycle/lifecycle-viewmodel/build.gradle
@@ -48,7 +48,7 @@
 }
 
 androidx {
-    name = "Android Lifecycle ViewModel"
+    name = "Lifecycle ViewModel"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Lifecycle ViewModel"
diff --git a/loader/loader/build.gradle b/loader/loader/build.gradle
index e9ff426..5b46db6 100644
--- a/loader/loader/build.gradle
+++ b/loader/loader/build.gradle
@@ -23,7 +23,7 @@
 }
 
 androidx {
-    name = "Android Support Library loader"
+    name = "loader"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2011"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren\'t a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/media/media/build.gradle b/media/media/build.gradle
index 91a6177..783d543 100644
--- a/media/media/build.gradle
+++ b/media/media/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Support Library media compat"
+    name = "Media"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.MEDIA
     inceptionYear = "2011"
diff --git a/media2/media2-common/build.gradle b/media2/media2-common/build.gradle
index 8c0570f..46c5577 100644
--- a/media2/media2-common/build.gradle
+++ b/media2/media2-common/build.gradle
@@ -62,7 +62,7 @@
 }
 
 androidx {
-    name = "AndroidX media2 common library"
+    name = "Media2 Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Media2 Common"
diff --git a/media2/media2-exoplayer/build.gradle b/media2/media2-exoplayer/build.gradle
index 291a8bc..c7873df 100644
--- a/media2/media2-exoplayer/build.gradle
+++ b/media2/media2-exoplayer/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "Media2 repackaged ExoPlayer dependency"
+    name = "Media2 ExoPlayer"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Repackaged ExoPlayer for 'media2' artifact"
diff --git a/media2/media2-player/build.gradle b/media2/media2-player/build.gradle
index c11da0f..ca8a752 100644
--- a/media2/media2-player/build.gradle
+++ b/media2/media2-player/build.gradle
@@ -49,7 +49,7 @@
 }
 
 androidx {
-    name = "AndroidX media2 player library"
+    name = "Media2 Player"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Media2 Player"
diff --git a/media2/media2-session/build.gradle b/media2/media2-session/build.gradle
index 8830b4f..66b502d 100644
--- a/media2/media2-session/build.gradle
+++ b/media2/media2-session/build.gradle
@@ -56,7 +56,7 @@
 }
 
 androidx {
-    name = "AndroidX media2 session library"
+    name = "Media2 Session"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Media2 Session"
diff --git a/media2/media2-widget/build.gradle b/media2/media2-widget/build.gradle
index d4452b3..ceee35f 100644
--- a/media2/media2-widget/build.gradle
+++ b/media2/media2-widget/build.gradle
@@ -56,7 +56,7 @@
 }
 
 androidx {
-    name = "AndroidX media2 widget library"
+    name = "Media2 Widget"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "AndroidX Media2 Widget"
diff --git a/mediarouter/mediarouter-testing/build.gradle b/mediarouter/mediarouter-testing/build.gradle
index 5d2fbf6..0e39af2 100644
--- a/mediarouter/mediarouter-testing/build.gradle
+++ b/mediarouter/mediarouter-testing/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "AndroidX MediaRouter Testing"
+    name = "MediaRouter Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2021"
     description = "Test utilities for AndroidX MediaRouter"
diff --git a/mediarouter/mediarouter/build.gradle b/mediarouter/mediarouter/build.gradle
index 2cb2454..46de044 100644
--- a/mediarouter/mediarouter/build.gradle
+++ b/mediarouter/mediarouter/build.gradle
@@ -57,7 +57,7 @@
 }
 
 androidx {
-    name = "Android MediaRouter Support Library"
+    name = "MediaRouter"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2013"
     description = "Android MediaRouter Support Library"
diff --git a/metrics/metrics-performance/build.gradle b/metrics/metrics-performance/build.gradle
index 94fcacb..8c474b0 100644
--- a/metrics/metrics-performance/build.gradle
+++ b/metrics/metrics-performance/build.gradle
@@ -59,7 +59,7 @@
 
 androidx {
 
-    name = "AndroidX Metrics"
+    name = "Metrics"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2021"
     description = "Library for tracking and reporting various runtime metrics for applications"
diff --git a/navigation/navigation-common-ktx/build.gradle b/navigation/navigation-common-ktx/build.gradle
index 03904c3..b2f94223 100644
--- a/navigation/navigation-common-ktx/build.gradle
+++ b/navigation/navigation-common-ktx/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Navigation Common Kotlin Extensions"
+    name = "Navigation Common Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Navigation-Common-Ktx"
diff --git a/navigation/navigation-common/build.gradle b/navigation/navigation-common/build.gradle
index 954e0da..91a97ad3 100644
--- a/navigation/navigation-common/build.gradle
+++ b/navigation/navigation-common/build.gradle
@@ -67,7 +67,7 @@
 }
 
 androidx {
-    name = "Android Navigation Common"
+    name = "Navigation Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Navigation-Common"
diff --git a/navigation/navigation-compose/samples/build.gradle b/navigation/navigation-compose/samples/build.gradle
index b71e29c..b229762 100644
--- a/navigation/navigation-compose/samples/build.gradle
+++ b/navigation/navigation-compose/samples/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "AndroidX Compose UI Navigation Integration Samples"
+    name = "Compose UI Navigation Integration Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
     description = "Samples for Compose integration with Navigation"
diff --git a/navigation/navigation-dynamic-features-fragment/build.gradle b/navigation/navigation-dynamic-features-fragment/build.gradle
index 80119e7..931ddb1 100644
--- a/navigation/navigation-dynamic-features-fragment/build.gradle
+++ b/navigation/navigation-dynamic-features-fragment/build.gradle
@@ -64,7 +64,7 @@
 }
 
 androidx {
-    name = "Android Dynamic Feature Navigation Fragment"
+    name = "Dynamic Feature Navigation Fragment"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android Dynamic Feature Navigation Fragment"
diff --git a/navigation/navigation-dynamic-features-runtime/build.gradle b/navigation/navigation-dynamic-features-runtime/build.gradle
index e722e52..497c5ea 100644
--- a/navigation/navigation-dynamic-features-runtime/build.gradle
+++ b/navigation/navigation-dynamic-features-runtime/build.gradle
@@ -60,7 +60,7 @@
 }
 
 androidx {
-    name = "Android Dynamic Feature Navigation Runtime"
+    name = "Dynamic Feature Navigation Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android Dynamic Feature Navigation Runtime"
diff --git a/navigation/navigation-fragment-ktx/build.gradle b/navigation/navigation-fragment-ktx/build.gradle
index 2cb0659..bd96b86 100644
--- a/navigation/navigation-fragment-ktx/build.gradle
+++ b/navigation/navigation-fragment-ktx/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "Android Navigation Fragment Kotlin Extensions"
+    name = "Navigation Fragment Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Navigation-Fragment-Ktx"
diff --git a/navigation/navigation-fragment/build.gradle b/navigation/navigation-fragment/build.gradle
index f8284f5..5edeaf7 100644
--- a/navigation/navigation-fragment/build.gradle
+++ b/navigation/navigation-fragment/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "Android Navigation Fragment"
+    name = "Navigation Fragment"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Navigation-Fragment"
diff --git a/navigation/navigation-runtime-ktx/build.gradle b/navigation/navigation-runtime-ktx/build.gradle
index 1b497c7..4663086 100644
--- a/navigation/navigation-runtime-ktx/build.gradle
+++ b/navigation/navigation-runtime-ktx/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "Android Navigation Runtime Kotlin Extensions"
+    name = "Navigation Runtime Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Navigation-Runtime-Ktx"
diff --git a/navigation/navigation-runtime-truth/build.gradle b/navigation/navigation-runtime-truth/build.gradle
index dfc5054..4ff4554f 100644
--- a/navigation/navigation-runtime-truth/build.gradle
+++ b/navigation/navigation-runtime-truth/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android Navigation Runtime Truth"
+    name = "Navigation Runtime Truth"
     publish = Publish.NONE
     inceptionYear = "2019"
     description = "Android Navigation-Runtime-Truth"
diff --git a/navigation/navigation-runtime/build.gradle b/navigation/navigation-runtime/build.gradle
index c7ebc80..ff856e6 100644
--- a/navigation/navigation-runtime/build.gradle
+++ b/navigation/navigation-runtime/build.gradle
@@ -60,7 +60,7 @@
 }
 
 androidx {
-    name = "Android Navigation Runtime"
+    name = "Navigation Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Navigation-Runtime"
diff --git a/navigation/navigation-safe-args-generator/build.gradle b/navigation/navigation-safe-args-generator/build.gradle
index 4b4c91f..988bc00 100644
--- a/navigation/navigation-safe-args-generator/build.gradle
+++ b/navigation/navigation-safe-args-generator/build.gradle
@@ -60,7 +60,7 @@
 
 
 androidx {
-    name = "Android Navigation TypeSafe Arguments Generator"
+    name = "Navigation TypeSafe Arguments Generator"
     type = LibraryType.OTHER_CODE_PROCESSOR
     inceptionYear = "2017"
     description = "Android Navigation TypeSafe Arguments Generator"
diff --git a/navigation/navigation-safe-args-gradle-plugin/build.gradle b/navigation/navigation-safe-args-gradle-plugin/build.gradle
index 1d740b2..08697dc 100644
--- a/navigation/navigation-safe-args-gradle-plugin/build.gradle
+++ b/navigation/navigation-safe-args-gradle-plugin/build.gradle
@@ -50,7 +50,7 @@
 }
 
 androidx {
-    name = "Android Navigation TypeSafe Arguments Gradle Plugin"
+    name = "Navigation TypeSafe Arguments Gradle Plugin"
     type = LibraryType.GRADLE_PLUGIN
     inceptionYear = "2017"
     description = "Android Navigation TypeSafe Arguments Gradle Plugin"
diff --git a/navigation/navigation-testing/build.gradle b/navigation/navigation-testing/build.gradle
index d30a3fc..4008f8e 100644
--- a/navigation/navigation-testing/build.gradle
+++ b/navigation/navigation-testing/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android Navigation Testing"
+    name = "Navigation Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Navigation-Testing"
diff --git a/navigation/navigation-ui-ktx/build.gradle b/navigation/navigation-ui-ktx/build.gradle
index 3cbe68b..23f6129 100644
--- a/navigation/navigation-ui-ktx/build.gradle
+++ b/navigation/navigation-ui-ktx/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "Android Navigation UI Kotlin Extensions"
+    name = "Navigation UI Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Navigation-UI-Ktx"
diff --git a/navigation/navigation-ui/build.gradle b/navigation/navigation-ui/build.gradle
index 5dd6cca..4877297 100644
--- a/navigation/navigation-ui/build.gradle
+++ b/navigation/navigation-ui/build.gradle
@@ -55,7 +55,7 @@
 }
 
 androidx {
-    name = "Android Navigation UI"
+    name = "Navigation UI"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Navigation-UI"
diff --git a/paging/paging-common-ktx/build.gradle b/paging/paging-common-ktx/build.gradle
index bab41ca..f5a7a7e 100644
--- a/paging/paging-common-ktx/build.gradle
+++ b/paging/paging-common-ktx/build.gradle
@@ -26,7 +26,7 @@
 }
 
 androidx {
-    name = "Android Paging-Common Kotlin Extensions"
+    name = "Paging-Common Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for 'paging-common' artifact"
diff --git a/paging/paging-common/build.gradle b/paging/paging-common/build.gradle
index 00ad658..bbc62bf 100644
--- a/paging/paging-common/build.gradle
+++ b/paging/paging-common/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Paging-Common"
+    name = "Paging-Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Paging-Common"
diff --git a/paging/paging-compose/build.gradle b/paging/paging-compose/build.gradle
index d31e914..8affe5a 100644
--- a/paging/paging-compose/build.gradle
+++ b/paging/paging-compose/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "Android Paging-Compose"
+    name = "Paging-Compose"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.PAGING_COMPOSE
     inceptionYear = "2020"
diff --git a/paging/paging-compose/samples/build.gradle b/paging/paging-compose/samples/build.gradle
index 6fd15b4..753063b 100644
--- a/paging/paging-compose/samples/build.gradle
+++ b/paging/paging-compose/samples/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Paging Compose Samples"
+    name = "Paging Compose Samples"
     type = LibraryType.SAMPLES
     mavenVersion = LibraryVersions.PAGING_COMPOSE
     inceptionYear = "2020"
diff --git a/paging/paging-guava/build.gradle b/paging/paging-guava/build.gradle
index 041702f..f0151c2 100644
--- a/paging/paging-guava/build.gradle
+++ b/paging/paging-guava/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "Android Paging Guava"
+    name = "Paging Guava"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android Paging Guava"
diff --git a/paging/paging-runtime-ktx/build.gradle b/paging/paging-runtime-ktx/build.gradle
index 3f2e05d..f674b7e 100644
--- a/paging/paging-runtime-ktx/build.gradle
+++ b/paging/paging-runtime-ktx/build.gradle
@@ -29,7 +29,7 @@
 }
 
 androidx {
-    name = "Android Paging-Runtime Kotlin Extensions"
+    name = "Paging-Runtime Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for 'paging-runtime' artifact"
diff --git a/paging/paging-runtime/build.gradle b/paging/paging-runtime/build.gradle
index 47fdac8..de64d71 100644
--- a/paging/paging-runtime/build.gradle
+++ b/paging/paging-runtime/build.gradle
@@ -61,7 +61,7 @@
 }
 
 androidx {
-    name = "Android Paging-Runtime"
+    name = "Paging-Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Paging-Runtime"
diff --git a/paging/paging-rxjava2-ktx/build.gradle b/paging/paging-rxjava2-ktx/build.gradle
index a355219..b53bd80 100644
--- a/paging/paging-rxjava2-ktx/build.gradle
+++ b/paging/paging-rxjava2-ktx/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Android Paging RxJava2 Kotlin Extensions"
+    name = "Paging RxJava2 Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for 'paging-rxjava2' artifact"
diff --git a/paging/paging-rxjava2/build.gradle b/paging/paging-rxjava2/build.gradle
index c830a91..5f779d0 100644
--- a/paging/paging-rxjava2/build.gradle
+++ b/paging/paging-rxjava2/build.gradle
@@ -47,7 +47,7 @@
 }
 
 androidx {
-    name = "Android Paging-RXJava2"
+    name = "Paging-RXJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Paging-RXJava2"
diff --git a/paging/paging-rxjava3/build.gradle b/paging/paging-rxjava3/build.gradle
index dc27213..05d795c 100644
--- a/paging/paging-rxjava3/build.gradle
+++ b/paging/paging-rxjava3/build.gradle
@@ -45,7 +45,7 @@
 }
 
 androidx {
-    name = "Android Paging-RxJava3"
+    name = "Paging-RxJava3"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Paging-RxJava3"
diff --git a/paging/paging-testing/build.gradle b/paging/paging-testing/build.gradle
index 18e00f6..9557e62 100644
--- a/paging/paging-testing/build.gradle
+++ b/paging/paging-testing/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "androidx.paging:paging-testing"
+    name = "Paging Testing Extensions"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Test artifact for Paging implementation"
diff --git a/paging/samples/build.gradle b/paging/samples/build.gradle
index 4a7e36a..9e5516a 100644
--- a/paging/samples/build.gradle
+++ b/paging/samples/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "AndroidX Paging Samples"
+    name = "Paging Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2019"
     description = "Contains the sample code for the Androidx Paging library"
diff --git a/palette/palette/build.gradle b/palette/palette/build.gradle
index 90bdee7..df6b451 100644
--- a/palette/palette/build.gradle
+++ b/palette/palette/build.gradle
@@ -17,7 +17,7 @@
 }
 
 androidx {
-    name = "Android Support Palette"
+    name = "Palette"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2014"
     description = "Android Support Palette"
diff --git a/percentlayout/percentlayout/build.gradle b/percentlayout/percentlayout/build.gradle
index a28d3b0..737f4d4 100644
--- a/percentlayout/percentlayout/build.gradle
+++ b/percentlayout/percentlayout/build.gradle
@@ -24,7 +24,7 @@
 }
 
 androidx {
-    name = "Android Percent Support Library"
+    name = "Percent"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2015"
     description = "Android Percent Support Library"
diff --git a/preference/preference-ktx/build.gradle b/preference/preference-ktx/build.gradle
index ebef733..e6e8c4f 100644
--- a/preference/preference-ktx/build.gradle
+++ b/preference/preference-ktx/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "Android Preferences KTX"
+    name = "Preferences KTX"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for preferences"
diff --git a/preference/preference/build.gradle b/preference/preference/build.gradle
index 366ccdc..0e7815d 100644
--- a/preference/preference/build.gradle
+++ b/preference/preference/build.gradle
@@ -64,7 +64,7 @@
 }
 
 androidx {
-    name = "AndroidX Preference"
+    name = "Preference"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2015"
     description = "AndroidX Preference"
diff --git a/print/print/build.gradle b/print/print/build.gradle
index 3b8be7c..6e9dc83 100644
--- a/print/print/build.gradle
+++ b/print/print/build.gradle
@@ -10,7 +10,7 @@
 }
 
 androidx {
-    name = "Android Support Library Print"
+    name = "Print"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/privacysandbox/ads/ads-adservices/build.gradle b/privacysandbox/ads/ads-adservices/build.gradle
index 70c6da1..13284aa 100644
--- a/privacysandbox/ads/ads-adservices/build.gradle
+++ b/privacysandbox/ads/ads-adservices/build.gradle
@@ -50,7 +50,7 @@
 }
 
 androidx {
-    name = "Androidx library for Privacy Preserving APIs."
+    name = "Privacy Sandbox for Ad Services"
     type = LibraryType.PUBLISHED_LIBRARY
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2022"
diff --git a/profileinstaller/profileinstaller/build.gradle b/profileinstaller/profileinstaller/build.gradle
index ba3d60d..793c5e5 100644
--- a/profileinstaller/profileinstaller/build.gradle
+++ b/profileinstaller/profileinstaller/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "androidx.profileinstaller:profileinstaller"
+    name = "Profile Installer"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Allows libraries to prepopulate ahead of time compilation traces to be read by" +
diff --git a/recommendation/recommendation/build.gradle b/recommendation/recommendation/build.gradle
index 25a96bf..50c69b0 100644
--- a/recommendation/recommendation/build.gradle
+++ b/recommendation/recommendation/build.gradle
@@ -17,7 +17,7 @@
 }
 
 androidx {
-    name = "Android Support Recommendation"
+    name = "Recommendation"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2015"
     description = "Android Support Recommendation"
diff --git a/recyclerview/recyclerview-selection/build.gradle b/recyclerview/recyclerview-selection/build.gradle
index 49f9cfd..12c9e66 100644
--- a/recyclerview/recyclerview-selection/build.gradle
+++ b/recyclerview/recyclerview-selection/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android RecyclerView Selection"
+    name = "RecyclerView Selection"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.RECYCLERVIEW_SELECTION
     inceptionYear = "2017"
diff --git a/recyclerview/recyclerview/build.gradle b/recyclerview/recyclerview/build.gradle
index aecfc856..8c7e013 100644
--- a/recyclerview/recyclerview/build.gradle
+++ b/recyclerview/recyclerview/build.gradle
@@ -58,7 +58,7 @@
 }
 
 androidx {
-    name = "Android Support RecyclerView"
+    name = "RecyclerView"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.RECYCLERVIEW
     inceptionYear = "2014"
diff --git a/resourceinspection/resourceinspection-annotation/build.gradle b/resourceinspection/resourceinspection-annotation/build.gradle
index 86bb07a..a5b9ce9 100644
--- a/resourceinspection/resourceinspection-annotation/build.gradle
+++ b/resourceinspection/resourceinspection-annotation/build.gradle
@@ -26,7 +26,7 @@
 }
 
 androidx {
-    name = "Android Resource Inspection - Annotations"
+    name = "Resource Inspection - Annotations"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Annotation processors for Android resource and layout inspection"
diff --git a/resourceinspection/resourceinspection-processor/build.gradle b/resourceinspection/resourceinspection-processor/build.gradle
index a633319..959ea3d 100644
--- a/resourceinspection/resourceinspection-processor/build.gradle
+++ b/resourceinspection/resourceinspection-processor/build.gradle
@@ -50,7 +50,7 @@
 }
 
 androidx {
-    name = "Android Resource Inspection - Annotation Processor"
+    name = "Resource Inspection - Annotation Processor"
     type = LibraryType.ANNOTATION_PROCESSOR
     inceptionYear = "2021"
     description = "Annotation processors for Android resource and layout inspection"
diff --git a/room/room-common/build.gradle b/room/room-common/build.gradle
index 151639e..bd514ec 100644
--- a/room/room-common/build.gradle
+++ b/room/room-common/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Room-Common"
+    name = "Room-Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room-Common"
diff --git a/room/room-compiler-processing-testing/build.gradle b/room/room-compiler-processing-testing/build.gradle
index 2d1f1e7c..abc8872 100644
--- a/room/room-compiler-processing-testing/build.gradle
+++ b/room/room-compiler-processing-testing/build.gradle
@@ -72,7 +72,7 @@
 }
 
 androidx {
-    name = "AndroidX Room XProcessor Testing"
+    name = "Room XProcessor Testing"
     type = LibraryType.ANNOTATION_PROCESSOR_UTILS
     inceptionYear = "2020"
     description = "Testing helpers for Room XProcessing APIs"
diff --git a/room/room-compiler-processing/build.gradle b/room/room-compiler-processing/build.gradle
index f3cabd0..f8d3190 100644
--- a/room/room-compiler-processing/build.gradle
+++ b/room/room-compiler-processing/build.gradle
@@ -98,7 +98,7 @@
 }
 
 androidx {
-    name = "AndroidX Room XProcessor"
+    name = "Room XProcessor"
     type = LibraryType.ANNOTATION_PROCESSOR_UTILS
     inceptionYear = "2020"
     description = "Processing Environment Abstraction for AndroidX Room"
diff --git a/room/room-compiler/build.gradle b/room/room-compiler/build.gradle
index 6b7096e..98470ed 100644
--- a/room/room-compiler/build.gradle
+++ b/room/room-compiler/build.gradle
@@ -299,7 +299,7 @@
 }
 
 androidx {
-    name = "Android Room Compiler"
+    name = "Room Compiler"
     type = LibraryType.ANNOTATION_PROCESSOR
     inceptionYear = "2017"
     description = "Android Room annotation processor"
diff --git a/room/room-gradle-plugin/build.gradle b/room/room-gradle-plugin/build.gradle
index 8b12c66..e9dfec6 100644
--- a/room/room-gradle-plugin/build.gradle
+++ b/room/room-gradle-plugin/build.gradle
@@ -81,7 +81,7 @@
 }
 
 androidx {
-    name = "Android Room Gradle Plugin"
+    name = "Room Gradle Plugin"
     type = LibraryType.GRADLE_PLUGIN
     inceptionYear = "2023"
     description = "Android Room Gradle Plugin"
diff --git a/room/room-guava/build.gradle b/room/room-guava/build.gradle
index 99c5ad7..572953f 100644
--- a/room/room-guava/build.gradle
+++ b/room/room-guava/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "Android Room Guava"
+    name = "Room Guava"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android Room Guava"
diff --git a/room/room-ktx/build.gradle b/room/room-ktx/build.gradle
index 5e4a868..3dfa666 100644
--- a/room/room-ktx/build.gradle
+++ b/room/room-ktx/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "Android Room Kotlin Extensions"
+    name = "Room Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android Room Kotlin Extensions"
diff --git a/room/room-migration/build.gradle b/room/room-migration/build.gradle
index 20954b0..3eb7477 100644
--- a/room/room-migration/build.gradle
+++ b/room/room-migration/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Room Migration"
+    name = "Room Migration"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room Migration"
diff --git a/room/room-runtime-lint/build.gradle b/room/room-runtime-lint/build.gradle
index ea43587..52cc23c 100644
--- a/room/room-runtime-lint/build.gradle
+++ b/room/room-runtime-lint/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "Android Room-Runtime Lint Checks"
+    name = "Room-Runtime Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2022"
     description = "Android Room-Runtime Lint Checks"
diff --git a/room/room-runtime/build.gradle b/room/room-runtime/build.gradle
index 5859784..f5a047d 100644
--- a/room/room-runtime/build.gradle
+++ b/room/room-runtime/build.gradle
@@ -73,7 +73,7 @@
 }
 
 androidx {
-    name = "Android Room-Runtime"
+    name = "Room-Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room-Runtime"
diff --git a/room/room-rxjava2/build.gradle b/room/room-rxjava2/build.gradle
index 6cc2e1e..c802802 100644
--- a/room/room-rxjava2/build.gradle
+++ b/room/room-rxjava2/build.gradle
@@ -39,7 +39,7 @@
 }
 
 androidx {
-    name = "Android Room RXJava2"
+    name = "Room RXJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room RXJava2"
diff --git a/room/room-rxjava3/build.gradle b/room/room-rxjava3/build.gradle
index fee4abe..3533c33 100644
--- a/room/room-rxjava3/build.gradle
+++ b/room/room-rxjava3/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "Android Room RXJava3"
+    name = "Room RXJava3"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Room RXJava3"
diff --git a/room/room-testing/build.gradle b/room/room-testing/build.gradle
index 1471e49..e8970dc 100644
--- a/room/room-testing/build.gradle
+++ b/room/room-testing/build.gradle
@@ -54,7 +54,7 @@
 }
 
 androidx {
-    name = "Android Room Testing"
+    name = "Room Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Room Testing"
diff --git a/security/security-app-authenticator-testing/build.gradle b/security/security-app-authenticator-testing/build.gradle
index 7f3ed40..e0e8856 100644
--- a/security/security-app-authenticator-testing/build.gradle
+++ b/security/security-app-authenticator-testing/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android Security App Package Authenticator Testing"
+    name = "Security App Authenticator Testing Extensions"
     type = LibraryType.PUBLISHED_TEST_LIBRARY
     mavenVersion = LibraryVersions.SECURITY_APP_AUTHENTICATOR_TESTING
     inceptionYear = "2021"
diff --git a/security/security-app-authenticator/build.gradle b/security/security-app-authenticator/build.gradle
index cb80735..de6d420 100644
--- a/security/security-app-authenticator/build.gradle
+++ b/security/security-app-authenticator/build.gradle
@@ -48,7 +48,7 @@
 }
 
 androidx {
-    name = "Android Security App Package Authenitcator Library"
+    name = "Security App Authenitcator"
     type = LibraryType.PUBLISHED_LIBRARY
     mavenVersion = LibraryVersions.SECURITY_APP_AUTHENTICATOR
     inceptionYear = "2020"
diff --git a/security/security-biometric/build.gradle b/security/security-biometric/build.gradle
index c8204ad..c48792f 100644
--- a/security/security-biometric/build.gradle
+++ b/security/security-biometric/build.gradle
@@ -43,7 +43,7 @@
 }
 
 androidx {
-    name = "AndroidX Security Biometric"
+    name = "Security Biometric"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.SECURITY_BIOMETRIC
     inceptionYear = "2020"
diff --git a/security/security-crypto-ktx/build.gradle b/security/security-crypto-ktx/build.gradle
index adf0c8b..6717a1f 100644
--- a/security/security-crypto-ktx/build.gradle
+++ b/security/security-crypto-ktx/build.gradle
@@ -42,7 +42,7 @@
 }
 
 androidx {
-    name = "AndroidX Security Kotlin Extensions"
+    name = "Security Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.SECURITY
     inceptionYear = "2020"
diff --git a/security/security-crypto/build.gradle b/security/security-crypto/build.gradle
index 4b86de9..f33cc83 100644
--- a/security/security-crypto/build.gradle
+++ b/security/security-crypto/build.gradle
@@ -46,7 +46,7 @@
 }
 
 androidx {
-    name = "AndroidX Security"
+    name = "Security"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.SECURITY
     inceptionYear = "2019"
diff --git a/security/security-identity-credential/build.gradle b/security/security-identity-credential/build.gradle
index d6b322a..b81043e 100644
--- a/security/security-identity-credential/build.gradle
+++ b/security/security-identity-credential/build.gradle
@@ -45,7 +45,7 @@
 }
 
 androidx {
-    name = "AndroidX Security"
+    name = "Security"
     publish = Publish.SNAPSHOT_AND_RELEASE
     runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
     mavenVersion = LibraryVersions.SECURITY_IDENTITY_CREDENTIAL
diff --git a/sharetarget/sharetarget/build.gradle b/sharetarget/sharetarget/build.gradle
index 233ff32..4c1c02f 100644
--- a/sharetarget/sharetarget/build.gradle
+++ b/sharetarget/sharetarget/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "AndroidX Share Target Support Library"
+    name = "Share Target"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "ShareTarget"
diff --git a/slice/slice-benchmark/build.gradle b/slice/slice-benchmark/build.gradle
index 1e151d0..6cfa1f1 100644
--- a/slice/slice-benchmark/build.gradle
+++ b/slice/slice-benchmark/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "Slices Benchmarks"
+    name = "Slice Benchmarks"
     publish = Publish.NONE // Library is deprecated pending removal.
     mavenVersion = LibraryVersions.SLICE_BENCHMARK
     inceptionYear = "2018"
diff --git a/slice/slice-builders-ktx/build.gradle b/slice/slice-builders-ktx/build.gradle
index cbd1af6..c67b6c7 100644
--- a/slice/slice-builders-ktx/build.gradle
+++ b/slice/slice-builders-ktx/build.gradle
@@ -45,7 +45,7 @@
 }
 
 androidx {
-    name = "Slice builders KTX"
+    name = "Slice Builders Kotlin Extensions"
     publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
     runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
     mavenVersion = LibraryVersions.SLICE_BUILDERS_KTX
diff --git a/slice/slice-builders/build.gradle b/slice/slice-builders/build.gradle
index a8c0dbb..06f184e 100644
--- a/slice/slice-builders/build.gradle
+++ b/slice/slice-builders/build.gradle
@@ -31,7 +31,7 @@
 }
 
 androidx {
-    name = "Slice builders"
+    name = "Slice Builders"
     publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
     runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
     mavenVersion = LibraryVersions.SLICE
diff --git a/slice/slice-core/build.gradle b/slice/slice-core/build.gradle
index 03a0441..33028b2 100644
--- a/slice/slice-core/build.gradle
+++ b/slice/slice-core/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Common utilities for slices"
+    name = "Slice Core"
     publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
     runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
     mavenVersion = LibraryVersions.SLICE
diff --git a/slice/slice-test/build.gradle b/slice/slice-test/build.gradle
index a7330d5..6913178 100644
--- a/slice/slice-test/build.gradle
+++ b/slice/slice-test/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Slice test code"
+    name = "Slice Test Extensions"
     type = LibraryType.INTERNAL_TEST_LIBRARY
     publish = Publish.NONE // Library is deprecated pending removal.
     mavenVersion = LibraryVersions.SLICE
diff --git a/slice/slice-view/build.gradle b/slice/slice-view/build.gradle
index 8f8c858..14f019d 100644
--- a/slice/slice-view/build.gradle
+++ b/slice/slice-view/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "Slice views"
+    name = "Slice Views"
     publish = Publish.SNAPSHOT_ONLY // Library is deprecated pending removal.
     runApiTasks = new RunApiTasks.Yes() // Pending removal, but keep API files for now.
     mavenVersion = LibraryVersions.SLICE
diff --git a/slidingpanelayout/slidingpanelayout/build.gradle b/slidingpanelayout/slidingpanelayout/build.gradle
index 6a29dca..58cbeb8 100644
--- a/slidingpanelayout/slidingpanelayout/build.gradle
+++ b/slidingpanelayout/slidingpanelayout/build.gradle
@@ -23,7 +23,7 @@
 }
 
 androidx {
-    name = "Android Support Library Sliding Pane Layout"
+    name = "Sliding Pane Layout"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "SlidingPaneLayout offers a responsive, two pane layout that automatically switches between overlapping panes on smaller devices to a side by side view on larger devices."
diff --git a/sqlite/sqlite-framework/build.gradle b/sqlite/sqlite-framework/build.gradle
index 0169f43..65eb1e4 100644
--- a/sqlite/sqlite-framework/build.gradle
+++ b/sqlite/sqlite-framework/build.gradle
@@ -37,7 +37,7 @@
 }
 
 androidx {
-    name = "Android Support SQLite - Framework Implementation"
+    name = "SQLite Framework Integration"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "The implementation of Support SQLite library using the framework code."
diff --git a/sqlite/sqlite-inspection/build.gradle b/sqlite/sqlite-inspection/build.gradle
index da58266..3210e2c 100644
--- a/sqlite/sqlite-inspection/build.gradle
+++ b/sqlite/sqlite-inspection/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android SQLite Inspector"
+    name = "SQLite Inspector"
     type = LibraryType.IDE_PLUGIN
     // Decouple SQLITE_INSPECTOR because it depends on
     // the inspection protocol, which is alpha
diff --git a/sqlite/sqlite-ktx/build.gradle b/sqlite/sqlite-ktx/build.gradle
index a793599..5698d49 100644
--- a/sqlite/sqlite-ktx/build.gradle
+++ b/sqlite/sqlite-ktx/build.gradle
@@ -31,7 +31,7 @@
 }
 
 androidx {
-    name = "Android DB KTX"
+    name = "SQLite Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Kotlin extensions for DB"
diff --git a/sqlite/sqlite/build.gradle b/sqlite/sqlite/build.gradle
index 580912e..5d64abf 100644
--- a/sqlite/sqlite/build.gradle
+++ b/sqlite/sqlite/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Android DB"
+    name = "SQLite"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android DB"
diff --git a/startup/startup-runtime-lint/build.gradle b/startup/startup-runtime-lint/build.gradle
index 0a10bc6..2ca037c 100644
--- a/startup/startup-runtime-lint/build.gradle
+++ b/startup/startup-runtime-lint/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android App Startup Runtime Lint Checks"
+    name = "Startup Runtime Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2020"
     description = "Android App Startup Runtime"
diff --git a/startup/startup-runtime/build.gradle b/startup/startup-runtime/build.gradle
index 9cfaac9..d4f9766 100644
--- a/startup/startup-runtime/build.gradle
+++ b/startup/startup-runtime/build.gradle
@@ -49,7 +49,7 @@
 }
 
 androidx {
-    name = "Android App Startup Runtime"
+    name = "Startup Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android App Startup Runtime"
diff --git a/swiperefreshlayout/swiperefreshlayout/build.gradle b/swiperefreshlayout/swiperefreshlayout/build.gradle
index 8450677..a80a5e5 100644
--- a/swiperefreshlayout/swiperefreshlayout/build.gradle
+++ b/swiperefreshlayout/swiperefreshlayout/build.gradle
@@ -30,7 +30,7 @@
 }
 
 androidx {
-    name = "Android Support Library Custom View"
+    name = "Swipe Refresh Layout"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/test/ext/junit-gtest/build.gradle b/test/ext/junit-gtest/build.gradle
index be6c1fd..868ab98 100644
--- a/test/ext/junit-gtest/build.gradle
+++ b/test/ext/junit-gtest/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX JUnit GTest"
+    name = "JUnit GTest"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Run GTest tests on Android devices"
diff --git a/test/screenshot/screenshot/build.gradle b/test/screenshot/screenshot/build.gradle
index 7147d25..69303c3 100644
--- a/test/screenshot/screenshot/build.gradle
+++ b/test/screenshot/screenshot/build.gradle
@@ -46,7 +46,7 @@
 }
 
 androidx {
-    name = "AndroidX Library Screenshot Test"
+    name = "Screenshot Test"
     type = LibraryType.INTERNAL_TEST_LIBRARY
 }
 
diff --git a/test/uiautomator/uiautomator/build.gradle b/test/uiautomator/uiautomator/build.gradle
index ef6ca7c..b1dd210 100644
--- a/test/uiautomator/uiautomator/build.gradle
+++ b/test/uiautomator/uiautomator/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "Android UIAutomator"
+    name = "UIAutomator"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2012"
     description = "UI testing framework suitable for cross-app functional UI testing"
diff --git a/tracing/tracing-ktx/build.gradle b/tracing/tracing-ktx/build.gradle
index 9cfe63d..a40116c 100644
--- a/tracing/tracing-ktx/build.gradle
+++ b/tracing/tracing-ktx/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "Android Tracing Runtime Kotlin Extensions"
+    name = "Tracing Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Tracing"
diff --git a/tracing/tracing-perfetto-binary/build.gradle b/tracing/tracing-perfetto-binary/build.gradle
index 6a2f998..c663488 100644
--- a/tracing/tracing-perfetto-binary/build.gradle
+++ b/tracing/tracing-perfetto-binary/build.gradle
@@ -82,7 +82,7 @@
 }
 
 androidx {
-    name = "AndroidX Tracing: Perfetto SDK Native Dependencies"
+    name = "Tracing Perfetto Binary"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.TRACING_PERFETTO
     inceptionYear = "2022"
diff --git a/tracing/tracing-perfetto-common/build.gradle b/tracing/tracing-perfetto-common/build.gradle
index 4d9548c..ac22d616 100644
--- a/tracing/tracing-perfetto-common/build.gradle
+++ b/tracing/tracing-perfetto-common/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "AndroidX Tracing: Perfetto Common"
+    name = "Tracing Perfetto Common"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.TRACING_PERFETTO
     inceptionYear = "2022"
diff --git a/tracing/tracing-perfetto/build.gradle b/tracing/tracing-perfetto/build.gradle
index 9e6c8fb..5632eb7 100644
--- a/tracing/tracing-perfetto/build.gradle
+++ b/tracing/tracing-perfetto/build.gradle
@@ -58,7 +58,7 @@
 }
 
 androidx {
-    name = "AndroidX Tracing: Perfetto SDK"
+    name = "Tracing Perfetto"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.TRACING_PERFETTO
     inceptionYear = "2022"
diff --git a/tracing/tracing/build.gradle b/tracing/tracing/build.gradle
index 032edf2..1f0851b 100644
--- a/tracing/tracing/build.gradle
+++ b/tracing/tracing/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Tracing"
+    name = "Tracing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android Tracing"
diff --git a/transition/transition/build.gradle b/transition/transition/build.gradle
index e1080ed..1518fbe 100644
--- a/transition/transition/build.gradle
+++ b/transition/transition/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "Android Transition Support Library"
+    name = "Transition"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2016"
     description = "Android Transition Support Library"
diff --git a/tv/tv-foundation/build.gradle b/tv/tv-foundation/build.gradle
index a53a44ee..eace93c 100644
--- a/tv/tv-foundation/build.gradle
+++ b/tv/tv-foundation/build.gradle
@@ -67,7 +67,7 @@
 }
 
 androidx {
-    name = "androidx.tv:tv-foundation"
+    name = "TV Foundation"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "This library makes it easier for developers" +
diff --git a/tv/tv-material/build.gradle b/tv/tv-material/build.gradle
index 334a3f1..760e574 100644
--- a/tv/tv-material/build.gradle
+++ b/tv/tv-material/build.gradle
@@ -57,7 +57,7 @@
 }
 
 androidx {
-    name = "androidx.tv:tv-material"
+    name = "TV Material"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "build TV applications using controls that adhere to Material Design Language."
diff --git a/tvprovider/tvprovider/build.gradle b/tvprovider/tvprovider/build.gradle
index 3ca9e91..4c19140 100644
--- a/tvprovider/tvprovider/build.gradle
+++ b/tvprovider/tvprovider/build.gradle
@@ -24,7 +24,7 @@
 }
 
 androidx {
-    name = "Android Support TV Provider"
+    name = "TV Provider"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "Android Support Library for TV Provider"
diff --git a/vectordrawable/vectordrawable-animated/build.gradle b/vectordrawable/vectordrawable-animated/build.gradle
index 2217ba2..8fd4fa3 100644
--- a/vectordrawable/vectordrawable-animated/build.gradle
+++ b/vectordrawable/vectordrawable-animated/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "Android Support AnimatedVectorDrawable"
+    name = "AnimatedVectorDrawable"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.VECTORDRAWABLE_ANIMATED
     inceptionYear = "2015"
diff --git a/vectordrawable/vectordrawable-seekable/build.gradle b/vectordrawable/vectordrawable-seekable/build.gradle
index aac1763..fa14340 100644
--- a/vectordrawable/vectordrawable-seekable/build.gradle
+++ b/vectordrawable/vectordrawable-seekable/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Android SeekableAnimatedVectorDrawable"
+    name = "SeekableAnimatedVectorDrawable"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.VECTORDRAWABLE_SEEKABLE
     inceptionYear = "2020"
diff --git a/vectordrawable/vectordrawable/build.gradle b/vectordrawable/vectordrawable/build.gradle
index 9a818af..1d61639 100644
--- a/vectordrawable/vectordrawable/build.gradle
+++ b/vectordrawable/vectordrawable/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "Android Support VectorDrawable"
+    name = "VectorDrawable"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.VECTORDRAWABLE
     inceptionYear = "2015"
diff --git a/viewpager/viewpager/build.gradle b/viewpager/viewpager/build.gradle
index 583c085..0bf2230 100644
--- a/viewpager/viewpager/build.gradle
+++ b/viewpager/viewpager/build.gradle
@@ -21,7 +21,7 @@
 }
 
 androidx {
-    name = "Android Support Library View Pager"
+    name = "ViewPager"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "The Support Library is a static library that you can add to your Android application in order to use APIs that are either not available for older platform versions or utility APIs that aren't a part of the framework APIs. Compatible on devices running API 14 or later."
diff --git a/viewpager2/viewpager2/build.gradle b/viewpager2/viewpager2/build.gradle
index 7397c66..fcba271 100644
--- a/viewpager2/viewpager2/build.gradle
+++ b/viewpager2/viewpager2/build.gradle
@@ -52,7 +52,7 @@
 }
 
 androidx {
-    name = "AndroidX Widget ViewPager2"
+    name = "ViewPager2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
     description = "AndroidX Widget ViewPager2"
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/current.txt b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
index 18e01b6..df7ffb0 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/current.txt
@@ -24,17 +24,17 @@
   public static final class DynamicTypeEvaluator.Config {
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
-    method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
     method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
     method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
   }
 
   public static final class DynamicTypeEvaluator.Config.Builder {
     ctor public DynamicTypeEvaluator.Config.Builder();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
-    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
   }
@@ -48,14 +48,24 @@
     method public void onInvalidated();
   }
 
+  public interface PlatformDataProvider {
+    method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+    method public void unregisterForData();
+  }
+
+  public interface PlatformDataReceiver {
+    method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+  }
+
   public interface QuotaManager {
     method public void releaseQuota(int);
     method public boolean tryAcquireQuota(int);
   }
 
   public class StateStore {
-    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
-    method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
+    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
     field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
   }
 
@@ -71,22 +81,3 @@
 
 }
 
-package androidx.wear.protolayout.expression.pipeline.sensor {
-
-  public interface SensorGateway {
-    method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
-    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
-    field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
-  }
-
-  public static interface SensorGateway.Consumer {
-    method @AnyThread public void onData(double);
-    method @AnyThread public default void onInvalidated();
-    method @AnyThread public default void onPreUpdate();
-  }
-
-}
-
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
index 18e01b6..df7ffb0 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/public_plus_experimental_current.txt
@@ -24,17 +24,17 @@
   public static final class DynamicTypeEvaluator.Config {
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
-    method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
     method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
     method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
   }
 
   public static final class DynamicTypeEvaluator.Config.Builder {
     ctor public DynamicTypeEvaluator.Config.Builder();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
-    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
   }
@@ -48,14 +48,24 @@
     method public void onInvalidated();
   }
 
+  public interface PlatformDataProvider {
+    method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+    method public void unregisterForData();
+  }
+
+  public interface PlatformDataReceiver {
+    method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+  }
+
   public interface QuotaManager {
     method public void releaseQuota(int);
     method public boolean tryAcquireQuota(int);
   }
 
   public class StateStore {
-    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
-    method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
+    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
     field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
   }
 
@@ -71,22 +81,3 @@
 
 }
 
-package androidx.wear.protolayout.expression.pipeline.sensor {
-
-  public interface SensorGateway {
-    method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
-    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
-    field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
-  }
-
-  public static interface SensorGateway.Consumer {
-    method @AnyThread public void onData(double);
-    method @AnyThread public default void onInvalidated();
-    method @AnyThread public default void onPreUpdate();
-  }
-
-}
-
diff --git a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
index 6dd8857..8d2f955 100644
--- a/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression-pipeline/api/restricted_current.txt
@@ -24,17 +24,17 @@
   public static final class DynamicTypeEvaluator.Config {
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getAnimationQuotaManager();
     method public androidx.wear.protolayout.expression.pipeline.QuotaManager? getDynamicTypesQuotaManager();
-    method public androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway? getSensorGateway();
+    method public java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.pipeline.PlatformDataProvider!> getPlatformDataProviders();
     method public androidx.wear.protolayout.expression.pipeline.StateStore? getStateStore();
     method public androidx.wear.protolayout.expression.pipeline.TimeGateway? getTimeGateway();
   }
 
   public static final class DynamicTypeEvaluator.Config.Builder {
     ctor public DynamicTypeEvaluator.Config.Builder();
+    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder addPlatformDataProvider(androidx.wear.protolayout.expression.pipeline.PlatformDataProvider, java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config build();
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setAnimationQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setDynamicTypesQuotaManager(androidx.wear.protolayout.expression.pipeline.QuotaManager);
-    method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setSensorGateway(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setStateStore(androidx.wear.protolayout.expression.pipeline.StateStore);
     method public androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator.Config.Builder setTimeGateway(androidx.wear.protolayout.expression.pipeline.TimeGateway);
   }
@@ -48,16 +48,32 @@
     method public void onInvalidated();
   }
 
+  public interface PlatformDataProvider {
+    method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+    method public void unregisterForData();
+  }
+
+  public interface PlatformDataReceiver {
+    method public void onData(java.util.Map<androidx.wear.protolayout.expression.PlatformDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method public void onInvalidated(java.util.Set<androidx.wear.protolayout.expression.PlatformDataKey<?>!>);
+  }
+
   public interface QuotaManager {
     method public void releaseQuota(int);
     method public boolean tryAcquireQuota(int);
   }
 
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class SensorGatewaySingleDataProvider implements androidx.wear.protolayout.expression.pipeline.PlatformDataProvider {
+    ctor public SensorGatewaySingleDataProvider(androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway, androidx.wear.protolayout.expression.PlatformDataKey<?>);
+    method public void registerForData(java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.PlatformDataReceiver);
+    method public void unregisterForData();
+  }
+
   public class StateStore {
-    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public StateStore(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue!>);
-    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
-    method @UiThread public void setStateEntryValues(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!>);
-    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @UiThread public void setStateEntryValuesProto(java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue!>);
+    ctor @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public StateStore(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
+    method public static androidx.wear.protolayout.expression.pipeline.StateStore create(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method @UiThread public void setAppStateEntryValues(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!>);
+    method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @UiThread public void setAppStateEntryValuesProto(java.util.Map<androidx.wear.protolayout.expression.AppDataKey<?>!,androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue!>);
     field public static final int MAX_STATE_ENTRY_COUNT = 100; // 0x64
   }
 
@@ -75,15 +91,12 @@
 
 package androidx.wear.protolayout.expression.pipeline.sensor {
 
-  public interface SensorGateway {
+  @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public interface SensorGateway {
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void disableUpdates();
     method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public void enableUpdates();
-    method @UiThread public void registerSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void registerSensorGatewayConsumer(int, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    method @UiThread public void unregisterSensorGatewayConsumer(int, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
-    field @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1; // 0x1
-    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final int SENSOR_DATA_TYPE_HEART_RATE = 0; // 0x0
-    field public static final int SENSOR_DATA_TYPE_INVALID = -1; // 0xffffffff
+    method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
+    method @UiThread public void registerSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, java.util.concurrent.Executor, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
+    method @UiThread public void unregisterSensorGatewayConsumer(androidx.wear.protolayout.expression.PlatformDataKey<?>, androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.Consumer);
   }
 
   public static interface SensorGateway.Consumer {
diff --git a/wear/protolayout/protolayout-expression-pipeline/build.gradle b/wear/protolayout/protolayout-expression-pipeline/build.gradle
index d9db9ac..4f92627 100644
--- a/wear/protolayout/protolayout-expression-pipeline/build.gradle
+++ b/wear/protolayout/protolayout-expression-pipeline/build.gradle
@@ -50,7 +50,7 @@
 }
 
 androidx {
-    name = "ProtoLayout Dynamic Expression Evaluation Pipeline"
+    name = "ProtoLayout Expression Pipeline"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Evaluate dynamic expressions."
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
index c95560c..1651688 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/BoolNodes.java
@@ -19,6 +19,7 @@
 import android.util.Log;
 
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ComparisonFloatOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ComparisonInt32Op;
@@ -65,7 +66,8 @@
                 DynamicTypeValueReceiverWithPreUpdate<Boolean> downstream) {
             super(
                     stateStore,
-                    protoNode.getSourceKey(),
+                    StateSourceNode.<DynamicBool>createKey(
+                            protoNode.getSourceNamespace(), protoNode.getSourceKey()),
                     se -> se.getBoolVal().getValue(),
                     downstream);
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
index 315eaf7..ed1d027 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/ColorNodes.java
@@ -19,6 +19,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedColor;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateColorSource;
@@ -64,7 +65,8 @@
                 DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
             super(
                     stateStore,
-                    protoNode.getSourceKey(),
+                    StateSourceNode.<DynamicColor>createKey(
+                            protoNode.getSourceNamespace(), protoNode.getSourceKey()),
                     se -> se.getColorVal().getArgb(),
                     downstream);
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
index 3deccea..a247482 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/DynamicTypeEvaluator.java
@@ -18,6 +18,7 @@
 
 import static java.util.Collections.emptyMap;
 
+import android.annotation.SuppressLint;
 import android.icu.util.ULocale;
 import android.os.Handler;
 import android.os.Looper;
@@ -26,7 +27,9 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
+import androidx.collection.ArrayMap;
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
 import androidx.wear.protolayout.expression.pipeline.BoolNodes.ComparisonFloatNode;
 import androidx.wear.protolayout.expression.pipeline.BoolNodes.ComparisonInt32Node;
 import androidx.wear.protolayout.expression.pipeline.BoolNodes.FixedBoolNode;
@@ -53,7 +56,7 @@
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FloatToInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
-import androidx.wear.protolayout.expression.pipeline.Int32Nodes.PlatformInt32SourceNode;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.LegacyPlatformInt32SourceNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.FixedStringNode;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.FloatFormatNode;
@@ -82,6 +85,8 @@
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -133,27 +138,28 @@
     @NonNull private final QuotaManager mAnimationQuotaManager;
     @NonNull private final QuotaManager mDynamicTypesQuotaManager;
     @NonNull private final EpochTimePlatformDataSource mTimeDataSource;
-    @Nullable private final SensorGatewayPlatformDataSource mSensorGatewayDataSource;
 
     /** Configuration for creating {@link DynamicTypeEvaluator}. */
     public static final class Config {
         @Nullable private final StateStore mStateStore;
         @Nullable private final QuotaManager mAnimationQuotaManager;
         @Nullable private final TimeGateway mTimeGateway;
-        @Nullable private final SensorGateway mSensorGateway;
         @Nullable private final QuotaManager mDynamicTypesQuotaManager;
+        @NonNull private final Map<PlatformDataKey<?>, PlatformDataProvider>
+                mSourceKeyToDataProviders = new ArrayMap<>();
 
         Config(
                 @Nullable StateStore stateStore,
                 @Nullable QuotaManager animationQuotaManager,
                 @Nullable QuotaManager dynamicTypesQuotaManager,
                 @Nullable TimeGateway timeGateway,
-                @Nullable SensorGateway sensorGateway) {
+                @NonNull Map<PlatformDataKey<?>, PlatformDataProvider>
+                        sourceKeyToDataProviders) {
             this.mStateStore = stateStore;
             this.mAnimationQuotaManager = animationQuotaManager;
             this.mTimeGateway = timeGateway;
-            this.mSensorGateway = sensorGateway;
             this.mDynamicTypesQuotaManager = dynamicTypesQuotaManager;
+            this.mSourceKeyToDataProviders.putAll(sourceKeyToDataProviders);
         }
 
         /** Builds a {@link DynamicTypeEvaluator.Config}. */
@@ -162,8 +168,8 @@
             @Nullable private QuotaManager mAnimationQuotaManager = null;
             @Nullable private QuotaManager mDynamicTypesQuotaManager;
             @Nullable private TimeGateway mTimeGateway = null;
-
-            @Nullable private SensorGateway mSensorGateway = null;
+            @NonNull private final Map<PlatformDataKey<?>, PlatformDataProvider>
+                    mSourceKeyToDataProviders = new ArrayMap<>();
 
             /**
              * Sets the state store that will be used for dereferencing the state keys in the
@@ -216,14 +222,34 @@
             }
 
             /**
-             * Sets the gateway used for sensor data.
+             * Add a platform data provider and specify the keys it can provide dynamic data for.
              *
-             * <p>If not set, sensor data will not be available (sensor bindings will trigger {@link
-             * DynamicTypeValueReceiver#onInvalidated()}).
+             * <p> The provider must support at least one key. If the provider supports multiple
+             * keys, they should not be independent, as their values should always update together.
+             * One data key must not have multiple providers, or an exception will be thrown.
+             *
+             * @throws IllegalArgumentException If a PlatformDataProvider supports an empty key
+             * set or if a key has multiple data providers.
              */
+            @SuppressLint("MissingGetterMatchingBuilder")
             @NonNull
-            public Builder setSensorGateway(@NonNull SensorGateway value) {
-                mSensorGateway = value;
+            public Builder addPlatformDataProvider(
+                    @NonNull PlatformDataProvider platformDataProvider,
+                    @NonNull Set<PlatformDataKey<?>> supportedDataKeys
+            ) {
+                if (supportedDataKeys.isEmpty()) {
+                    throw new IllegalArgumentException(
+                            "The PlatformDataProvider must support at least one key");
+                }
+                for (PlatformDataKey<?> dataKey : supportedDataKeys) {
+                    // Throws exception when one data key has multiple providers.
+                    if (mSourceKeyToDataProviders.containsKey(dataKey)) {
+                        throw new IllegalArgumentException(String.format(
+                                "Multiple data providers for PlatformDataKey (%s)", dataKey));
+                    }
+                    mSourceKeyToDataProviders.put(dataKey, platformDataProvider);
+                }
+
                 return this;
             }
 
@@ -234,7 +260,7 @@
                         mAnimationQuotaManager,
                         mDynamicTypesQuotaManager,
                         mTimeGateway,
-                        mSensorGateway);
+                        mSourceKeyToDataProviders);
             }
         }
 
@@ -269,15 +295,6 @@
         }
 
         /**
-         * Gets the gateway used for sensor data, or {@code null} if sensor data is unavailable
-         * (sensor bindings will trigger {@link DynamicTypeValueReceiver#onInvalidated()}).
-         */
-        @Nullable
-        public SensorGateway getSensorGateway() {
-            return mSensorGateway;
-        }
-
-        /**
          * Gets the gateway used for time data, or {@code null} if a default 1hz {@link TimeGateway}
          * that utilizes a main-thread {@code Handler} to trigger is used.
          */
@@ -285,6 +302,15 @@
         public TimeGateway getTimeGateway() {
             return mTimeGateway;
         }
+
+        /**
+         * Returns any available mapping between source key and its data provider.
+         */
+        @NonNull
+        public Map<PlatformDataKey<?>, PlatformDataProvider> getPlatformDataProviders() {
+            return new ArrayMap<>(
+                    (ArrayMap<PlatformDataKey<?>, PlatformDataProvider>) mSourceKeyToDataProviders);
+        }
     }
 
     /** Constructs a {@link DynamicTypeEvaluator}. */
@@ -307,12 +333,8 @@
             ((TimeGatewayImpl) timeGateway).enableUpdates();
         }
         this.mTimeDataSource = new EpochTimePlatformDataSource(uiExecutor, timeGateway);
-        if (config.getSensorGateway() != null) {
-            this.mSensorGatewayDataSource =
-                    new SensorGatewayPlatformDataSource(uiExecutor, config.getSensorGateway());
-        } else {
-            this.mSensorGatewayDataSource = null;
-        }
+
+        this.mStateStore.putAllPlatformProviders(config.getPlatformDataProviders());
     }
 
     /**
@@ -528,10 +550,8 @@
                 }
             case STATE_SOURCE:
                 {
-                    node =
-                            new StateStringNode(
-                                    mStateStore, stringSource.getStateSource(), consumer);
-                    break;
+                   node = new StateStringNode(mStateStore, stringSource.getStateSource(), consumer);
+                   break;
                 }
             case CONDITIONAL_OP:
                 {
@@ -595,13 +615,13 @@
             case FIXED:
                 node = new FixedInt32Node(int32Source.getFixed(), consumer);
                 break;
-            case PLATFORM_SOURCE:
-                node =
-                        new PlatformInt32SourceNode(
-                                int32Source.getPlatformSource(),
-                                mSensorGatewayDataSource,
-                                consumer);
+            case PLATFORM_SOURCE: {
+                node = new LegacyPlatformInt32SourceNode(
+                        mStateStore,
+                        int32Source.getPlatformSource(),
+                        consumer);
                 break;
+            }
             case ARITHMETIC_OPERATION:
                 {
                     ArithmeticInt32Node arithmeticNode =
@@ -621,9 +641,8 @@
                 }
             case STATE_SOURCE:
                 {
-                    node =
-                            new StateInt32SourceNode(
-                                    mStateStore, int32Source.getStateSource(), consumer);
+                    node = new StateInt32SourceNode(
+                            mStateStore, int32Source.getStateSource(), consumer);
                     break;
                 }
             case CONDITIONAL_OP:
@@ -819,9 +838,8 @@
                 node = new FixedFloatNode(floatSource.getFixed(), consumer);
                 break;
             case STATE_SOURCE:
-                node =
-                        new StateFloatSourceNode(
-                                mStateStore, floatSource.getStateSource(), consumer);
+                node = new StateFloatSourceNode(
+                        mStateStore, floatSource.getStateSource(), consumer);
                 break;
             case ARITHMETIC_OPERATION:
                 {
@@ -920,9 +938,8 @@
                 node = new FixedColorNode(colorSource.getFixed(), consumer);
                 break;
             case STATE_SOURCE:
-                node =
-                        new StateColorSourceNode(
-                                mStateStore, colorSource.getStateSource(), consumer);
+                node = new StateColorSourceNode(
+                        mStateStore, colorSource.getStateSource(), consumer);
                 break;
             case ANIMATABLE_FIXED:
                 // We don't have to check if enableAnimations is true, because if it's false and
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
index 71ddbd09..9ebd1b1 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/FloatNodes.java
@@ -21,6 +21,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedFloat;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticFloatOp;
@@ -72,7 +73,8 @@
                 DynamicTypeValueReceiverWithPreUpdate<Float> downstream) {
             super(
                     stateStore,
-                    protoNode.getSourceKey(),
+                    StateSourceNode.<DynamicFloat>createKey(
+                            protoNode.getSourceNamespace(), protoNode.getSourceKey()),
                     se -> se.getFloatVal().getValue(),
                     downstream);
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
index d542928..5893701 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/Int32Nodes.java
@@ -23,6 +23,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
+import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedInt32;
 import androidx.wear.protolayout.expression.proto.DynamicProto.ArithmeticInt32Op;
@@ -70,61 +74,31 @@
     }
 
     /** Dynamic integer node that gets value from the platform source. */
-    static class PlatformInt32SourceNode implements DynamicDataSourceNode<Integer> {
-        private static final String TAG = "PlatformInt32SourceNode";
+    static class LegacyPlatformInt32SourceNode extends StateSourceNode<Integer> {
 
-        @Nullable private final SensorGatewayPlatformDataSource mSensorGatewaySource;
-        private final PlatformInt32SourceType mPlatformSourceType;
-        private final DynamicTypeValueReceiverWithPreUpdate<Integer> mDownstream;
-
-        PlatformInt32SourceNode(
+        LegacyPlatformInt32SourceNode(
+                StateStore stateStore,
                 PlatformInt32Source protoNode,
-                @Nullable SensorGatewayPlatformDataSource sensorGatewaySource,
                 DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
-            this.mPlatformSourceType = protoNode.getSourceType();
-            if (mPlatformSourceType
-                            == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE
-                    || mPlatformSourceType
-                            == PlatformInt32SourceType
-                                    .PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT) {
-                this.mSensorGatewaySource = sensorGatewaySource;
-            } else {
-                this.mSensorGatewaySource = null;
-                Log.w(TAG, "Unknown PlatformInt32SourceType: " + mPlatformSourceType);
-            }
-            this.mDownstream = downstream;
+            super(
+                    stateStore,
+                    getDataKey(protoNode.getSourceType()),
+                    se -> se.getInt32Val().getValue(),
+                    downstream);
         }
 
-        @Override
-        @UiThread
-        public void preInit() {
-            if (mSensorGatewaySource != null) {
-                mDownstream.onPreUpdate();
+        @NonNull
+        private static DynamicDataKey<?> getDataKey(PlatformInt32SourceType type) {
+            if (type == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE) {
+                return PlatformHealthSources.HEART_RATE_BPM;
             }
-        }
 
-        @Override
-        @UiThread
-        public void init() {
-            if (mSensorGatewaySource != null) {
-                try {
-                    mSensorGatewaySource.registerForData(mPlatformSourceType, mDownstream);
-                } catch (SecurityException e) {
-                    // Package does not have the permission to request the health data.
-                    Log.w(TAG, e.getMessage(), e);
-                    mDownstream.onInvalidated();
-                }
-            } else {
-                mDownstream.onInvalidated();
+            if (type == PlatformInt32SourceType.PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT) {
+                return PlatformHealthSources.DAILY_STEPS;
             }
-        }
 
-        @Override
-        @UiThread
-        public void destroy() {
-            if (mSensorGatewaySource != null) {
-                mSensorGatewaySource.unregisterForData(mPlatformSourceType, mDownstream);
-            }
+            throw new IllegalArgumentException(
+                    "Unknown DynamicInt32 platform source type: " + type);
         }
     }
 
@@ -175,7 +149,8 @@
                 DynamicTypeValueReceiverWithPreUpdate<Integer> downstream) {
             super(
                     stateStore,
-                    protoNode.getSourceKey(),
+                    StateSourceNode.<DynamicInt32>createKey(
+                            protoNode.getSourceNamespace(), protoNode.getSourceKey()),
                     se -> se.getInt32Val().getValue(),
                     downstream);
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java
new file mode 100644
index 0000000..6380561
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * This interface is used by platform data providers to yield dynamic data for their supported data
+ * keys.
+ *
+ * <p> It's up to the implementations to check if the expression provider has the required
+ * permission before sending data with {@link PlatformDataReceiver#onData(Map)} )}. If a required
+ * permission is not granted or is revoked they should stop sending more data and call
+ * {@link DynamicTypeValueReceiver#onInvalidated()} instead.
+ */
+public interface PlatformDataProvider {
+    /**
+     * Registers a callback for receiving the platform data from this provider.
+     *
+     * <p> The implementation should periodically send the dynamic data values for the set of
+     * {@link PlatformDataKey}s specified when registering this {@link PlatformDataProvider} in
+     * {@link DynamicTypeEvaluator.Config.Builder#addPlatformDataProvider}
+     */
+    void registerForData(@NonNull Executor executor, @NonNull PlatformDataReceiver callback);
+
+    /**
+     * Unregister from the provider.
+     */
+    void unregisterForData();
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java
new file mode 100644
index 0000000..f50e2a2
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/PlatformDataReceiver.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Callback for receiving a PlatformDataProvider's new data.
+ */
+public interface PlatformDataReceiver {
+    /**
+     * Called when the registered data provider is sending new values.
+     */
+    void onData(@NonNull Map<PlatformDataKey<?>, DynamicDataValue> newData);
+
+    /** Called when the data provider has an invalid result. */
+    void onInvalidated(@NonNull Set<PlatformDataKey<?>> keys);
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java
deleted file mode 100644
index 9297ea7..0000000
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewayPlatformDataSource.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.wear.protolayout.expression.pipeline;
-
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-
-import androidx.annotation.DoNotInline;
-import androidx.annotation.RequiresApi;
-import androidx.collection.ArrayMap;
-import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
-import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway.SensorDataType;
-import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
-
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-/** Utility for sensor data source. */
-class SensorGatewayPlatformDataSource {
-    private static final String TAG = "SensorGtwPltDataSource";
-    final Executor mUiExecutor;
-    private final SensorGateway mSensorGateway;
-    private final Map<
-            DynamicTypeValueReceiverWithPreUpdate<Integer>, SensorGateway.Consumer>
-            mCallbackToRegisteredSensorConsumer = new ArrayMap<>();
-
-    SensorGatewayPlatformDataSource(Executor uiExecutor, SensorGateway sensorGateway) {
-        this.mUiExecutor = uiExecutor;
-        this.mSensorGateway = sensorGateway;
-    }
-
-    @SensorDataType
-    private static int mapSensorPlatformSource(PlatformInt32SourceType platformSource) {
-        switch (platformSource) {
-            case PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE:
-                return SensorGateway.SENSOR_DATA_TYPE_HEART_RATE;
-            case PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT:
-                if (VERSION.SDK_INT >= VERSION_CODES.Q) {
-                    return Api29Impl.getSensorDataTypeDailyStepCount();
-                } else {
-                    return SensorGateway.SENSOR_DATA_TYPE_INVALID;
-                }
-            default:
-                throw new IllegalArgumentException("Unknown PlatformSourceType");
-        }
-    }
-
-    @SuppressWarnings("ExecutorTaskName")
-    public void registerForData(
-            PlatformInt32SourceType sourceType,
-            DynamicTypeValueReceiverWithPreUpdate<Integer> callback) {
-        @SensorDataType int sensorDataType = mapSensorPlatformSource(sourceType);
-        SensorGateway.Consumer sensorConsumer =
-                new SensorGateway.Consumer() {
-                    @Override
-                    public void onPreUpdate() {
-                        mUiExecutor.execute(callback::onPreUpdate);
-                    }
-
-                    @Override
-                    public void onData(double value) {
-                        mUiExecutor.execute(() -> callback.onData((int) value));
-                    }
-
-                    @Override
-                    public void onInvalidated() {
-                        mUiExecutor.execute(callback::onInvalidated);
-                    }
-                };
-        mCallbackToRegisteredSensorConsumer.put(callback, sensorConsumer);
-        mSensorGateway.registerSensorGatewayConsumer(sensorDataType, sensorConsumer);
-    }
-
-    public void unregisterForData(
-            PlatformInt32SourceType sourceType,
-            DynamicTypeValueReceiverWithPreUpdate<Integer> consumer) {
-        @SensorDataType int sensorDataType = mapSensorPlatformSource(sourceType);
-        SensorGateway.Consumer sensorConsumer = mCallbackToRegisteredSensorConsumer.get(consumer);
-        if (sensorConsumer != null) {
-            mSensorGateway.unregisterSensorGatewayConsumer(sensorDataType, sensorConsumer);
-        }
-    }
-
-    @RequiresApi(VERSION_CODES.Q)
-    private static class Api29Impl {
-        @DoNotInline
-        static int getSensorDataTypeDailyStepCount() {
-            return SensorGateway.SENSOR_DATA_TYPE_DAILY_STEP_COUNT;
-        }
-    }
-}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java
new file mode 100644
index 0000000..ee1671e
--- /dev/null
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/SensorGatewaySingleDataProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression.pipeline;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.annotation.RestrictTo.Scope;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/** This provider provides sensor data as state value. */
+@RestrictTo(Scope.LIBRARY_GROUP_PREFIX)
+public class SensorGatewaySingleDataProvider implements PlatformDataProvider {
+    @NonNull private final SensorGateway mSensorGateway;
+    @NonNull final PlatformDataKey<?> mSupportedKey;
+    @Nullable private SensorGateway.Consumer mSensorGatewayConsumer = null;
+
+    public SensorGatewaySingleDataProvider(
+            @NonNull SensorGateway sensorGateway,
+            @NonNull PlatformDataKey<?> supportedKey
+    ) {
+        this.mSensorGateway = sensorGateway;
+        this.mSupportedKey = supportedKey;
+    }
+
+    @Override
+    @SuppressWarnings("HiddenTypeParameters")
+    public void registerForData(
+            @NonNull Executor executor, @NonNull PlatformDataReceiver callback) {
+        SensorGateway.Consumer sensorConsumer =
+                new SensorGateway.Consumer() {
+                    @Override
+                    public void onData(double value) {
+                        executor.execute(() -> callback.onData(
+                                Map.of(mSupportedKey, DynamicDataValue.fromFloat((float) value)))
+                        );
+                    }
+
+                    @Override
+                    public void onInvalidated() {
+                        executor.execute(() -> callback.onInvalidated(
+                                Collections.singleton(mSupportedKey)));
+                    }
+                };
+        mSensorGatewayConsumer = sensorConsumer;
+        mSensorGateway.registerSensorGatewayConsumer(mSupportedKey, sensorConsumer);
+    }
+
+    @Override
+    public void unregisterForData() {
+        if (mSensorGatewayConsumer != null) {
+            mSensorGateway.unregisterSensorGatewayConsumer(mSupportedKey, mSensorGatewayConsumer);
+            mSensorGatewayConsumer = null;
+        }
+    }
+}
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
index 3645fef..1cd0634 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateSourceNode.java
@@ -18,25 +18,29 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.UiThread;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicType;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import java.util.function.Function;
 
 class StateSourceNode<T>
         implements DynamicDataSourceNode<T>,
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> {
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> {
     private final StateStore mStateStore;
-    private final String mBindKey;
-    private final Function<StateEntryValue, T> mStateExtractor;
+    private final DynamicDataKey<?> mKey;
+    private final Function<DynamicDataValue, T> mStateExtractor;
     private final DynamicTypeValueReceiverWithPreUpdate<T> mDownstream;
 
     StateSourceNode(
             StateStore stateStore,
-            String bindKey,
-            Function<StateEntryValue, T> stateExtractor,
+            DynamicDataKey<?> key,
+            Function<DynamicDataValue, T> stateExtractor,
             DynamicTypeValueReceiverWithPreUpdate<T> downstream) {
         this.mStateStore = stateStore;
-        this.mBindKey = bindKey;
+        this.mKey = key;
         this.mStateExtractor = stateExtractor;
         this.mDownstream = downstream;
     }
@@ -50,8 +54,8 @@
     @Override
     @UiThread
     public void init() {
-        mStateStore.registerCallback(mBindKey, this);
-        StateEntryValue item = mStateStore.getStateEntryValuesProto(mBindKey);
+        mStateStore.registerCallback(mKey, this);
+        DynamicDataValue item = mStateStore.getDynamicDataValuesProto(mKey);
 
         if (item != null) {
             this.onData(item);
@@ -63,7 +67,7 @@
     @Override
     @UiThread
     public void destroy() {
-        mStateStore.unregisterCallback(mBindKey, this);
+        mStateStore.unregisterCallback(mKey, this);
     }
 
     @Override
@@ -72,7 +76,7 @@
     }
 
     @Override
-    public void onData(@NonNull StateEntryValue newData) {
+    public void onData(@NonNull DynamicDataValue newData) {
         T actualValue = mStateExtractor.apply(newData);
         mDownstream.onData(actualValue);
     }
@@ -81,4 +85,13 @@
     public void onInvalidated() {
         mDownstream.onInvalidated();
     }
+
+    @NonNull
+    static <T extends DynamicType> DynamicDataKey<T> createKey(
+           @NonNull String namespace, @NonNull String key) {
+        if (namespace.isEmpty()) {
+            return new AppDataKey<T>(key);
+        }
+        return new PlatformDataKey<T>(namespace, key);
+    }
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
index f722bbb..c42ba8f 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StateStore.java
@@ -19,6 +19,8 @@
 import static java.util.stream.Collectors.toMap;
 
 import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.Looper;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -26,13 +28,17 @@
 import androidx.annotation.UiThread;
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.DynamicDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
+import androidx.wear.protolayout.expression.PlatformDataKey;
 
 import java.util.Collections;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.stream.Stream;
 
 /**
@@ -52,12 +58,29 @@
      */
     @SuppressLint("MinMaxConstant")
     public static final int MAX_STATE_ENTRY_COUNT = 100;
-    @NonNull private final Map<String, StateEntryValue> mCurrentState = new ArrayMap<>();
+
+    private final Executor mUiExecutor;
+    @NonNull private final Map<AppDataKey<?>, DynamicDataValue> mCurrentAppState
+            = new ArrayMap<>();
 
     @NonNull
-    private final Map<String, Set<DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>>>
+    private final Map<PlatformDataKey<?>, DynamicDataValue> mCurrentPlatformData
+            = new ArrayMap<>();
+
+    @NonNull
+    private final
+    Map<DynamicDataKey<?>,
+            Set<DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue>>>
             mRegisteredCallbacks = new ArrayMap<>();
 
+    @NonNull
+    private final Map<PlatformDataKey<?>, PlatformDataProvider>
+            mSourceKeyToDataProviders = new ArrayMap<>();
+
+    @NonNull
+    private final Map<PlatformDataProvider, Integer> mProviderToRegisteredKeyCount
+            = new ArrayMap<>();
+
     /**
      * Creates a {@link StateStore}.
      *
@@ -66,20 +89,28 @@
      */
     @NonNull
     public static StateStore create(
-            @NonNull Map<String, StateEntryBuilders.StateEntryValue> initialState) {
+            @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue>
+                    initialState) {
         return new StateStore(toProto(initialState));
     }
 
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
-    public StateStore(@NonNull Map<String, StateEntryValue> initialState) {
+    public StateStore(
+            @NonNull Map<AppDataKey<?>, DynamicDataValue> initialState) {
         if (initialState.size() > MAX_STATE_ENTRY_COUNT) {
             throw stateTooLargeException(initialState.size());
         }
-        mCurrentState.putAll(initialState);
+        mCurrentAppState.putAll(initialState);
+        mUiExecutor = new MainThreadExecutor(new Handler(Looper.getMainLooper()));
+    }
+
+    void putAllPlatformProviders(
+            @NonNull Map<PlatformDataKey<?>, PlatformDataProvider> sourceKeyToDataProviders) {
+        mSourceKeyToDataProviders.putAll(sourceKeyToDataProviders);
     }
 
     /**
-     * Sets the given state, replacing the current state.
+     * Sets the given app state, replacing the current app state.
      *
      * <p>Informs registered listeners of changed values, invalidates removed values.
      *
@@ -88,13 +119,13 @@
      * will stay in place.
      */
     @UiThread
-    public void setStateEntryValues(
-            @NonNull Map<String, StateEntryBuilders.StateEntryValue> newState) {
-        setStateEntryValuesProto(toProto(newState));
+    public void setAppStateEntryValues(
+            @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> newState) {
+        setAppStateEntryValuesProto(toProto(newState));
     }
 
     /**
-     * Sets the given state, replacing the current state.
+     * Sets the given app state, replacing the current app state.
      *
      * <p>Informs registered listeners of changed values, invalidates removed values.
      *
@@ -104,94 +135,230 @@
      */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
     @UiThread
-    public void setStateEntryValuesProto(@NonNull Map<String, StateEntryValue> newState) {
+    public void setAppStateEntryValuesProto(
+            @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
         if (newState.size() > MAX_STATE_ENTRY_COUNT) {
             throw stateTooLargeException(newState.size());
         }
 
         // Figure out which nodes have actually changed.
-        Set<String> removedKeys = getRemovedKeys(newState);
-        Map<String, StateEntryValue> changedEntries = getChangedEntries(newState);
+        Set<AppDataKey<?>> removedKeys = getRemovedAppKeys(newState);
+        Map<AppDataKey<?>, DynamicDataValue> changedEntries = getChangedAppEntries(newState);
 
         Stream.concat(removedKeys.stream(), changedEntries.keySet().stream())
                 .forEach(
                         key -> {
-                            for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback :
+                            for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
                                     mRegisteredCallbacks.getOrDefault(
                                             key, Collections.emptySet())) {
                                 callback.onPreUpdate();
                             }
                         });
 
-        mCurrentState.clear();
-        mCurrentState.putAll(newState);
+        mCurrentAppState.clear();
+        mCurrentAppState.putAll(newState);
 
-        for (String key : removedKeys) {
-            for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback :
+        for (AppDataKey<?> key : removedKeys) {
+            for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
                     mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
                 callback.onInvalidated();
             }
         }
-        for (Entry<String, StateEntryValue> entry : changedEntries.entrySet()) {
-            for (DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback :
+        for (Entry<AppDataKey<?>, DynamicDataValue> entry
+                : changedEntries.entrySet()) {
+            for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
                     mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
                 callback.onData(entry.getValue());
             }
         }
     }
 
-    /** Gets state with the given key. */
-    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-    @UiThread
-    @Nullable
-    public StateEntryValue getStateEntryValuesProto(@NonNull String key) {
-        return mCurrentState.get(key);
+    /**
+     * Update the given platform data item.
+     *
+     * <p>Informs registered listeners of changed values.
+     */
+    void updatePlatformDataEntries(
+            @NonNull Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue> newData) {
+        updatePlatformDataEntryProto(
+                newData.entrySet().stream().collect(
+                        toMap(Entry::getKey, entry -> entry.getValue().toDynamicDataValueProto()))
+        );
     }
 
     /**
-     * Registers the given callback for updates to the state for the given key.
+     * Update the given platform data item.
+     *
+     * <p>Informs registered listeners of changed values.
+     */
+    void updatePlatformDataEntryProto(
+            @NonNull Map<PlatformDataKey<?>, DynamicDataValue> newData) {
+        Map<PlatformDataKey<?>, DynamicDataValue> changedEntries = new ArrayMap<>();
+        for (Entry<PlatformDataKey<?>, DynamicDataValue> newEntry : newData.entrySet()) {
+            DynamicDataValue currentEntry = mCurrentPlatformData.get(newEntry.getKey());
+            if (currentEntry == null || !currentEntry.equals(newEntry.getValue())) {
+                changedEntries.put(newEntry.getKey(), newEntry.getValue());
+            }
+        }
+
+        for (Entry<PlatformDataKey<?>, DynamicDataValue> entry : changedEntries.entrySet()) {
+            for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+                    mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
+                callback.onPreUpdate();
+            }
+        }
+
+        for (Entry<PlatformDataKey<?>, DynamicDataValue> entry : changedEntries.entrySet()) {
+            for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+                    mRegisteredCallbacks.getOrDefault(entry.getKey(), Collections.emptySet())) {
+                callback.onData(entry.getValue());
+            }
+            mCurrentPlatformData.put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    /**
+     * Remove the platform data item with the given key.
+     *
+     * <p>Informs registered listeners by invalidating removed values.
+     */
+    void removePlatformDataEntry(@NonNull Set<PlatformDataKey<?>> keys) {
+        for (PlatformDataKey<?> key : keys) {
+            if (mCurrentPlatformData.get(key) != null) {
+                for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+                        mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
+                    callback.onPreUpdate();
+                }
+            }
+        }
+
+        for (PlatformDataKey<?> key : keys) {
+            if (mCurrentPlatformData.get(key) != null) {
+                for (DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback :
+                        mRegisteredCallbacks.getOrDefault(key, Collections.emptySet())) {
+                    callback.onInvalidated();
+                }
+                mCurrentPlatformData.remove(key);
+            }
+        }
+    }
+
+    /** Gets dynamic value with the given {@code key}. */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    @UiThread
+    @Nullable
+    public DynamicDataValue getDynamicDataValuesProto(@NonNull DynamicDataKey<?> key) {
+        if (key instanceof AppDataKey) {
+            return mCurrentAppState.get(key);
+        }
+
+        if (key instanceof PlatformDataKey) {
+            return mCurrentPlatformData.get(key);
+        }
+
+        return null;
+    }
+
+    /**
+     * Registers the given callback for updates to the data item for the given {@code key}.
      *
      * <p>Note that the callback will be executed on the UI thread.
      */
     @UiThread
     void registerCallback(
-            @NonNull String key,
-            @NonNull DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback) {
+            @NonNull DynamicDataKey<?> key,
+            @NonNull DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback) {
         mRegisteredCallbacks.computeIfAbsent(key, k -> new ArraySet<>()).add(callback);
+
+        if (!(key instanceof PlatformDataKey) ||
+                (mRegisteredCallbacks.containsKey(key) && mRegisteredCallbacks.get(key).size() > 1)
+        ) {
+            return;
+        }
+
+        PlatformDataProvider platformDataProvider = mSourceKeyToDataProviders.get(key);
+        if (platformDataProvider != null) {
+            int registeredKeyCount =
+                    mProviderToRegisteredKeyCount.getOrDefault(platformDataProvider, 0);
+
+            if (registeredKeyCount == 0) {
+                platformDataProvider.registerForData(
+                        mUiExecutor,
+                        new PlatformDataReceiver() {
+                            @Override
+                            public void onData(
+                                    @NonNull
+                                    Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue>
+                                            newData) {
+                                updatePlatformDataEntries(newData);
+                            }
+
+                            @Override
+                            public void onInvalidated(@NonNull Set<PlatformDataKey<?>> keys) {
+                                removePlatformDataEntry(keys);
+                            }
+                        });
+            }
+
+            mProviderToRegisteredKeyCount.put(platformDataProvider, registeredKeyCount + 1);
+        } else {
+            throw new IllegalArgumentException(
+                    String.format("No platform data provider for %s", key));
+        }
     }
 
-    /** Unregisters from receiving the updates. */
+    /** Unregisters the callback for the given {@code key} from receiving the updates. */
     @UiThread
     void unregisterCallback(
-            @NonNull String key,
-            @NonNull DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> callback) {
-        Set<DynamicTypeValueReceiverWithPreUpdate<StateEntryValue>> callbackSet =
+            @NonNull DynamicDataKey<?> key,
+            @NonNull DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> callback) {
+
+        Set<DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue>> callbackSet =
                 mRegisteredCallbacks.get(key);
         if (callbackSet != null) {
             callbackSet.remove(callback);
+
+            if (!(key instanceof PlatformDataKey) || !callbackSet.isEmpty()) {
+                return;
+            }
+
+            PlatformDataProvider platformDataProvider = mSourceKeyToDataProviders.get(key);
+            if (platformDataProvider != null) {
+                int registeredKeyCount =
+                        mProviderToRegisteredKeyCount.getOrDefault(platformDataProvider, 0);
+                if (registeredKeyCount == 1) {
+                    platformDataProvider.unregisterForData();
+                }
+                mProviderToRegisteredKeyCount.put(platformDataProvider, registeredKeyCount - 1);
+            } else {
+                throw new IllegalArgumentException(
+                        String.format("No platform data provider for %s", key));
+            }
         }
     }
 
     @NonNull
-    private static Map<String, StateEntryValue> toProto(
-            @NonNull Map<String, StateEntryBuilders.StateEntryValue> value) {
+    private static Map<AppDataKey<?>, DynamicDataValue> toProto(
+            @NonNull Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> value) {
         return value.entrySet().stream()
-                .collect(toMap(Entry::getKey, entry -> entry.getValue().toStateEntryValueProto()));
+                .collect(toMap(Entry::getKey, entry -> entry.getValue().toDynamicDataValueProto()));
     }
 
     @NonNull
-    private Set<String> getRemovedKeys(@NonNull Map<String, StateEntryValue> newState) {
-        Set<String> result = new ArraySet<>(mCurrentState.keySet());
+    private Set<AppDataKey<?>> getRemovedAppKeys(
+            @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
+        Set<AppDataKey<?>> result = new ArraySet<>(mCurrentAppState.keySet());
         result.removeAll(newState.keySet());
         return result;
     }
 
     @NonNull
-    private Map<String, StateEntryValue> getChangedEntries(
-            @NonNull Map<String, StateEntryValue> newState) {
-        Map<String, StateEntryValue> result = new ArrayMap<>();
-        for (Entry<String, StateEntryValue> newEntry : newState.entrySet()) {
-            StateEntryValue currentEntry = mCurrentState.get(newEntry.getKey());
+    private Map<AppDataKey<?>, DynamicDataValue> getChangedAppEntries(
+            @NonNull Map<AppDataKey<?>, DynamicDataValue> newState) {
+        Map<AppDataKey<?>, DynamicDataValue> result = new ArrayMap<>();
+        for (Entry<AppDataKey<?>, DynamicDataValue> newEntry
+                : newState.entrySet()) {
+            DynamicDataValue currentEntry = mCurrentAppState.get(newEntry.getKey());
             if (currentEntry == null || !currentEntry.equals(newEntry.getValue())) {
                 result.put(newEntry.getKey(), newEntry.getValue());
             }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
index e168776..77dcfc4 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/StringNodes.java
@@ -19,6 +19,7 @@
 import static java.lang.Math.min;
 
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateStringSource;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
 
@@ -104,7 +105,8 @@
                 DynamicTypeValueReceiverWithPreUpdate<String> downstream) {
             super(
                     stateStore,
-                    protoNode.getSourceKey(),
+                    StateSourceNode.<DynamicString>createKey(
+                            protoNode.getSourceNamespace(), protoNode.getSourceKey()),
                     se -> truncate(se.getStringVal().getValue()),
                     downstream);
         }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
index d6f656d..b6eef40 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/main/java/androidx/wear/protolayout/expression/pipeline/sensor/SensorGateway.java
@@ -16,58 +16,23 @@
 
 package androidx.wear.protolayout.expression.pipeline.sensor;
 
-import android.Manifest;
-import android.os.Build.VERSION_CODES;
-
 import androidx.annotation.AnyThread;
-import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-import androidx.annotation.RequiresPermission;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.annotation.UiThread;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.Executor;
 
 /**
  * Gateway for proto layout expression library to be able to access sensor data, e.g. health data.
  */
+@RestrictTo(Scope.LIBRARY_GROUP_PREFIX)
 public interface SensorGateway {
 
-    /** Sensor data types that can be subscribed to from {@link SensorGateway}. */
-    @RestrictTo(Scope.LIBRARY_GROUP)
-    @Retention(RetentionPolicy.SOURCE)
-    @RequiresApi(VERSION_CODES.Q)
-    @IntDef({
-        SENSOR_DATA_TYPE_INVALID,
-        SENSOR_DATA_TYPE_HEART_RATE,
-        SENSOR_DATA_TYPE_DAILY_STEP_COUNT
-    })
-    public @interface SensorDataType {};
-
-    /** Invalid data type. Used to return error states. */
-    int SENSOR_DATA_TYPE_INVALID = -1;
-
-    /**
-     * The user's current heart rate. This is an instantaneous reading from the last time it was
-     * sampled. Note that this means that apps which subscribe to passive heart rate data may not
-     * receive exact heart rate data; it will be batched to a given period.
-     */
-    @RequiresPermission(Manifest.permission.BODY_SENSORS)
-    int SENSOR_DATA_TYPE_HEART_RATE = 0;
-
-    /**
-     * The user's current daily step count. Note that this data type will reset to zero at midnight.
-     * each day, and any subscriptions to this data type will log the number of steps the user has
-     * done since 12:00AM local time.
-     */
-    @RequiresApi(VERSION_CODES.Q)
-    @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
-    int SENSOR_DATA_TYPE_DAILY_STEP_COUNT = 1;
-
     /**
      * Consumer for sensor data.
      *
@@ -147,15 +112,15 @@
      * type.
      *
      * <p>Note that the callback will be executed on the single background thread (implementation
-     * dependent). To specify the execution thread, use {@link #registerSensorGatewayConsumer(int,
-     * Executor, Consumer)}.
+     * dependent). To specify the execution thread, use {@link #registerSensorGatewayConsumer(
+     * PlatformDataKey, Executor, Consumer)}.
      *
      * @throws SecurityException if the provider does not have permission to provide requested data
      *     type.
      */
     @UiThread
     void registerSensorGatewayConsumer(
-            @SensorDataType int requestedDataType, @NonNull Consumer consumer);
+            @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer);
 
     /**
      * Register for updates for the given data type. This may cause {@link Consumer} to immediately
@@ -172,12 +137,12 @@
      */
     @UiThread
     void registerSensorGatewayConsumer(
-            @SensorDataType int requestedDataType,
+            @NonNull PlatformDataKey<?> key,
             @NonNull /* @CallbackExecutor */ Executor executor,
             @NonNull Consumer consumer);
 
     /** Unregister for updates for the given data type. */
     @UiThread
     void unregisterSensorGatewayConsumer(
-            @SensorDataType int requestedDataType, @NonNull Consumer consumer);
+            @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer);
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
index e5f987c..bf04b5e 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/BoolNodesTest.java
@@ -23,13 +23,15 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
 import androidx.wear.protolayout.expression.pipeline.BoolNodes.FixedBoolNode;
 import androidx.wear.protolayout.expression.pipeline.BoolNodes.StateBoolNode;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.expression.proto.DynamicProto.LogicalBoolOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateBoolSource;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedBool;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 import com.google.common.collect.ImmutableMap;
 import java.util.ArrayList;
 import java.util.List;
@@ -57,8 +59,8 @@
     StateStore oss =
         new StateStore(
             ImmutableMap.of(
-                "foo",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicBool>("foo"),
+                DynamicDataValue.newBuilder()
                     .setBoolVal(FixedBool.newBuilder().setValue(true))
                     .build()));
 
@@ -77,8 +79,8 @@
     StateStore oss =
         new StateStore(
             ImmutableMap.of(
-                "foo",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicBool>("foo"),
+                DynamicDataValue.newBuilder()
                     .setBoolVal(FixedBool.newBuilder().setValue(true))
                     .build()));
 
@@ -90,10 +92,10 @@
 
     results.clear();
 
-    oss.setStateEntryValuesProto(
+    oss.setAppStateEntryValuesProto(
         ImmutableMap.of(
-            "foo",
-            StateEntryValue.newBuilder()
+            new AppDataKey<DynamicBool>("foo"),
+            DynamicDataValue.newBuilder()
                 .setBoolVal(FixedBool.newBuilder().setValue(false))
                 .build()));
 
@@ -103,11 +105,12 @@
   @Test
   public void stateBoolNoUpdatesAfterDestroy() {
     List<Boolean> results = new ArrayList<>();
+    AppDataKey<DynamicBool> keyFoo = new AppDataKey<>("foo");
     StateStore oss =
         new StateStore(
             ImmutableMap.of(
-                "foo",
-                StateEntryValue.newBuilder()
+                keyFoo,
+                DynamicDataValue.newBuilder()
                     .setBoolVal(FixedBool.newBuilder().setValue(false))
                     .build()));
 
@@ -120,10 +123,10 @@
 
     results.clear();
     node.destroy();
-    oss.setStateEntryValuesProto(
+    oss.setAppStateEntryValuesProto(
         ImmutableMap.of(
-            "foo",
-            StateEntryValue.newBuilder()
+                keyFoo,
+                DynamicDataValue.newBuilder()
                 .setBoolVal(FixedBool.newBuilder().setValue(true))
                 .build()));
     assertThat(results).isEmpty();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
index 20e1177..cbf06ed 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ColorNodesTest.java
@@ -25,6 +25,8 @@
 import android.os.Looper;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.AnimatableFixedColorNode;
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.DynamicAnimatedColorNode;
 import androidx.wear.protolayout.expression.pipeline.ColorNodes.FixedColorNode;
@@ -33,7 +35,7 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto.AnimatableFixedColor;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateColorSource;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedColor;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
@@ -49,6 +51,7 @@
 
     private static final int FROM_COLOR = 0xFF00FF00;
     private static final int TO_COLOR = 0xFFFF00FF;
+    private static final AppDataKey<DynamicColor> KEY_FOO = new AppDataKey<>("foo");
 
     @Test
     public void fixedColorNode() {
@@ -69,8 +72,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
                                         .build()));
 
@@ -90,8 +93,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
                                         .build()));
         StateColorSource protoNode = StateColorSource.newBuilder().setSourceKey("foo").build();
@@ -100,10 +103,10 @@
 
         node.preInit();
         node.init();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
                                 .build()));
 
@@ -116,8 +119,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(FixedColor.newBuilder().setArgb(FROM_COLOR))
                                         .build()));
         StateColorSource protoNode = StateColorSource.newBuilder().setSourceKey("foo").build();
@@ -130,10 +133,10 @@
 
         results.clear();
         node.destroy();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
                                 .build()));
         assertThat(results).isEmpty();
@@ -213,8 +216,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(
                                                 FixedColor.newBuilder().setArgb(FROM_COLOR).build())
                                         .build()));
@@ -233,10 +236,10 @@
         stateNode.preInit();
         stateNode.init();
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(TO_COLOR))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -256,8 +259,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(
                                                 FixedColor.newBuilder().setArgb(color1).build())
                                         .build()));
@@ -277,10 +280,10 @@
         stateNode.init();
 
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(color2))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -291,10 +294,10 @@
 
         colorNode.setVisibility(true);
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(color3))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -316,8 +319,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setColorVal(
                                                 FixedColor.newBuilder().setArgb(color1).build())
                                         .build()));
@@ -339,10 +342,10 @@
         stateNode.init();
 
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(color2))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -352,10 +355,10 @@
         // Release the only quota
         quotaManager.releaseQuota(1);
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(color3))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
index 9a466a2..a1acb98 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/FloatNodeTest.java
@@ -25,6 +25,8 @@
 import android.os.Looper;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.AnimatableFixedFloatNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.ArithmeticFloatNode;
 import androidx.wear.protolayout.expression.pipeline.FloatNodes.DynamicAnimatedFloatNode;
@@ -40,7 +42,7 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateInt32Source;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
@@ -54,6 +56,8 @@
 @RunWith(AndroidJUnit4.class)
 public class FloatNodeTest {
 
+    private static final AppDataKey<DynamicFloat> KEY_FOO = new AppDataKey<>("foo");
+
     @Test
     public void fixedFloatNodesTest() {
         List<Float> results = new ArrayList<>();
@@ -75,8 +79,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setFloatVal(FixedFloat.newBuilder().setValue(testValue))
                                         .build()));
 
@@ -99,8 +103,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setFloatVal(FixedFloat.newBuilder().setValue(oldValue))
                                         .build()));
 
@@ -112,10 +116,10 @@
         node.init();
         assertThat(results).containsExactly(oldValue);
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(newValue))
                                 .build()));
 
@@ -131,8 +135,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setFloatVal(FixedFloat.newBuilder().setValue(oldValue))
                                         .build()));
 
@@ -147,10 +151,10 @@
         results.clear();
         node.destroy();
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(newValue))
                                 .build()));
 
@@ -177,8 +181,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setFloatVal(FixedFloat.newBuilder().setValue(oldRhsValue))
                                         .build()));
         StateFloatSource rhsProtoNode = StateFloatSource.newBuilder().setSourceKey("foo").build();
@@ -191,10 +195,10 @@
         assertThat(results).containsExactly(lhsValue + oldRhsValue);
 
         float newRhsValue = 7.8f;
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(newRhsValue))
                                 .build()));
         assertThat(results)
@@ -211,8 +215,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setInt32Val(FixedInt32.newBuilder().setValue(oldIntValue))
                                         .build()));
 
@@ -226,10 +230,10 @@
         assertThat(results).containsExactly((float) oldIntValue);
 
         int newIntValue = 12;
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(newIntValue))
                                 .build()));
 
@@ -319,8 +323,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setFloatVal(
                                                 FixedFloat.newBuilder().setValue(value1).build())
                                         .build()));
@@ -340,10 +344,10 @@
         stateNode.init();
 
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(value2))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -354,10 +358,10 @@
 
         floatNode.setVisibility(true);
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(value3))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
index 58f8fd6..2738f50 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/Int32NodesTest.java
@@ -26,12 +26,17 @@
 import android.os.Looper;
 
 import androidx.annotation.NonNull;
+import androidx.collection.ArrayMap;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.PlatformDataKey;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.AnimatableFixedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.DynamicAnimatedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.FixedInt32Node;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.GetDurationPartOpNode;
-import androidx.wear.protolayout.expression.pipeline.Int32Nodes.PlatformInt32SourceNode;
+import androidx.wear.protolayout.expression.pipeline.Int32Nodes.LegacyPlatformInt32SourceNode;
 import androidx.wear.protolayout.expression.pipeline.Int32Nodes.StateInt32SourceNode;
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationSpec;
@@ -42,7 +47,7 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto.PlatformInt32SourceType;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateInt32Source;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
@@ -56,14 +61,19 @@
 
 import java.time.Duration;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Executor;
 
 @RunWith(AndroidJUnit4.class)
 public class Int32NodesTest {
-    @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
 
-    @Mock private DynamicTypeValueReceiverWithPreUpdate<Integer> mMockValueReceiver;
+    @Mock
+    private DynamicTypeValueReceiverWithPreUpdate<Integer> mMockValueReceiver;
+
+    private static final AppDataKey<DynamicInt32> KEY_FOO = new AppDataKey<>("foo");
 
     @Test
     public void testFixedInt32Node() {
@@ -85,36 +95,36 @@
         Duration duration = Duration.ofSeconds(123456);
 
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_DAYS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_DAYS))
                 .isEqualTo(1);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_HOURS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_HOURS))
                 .isEqualTo(10);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
                 .isEqualTo(17);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
                 .isEqualTo(36);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
                 .isEqualTo(1);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
                 .isEqualTo(34);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
                 .isEqualTo(2057);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
                 .isEqualTo(123456);
     }
 
@@ -125,36 +135,36 @@
         Duration duration = Duration.ofSeconds(-123456);
 
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_DAYS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_DAYS))
                 .isEqualTo(1);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_HOURS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_HOURS))
                 .isEqualTo(10);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_MINUTES))
                 .isEqualTo(17);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_SECONDS))
                 .isEqualTo(36);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_DAYS))
                 .isEqualTo(-1);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_HOURS))
                 .isEqualTo(-34);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_MINUTES))
                 .isEqualTo(-2057);
         assertThat(
-                        createGetDurationPartOpNodeAndGetPart(
-                                duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
+                createGetDurationPartOpNodeAndGetPart(
+                        duration, DurationPartType.DURATION_PART_TYPE_TOTAL_SECONDS))
                 .isEqualTo(-123456);
     }
 
@@ -174,8 +184,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setInt32Val(FixedInt32.newBuilder().setValue(65))
                                         .build()));
 
@@ -195,8 +205,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setInt32Val(FixedInt32.newBuilder().setValue(65))
                                         .build()));
 
@@ -209,10 +219,10 @@
 
         results.clear();
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(12))
                                 .build()));
 
@@ -302,8 +312,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setInt32Val(
                                                 FixedInt32.newBuilder().setValue(value1).build())
                                         .build()));
@@ -323,10 +333,10 @@
         stateNode.init();
 
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(value2))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -337,10 +347,10 @@
 
         int32Node.setVisibility(true);
         results.clear();
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(value3))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -355,16 +365,22 @@
     @Test
     public void platformInt32Source_propagatesInvalidatedSignal() {
         FakeSensorGateway fakeSensorGateway = new FakeSensorGateway();
+        StateStore stateStore = new StateStore(new ArrayMap<>());
+        stateStore.putAllPlatformProviders(
+                Collections.singletonMap(
+                        PlatformHealthSources.HEART_RATE_BPM,
+                        new SensorGatewaySingleDataProvider(
+                                fakeSensorGateway, PlatformHealthSources.HEART_RATE_BPM)));
         PlatformInt32Source platformSource =
                 PlatformInt32Source.newBuilder()
                         .setSourceType(
                                 PlatformInt32SourceType
                                         .PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE)
                         .build();
-        PlatformInt32SourceNode platformSourceNode =
-                new PlatformInt32SourceNode(
+        LegacyPlatformInt32SourceNode platformSourceNode =
+                new LegacyPlatformInt32SourceNode(
+                        stateStore,
                         platformSource,
-                        new SensorGatewayPlatformDataSource(Runnable::run, fakeSensorGateway),
                         mMockValueReceiver);
 
         platformSourceNode.preInit();
@@ -381,28 +397,30 @@
         final List<Consumer> registeredConsumers = new ArrayList<>();
 
         @Override
-        public void enableUpdates() {}
+        public void enableUpdates() {
+        }
 
         @Override
-        public void disableUpdates() {}
+        public void disableUpdates() {
+        }
 
         @Override
         public void registerSensorGatewayConsumer(
-                @SensorDataType int requestedDataType, @NonNull Consumer consumer) {
+                @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer) {
             registeredConsumers.add(consumer);
         }
 
         @Override
         public void registerSensorGatewayConsumer(
-                @SensorDataType int requestedDataType,
+                @NonNull PlatformDataKey<?> key,
                 @NonNull Executor executor,
                 @NonNull Consumer consumer) {
-            registerSensorGatewayConsumer(requestedDataType, consumer);
+            registerSensorGatewayConsumer(key, consumer);
         }
 
         @Override
         public void unregisterSensorGatewayConsumer(
-                @SensorDataType int requestedDataType, @NonNull Consumer consumer) {
+                @NonNull PlatformDataKey<?> key, @NonNull Consumer consumer) {
             registeredConsumers.remove(consumer);
         }
     }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
index 2f62ea9..4480847 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/ParametrizedDynamicTypeEvaluatorTest.java
@@ -38,11 +38,12 @@
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedBool;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -63,36 +64,38 @@
 public class ParametrizedDynamicTypeEvaluatorTest {
     @ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
     public static ImmutableList<Object[]> params() {
+        AppDataKey<DynamicInt32> int32Source = new AppDataKey<>("state_int_15");
         ParametrizedDynamicTypeEvaluatorTest.TestCase<?>[] testCases = {
             test(constant("hello"), "hello"),
-            test(DynamicString.fromState("state_hello_world"), "hello_world"),
+            test(DynamicString.from(new AppDataKey<>("state_hello_world")), "hello_world"),
             test(DynamicInt32.constant(5).format(), "5"),
             test(DynamicInt32.constant(10), 10),
-            test(DynamicInt32.fromState("state_int_15"), 15),
-            test(DynamicInt32.fromState("state_int_15").plus(DynamicInt32.constant(2)), 17),
-            test(DynamicInt32.fromState("state_int_15").minus(DynamicInt32.constant(5)), 10),
-            test(DynamicInt32.fromState("state_int_15").times(DynamicInt32.constant(2)), 30),
-            test(DynamicInt32.fromState("state_int_15").div(DynamicInt32.constant(3)), 5),
-            test(DynamicInt32.fromState("state_int_15").rem(DynamicInt32.constant(2)), 1),
-            test(DynamicInt32.fromState("state_int_15").plus(2), 17),
-            test(DynamicInt32.fromState("state_int_15").minus(5), 10),
-            test(DynamicInt32.fromState("state_int_15").times(2), 30),
-            test(DynamicInt32.fromState("state_int_15").div(3), 5),
-            test(DynamicInt32.fromState("state_int_15").rem(2), 1),
-            test(DynamicInt32.fromState("state_int_15").plus(2.5f), 17.5f),
-            test(DynamicInt32.fromState("state_int_15").minus(5.5f), 9.5f),
-            test(DynamicInt32.fromState("state_int_15").times(2.5f), 37.5f),
-            test(DynamicInt32.fromState("state_int_15").div(2.0f), 7.5f),
-            test(DynamicInt32.fromState("state_int_15").rem(4.5f), 1.5f),
-            test(DynamicInt32.fromState("state_int_15").plus(DynamicFloat.constant(2.5f)), 17.5f),
-            test(DynamicInt32.fromState("state_int_15").minus(DynamicFloat.constant(5.5f)), 9.5f),
-            test(DynamicInt32.fromState("state_int_15").times(DynamicFloat.constant(2.5f)), 37.5f),
-            test(DynamicInt32.fromState("state_int_15").div(DynamicFloat.constant(2.0f)), 7.5f),
-            test(DynamicInt32.fromState("state_int_15").rem(DynamicFloat.constant(4.5f)), 1.5f),
+            test(DynamicInt32.from(int32Source), 15),
+            test(DynamicInt32.from(int32Source).plus(DynamicInt32.constant(2)), 17),
+            test(DynamicInt32.from(int32Source).minus(DynamicInt32.constant(5)), 10),
+            test(DynamicInt32.from(int32Source).times(DynamicInt32.constant(2)), 30),
+            test(DynamicInt32.from(int32Source).div(DynamicInt32.constant(3)), 5),
+            test(DynamicInt32.from(int32Source).rem(DynamicInt32.constant(2)), 1),
+            test(DynamicInt32.from(int32Source).plus(2), 17),
+            test(DynamicInt32.from(int32Source).minus(5), 10),
+            test(DynamicInt32.from(int32Source).times(2), 30),
+            test(DynamicInt32.from(int32Source).div(3), 5),
+            test(DynamicInt32.from(int32Source).rem(2), 1),
+            test(DynamicInt32.from(int32Source).plus(2.5f), 17.5f),
+            test(DynamicInt32.from(int32Source).minus(5.5f), 9.5f),
+            test(DynamicInt32.from(int32Source).times(2.5f), 37.5f),
+            test(DynamicInt32.from(int32Source).div(2.0f), 7.5f),
+            test(DynamicInt32.from(int32Source).rem(4.5f), 1.5f),
+            test(DynamicInt32.from(int32Source).plus(DynamicFloat.constant(2.5f)), 17.5f),
+            test(DynamicInt32.from(int32Source).minus(DynamicFloat.constant(5.5f)), 9.5f),
+            test(DynamicInt32.from(int32Source).times(DynamicFloat.constant(2.5f)), 37.5f),
+            test(DynamicInt32.from(int32Source).div(DynamicFloat.constant(2.0f)), 7.5f),
+            test(DynamicInt32.from(int32Source).rem(DynamicFloat.constant(4.5f)), 1.5f),
             test(DynamicFloat.constant(5.0f), 5.0f),
             testForInvalidValue(DynamicFloat.constant(Float.NaN)),
             testForInvalidValue(DynamicFloat.constant(Float.NaN).plus(5.0f)),
-            test(DynamicFloat.fromState("state_float_1.5"), 1.5f),
+            test(DynamicFloat.from(
+                    new AppDataKey<>("state_float_1.5")), 1.5f),
             test(DynamicFloat.constant(1234.567f).asInt(), 1234),
             test(DynamicFloat.constant(0.967f).asInt(), 0),
             test(DynamicFloat.constant(-1234.967f).asInt(), -1235),
@@ -146,9 +149,11 @@
             test(DynamicBool.constant(true).or(DynamicBool.constant(false)), true),
             test(DynamicBool.constant(false).or(DynamicBool.constant(true)), true),
             test(DynamicBool.constant(false).or(DynamicBool.constant(false)), false),
-            test(DynamicBool.fromState("state_bool_true"), true),
+            test(DynamicBool.from(
+                    new AppDataKey<>("state_bool_true")), true),
             test(DynamicBool.constant(false), false),
-            test(DynamicBool.fromState("state_bool_false"), false),
+            test(DynamicBool.from(
+                    new AppDataKey<>("state_bool_false")), false),
             test(DynamicInt32.constant(5).eq(DynamicInt32.constant(5)), true),
             test(DynamicInt32.constant(5).eq(DynamicInt32.constant(6)), false),
             test(DynamicInt32.constant(5).ne(DynamicInt32.constant(5)), false),
@@ -204,7 +209,8 @@
                             .elseUse(constant("World")),
                     "World"),
             test(
-                    DynamicString.fromState("state_hello_world")
+                    DynamicString.from(
+                            new AppDataKey<>("state_hello_world"))
                             .concat(DynamicString.constant("_test")),
                     "hello_world_test"),
             test(
@@ -504,26 +510,26 @@
         return DynamicDuration.withSecondsPrecision(Duration.ofSeconds(seconds));
     }
 
-    private static ImmutableMap<String, StateEntryValue> generateExampleState() {
+    private static ImmutableMap<AppDataKey<?>, DynamicDataValue> generateExampleState() {
         return ImmutableMap.of(
-                "state_hello_world",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicString>("state_hello_world"),
+                DynamicDataValue.newBuilder()
                         .setStringVal(FixedString.newBuilder().setValue("hello_world"))
                         .build(),
-                "state_int_15",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicInt32>("state_int_15"),
+                DynamicDataValue.newBuilder()
                         .setInt32Val(FixedInt32.newBuilder().setValue(15))
                         .build(),
-                "state_float_1.5",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicFloat>("state_float_1.5"),
+                DynamicDataValue.newBuilder()
                         .setFloatVal(FixedFloat.newBuilder().setValue(1.5f))
                         .build(),
-                "state_bool_true",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicBool>("state_bool_true"),
+                DynamicDataValue.newBuilder()
                         .setBoolVal(FixedBool.newBuilder().setValue(true))
                         .build(),
-                "state_bool_false",
-                StateEntryValue.newBuilder()
+                new AppDataKey<DynamicBool>("state_bool_false"),
+                DynamicDataValue.newBuilder()
                         .setBoolVal(FixedBool.newBuilder().setValue(false))
                         .build());
     }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
index ae1630d..3712441 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StateStoreTest.java
@@ -25,10 +25,17 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoInteractions;
 
+import android.util.ArrayMap;
+
+import androidx.annotation.NonNull;
+import androidx.collection.ArraySet;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.PlatformDataKey;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.truth.Expect;
@@ -41,101 +48,206 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Executor;
 
 @RunWith(AndroidJUnit4.class)
 public class StateStoreTest {
     @Rule public Expect mExpect = Expect.create();
 
+    private static final AppDataKey<DynamicString> KEY_FOO = new AppDataKey<>("foo");
+    private static final AppDataKey<DynamicString> KEY_BAZ = new AppDataKey<>("baz");
+
+    private static final PlatformDataKey<DynamicString> KEY_FOO_PLATFORM
+            = new PlatformDataKey<>("platform", "foo");
+    private static final PlatformDataKey<DynamicString> KEY_BAZ_PLATFORM
+            = new PlatformDataKey<>("platform","baz");
+
     private final StateStore mStateStoreUnderTest =
             new StateStore(
                     ImmutableMap.of(
-                            "foo", buildStateEntry("bar"),
-                            "baz", buildStateEntry("foobar")));
+                            KEY_FOO, buildDynamicDataValue("bar"),
+                            KEY_BAZ, buildDynamicDataValue("foobar")));
 
     public StateStoreTest() {}
 
     @Test
     public void setBuilderApi() {
-        mStateStoreUnderTest.setStateEntryValues(
-                ImmutableMap.of("foo", StateEntryBuilders.StateEntryValue.fromString("baz")));
+        mStateStoreUnderTest.setAppStateEntryValues(
+                ImmutableMap.of(
+                        KEY_FOO, DynamicDataBuilders.DynamicDataValue.fromString("baz")));
 
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
-                .isEqualTo(buildStateEntry("baz"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+                .isEqualTo(buildDynamicDataValue("baz"));
+
+        // This should have been cleared...
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ)).isNull();
     }
 
     @Test
     public void initState_largeNumberOfEntries_throws() {
-        Map<String, StateEntryBuilders.StateEntryValue> state = new HashMap<>();
+        Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> state = new HashMap<>();
         for (int i = 0; i < StateStore.MAX_STATE_ENTRY_COUNT + 10; i++) {
-            state.put(Integer.toString(i), StateEntryBuilders.StateEntryValue.fromString("baz"));
+            state.put(
+                    new AppDataKey<DynamicString>(Integer.toString(i)),
+                    DynamicDataBuilders.DynamicDataValue.fromString("baz"));
         }
         assertThrows(IllegalStateException.class, () -> StateStore.create(state));
     }
 
     @Test
     public void newState_largeNumberOfEntries_throws() {
-        Map<String, StateEntryBuilders.StateEntryValue> state = new HashMap<>();
+        Map<AppDataKey<?>, DynamicDataBuilders.DynamicDataValue> state = new HashMap<>();
         for (int i = 0; i < StateStore.MAX_STATE_ENTRY_COUNT + 10; i++) {
-            state.put(Integer.toString(i), StateEntryBuilders.StateEntryValue.fromString("baz"));
+            state.put(
+                    new AppDataKey<DynamicString>(Integer.toString(i)),
+                    DynamicDataBuilders.DynamicDataValue.fromString("baz"));
         }
         assertThrows(
-                IllegalStateException.class, () -> mStateStoreUnderTest.setStateEntryValues(state));
+                IllegalStateException.class,
+                () -> mStateStoreUnderTest.setAppStateEntryValues(state));
     }
 
     @Test
     public void canReadInitialState() {
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
-                .isEqualTo(buildStateEntry("bar"));
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("baz"))
-                .isEqualTo(buildStateEntry("foobar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+                .isEqualTo(buildDynamicDataValue("bar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+                .isEqualTo(buildDynamicDataValue("foobar"));
     }
 
     @Test
     public void unsetStateReturnsNull() {
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("AAAAAA")).isNull();
+        mExpect.that(
+                mStateStoreUnderTest.getDynamicDataValuesProto(new AppDataKey<>("AAAAAA"))
+                ).isNull();
     }
 
     @Test
     public void canSetNewState() {
-        mStateStoreUnderTest.setStateEntryValuesProto(
+        AppDataKey<DynamicString> keyNew = new AppDataKey<>("newKey");
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo", buildStateEntry("test"),
-                        "newKey", buildStateEntry("testNewKey")));
+                        KEY_FOO, buildDynamicDataValue("test"),
+                        keyNew, buildDynamicDataValue("testNewKey")));
 
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("foo"))
-                .isEqualTo(buildStateEntry("test"));
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("newKey"))
-                .isEqualTo(buildStateEntry("testNewKey"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+                .isEqualTo(buildDynamicDataValue("test"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(keyNew))
+                .isEqualTo(buildDynamicDataValue("testNewKey"));
 
         // This should have been cleared...
-        mExpect.that(mStateStoreUnderTest.getStateEntryValuesProto("baz")).isNull();
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ)).isNull();
+    }
+
+    @Test
+    public void canUpdatePlatformData() {
+        mStateStoreUnderTest.updatePlatformDataEntryProto(
+                Map.of(KEY_FOO_PLATFORM, buildDynamicDataValue("valueFoo1")));
+
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+                .isEqualTo(buildDynamicDataValue("bar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+                .isEqualTo(buildDynamicDataValue("foobar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+                .isEqualTo(buildDynamicDataValue("valueFoo1"));
+
+        mStateStoreUnderTest.updatePlatformDataEntryProto(
+                Map.of(KEY_FOO_PLATFORM, buildDynamicDataValue("valueFoo2"),
+                        KEY_BAZ_PLATFORM, buildDynamicDataValue("valueBaz")));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+                .isEqualTo(buildDynamicDataValue("valueFoo2"));
+
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO))
+                .isEqualTo(buildDynamicDataValue("bar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ))
+                .isEqualTo(buildDynamicDataValue("foobar"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_FOO_PLATFORM))
+                .isEqualTo(buildDynamicDataValue("valueFoo2"));
+        mExpect.that(mStateStoreUnderTest.getDynamicDataValuesProto(KEY_BAZ_PLATFORM))
+                .isEqualTo(buildDynamicDataValue("valueBaz"));
     }
 
     @Test
     public void setStateFiresListeners() {
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb = buildStateUpdateCallbackMock();
-        mStateStoreUnderTest.registerCallback("foo", cb);
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
+        mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
-                ImmutableMap.of("foo", buildStateEntry("test")));
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
+                ImmutableMap.of(KEY_FOO, buildDynamicDataValue("test")));
 
         verify(cb).onPreUpdate();
-        verify(cb).onData(buildStateEntry("test"));
+        verify(cb).onData(buildDynamicDataValue("test"));
+    }
+
+    @Test
+    public void platformDataProvider_register_updateData_unregister() {
+        PlatformDataProviderUnderTest dataProvider = new PlatformDataProviderUnderTest();
+        Map<PlatformDataKey<?>, PlatformDataProvider> sourceKeyToDataProvider = new ArrayMap<>();
+        sourceKeyToDataProvider.put(KEY_FOO_PLATFORM, dataProvider);
+        sourceKeyToDataProvider.put(KEY_BAZ_PLATFORM, dataProvider);
+        mStateStoreUnderTest.putAllPlatformProviders(sourceKeyToDataProvider);
+
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo =
+                buildStateUpdateCallbackMock();
+        mStateStoreUnderTest.registerCallback(KEY_FOO_PLATFORM, cbFoo);
+        verify(cbFoo).onPreUpdate();
+        verify(cbFoo).onData(buildDynamicDataValue("fooValue"));
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbBaz =
+                buildStateUpdateCallbackMock();
+        mStateStoreUnderTest.registerCallback(KEY_BAZ_PLATFORM, cbBaz);
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo2 =
+                buildStateUpdateCallbackMock();
+        mStateStoreUnderTest.registerCallback(KEY_FOO_PLATFORM, cbFoo2);
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+
+        dataProvider.updateValues(
+                Map.of(KEY_FOO_PLATFORM,
+                        DynamicDataBuilders.DynamicDataValue.fromString("newFooValue"),
+                        KEY_BAZ_PLATFORM,
+                        DynamicDataBuilders.DynamicDataValue.fromString("newBazValue")
+                ));
+        verify(cbFoo, times(2)).onPreUpdate();
+        verify(cbFoo2).onPreUpdate();
+        verify(cbBaz).onPreUpdate();
+        verify(cbFoo).onData(buildDynamicDataValue("newFooValue"));
+        verify(cbFoo2).onData(buildDynamicDataValue("newFooValue"));
+        verify(cbBaz).onData(buildDynamicDataValue("newBazValue"));
+
+        dataProvider.updateValues(
+                Map.of(
+                        KEY_BAZ_PLATFORM,
+                        DynamicDataBuilders.DynamicDataValue.fromString("updatedBazValue")
+                ));
+        verify(cbFoo, times(1)).onData(buildDynamicDataValue("newFooValue"));
+        verify(cbFoo2, times(1)).onData(buildDynamicDataValue("newFooValue"));
+        verify(cbBaz).onData(buildDynamicDataValue("newBazValue"));
+
+        mStateStoreUnderTest.unregisterCallback(KEY_FOO_PLATFORM, cbFoo);
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+        mStateStoreUnderTest.unregisterCallback(KEY_FOO_PLATFORM, cbFoo2);
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(1);
+        mStateStoreUnderTest.unregisterCallback(KEY_BAZ_PLATFORM, cbBaz);
+        mExpect.that(dataProvider.mRegisterCount).isEqualTo(0);
     }
 
     @Test
     public void setStateFiresOnPreStateUpdateFirst() {
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb = buildStateUpdateCallbackMock();
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
 
         InOrder inOrder = Mockito.inOrder(cb);
 
-        mStateStoreUnderTest.registerCallback("foo", cb);
-        mStateStoreUnderTest.registerCallback("baz", cb);
+        mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
+        mStateStoreUnderTest.registerCallback(KEY_BAZ, cb);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo", buildStateEntry("testFoo"),
-                        "baz", buildStateEntry("testBaz")));
+                        KEY_FOO, buildDynamicDataValue("testFoo"),
+                        KEY_BAZ, buildDynamicDataValue("testBaz")));
 
         inOrder.verify(cb, times(2)).onPreUpdate();
         inOrder.verify(cb, times(2)).onData(any());
@@ -144,41 +256,44 @@
 
     @Test
     public void setStateOnlyFiresListenersForChangedData() {
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cbFoo =
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbFoo =
                 buildStateUpdateCallbackMock();
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cbBaz =
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cbBaz =
                 buildStateUpdateCallbackMock();
-        mStateStoreUnderTest.registerCallback("foo", cbFoo);
-        mStateStoreUnderTest.registerCallback("baz", cbBaz);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
+        mStateStoreUnderTest.registerCallback(KEY_FOO, cbFoo);
+        mStateStoreUnderTest.registerCallback(KEY_BAZ, cbBaz);
+
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo", buildStateEntry("test"),
-                        "baz", buildStateEntry("foobar")));
+                        KEY_FOO, buildDynamicDataValue("test"),
+                        KEY_BAZ, buildDynamicDataValue("foobar")));
 
         verify(cbFoo).onPreUpdate();
-        verify(cbFoo).onData(buildStateEntry("test"));
+        verify(cbFoo).onData(buildDynamicDataValue("test"));
         verify(cbBaz, never()).onPreUpdate();
-        verify(cbBaz, never()).onData(buildStateEntry("test"));
+        verify(cbBaz, never()).onData(buildDynamicDataValue("test"));
     }
 
     @Test
     public void removeStateFiresInvalidated() {
-        mStateStoreUnderTest.setStateEntryValuesProto(
+        AppDataKey<DynamicString> keyInvalidated = new AppDataKey<>("invalidated");
+        AppDataKey<DynamicString> keyNotInvalidated = new AppDataKey<>("notInvalidated");
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "invalidated",
-                        buildStateEntry("value"),
-                        "notInvalidated",
-                        buildStateEntry("value")));
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> invalidated =
+                        keyInvalidated,
+                        buildDynamicDataValue("value"),
+                        keyNotInvalidated,
+                        buildDynamicDataValue("value")));
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> invalidated =
                 buildStateUpdateCallbackMock();
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> notInvalidated =
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> notInvalidated =
                 buildStateUpdateCallbackMock();
-        mStateStoreUnderTest.registerCallback("invalidated", invalidated);
-        mStateStoreUnderTest.registerCallback("notInvalidated", notInvalidated);
+        mStateStoreUnderTest.registerCallback(keyInvalidated, invalidated);
+        mStateStoreUnderTest.registerCallback(keyNotInvalidated, notInvalidated);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
-                ImmutableMap.of("notInvalidated", buildStateEntry("value")));
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
+                ImmutableMap.of(keyNotInvalidated, buildDynamicDataValue("value")));
 
         verify(invalidated).onPreUpdate();
         verify(invalidated).onInvalidated();
@@ -189,31 +304,83 @@
     @SuppressWarnings("unchecked")
     @Test
     public void canUnregisterListeners() {
-        DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> cb = buildStateUpdateCallbackMock();
-        mStateStoreUnderTest.registerCallback("foo", cb);
+        DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> cb = buildStateUpdateCallbackMock();
+        mStateStoreUnderTest.registerCallback(KEY_FOO, cb);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
-                ImmutableMap.of("foo", buildStateEntry("test")));
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
+                ImmutableMap.of(KEY_FOO, buildDynamicDataValue("test")));
 
         reset(cb);
-        mStateStoreUnderTest.unregisterCallback("foo", cb);
 
-        mStateStoreUnderTest.setStateEntryValuesProto(
-                ImmutableMap.of("foo", buildStateEntry("testAgain")));
+        mStateStoreUnderTest.unregisterCallback(KEY_FOO, cb);
+
+        mStateStoreUnderTest.setAppStateEntryValuesProto(
+                ImmutableMap.of(KEY_FOO, buildDynamicDataValue("testAgain")));
 
         verifyNoInteractions(cb);
     }
 
     @SuppressWarnings("unchecked")
-    private DynamicTypeValueReceiverWithPreUpdate<StateEntryValue> buildStateUpdateCallbackMock() {
+    private DynamicTypeValueReceiverWithPreUpdate<DynamicDataValue> buildStateUpdateCallbackMock() {
         // This needs an unchecked cast because of the generic; this method just centralizes the
         // warning suppression.
         return mock(DynamicTypeValueReceiverWithPreUpdate.class);
     }
 
-    private StateEntryValue buildStateEntry(String value) {
-        return StateEntryValue.newBuilder()
+    private DynamicDataValue buildDynamicDataValue(String value) {
+        return DynamicDataValue.newBuilder()
                 .setStringVal(FixedString.newBuilder().setValue(value))
                 .build();
     }
+
+    private class PlatformDataProviderUnderTest implements PlatformDataProvider {
+
+        private PlatformDataReceiver mRegisteredCallback = null;
+
+        private final Map<PlatformDataKey<?>, DynamicDataBuilders.DynamicDataValue> mCurrentValue =
+                new ArrayMap<>();
+
+        private final Set<PlatformDataKey<?>> mSupportedKeys= new ArraySet<>();
+
+        int mRegisterCount = 0;
+
+        PlatformDataProviderUnderTest() {
+            mSupportedKeys.add(KEY_FOO_PLATFORM);
+            mSupportedKeys.add(KEY_BAZ_PLATFORM);
+            mCurrentValue.put(
+                    KEY_FOO_PLATFORM,
+                    DynamicDataBuilders.DynamicDataValue.fromString("fooValue")
+            );
+            mCurrentValue.put(
+                    KEY_BAZ_PLATFORM,
+                    DynamicDataBuilders.DynamicDataValue.fromString("bazValue")
+            );
+        }
+
+        public void updateValues(
+                @NonNull Map<PlatformDataKey<?> , DynamicDataBuilders.DynamicDataValue> newData) {
+            mCurrentValue.putAll(newData);
+            if (mRegisteredCallback != null) {
+                mRegisteredCallback.onData(mCurrentValue);
+            }
+        }
+
+        @Override
+        public void registerForData(
+                @NonNull Executor executor,
+                @NonNull PlatformDataReceiver callback) {
+                mRegisterCount++;
+                mRegisteredCallback = callback;
+                executor.execute(() -> callback.onData(mCurrentValue));
+        }
+
+        @Override
+        public void unregisterForData() {
+            if (mRegisteredCallback != null) {
+                mRegisteredCallback.onInvalidated(mSupportedKeys);
+                mRegisterCount--;
+                mRegisteredCallback = null;
+            }
+        }
+    }
 }
diff --git a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
index 7b74e8ed..f9afae6 100644
--- a/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
+++ b/wear/protolayout/protolayout-expression-pipeline/src/test/java/androidx/wear/protolayout/expression/pipeline/StringNodesTest.java
@@ -23,6 +23,8 @@
 import android.icu.util.ULocale;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.FixedStringNode;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.Int32FormatNode;
 import androidx.wear.protolayout.expression.pipeline.StringNodes.StateStringNode;
@@ -30,7 +32,7 @@
 import androidx.wear.protolayout.expression.proto.DynamicProto.Int32FormatOp;
 import androidx.wear.protolayout.expression.proto.DynamicProto.StateStringSource;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 
 import com.google.common.collect.ImmutableMap;
 
@@ -43,6 +45,7 @@
 
 @RunWith(AndroidJUnit4.class)
 public class StringNodesTest {
+    private static final AppDataKey<DynamicString> KEY_FOO = new AppDataKey<>("foo");
     @Test
     public void fixedStringNodeTest() {
         List<String> results = new ArrayList<>();
@@ -106,8 +109,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setStringVal(FixedString.newBuilder().setValue("bar"))
                                         .build()));
 
@@ -129,8 +132,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setStringVal(
                                                 FixedString.newBuilder().setValue(string500chars))
                                         .build()));
@@ -152,8 +155,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setStringVal(FixedString.newBuilder().setValue("bar"))
                                         .build()));
 
@@ -166,10 +169,10 @@
 
         results.clear();
 
-        oss.setStateEntryValuesProto(
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(FixedString.newBuilder().setValue("baz"))
                                 .build()));
 
@@ -208,8 +211,8 @@
         StateStore oss =
                 new StateStore(
                         ImmutableMap.of(
-                                "foo",
-                                StateEntryValue.newBuilder()
+                                KEY_FOO,
+                                DynamicDataValue.newBuilder()
                                         .setStringVal(FixedString.newBuilder().setValue("bar"))
                                         .build()));
 
@@ -223,10 +226,11 @@
 
         results.clear();
         node.destroy();
-        oss.setStateEntryValuesProto(
+
+        oss.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        KEY_FOO,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(FixedString.newBuilder().setValue("baz"))
                                 .build()));
         assertThat(results).isEmpty();
diff --git a/wear/protolayout/protolayout-expression/api/current.txt b/wear/protolayout/protolayout-expression/api/current.txt
index b4f26d0..7f2e9cb 100644
--- a/wear/protolayout/protolayout-expression/api/current.txt
+++ b/wear/protolayout/protolayout-expression/api/current.txt
@@ -78,6 +78,10 @@
     method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
   }
 
+  public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public AppDataKey(String);
+  }
+
   public class ConditionScopes {
   }
 
@@ -98,8 +102,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
   public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicColorByteArray();
   }
@@ -138,8 +142,8 @@
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
   public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicStringByteArray();
   }
@@ -277,15 +281,31 @@
   public static interface DynamicBuilders.DynamicType {
   }
 
-  public final class StateEntryBuilders {
+  public final class DynamicDataBuilders {
   }
 
-  public static interface StateEntryBuilders.StateEntryValue {
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
+  public static interface DynamicDataBuilders.DynamicDataValue {
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+  }
+
+  public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public String getKey();
+    method public String getNamespace();
+  }
+
+  public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public PlatformDataKey(String, String);
+  }
+
+  public class PlatformHealthSources {
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
   }
 
   public final class VersionBuilders {
diff --git a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
index adf05da..ace5549 100644
--- a/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout-expression/api/public_plus_experimental_current.txt
@@ -78,6 +78,10 @@
     method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
   }
 
+  public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public AppDataKey(String);
+  }
+
   public class ConditionScopes {
   }
 
@@ -98,8 +102,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
   public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicColorByteArray();
   }
@@ -138,8 +142,8 @@
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
   public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicStringByteArray();
   }
@@ -277,28 +281,39 @@
   public static interface DynamicBuilders.DynamicType {
   }
 
+  public final class DynamicDataBuilders {
+  }
+
+  public static interface DynamicDataBuilders.DynamicDataValue {
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+  }
+
+  public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public String getKey();
+    method public String getNamespace();
+  }
+
   @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ExperimentalProtoLayoutExtensionApi {
   }
 
-  @androidx.wear.protolayout.expression.ProtoLayoutExperimental public class PlatformHealthSources {
-    method @RequiresApi(android.os.Build.VERSION_CODES.Q) @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
-    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) @androidx.wear.protolayout.expression.ProtoLayoutExperimental public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 heartRateBpm();
+  public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public PlatformDataKey(String, String);
+  }
+
+  public class PlatformHealthSources {
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
   }
 
   @RequiresOptIn(level=androidx.annotation.RequiresOptIn.Level.ERROR) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD}) public @interface ProtoLayoutExperimental {
   }
 
-  public final class StateEntryBuilders {
-  }
-
-  public static interface StateEntryBuilders.StateEntryValue {
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
-  }
-
   public final class VersionBuilders {
   }
 
diff --git a/wear/protolayout/protolayout-expression/api/restricted_current.txt b/wear/protolayout/protolayout-expression/api/restricted_current.txt
index b4f26d0..7f2e9cb 100644
--- a/wear/protolayout/protolayout-expression/api/restricted_current.txt
+++ b/wear/protolayout/protolayout-expression/api/restricted_current.txt
@@ -78,6 +78,10 @@
     method public androidx.wear.protolayout.expression.AnimationParameterBuilders.Repeatable.Builder setReverseRepeatOverride(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationParameters);
   }
 
+  public final class AppDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public AppDataKey(String);
+  }
+
   public class ConditionScopes {
   }
 
@@ -98,8 +102,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool and(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool constant(boolean);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool ne(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool negate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool or(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
@@ -109,13 +113,13 @@
   public static interface DynamicBuilders.DynamicColor extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(@ColorInt int, @ColorInt int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor animate();
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor constant(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicColor!,java.lang.Integer!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicColorByteArray();
   }
@@ -138,8 +142,8 @@
   public static interface DynamicBuilders.DynamicFloat extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(float, float, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 asInt();
@@ -151,8 +155,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat.FloatFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(float);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat);
@@ -207,8 +211,8 @@
   public static interface DynamicBuilders.DynamicInt32 extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(int, int, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(String, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>, androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate(androidx.wear.protolayout.expression.AnimationParameterBuilders.AnimationSpec);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 animate();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat asFloat();
@@ -221,8 +225,8 @@
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool eq(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format();
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString format(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32.IntFormatter);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 fromState(String);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gt(int);
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool gte(androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32);
@@ -268,8 +272,8 @@
   public static interface DynamicBuilders.DynamicString extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType {
     method public default androidx.wear.protolayout.expression.DynamicBuilders.DynamicString concat(androidx.wear.protolayout.expression.DynamicBuilders.DynamicString);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString constant(String);
+    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString from(androidx.wear.protolayout.expression.DynamicDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!>);
     method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromByteArray(byte[]);
-    method public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicString fromState(String);
     method public static androidx.wear.protolayout.expression.ConditionScopes.ConditionScope<androidx.wear.protolayout.expression.DynamicBuilders.DynamicString!,java.lang.String!> onCondition(androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool);
     method public default byte[] toDynamicStringByteArray();
   }
@@ -277,15 +281,31 @@
   public static interface DynamicBuilders.DynamicType {
   }
 
-  public final class StateEntryBuilders {
+  public final class DynamicDataBuilders {
   }
 
-  public static interface StateEntryBuilders.StateEntryValue {
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromBool(boolean);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromColor(@ColorInt int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromFloat(float);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromInt(int);
-    method public static androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue fromString(String);
+  public static interface DynamicDataBuilders.DynamicDataValue {
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromBool(boolean);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromColor(@ColorInt int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromFloat(float);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromInt(int);
+    method public static androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue fromString(String);
+  }
+
+  public abstract class DynamicDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> {
+    method public String getKey();
+    method public String getNamespace();
+  }
+
+  public final class PlatformDataKey<T extends androidx.wear.protolayout.expression.DynamicBuilders.DynamicType> extends androidx.wear.protolayout.expression.DynamicDataKey<T> {
+    ctor public PlatformDataKey(String, String);
+  }
+
+  public class PlatformHealthSources {
+    method @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32 dailySteps();
+    method @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat heartRateBpm();
+    field @RequiresPermission(android.Manifest.permission.ACTIVITY_RECOGNITION) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32!> DAILY_STEPS;
+    field @RequiresPermission(android.Manifest.permission.BODY_SENSORS) public static final androidx.wear.protolayout.expression.PlatformDataKey<androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat!> HEART_RATE_BPM;
   }
 
   public final class VersionBuilders {
diff --git a/wear/protolayout/protolayout-expression/build.gradle b/wear/protolayout/protolayout-expression/build.gradle
index c9777d4..f0bf70b 100644
--- a/wear/protolayout/protolayout-expression/build.gradle
+++ b/wear/protolayout/protolayout-expression/build.gradle
@@ -49,7 +49,7 @@
 }
 
 androidx {
-    name = "ProtoLayout Dynamic Expression"
+    name = "ProtoLayout Expression"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "Create dynamic expressions (for late evaluation by a remote evaluator)."
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java
new file mode 100644
index 0000000..e350a5f
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/AppDataKey.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Represent a {@link DynamicDataKey} that references app/tile pushed state data.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public final class AppDataKey<T extends DynamicBuilders.DynamicType> extends DynamicDataKey<T> {
+    @NonNull private static final String DEFAULT_NAMESPACE = "";
+
+    /**
+     * Create a {@link AppDataKey} with the specified key.
+     * @param key The key in the state to bind to.
+     */
+    public AppDataKey(@NonNull String key) {
+        super(DEFAULT_NAMESPACE, key);
+    }
+}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
index 9374277..162b840 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicBuilders.java
@@ -36,7 +36,7 @@
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInstant;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInt32;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedString;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.protobuf.ExtensionRegistryLite;
 import androidx.wear.protolayout.protobuf.InvalidProtocolBufferException;
@@ -677,6 +677,16 @@
             return mImpl.getSourceKey();
         }
 
+        /**
+         * Gets the namespace for the state key.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceNamespace() {
+            return mImpl.getSourceNamespace();
+        }
+
         @Override
         @RestrictTo(Scope.LIBRARY_GROUP)
         @Nullable
@@ -712,7 +722,12 @@
         @Override
         @NonNull
         public String toString() {
-            return "StateInt32Source{" + "sourceKey=" + getSourceKey() + "}";
+            return "StateInt32Source{"
+                    + "sourceKey="
+                    + getSourceKey()
+                    + ", sourceNamespace="
+                    + getSourceNamespace()
+                    + "}";
         }
 
         /** Builder for {@link StateInt32Source}. */
@@ -735,6 +750,18 @@
                 return this;
             }
 
+            /**
+             * Sets the name space for the state key.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+                mImpl.setSourceNamespace(sourceNamespace);
+                mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+                return this;
+            }
+
             @Override
             @NonNull
             public StateInt32Source build() {
@@ -1507,12 +1534,14 @@
         /**
          * Creates a {@link DynamicInt32} that is bound to the value of an item of the State.
          *
-         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
          */
         @NonNull
-        static DynamicInt32 fromState(@NonNull String stateKey) {
-            return new StateInt32Source.Builder().setSourceKey(stateKey).build();
+        static DynamicInt32 from(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
+            return new StateInt32Source.Builder()
+                    .setSourceKey(dynamicDataKey.getKey())
+                    .setSourceNamespace(dynamicDataKey.getNamespace())
+                    .build();
         }
 
         /**
@@ -1548,12 +1577,13 @@
          * time the state value changes, this {@link DynamicInt32} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value.
          */
         @NonNull
-        static DynamicInt32 animate(@NonNull String stateKey) {
-            return new AnimatableDynamicInt32.Builder().setInput(fromState(stateKey)).build();
+        static DynamicInt32 animate(@NonNull DynamicDataKey<DynamicInt32> dynamicDataKey) {
+            return new AnimatableDynamicInt32.Builder()
+                    .setInput(from(dynamicDataKey))
+                    .build();
         }
 
         /**
@@ -1561,15 +1591,15 @@
          * time the state value changes, this {@link DynamicInt32} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with an int value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with an int value
          * @param animationSpec The animation parameters.
          */
         @NonNull
         static DynamicInt32 animate(
-                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+                @NonNull DynamicDataKey<DynamicInt32> dynamicDataKey,
+                @NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicInt32.Builder()
-                    .setInput(fromState(stateKey))
+                    .setInput(from(dynamicDataKey))
                     .setAnimationSpec(animationSpec)
                     .build();
         }
@@ -2643,6 +2673,17 @@
             return mImpl.getSourceKey();
         }
 
+        /**
+         * Gets the namespace for the state key.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceNamespace() {
+            return mImpl.getSourceNamespace();
+        }
+
+
         @Override
         @RestrictTo(Scope.LIBRARY_GROUP)
         @Nullable
@@ -2678,7 +2719,11 @@
         @Override
         @NonNull
         public String toString() {
-            return "StateStringSource{" + "sourceKey=" + getSourceKey() + "}";
+            return "StateStringSource{"+ "sourceKey="
+                    + getSourceKey()
+                    + ", sourceNamespace="
+                    + getSourceNamespace()
+                    + "}";
         }
 
         /** Builder for {@link StateStringSource}. */
@@ -2701,6 +2746,18 @@
                 return this;
             }
 
+            /**
+             * Sets the name space for the state key.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+                mImpl.setSourceNamespace(sourceNamespace);
+                mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+                return this;
+            }
+
             @Override
             @NonNull
             public StateStringSource build() {
@@ -3258,12 +3315,14 @@
          * Creates a {@link DynamicString} that is bound to the value of an item of the State. The
          * resulted {@link DynamicString} is subject to being truncated if it's too long.
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a string value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a string value.
          */
         @NonNull
-        static DynamicString fromState(@NonNull String stateKey) {
-            return new StateStringSource.Builder().setSourceKey(stateKey).build();
+        static DynamicString from(@NonNull DynamicDataKey<DynamicString> dynamicDataKey) {
+            return new StateStringSource.Builder()
+                    .setSourceKey(dynamicDataKey.getKey())
+                    .setSourceNamespace(dynamicDataKey.getNamespace())
+                    .build();
         }
 
         /**
@@ -3520,6 +3579,17 @@
             return mImpl.getSourceKey();
         }
 
+        /**
+         * Gets the namespace for the state key.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceNamespace() {
+            return mImpl.getSourceNamespace();
+        }
+
+
         @Override
         @RestrictTo(Scope.LIBRARY_GROUP)
         @Nullable
@@ -3555,7 +3625,11 @@
         @Override
         @NonNull
         public String toString() {
-            return "StateFloatSource{" + "sourceKey=" + getSourceKey() + "}";
+            return "StateFloatSource{"+ "sourceKey="
+                    + getSourceKey()
+                    + ", sourceNamespace="
+                    + getSourceNamespace()
+                    + "}";
         }
 
         /** Builder for {@link StateFloatSource}. */
@@ -3578,6 +3652,18 @@
                 return this;
             }
 
+            /**
+             * Sets the name space for the state key.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+                mImpl.setSourceNamespace(sourceNamespace);
+                mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+                return this;
+            }
+
             @Override
             @NonNull
             public StateFloatSource build() {
@@ -4029,12 +4115,14 @@
         /**
          * Creates a {@link DynamicFloat} that is bound to the value of an item of the State.
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
-         *     provider's state.
+         * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
          */
         @NonNull
-        static DynamicFloat fromState(@NonNull String stateKey) {
-            return new StateFloatSource.Builder().setSourceKey(stateKey).build();
+        static DynamicFloat from(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
+            return new StateFloatSource.Builder()
+                    .setSourceKey(dynamicDataKey.getKey())
+                    .setSourceNamespace(dynamicDataKey.getNamespace())
+                    .build();
         }
 
         /**
@@ -4071,12 +4159,13 @@
          * time the state value changes, this {@link DynamicFloat} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
-         *     providers state.
+         * @param dynamicDataKey The data source to a {@link DynamicDataValue} with a float value.
          */
         @NonNull
-        static DynamicFloat animate(@NonNull String stateKey) {
-            return new AnimatableDynamicFloat.Builder().setInput(fromState(stateKey)).build();
+        static DynamicFloat animate(@NonNull DynamicDataKey<DynamicFloat> dynamicDataKey) {
+            return new AnimatableDynamicFloat.Builder()
+                    .setInput(from(dynamicDataKey))
+                    .build();
         }
 
         /**
@@ -4084,15 +4173,15 @@
          * time the state value changes, this {@link DynamicFloat} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a float value from the
-         *     providers state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a float value.
          * @param animationSpec The animation parameters.
          */
         @NonNull
         static DynamicFloat animate(
-                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+                @NonNull DynamicDataKey<DynamicFloat> dynamicDataKey,
+                @NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicFloat.Builder()
-                    .setInput(fromState(stateKey))
+                    .setInput(from(dynamicDataKey))
                     .setAnimationSpec(animationSpec)
                     .build();
         }
@@ -4935,6 +5024,17 @@
             return mImpl.getSourceKey();
         }
 
+        /**
+         * Gets the namespace for the state key.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceNamespace() {
+            return mImpl.getSourceNamespace();
+        }
+
+
         @Override
         @RestrictTo(Scope.LIBRARY_GROUP)
         @Nullable
@@ -4970,7 +5070,12 @@
         @Override
         @NonNull
         public String toString() {
-            return "StateBoolSource{" + "sourceKey=" + getSourceKey() + "}";
+            return "StateBoolSource{"
+                    + "sourceKey="
+                    + getSourceKey()
+                    + ", sourceNamespace="
+                    + getSourceNamespace()
+                    + "}";
         }
 
         /** Builder for {@link StateBoolSource}. */
@@ -4994,6 +5099,18 @@
                 return this;
             }
 
+            /**
+             * Sets the name space for the state key.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+                mImpl.setSourceNamespace(sourceNamespace);
+                mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+                return this;
+            }
+
             @Override
             @NonNull
             public StateBoolSource build() {
@@ -5579,12 +5696,14 @@
         /**
          * Creates a {@link DynamicBool} that is bound to the value of an item of the State.
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a boolean value from the
-         *     provider's state.
+         * @param dynamicDataKey The key to a {@link DynamicDataValue} with a boolean value.
          */
         @NonNull
-        static DynamicBool fromState(@NonNull String stateKey) {
-            return new StateBoolSource.Builder().setSourceKey(stateKey).build();
+        static DynamicBool from(@NonNull DynamicDataKey<DynamicBool> dynamicDataKey) {
+            return new StateBoolSource.Builder()
+                    .setSourceKey(dynamicDataKey.getKey())
+                    .setSourceNamespace(dynamicDataKey.getNamespace())
+                    .build();
         }
 
         /**
@@ -5727,6 +5846,16 @@
             return mImpl.getSourceKey();
         }
 
+        /**
+         * Gets the namespace for the state key.
+         *
+         * @since 1.2
+         */
+        @NonNull
+        public String getSourceNamespace() {
+            return mImpl.getSourceNamespace();
+        }
+
         @Override
         @RestrictTo(Scope.LIBRARY_GROUP)
         @Nullable
@@ -5762,7 +5891,12 @@
         @Override
         @NonNull
         public String toString() {
-            return "StateColorSource{" + "sourceKey=" + getSourceKey() + "}";
+            return "StateColorSource{"
+                    + "sourceKey="
+                    + getSourceKey()
+                    + ", sourceNamespace="
+                    + getSourceNamespace()
+                    + "}";
         }
 
         /** Builder for {@link StateColorSource}. */
@@ -5785,6 +5919,18 @@
                 return this;
             }
 
+            /**
+             * Sets the name space for the state key.
+             *
+             * @since 1.2
+             */
+            @NonNull
+            public Builder setSourceNamespace(@NonNull String sourceNamespace) {
+                mImpl.setSourceNamespace(sourceNamespace);
+                mFingerprint.recordPropertyUpdate(2, sourceNamespace.hashCode());
+                return this;
+            }
+
             @Override
             @NonNull
             public StateColorSource build() {
@@ -6283,12 +6429,14 @@
         /**
          * Creates a {@link DynamicColor} that is bound to the value of an item of the State.
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
          */
         @NonNull
-        static DynamicColor fromState(@NonNull String stateKey) {
-            return new StateColorSource.Builder().setSourceKey(stateKey).build();
+        static DynamicColor from(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
+            return new StateColorSource.Builder()
+                    .setSourceKey(dynamicDataKey.getKey())
+                    .setSourceNamespace(dynamicDataKey.getNamespace())
+                    .build();
         }
 
         /**
@@ -6326,12 +6474,13 @@
          * time the state value changes, this {@link DynamicColor} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
          */
         @NonNull
-        static DynamicColor animate(@NonNull String stateKey) {
-            return new AnimatableDynamicColor.Builder().setInput(fromState(stateKey)).build();
+        static DynamicColor animate(@NonNull DynamicDataKey<DynamicColor> dynamicDataKey) {
+            return new AnimatableDynamicColor.Builder()
+                    .setInput(from(dynamicDataKey))
+                    .build();
         }
 
         /**
@@ -6339,15 +6488,15 @@
          * time the state value changes, this {@link DynamicColor} will animate from its current
          * value to the new value (from the state).
          *
-         * @param stateKey The key to a {@link StateEntryValue} with a color value from the
-         *     provider's state.
+         * @param dynamicDataKey The source key to a {@link DynamicDataValue} with a color value.
          * @param animationSpec The animation parameters.
          */
         @NonNull
         static DynamicColor animate(
-                @NonNull String stateKey, @NonNull AnimationSpec animationSpec) {
+                @NonNull DynamicDataKey<DynamicColor> dynamicDataKey,
+                @NonNull AnimationSpec animationSpec) {
             return new AnimatableDynamicColor.Builder()
-                    .setInput(fromState(stateKey))
+                    .setInput(from(dynamicDataKey))
                     .setAnimationSpec(animationSpec)
                     .build();
         }
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
similarity index 71%
rename from wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java
rename to wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
index 304b9b8..7f4eddd 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/StateEntryBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataBuilders.java
@@ -16,7 +16,6 @@
 
 package androidx.wear.protolayout.expression;
 
-import android.annotation.SuppressLint;
 import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -27,53 +26,53 @@
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedFloat;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedInt32;
 import androidx.wear.protolayout.expression.FixedValueBuilders.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
 
-/** Builders for state entries of a provider. */
-public final class StateEntryBuilders {
-  private StateEntryBuilders() {}
+/** Builders for dynamic data value of a provider. */
+public final class DynamicDataBuilders {
+  private DynamicDataBuilders() {}
 
   /**
-   * Interface defining a state entry value.
+   * Interface defining a dynamic data value.
    *
    * @since 1.2
    */
-  public interface StateEntryValue {
+  public interface DynamicDataValue {
     /**
      * Get the protocol buffer representation of this object.
      *
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    StateEntryProto.StateEntryValue toStateEntryValueProto();
+    DynamicDataProto.DynamicDataValue toDynamicDataValueProto();
 
-    /** Creates a boolean {@link StateEntryValue}. */
+    /** Creates a boolean {@link DynamicDataValue}. */
     @NonNull
-    static StateEntryValue fromBool(boolean constant) {
+    static DynamicDataValue fromBool(boolean constant) {
       return new FixedBool.Builder().setValue(constant).build();
     }
 
-    /** Creates a int {@link StateEntryValue}. */
+    /** Creates a int {@link DynamicDataValue}. */
     @NonNull
-    static StateEntryValue fromInt(int constant) {
+    static DynamicDataValue fromInt(int constant) {
       return new FixedInt32.Builder().setValue(constant).build();
     }
 
-    /** Creates a float {@link StateEntryValue}. */
+    /** Creates a float {@link DynamicDataValue}. */
     @NonNull
-    static StateEntryValue fromFloat(float constant) {
+    static DynamicDataValue fromFloat(float constant) {
       return new FixedFloat.Builder().setValue(constant).build();
     }
 
-    /** Creates a color {@link StateEntryValue}. */
+    /** Creates a color {@link DynamicDataValue}. */
     @NonNull
-    static StateEntryValue fromColor(@ColorInt int constant) {
+    static DynamicDataValue fromColor(@ColorInt int constant) {
       return new FixedColor.Builder().setArgb(constant).build();
     }
 
-    /** Creates a string {@link StateEntryValue}. */
+    /** Creates a string {@link DynamicDataValue}. */
     @NonNull
-    static StateEntryValue fromString(@NonNull String constant) {
+    static DynamicDataValue fromString(@NonNull String constant) {
       return new FixedString.Builder().setValue(constant).build();
     }
 
@@ -85,7 +84,7 @@
     @Nullable
     Fingerprint getFingerprint();
 
-    /** Builder to create {@link StateEntryValue} objects.
+    /** Builder to create {@link DynamicDataValue} objects.
      *
      */
     @RestrictTo(Scope.LIBRARY_GROUP)
@@ -93,7 +92,7 @@
 
       /** Builds an instance with values accumulated in this Builder. */
       @NonNull
-      StateEntryValue build();
+      DynamicDataValue build();
     }
   }
 
@@ -104,8 +103,8 @@
    */
   @RestrictTo(Scope.LIBRARY_GROUP)
   @NonNull
-  public static StateEntryValue stateEntryValueFromProto(
-      @NonNull StateEntryProto.StateEntryValue proto) {
+  public static DynamicDataValue dynamicDataValueFromProto(
+      @NonNull DynamicDataProto.DynamicDataValue proto) {
     if (proto.hasStringVal()) {
       return FixedString.fromProto(proto.getStringVal());
     }
@@ -121,6 +120,6 @@
     if (proto.hasColorVal()) {
       return FixedColor.fromProto(proto.getColorVal());
     }
-    throw new IllegalStateException("Proto was not a recognised instance of StateEntryValue");
+    throw new IllegalStateException("Proto was not a recognised instance of DynamicDataValue");
   }
 }
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java
new file mode 100644
index 0000000..29c060d
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/DynamicDataKey.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * Represent a key that references a dynamic value source, such as state pushed by app/tile or
+ * real-time data from the platform.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public abstract class DynamicDataKey<T extends DynamicBuilders.DynamicType> {
+    @NonNull private final String mKey;
+    @NonNull private final String mNamespace;
+
+    /**
+     * Create a {@link DynamicDataKey} with the specified key in the given namespace.
+     * @param namespace The namespace of the key for the dynamic data source.
+     * @param key The key that references the dynamic data source.
+     */
+    DynamicDataKey(@NonNull String namespace, @NonNull String key) {
+        mKey = key;
+        mNamespace = namespace;
+    }
+
+    /**
+     * Gets the key that references the dynamic data source
+     */
+    @NonNull public String getKey() {
+        return mKey;
+    }
+
+    /**
+     * Gets the namespace of the key for the dynamic data source.
+     */
+    @NonNull public String getNamespace() {
+        return mNamespace;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (other == this) {
+            return true;
+        }
+
+        if (!(other instanceof DynamicDataKey)) {
+            return false;
+        }
+
+        DynamicDataKey<?> comp = (DynamicDataKey<?>) other;
+
+        return mKey.equals(comp.getKey()) && mNamespace.equals(comp.getNamespace());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mKey,mNamespace);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return String.format("namespace = %s, key = %s", mNamespace, mKey);
+    }
+}
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
index f4f2cb7..5d6d870 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/FixedValueBuilders.java
@@ -24,7 +24,7 @@
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.expression.proto.DynamicProto;
 import androidx.wear.protolayout.expression.proto.FixedProto;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
 
 /**
  * Builders for fixed value primitive types that can be used in dynamic expressions and in for state
@@ -39,7 +39,7 @@
    * @since 1.2
    */
   static final class FixedInt32
-      implements DynamicBuilders.DynamicInt32, StateEntryBuilders.StateEntryValue {
+      implements DynamicBuilders.DynamicInt32, DynamicDataBuilders.DynamicDataValue {
     private final FixedProto.FixedInt32 mImpl;
     @Nullable private final Fingerprint mFingerprint;
 
@@ -92,8 +92,8 @@
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public StateEntryProto.StateEntryValue toStateEntryValueProto() {
-      return StateEntryProto.StateEntryValue.newBuilder().setInt32Val(mImpl).build();
+    public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+      return DynamicDataProto.DynamicDataValue.newBuilder().setInt32Val(mImpl).build();
     }
 
     @Override
@@ -105,7 +105,7 @@
     /** Builder for {@link FixedInt32}. */
     public static final class Builder
         implements DynamicBuilders.DynamicInt32.Builder,
-            StateEntryBuilders.StateEntryValue.Builder {
+            DynamicDataBuilders.DynamicDataValue.Builder {
       private final FixedProto.FixedInt32.Builder mImpl = FixedProto.FixedInt32.newBuilder();
       private final Fingerprint mFingerprint = new Fingerprint(974881783);
 
@@ -137,7 +137,7 @@
    * @since 1.2
    */
   static final class FixedString
-      implements DynamicBuilders.DynamicString, StateEntryBuilders.StateEntryValue {
+      implements DynamicBuilders.DynamicString, DynamicDataBuilders.DynamicDataValue {
     private final FixedProto.FixedString mImpl;
     @Nullable private final Fingerprint mFingerprint;
 
@@ -191,8 +191,8 @@
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public StateEntryProto.StateEntryValue toStateEntryValueProto() {
-      return StateEntryProto.StateEntryValue.newBuilder().setStringVal(mImpl).build();
+    public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+      return DynamicDataProto.DynamicDataValue.newBuilder().setStringVal(mImpl).build();
     }
 
     @Override
@@ -204,7 +204,7 @@
     /** Builder for {@link FixedString}. */
     public static final class Builder
         implements DynamicBuilders.DynamicString.Builder,
-            StateEntryBuilders.StateEntryValue.Builder {
+            DynamicDataBuilders.DynamicDataValue.Builder {
       private final FixedProto.FixedString.Builder mImpl = FixedProto.FixedString.newBuilder();
       private final Fingerprint mFingerprint = new Fingerprint(1963352072);
 
@@ -236,7 +236,7 @@
    * @since 1.2
    */
   static final class FixedFloat
-      implements DynamicBuilders.DynamicFloat, StateEntryBuilders.StateEntryValue {
+      implements DynamicBuilders.DynamicFloat, DynamicDataBuilders.DynamicDataValue {
     private final FixedProto.FixedFloat mImpl;
     @Nullable private final Fingerprint mFingerprint;
 
@@ -290,8 +290,8 @@
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public StateEntryProto.StateEntryValue toStateEntryValueProto() {
-      return StateEntryProto.StateEntryValue.newBuilder().setFloatVal(mImpl).build();
+    public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+      return DynamicDataProto.DynamicDataValue.newBuilder().setFloatVal(mImpl).build();
     }
 
     @Override
@@ -303,7 +303,7 @@
     /** Builder for {@link FixedFloat}. */
     public static final class Builder
         implements DynamicBuilders.DynamicFloat.Builder,
-            StateEntryBuilders.StateEntryValue.Builder {
+            DynamicDataBuilders.DynamicDataValue.Builder {
       private final FixedProto.FixedFloat.Builder mImpl = FixedProto.FixedFloat.newBuilder();
       private final Fingerprint mFingerprint = new Fingerprint(-144724541);
 
@@ -338,7 +338,7 @@
    * @since 1.2
    */
   static final class FixedBool
-      implements DynamicBuilders.DynamicBool, StateEntryBuilders.StateEntryValue {
+      implements DynamicBuilders.DynamicBool, DynamicDataBuilders.DynamicDataValue {
     private final FixedProto.FixedBool mImpl;
     @Nullable private final Fingerprint mFingerprint;
 
@@ -391,8 +391,8 @@
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public StateEntryProto.StateEntryValue toStateEntryValueProto() {
-      return StateEntryProto.StateEntryValue.newBuilder().setBoolVal(mImpl).build();
+    public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+      return DynamicDataProto.DynamicDataValue.newBuilder().setBoolVal(mImpl).build();
     }
 
     @Override
@@ -403,7 +403,8 @@
 
     /** Builder for {@link FixedBool}. */
     public static final class Builder
-        implements DynamicBuilders.DynamicBool.Builder, StateEntryBuilders.StateEntryValue.Builder {
+        implements DynamicBuilders.DynamicBool.Builder,
+            DynamicDataBuilders.DynamicDataValue.Builder {
       private final FixedProto.FixedBool.Builder mImpl = FixedProto.FixedBool.newBuilder();
       private final Fingerprint mFingerprint = new Fingerprint(-665116398);
 
@@ -436,7 +437,7 @@
    * @since 1.2
    */
   static final class FixedColor
-      implements DynamicBuilders.DynamicColor, StateEntryBuilders.StateEntryValue {
+      implements DynamicBuilders.DynamicColor, DynamicDataBuilders.DynamicDataValue {
     private final FixedProto.FixedColor mImpl;
     @Nullable private final Fingerprint mFingerprint;
 
@@ -490,8 +491,8 @@
     @Override
     @RestrictTo(Scope.LIBRARY_GROUP)
     @NonNull
-    public StateEntryProto.StateEntryValue toStateEntryValueProto() {
-      return StateEntryProto.StateEntryValue.newBuilder().setColorVal(mImpl).build();
+    public DynamicDataProto.DynamicDataValue toDynamicDataValueProto() {
+      return DynamicDataProto.DynamicDataValue.newBuilder().setColorVal(mImpl).build();
     }
 
     @Override
@@ -503,7 +504,7 @@
     /** Builder for {@link FixedColor}. */
     public static final class Builder
         implements DynamicBuilders.DynamicColor.Builder,
-            StateEntryBuilders.StateEntryValue.Builder {
+            DynamicDataBuilders.DynamicDataValue.Builder {
       private final FixedProto.FixedColor.Builder mImpl = FixedProto.FixedColor.newBuilder();
       private final Fingerprint mFingerprint = new Fingerprint(-1895809356);
 
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java
new file mode 100644
index 0000000..24ed21e
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformDataKey.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.RestrictTo;
+
+/**
+ * Represent a {@link DynamicDataKey} that references real-time data from the platform.
+ *
+ * <p> The [namespace, key] tuple creates the actual reference, so that a single key can refer to
+ * two different sources in two different namespaces.
+ *
+ * <p> The namespace must not be empty. Additionally, the "protolayout" namespace (and its
+ * lowercase and uppercase variations) are reserved for the default platform data sources and
+ * should not be used for any custom OEM data source. To choose the namespace that does not
+ * conflict with an existing one, use a unique prefix for your namespace, for example, company
+ * name or product name.
+ *
+ * @param <T> The data type of the dynamic values that this key is bound to.
+ */
+public final class PlatformDataKey<T extends DynamicBuilders.DynamicType> extends DynamicDataKey<T>
+{
+    @NonNull private static final String RESERVED_NAMESPACE = "protolayout";
+
+    /**
+     * Create a {@link PlatformDataKey} with the specified key in the given namespace.
+     *
+     * @param namespace The namespace of the key for the platform data source.
+     * @param key The key that references the platform data source.
+     */
+    public PlatformDataKey(@NonNull String namespace, @NonNull String key) {
+        super(namespace, key);
+        if (namespace.isEmpty()) {
+            throw new IllegalArgumentException("Custom data source namespace must not be empty.");
+        }
+
+        if (RESERVED_NAMESPACE.equalsIgnoreCase(namespace)) {
+            throw new IllegalArgumentException(String.format(
+                    "Custom data source must not use the reserved namespace:%s",
+                    RESERVED_NAMESPACE));
+        }
+    }
+
+    /**
+     * Create a {@link PlatformDataKey} with the specified key in the reserved namespace.
+     * This should only be used by protolayout library internally for default platform data sources.
+     *
+     * @param key The key that references the platform data source
+     */
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public PlatformDataKey(@NonNull String key) {
+        super(RESERVED_NAMESPACE, key);
+    }
+}
+
diff --git a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
index 0974b70..8be1449 100644
--- a/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
+++ b/wear/protolayout/protolayout-expression/src/main/java/androidx/wear/protolayout/expression/PlatformHealthSources.java
@@ -20,38 +20,57 @@
 import static androidx.wear.protolayout.expression.DynamicBuilders.PLATFORM_INT32_SOURCE_TYPE_DAILY_STEP_COUNT;
 
 import android.Manifest;
-import android.os.Build.VERSION_CODES;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
 import androidx.annotation.RequiresPermission;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat;
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
 import androidx.wear.protolayout.expression.DynamicBuilders.PlatformInt32Source;
 
 /** Utility class provides utils to access health data. */
-@ProtoLayoutExperimental
 public class PlatformHealthSources {
     private PlatformHealthSources() {
     }
 
-    /** Creates a {@link DynamicInt32} which receives the current heat rate from the sensor. */
-    @RequiresPermission(Manifest.permission.BODY_SENSORS)
-    @ProtoLayoutExperimental
+    /**
+     * The data source key for heart rate bpm data from default platform health sources.
+     */
     @NonNull
-    public static DynamicInt32 heartRateBpm() {
+    @RequiresPermission(Manifest.permission.BODY_SENSORS)
+    public static final PlatformDataKey<DynamicFloat> HEART_RATE_BPM =
+            new PlatformDataKey<>("HeartRate");
+
+    /**
+     * The data source key for daily step count data from default platform health sources.
+     */
+    @NonNull
+    @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
+    public static final PlatformDataKey<DynamicInt32> DAILY_STEPS =
+            new PlatformDataKey<>("Daily Steps");
+
+    /**
+     * Creates a {@link DynamicInt32} which receives the current heat rate from the sensor.
+     *
+     * <p> This method provides backward compatibility and is preferred over using {@code
+     * HEART_RATE_BPM} directly.
+     */
+    @RequiresPermission(Manifest.permission.BODY_SENSORS)
+    @NonNull
+    public static DynamicFloat heartRateBpm() {
         return new PlatformInt32Source.Builder()
                 .setSourceType(PLATFORM_INT32_SOURCE_TYPE_CURRENT_HEART_RATE)
-                .build();
+                .build().asFloat();
     }
 
     /**
      * Creates a {@link DynamicInt32} which receives the current daily steps from the sensor.
      * This is the total step count over a day, where the previous day ends and a new day begins at
      * 12:00 AM local time.
+     *
+     * <p> This method provides backward compatibility and is preferred over using {@code
+     * DAILY_STEPS} directly.
      */
-    @RequiresApi(VERSION_CODES.Q)
     @RequiresPermission(Manifest.permission.ACTIVITY_RECOGNITION)
-    @ProtoLayoutExperimental
     @NonNull
     public static DynamicInt32 dailySteps() {
         return new PlatformInt32Source.Builder()
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
index beb1207..c7263ec 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicBoolTest.java
@@ -51,7 +51,7 @@
 
     @Test
     public void stateEntryValueBool() {
-        DynamicBool stateBool = DynamicBool.fromState(STATE_KEY);
+        DynamicBool stateBool = DynamicBool.from(new AppDataKey<>(STATE_KEY));
 
         assertThat(stateBool.toDynamicBoolProto().getStateSource().getSourceKey())
                 .isEqualTo(STATE_KEY);
@@ -59,8 +59,8 @@
 
     @Test
     public void stateToString() {
-        assertThat(DynamicBool.fromState("key").toString())
-                .isEqualTo("StateBoolSource{sourceKey=key}");
+        assertThat(DynamicBool.from(new AppDataKey<>("key")).toString())
+                .isEqualTo("StateBoolSource{sourceKey=key, sourceNamespace=}");
     }
 
     @Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
index 9f03379..2751e61 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicColorTest.java
@@ -58,7 +58,7 @@
 
   @Test
   public void stateEntryValueColor() {
-    DynamicColor stateColor = DynamicColor.fromState(STATE_KEY);
+    DynamicColor stateColor = DynamicColor.from(new AppDataKey<>(STATE_KEY));
 
     assertThat(stateColor.toDynamicColorProto().getStateSource().getSourceKey())
         .isEqualTo(STATE_KEY);
@@ -66,8 +66,8 @@
 
   @Test
   public void stateToString() {
-    assertThat(DynamicColor.fromState("key").toString())
-        .isEqualTo("StateColorSource{sourceKey=key}");
+    assertThat(DynamicColor.from(new AppDataKey<>("key")).toString())
+        .isEqualTo("StateColorSource{sourceKey=key, sourceNamespace=}");
   }
 
   @Test
@@ -104,10 +104,11 @@
 
   @Test
   public void stateAnimatedColor() {
-    DynamicColor stateColor = DynamicColor.fromState(STATE_KEY);
+    AppDataKey<DynamicColor> source = new AppDataKey<>(STATE_KEY);
+    DynamicColor stateColor = DynamicColor.from(source);
 
-    DynamicColor animatedColor = DynamicColor.animate(STATE_KEY);
-    DynamicColor animatedColorWithSpec = DynamicColor.animate(STATE_KEY, SPEC);
+    DynamicColor animatedColor = DynamicColor.animate(source);
+    DynamicColor animatedColorWithSpec = DynamicColor.animate(source, SPEC);
 
     assertThat(animatedColor.toDynamicColorProto().getAnimatableDynamic().hasAnimationSpec())
         .isFalse();
@@ -124,7 +125,7 @@
   public void stateAnimatedToString() {
     assertThat(
             DynamicColor.animate(
-                    /* stateKey= */ "key",
+                    /* stateKey= */ new AppDataKey<>("key"),
                     new AnimationSpec.Builder()
                             .setAnimationParameters(
                                     new AnimationParameters.Builder().setDelayMillis(1).build())
@@ -132,7 +133,8 @@
                 .toString())
         .isEqualTo(
             "AnimatableDynamicColor{"
-                + "input=StateColorSource{sourceKey=key}, animationSpec=AnimationSpec{"
+                + "input=StateColorSource{sourceKey=key, sourceNamespace=}, "
+                + "animationSpec=AnimationSpec{"
                 + "animationParameters=AnimationParameters{durationMillis=0, easing=null, "
                 + "delayMillis=1}, repeatable=null}}");
   }
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java
new file mode 100644
index 0000000..47237c4
--- /dev/null
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicDataValueTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.protolayout.expression;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DynamicDataValueTest {
+  @Test
+  public void boolDynamicDataValue() {
+    DynamicDataValue boolDynamicDataValue = DynamicDataValue.fromBool(true);
+
+    assertThat(boolDynamicDataValue.toDynamicDataValueProto().getBoolVal().getValue()).isTrue();
+  }
+
+  @Test
+  public void colorDynamicDataValue() {
+    DynamicDataValue colorDynamicDataValue = DynamicDataValue.fromColor(0xff00ff00);
+
+    assertThat(colorDynamicDataValue.toDynamicDataValueProto().getColorVal().getArgb())
+        .isEqualTo(0xff00ff00);
+  }
+
+  @Test
+  public void floatDynamicDataValue() {
+    DynamicDataValue floatDynamicDataValue = DynamicDataValue.fromFloat(42.42f);
+
+    assertThat(floatDynamicDataValue.toDynamicDataValueProto().getFloatVal().getValue())
+        .isWithin(0.0001f)
+        .of(42.42f);
+  }
+
+  @Test
+  public void intDynamicDataValue() {
+    DynamicDataValue intDynamicDataValue = DynamicDataValue.fromInt(42);
+
+    assertThat(intDynamicDataValue.toDynamicDataValueProto().getInt32Val().getValue())
+            .isEqualTo(42);
+  }
+
+  @Test
+  public void stringDynamicDataValue() {
+    DynamicDataValue stringDynamicDataValue = DynamicDataValue.fromString("constant-value");
+
+    assertThat(stringDynamicDataValue.toDynamicDataValueProto().getStringVal().getValue())
+        .isEqualTo("constant-value");
+  }
+}
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
index d00b7f3..3036fbed 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicFloatTest.java
@@ -67,7 +67,7 @@
 
     @Test
     public void stateEntryValueFloat() {
-        DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
+        DynamicFloat stateFloat = DynamicFloat.from(new AppDataKey<>(STATE_KEY));
 
         assertThat(stateFloat.toDynamicFloatProto().getStateSource().getSourceKey())
                 .isEqualTo(STATE_KEY);
@@ -75,8 +75,8 @@
 
     @Test
     public void stateToString() {
-        assertThat(DynamicFloat.fromState("key").toString())
-                .isEqualTo("StateFloatSource{sourceKey=key}");
+        assertThat(DynamicFloat.from(new AppDataKey<>("key")).toString())
+                .isEqualTo("StateFloatSource{sourceKey=key, sourceNamespace=}");
     }
 
     @Test
@@ -198,10 +198,10 @@
 
     @Test
     public void stateAnimatedFloat() {
-        DynamicFloat stateFloat = DynamicFloat.fromState(STATE_KEY);
-
-        DynamicFloat animatedFloat = DynamicFloat.animate(STATE_KEY);
-        DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(STATE_KEY, SPEC);
+        AppDataKey<DynamicFloat> source = new AppDataKey<>(STATE_KEY);
+        DynamicFloat stateFloat = DynamicFloat.from(source);
+        DynamicFloat animatedFloat = DynamicFloat.animate(source);
+        DynamicFloat animatedFloatWithSpec = DynamicFloat.animate(source, SPEC);
 
         assertThat(animatedFloat.toDynamicFloatProto().getAnimatableDynamic().hasAnimationSpec())
                 .isFalse();
@@ -221,7 +221,7 @@
     public void stateAnimatedToString() {
         assertThat(
                         DynamicFloat.animate(
-                                        /* stateKey= */ "key",
+                                        new AppDataKey<>("key"),
                                         new AnimationSpec.Builder()
                                                 .setAnimationParameters(
                                                         new AnimationParameters.Builder()
@@ -230,7 +230,8 @@
                                                 .build())
                                 .toString())
                 .isEqualTo(
-                        "AnimatableDynamicFloat{input=StateFloatSource{sourceKey=key},"
+                        "AnimatableDynamicFloat{"
+                                + "input=StateFloatSource{sourceKey=key, sourceNamespace=},"
                                 + " animationSpec=AnimationSpec{animationParameters"
                                 + "=AnimationParameters{durationMillis=0,"
                                 + " easing=null, delayMillis=1}, repeatable=null}}");
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
index f87e5b5..a130199 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicInt32Test.java
@@ -48,7 +48,7 @@
 
     @Test
     public void stateEntryValueInt32() {
-        DynamicInt32 stateInt32 = DynamicInt32.fromState(STATE_KEY);
+        DynamicInt32 stateInt32 = DynamicInt32.from(new AppDataKey<>(STATE_KEY));
 
         assertThat(stateInt32.toDynamicInt32Proto().getStateSource().getSourceKey())
                 .isEqualTo(STATE_KEY);
@@ -56,8 +56,8 @@
 
     @Test
     public void stateToString() {
-        assertThat(DynamicInt32.fromState("key").toString())
-                .isEqualTo("StateInt32Source{sourceKey=key}");
+        assertThat(DynamicInt32.from(new AppDataKey<>("key")).toString())
+                .isEqualTo("StateInt32Source{sourceKey=key, sourceNamespace=}");
     }
 
     @Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
index b0f2be1..b33df22 100644
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
+++ b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/DynamicStringTest.java
@@ -46,7 +46,7 @@
 
   @Test
   public void stateEntryValueString() {
-    DynamicString stateString = DynamicString.fromState(STATE_KEY);
+    DynamicString stateString = DynamicString.from(new AppDataKey<>(STATE_KEY));
 
     assertThat(stateString.toDynamicStringProto().getStateSource().getSourceKey())
         .isEqualTo(STATE_KEY);
@@ -54,8 +54,8 @@
 
   @Test
   public void stateToString() {
-    assertThat(DynamicString.fromState("key").toString())
-        .isEqualTo("StateStringSource{sourceKey=key}");
+    assertThat(DynamicString.from(new AppDataKey<>("key")).toString())
+        .isEqualTo("StateStringSource{sourceKey=key, sourceNamespace=}");
   }
 
   @Test
diff --git a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java b/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java
deleted file mode 100644
index fae643d..0000000
--- a/wear/protolayout/protolayout-expression/src/test/java/androidx/wear/protolayout/expression/StateEntryValueTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.wear.protolayout.expression;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-
-@RunWith(RobolectricTestRunner.class)
-public final class StateEntryValueTest {
-  @Test
-  public void boolStateEntryValue() {
-    StateEntryValue boolStateEntryValue = StateEntryValue.fromBool(true);
-
-    assertThat(boolStateEntryValue.toStateEntryValueProto().getBoolVal().getValue()).isTrue();
-  }
-
-  @Test
-  public void colorStateEntryValue() {
-    StateEntryValue colorStateEntryValue = StateEntryValue.fromColor(0xff00ff00);
-
-    assertThat(colorStateEntryValue.toStateEntryValueProto().getColorVal().getArgb())
-        .isEqualTo(0xff00ff00);
-  }
-
-  @Test
-  public void floatStateEntryValue() {
-    StateEntryValue floatStateEntryValue = StateEntryValue.fromFloat(42.42f);
-
-    assertThat(floatStateEntryValue.toStateEntryValueProto().getFloatVal().getValue())
-        .isWithin(0.0001f)
-        .of(42.42f);
-  }
-
-  @Test
-  public void intStateEntryValue() {
-    StateEntryValue intStateEntryValue = StateEntryValue.fromInt(42);
-
-    assertThat(intStateEntryValue.toStateEntryValueProto().getInt32Val().getValue()).isEqualTo(42);
-  }
-
-  @Test
-  public void stringStateEntryValue() {
-    StateEntryValue stringStateEntryValue = StateEntryValue.fromString("constant-value");
-
-    assertThat(stringStateEntryValue.toStateEntryValueProto().getStringVal().getValue())
-        .isEqualTo("constant-value");
-  }
-}
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/action.proto b/wear/protolayout/protolayout-proto/src/main/proto/action.proto
index 589a31c..944843d 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/action.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/action.proto
@@ -4,7 +4,7 @@
 package androidx.wear.protolayout.proto;
 
 import "state.proto";
-import "state_entry.proto";
+import "dynamic_data.proto";
 
 option java_package = "androidx.wear.protolayout.proto";
 option java_outer_classname = "ActionProto";
@@ -101,5 +101,5 @@
   // The target key of the state item for this action.
   string target_key = 1;
   // The value to set the state item to, when this action is executed.
-  androidx.wear.protolayout.expression.proto.StateEntryValue value = 2;
+  androidx.wear.protolayout.expression.proto.DynamicDataValue value = 2;
 }
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
index b0729ce..bbb26b9 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dynamic.proto
@@ -75,6 +75,9 @@
 message StateInt32Source {
   // The key in the state to bind to.
   string source_key = 1;
+
+  // The namespace for the state key.
+  string source_namespace = 2;
 }
 
 // A conditional operator which yields an integer depending on the boolean
@@ -214,6 +217,9 @@
 message StateStringSource {
   // The key in the state to bind to.
   string source_key = 1;
+
+  // The namespace for the state key.
+  string source_namespace = 2;
 }
 
 // A conditional operator which yields an string depending on the boolean
@@ -299,6 +305,9 @@
 message StateFloatSource {
   // The key in the state to bind to.
   string source_key = 1;
+
+  // The namespace for the state key.
+  string source_namespace = 2;
 }
 
 // An operation to convert a Int32 value in the dynamic data pipeline to a Float
@@ -373,6 +382,9 @@
 message StateBoolSource {
   // The key in the state to bind to.
   string source_key = 1;
+
+  // The namespace for the state key.
+  string source_namespace = 2;
 }
 
 // The type of comparison used in ComparisonInt32Op and ComparisonFloatOp.
@@ -483,6 +495,9 @@
 message StateColorSource {
   // The key in the state to bind to.
   string source_key = 1;
+
+  // The namespace for the state key.
+  string source_namespace = 2;
 }
 
 // A static interpolation node, between two fixed color values.
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto b/wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
similarity index 70%
rename from wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto
rename to wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
index 622043d..f373b86 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/state_entry.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/dynamic_data.proto
@@ -1,4 +1,4 @@
-// State entries of a provider.
+// Dynamic data entries of a provider.
 syntax = "proto3";
 
 package androidx.wear.protolayout.expression.proto;
@@ -6,10 +6,10 @@
 import "fixed.proto";
 
 option java_package = "androidx.wear.protolayout.expression.proto";
-option java_outer_classname = "StateEntryProto";
+option java_outer_classname = "DynamicDataProto";
 
-// A state entry value.
-message StateEntryValue {
+// A dynamic data value.
+message DynamicDataValue {
   oneof inner {
     FixedString string_val = 1;
     FixedInt32 int32_val = 2;
diff --git a/wear/protolayout/protolayout-proto/src/main/proto/state.proto b/wear/protolayout/protolayout-proto/src/main/proto/state.proto
index 162077e..8929f1e 100644
--- a/wear/protolayout/protolayout-proto/src/main/proto/state.proto
+++ b/wear/protolayout/protolayout-proto/src/main/proto/state.proto
@@ -3,7 +3,7 @@
 
 package androidx.wear.protolayout.proto;
 
-import "state_entry.proto";
+import "dynamic_data.proto";
 
 option java_package = "androidx.wear.protolayout.proto";
 option java_outer_classname = "StateProto";
@@ -14,6 +14,6 @@
   string last_clickable_id = 1;
 
   // Any shared state between the provider and renderer.
-  map<string, androidx.wear.protolayout.expression.proto.StateEntryValue>
+  map<string, androidx.wear.protolayout.expression.proto.DynamicDataValue>
       id_to_value = 2;
 }
diff --git a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
index 208c686..3b0a666 100644
--- a/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
+++ b/wear/protolayout/protolayout-renderer/src/main/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipeline.java
@@ -40,6 +40,7 @@
 import androidx.collection.ArrayMap;
 import androidx.collection.ArraySet;
 import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.PlatformHealthSources;
 import androidx.wear.protolayout.expression.pipeline.BoundDynamicType;
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest;
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator;
@@ -47,6 +48,7 @@
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver;
 import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
 import androidx.wear.protolayout.expression.pipeline.QuotaManager;
+import androidx.wear.protolayout.expression.pipeline.SensorGatewaySingleDataProvider;
 import androidx.wear.protolayout.expression.pipeline.StateStore;
 import androidx.wear.protolayout.expression.pipeline.TimeGatewayImpl;
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway;
@@ -65,6 +67,7 @@
 import androidx.wear.protolayout.renderer.dynamicdata.NodeInfo.ResolvedAvd;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -145,7 +148,16 @@
                         .setStateStore(stateStore);
         evaluatorConfigBuilder.setDynamicTypesQuotaManager(dynamicNodeQuotaManager);
         if (sensorGateway != null) {
-            evaluatorConfigBuilder.setSensorGateway(sensorGateway);
+            evaluatorConfigBuilder.addPlatformDataProvider(
+                    new SensorGatewaySingleDataProvider(
+                            sensorGateway, PlatformHealthSources.HEART_RATE_BPM),
+                    Collections.singleton(PlatformHealthSources.HEART_RATE_BPM)
+            );
+            evaluatorConfigBuilder.addPlatformDataProvider(
+                    new SensorGatewaySingleDataProvider(
+                            sensorGateway, PlatformHealthSources.DAILY_STEPS),
+                    Collections.singleton(PlatformHealthSources.DAILY_STEPS)
+            );
         }
         if (enableAnimations) {
             evaluatorConfigBuilder.setAnimationQuotaManager(animationQuotaManager);
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
index d89a564..12e7936 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/dynamicdata/ProtoLayoutDynamicDataPipelineTest.java
@@ -42,6 +42,8 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
 import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
 import androidx.wear.protolayout.expression.pipeline.QuotaManager;
 import androidx.wear.protolayout.expression.pipeline.StateStore;
@@ -70,7 +72,7 @@
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 import androidx.wear.protolayout.proto.ColorProto.ColorProp;
 import androidx.wear.protolayout.proto.DimensionProto.DegreesProp;
 import androidx.wear.protolayout.proto.DimensionProto.DpProp;
@@ -1926,20 +1928,20 @@
     }
 
     private void setFloatStateVal(String key, float val) {
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        key,
-                        StateEntryValue.newBuilder()
+                        new AppDataKey<DynamicBuilders.DynamicFloat>(key),
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(val))
                                 .build()));
         shadowOf(getMainLooper()).idle();
     }
 
     private void setBoolStateVal(String key, boolean val) {
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        key,
-                        StateEntryValue.newBuilder()
+                        new AppDataKey<DynamicBuilders.DynamicBool>(key),
+                        DynamicDataValue.newBuilder()
                                 .setBoolVal(FixedBool.newBuilder().setValue(val))
                                 .build()));
         shadowOf(getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
index 9a529c2..1eb0e31 100644
--- a/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
+++ b/wear/protolayout/protolayout-renderer/src/test/java/androidx/wear/protolayout/renderer/inflater/ProtoLayoutInflaterTest.java
@@ -75,6 +75,8 @@
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.vectordrawable.graphics.drawable.SeekableAnimatedVectorDrawable;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
 import androidx.wear.protolayout.expression.pipeline.FixedQuotaManagerImpl;
 import androidx.wear.protolayout.expression.pipeline.StateStore;
 import androidx.wear.protolayout.expression.proto.AnimationParameterProto.AnimationParameters;
@@ -94,7 +96,7 @@
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedFloat;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedInt32;
 import androidx.wear.protolayout.expression.proto.FixedProto.FixedString;
-import androidx.wear.protolayout.expression.proto.StateEntryProto.StateEntryValue;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto.DynamicDataValue;
 import androidx.wear.protolayout.proto.ActionProto.Action;
 import androidx.wear.protolayout.proto.ActionProto.AndroidActivity;
 import androidx.wear.protolayout.proto.ActionProto.AndroidBooleanExtra;
@@ -415,38 +417,40 @@
         assertThat(tv.isImportantForAccessibility()).isTrue();
         assertThat(info.isFocusable()).isTrue();
 
-        mStateStore.setStateEntryValuesProto(
+        AppDataKey<DynamicBuilders.DynamicString> keyContent = new AppDataKey<>("content");
+        AppDataKey<DynamicBuilders.DynamicString> keyState = new AppDataKey<>("state");
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "content",
-                        StateEntryValue.newBuilder()
+                        keyContent,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(
                                         FixedString.newBuilder()
                                                 .setValue(initialDynamicContentDescription))
                                 .build(),
-                        "state",
-                        StateEntryValue.newBuilder()
+                        keyState,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(
                                         FixedString.newBuilder()
                                                 .setValue(initialDynamicStateDescription))
                                 .build()));
 
         info = AccessibilityNodeInfoCompat.wrap(tv.createAccessibilityNodeInfo());
-        assertThat(mStateStore.getStateEntryValuesProto("content").getStringVal().getValue())
+        assertThat(mStateStore.getDynamicDataValuesProto(keyContent).getStringVal().getValue())
                 .isEqualTo(initialDynamicContentDescription);
         assertThat(info.getContentDescription().toString())
                 .isEqualTo(initialDynamicContentDescription);
         assertThat(info.getStateDescription().toString()).isEqualTo(initialDynamicStateDescription);
 
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "content",
-                        StateEntryValue.newBuilder()
+                        keyContent,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(
                                         FixedString.newBuilder()
                                                 .setValue(targetDynamicContentDescription))
                                 .build(),
-                        "state",
-                        StateEntryValue.newBuilder()
+                        keyState,
+                        DynamicDataValue.newBuilder()
                                 .setStringVal(
                                         FixedString.newBuilder()
                                                 .setValue(targetDynamicStateDescription))
@@ -1675,10 +1679,10 @@
         Drawable drawableAVDSeekable = imageAVDSeekable.getDrawable();
         assertThat(drawableAVDSeekable).isInstanceOf(SeekableAnimatedVectorDrawable.class);
 
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "anim_val",
-                        StateEntryValue.newBuilder()
+                        new AppDataKey<DynamicBuilders.DynamicFloat>("anim_val"),
+                        DynamicDataValue.newBuilder()
                                 .setFloatVal(FixedFloat.newBuilder().setValue(0.44f))
                                 .build()));
         shadowOf(getMainLooper()).idle();
@@ -2125,10 +2129,11 @@
 
     @Test
     public void inflate_arcLine_dynamicData_updatesArcLength() {
-        mStateStore.setStateEntryValuesProto(
+        AppDataKey<DynamicBuilders.DynamicInt32> keyFoo = new AppDataKey<>("foo");
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        keyFoo,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(10))
                                 .build()));
 
@@ -2173,10 +2178,10 @@
         WearCurvedLineView line = (WearCurvedLineView) sizedContainer.getChildAt(0);
         assertThat(line.getLineSweepAngleDegrees()).isEqualTo(10);
 
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        keyFoo,
+                        DynamicDataValue.newBuilder()
                                 .setInt32Val(FixedInt32.newBuilder().setValue(20))
                                 .build()));
 
@@ -2270,10 +2275,11 @@
 
     @Test
     public void inflate_text_dynamicColor_updatesColor() {
-        mStateStore.setStateEntryValuesProto(
+        AppDataKey<DynamicBuilders.DynamicColor> keyFoo = new AppDataKey<>("foo");
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        keyFoo,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(0xFFFFFFFF))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
@@ -2301,10 +2307,10 @@
         TextView tv = (TextView) rootLayout.getChildAt(0);
         assertThat(tv.getCurrentTextColor()).isEqualTo(0xFFFFFFFF);
 
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "foo",
-                        StateEntryValue.newBuilder()
+                        keyFoo,
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(0x11111111))
                                 .build()));
 
@@ -2316,10 +2322,10 @@
         // Must match a resource ID in buildResources
         String protoResId = "android";
 
-        mStateStore.setStateEntryValuesProto(
+        mStateStore.setAppStateEntryValuesProto(
                 ImmutableMap.of(
-                        "tint",
-                        StateEntryValue.newBuilder()
+                        new AppDataKey<DynamicBuilders.DynamicColor>("tint"),
+                        DynamicDataValue.newBuilder()
                                 .setColorVal(FixedColor.newBuilder().setArgb(0xFFFFFFFF))
                                 .build()));
         shadowOf(Looper.getMainLooper()).idle();
diff --git a/wear/protolayout/protolayout/api/current.txt b/wear/protolayout/protolayout/api/current.txt
index 506910e9..7b83100 100644
--- a/wear/protolayout/protolayout/api/current.txt
+++ b/wear/protolayout/protolayout/api/current.txt
@@ -117,15 +117,15 @@
   }
 
   public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
-    method public String getTargetKey();
-    method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+    method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+    method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
   }
 
   public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
     ctor public ActionBuilders.SetStateAction.Builder();
     method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
   }
 
   public final class ColorBuilders {
@@ -993,13 +993,13 @@
   }
 
   public static final class StateBuilders.State {
-    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
     method public String getLastClickableId();
   }
 
   public static final class StateBuilders.State.Builder {
     ctor public StateBuilders.State.Builder();
-    method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
     method public androidx.wear.protolayout.StateBuilders.State build();
   }
 
diff --git a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
index ce4acaa..3c60bcf 100644
--- a/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
+++ b/wear/protolayout/protolayout/api/public_plus_experimental_current.txt
@@ -117,15 +117,15 @@
   }
 
   public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
-    method public String getTargetKey();
-    method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+    method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+    method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
   }
 
   public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
     ctor public ActionBuilders.SetStateAction.Builder();
     method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
   }
 
   public final class ColorBuilders {
@@ -1211,13 +1211,13 @@
   }
 
   public static final class StateBuilders.State {
-    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
     method public String getLastClickableId();
   }
 
   public static final class StateBuilders.State.Builder {
     ctor public StateBuilders.State.Builder();
-    method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
     method public androidx.wear.protolayout.StateBuilders.State build();
   }
 
diff --git a/wear/protolayout/protolayout/api/restricted_current.txt b/wear/protolayout/protolayout/api/restricted_current.txt
index 506910e9..7b83100 100644
--- a/wear/protolayout/protolayout/api/restricted_current.txt
+++ b/wear/protolayout/protolayout/api/restricted_current.txt
@@ -117,15 +117,15 @@
   }
 
   public static final class ActionBuilders.SetStateAction implements androidx.wear.protolayout.ActionBuilders.LocalAction {
-    method public String getTargetKey();
-    method public androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue? getValue();
+    method public androidx.wear.protolayout.expression.AppDataKey<?> getTargetKey();
+    method public androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue? getValue();
   }
 
   public static final class ActionBuilders.SetStateAction.Builder implements androidx.wear.protolayout.ActionBuilders.LocalAction.Builder {
     ctor public ActionBuilders.SetStateAction.Builder();
     method public androidx.wear.protolayout.ActionBuilders.SetStateAction build();
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(String);
-    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setTargetKey(androidx.wear.protolayout.expression.AppDataKey<?>);
+    method public androidx.wear.protolayout.ActionBuilders.SetStateAction.Builder setValue(androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
   }
 
   public final class ColorBuilders {
@@ -993,13 +993,13 @@
   }
 
   public static final class StateBuilders.State {
-    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue!> getIdToValueMapping();
+    method public java.util.Map<java.lang.String!,androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue!> getIdToValueMapping();
     method public String getLastClickableId();
   }
 
   public static final class StateBuilders.State.Builder {
     ctor public StateBuilders.State.Builder();
-    method public androidx.wear.protolayout.StateBuilders.State.Builder addIdToValueMapping(String, androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue);
+    method public androidx.wear.protolayout.StateBuilders.State.Builder addKeyToValueMapping(androidx.wear.protolayout.expression.AppDataKey<?>, androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue);
     method public androidx.wear.protolayout.StateBuilders.State build();
   }
 
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
index b0706de..b0ef69b 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/ActionBuilders.java
@@ -26,9 +26,10 @@
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
 import androidx.wear.protolayout.StateBuilders.State;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
 import androidx.wear.protolayout.expression.Fingerprint;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
 import androidx.wear.protolayout.proto.ActionProto;
 import java.util.Collections;
 import java.util.HashMap;
@@ -923,8 +924,9 @@
      * @since 1.2
      */
     @NonNull
-    public String getTargetKey() {
-      return mImpl.getTargetKey();
+    public AppDataKey<?> getTargetKey() {
+
+      return new AppDataKey<>(mImpl.getTargetKey());
     }
 
     /**
@@ -933,9 +935,9 @@
      * @since 1.2
      */
     @Nullable
-    public StateEntryValue getValue() {
+    public DynamicDataValue getValue() {
       if (mImpl.hasValue()) {
-        return StateEntryBuilders.stateEntryValueFromProto(mImpl.getValue());
+        return DynamicDataBuilders.dynamicDataValueFromProto(mImpl.getValue());
       } else {
         return null;
       }
@@ -979,8 +981,8 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setTargetKey(@NonNull String targetKey) {
-        mImpl.setTargetKey(targetKey);
+      public Builder setTargetKey(@NonNull AppDataKey<?> targetKey) {
+        mImpl.setTargetKey(targetKey.getKey());
         mFingerprint.recordPropertyUpdate(1, targetKey.hashCode());
         return this;
       }
@@ -991,8 +993,8 @@
        * @since 1.2
        */
       @NonNull
-      public Builder setValue(@NonNull StateEntryValue value) {
-        mImpl.setValue(value.toStateEntryValueProto());
+      public Builder setValue(@NonNull DynamicDataValue value) {
+        mImpl.setValue(value.toDynamicDataValueProto());
         mFingerprint.recordPropertyUpdate(
             2, checkNotNull(value.getFingerprint()).aggregateValueAsInt());
         return this;
diff --git a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
index 0fb8101..a5a256b 100644
--- a/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
+++ b/wear/protolayout/protolayout/src/main/java/androidx/wear/protolayout/StateBuilders.java
@@ -23,10 +23,11 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.RestrictTo;
 import androidx.annotation.RestrictTo.Scope;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
 import androidx.wear.protolayout.expression.Fingerprint;
-import androidx.wear.protolayout.expression.StateEntryBuilders;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
 import androidx.wear.protolayout.proto.StateProto;
 import java.util.Collections;
 import java.util.HashMap;
@@ -67,11 +68,13 @@
      * @since 1.2
      */
     @NonNull
-    public Map<String, StateEntryValue> getIdToValueMapping() {
-      Map<String, StateEntryValue> map = new HashMap<>();
-      for (Entry<String, StateEntryProto.StateEntryValue> entry :
+    public Map<String, DynamicDataValue> getIdToValueMapping() {
+      Map<String, DynamicDataValue> map = new HashMap<>();
+      for (Entry<String, DynamicDataProto.DynamicDataValue> entry :
           mImpl.getIdToValueMap().entrySet()) {
-        map.put(entry.getKey(), StateEntryBuilders.stateEntryValueFromProto(entry.getValue()));
+        map.put(
+                entry.getKey(),
+                DynamicDataBuilders.dynamicDataValueFromProto(entry.getValue()));
       }
       return Collections.unmodifiableMap(map);
     }
@@ -142,10 +145,13 @@
        */
       @SuppressLint("MissingGetterMatchingBuilder")
       @NonNull
-      public Builder addIdToValueMapping(@NonNull String id, @NonNull StateEntryValue value) {
-        mImpl.putIdToValue(id, value.toStateEntryValueProto());
+      public Builder addKeyToValueMapping(
+              @NonNull AppDataKey<?> sourceKey,
+              @NonNull DynamicDataValue value) {
+        mImpl.putIdToValue(sourceKey.getKey(), value.toDynamicDataValueProto());
         mFingerprint.recordPropertyUpdate(
-            id.hashCode(), checkNotNull(value.getFingerprint()).aggregateValueAsInt());
+                sourceKey.getKey().hashCode(),
+                checkNotNull(value.getFingerprint()).aggregateValueAsInt());
         return this;
       }
 
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
index 39aa11e..fa0d083 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ActionBuildersTest.java
@@ -20,7 +20,9 @@
 
 import android.content.ComponentName;
 
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
+import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
 import androidx.wear.protolayout.proto.ActionProto;
 
 import org.junit.Test;
@@ -36,15 +38,15 @@
 
     @Test
     public void setStateAction() {
-        String key = "key";
-        StateEntryBuilders.StateEntryValue value = StateEntryBuilders.StateEntryValue.fromString(
-                "value");
+        AppDataKey<DynamicBuilders.DynamicString> key = new AppDataKey<>("key");
+        DynamicDataBuilders.DynamicDataValue value =
+                DynamicDataBuilders.DynamicDataValue.fromString("value");
         ActionBuilders.SetStateAction setStateAction = new ActionBuilders.SetStateAction.Builder()
                 .setTargetKey(key).setValue(value).build();
 
         assertThat(setStateAction.getTargetKey()).isEqualTo(key);
-        assertThat(setStateAction.getValue().toStateEntryValueProto()).isEqualTo(
-                value.toStateEntryValueProto());
+        assertThat(setStateAction.getValue().toDynamicDataValueProto()).isEqualTo(
+                value.toDynamicDataValueProto());
     }
 
     @Test
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
index 078ae25..a37cb28 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ColorBuildersTest.java
@@ -23,6 +23,7 @@
 import android.graphics.Color;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.ColorProto;
 
 import org.junit.Test;
@@ -34,13 +35,17 @@
     private static final String STATE_KEY = "state-key";
     private static final ColorBuilders.ColorProp COLOR =
             new ColorBuilders.ColorProp.Builder(Color.RED)
-                    .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicColor.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
 
     @SuppressWarnings("deprecation")
     private static final ColorBuilders.ColorProp.Builder COLOR_BUILDER_WITHOUT_STATIC_VALUE =
             new ColorBuilders.ColorProp.Builder()
-                    .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY));
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicColor.from(
+                                    new AppDataKey<>(STATE_KEY)));
 
     @Test
     public void colorPropSupportsDynamicColor() {
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
index 81f3b67..cdee4a9 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/DimensionBuildersTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertThrows;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.DimensionProto;
 
 import org.junit.Test;
@@ -34,23 +35,31 @@
     private static final String STATE_KEY = "state-key";
     private static final DimensionBuilders.DpProp DP_PROP =
             new DimensionBuilders.DpProp.Builder(3.14f)
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
 
     @SuppressWarnings("deprecation")
     private static final DimensionBuilders.DpProp.Builder DP_PROP_WITHOUT_STATIC_VALUE =
             new DimensionBuilders.DpProp.Builder()
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY));
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)));
 
     private static final DimensionBuilders.DegreesProp DEGREES_PROP =
             new DimensionBuilders.DegreesProp.Builder(3.14f)
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
 
     @SuppressWarnings("deprecation")
     private static final DimensionBuilders.DegreesProp.Builder DEGREES_PROP_WITHOUT_STATIC_VALUE =
             new DimensionBuilders.DegreesProp.Builder()
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY));
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)));
 
     @Test
     public void dpPropSupportsDynamicValue() {
@@ -113,7 +122,8 @@
     public void wrappedMinSize_throwsWhenSetToDynamicValue() {
         DimensionBuilders.DpProp minSizeDynamic =
                 new DimensionBuilders.DpProp.Builder(42)
-                        .setDynamicValue(DynamicBuilders.DynamicFloat.fromState("some-state"))
+                        .setDynamicValue(DynamicBuilders.DynamicFloat.from(
+                                new AppDataKey<>("some-state")))
                         .build();
         assertThrows(
                 IllegalArgumentException.class,
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
index 3b6107e..691b328 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/LayoutElementBuildersTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertThrows;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.DimensionProto;
 import androidx.wear.protolayout.proto.LayoutElementProto;
 import androidx.wear.protolayout.proto.TypesProto;
@@ -34,7 +35,9 @@
     private static final String STATE_KEY = "state-key";
     private static final DimensionBuilders.DegreesProp DEGREES_PROP =
             new DimensionBuilders.DegreesProp.Builder(10)
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
     private static final DimensionBuilders.AngularLayoutConstraint DEGREES_PROP_CONSTRAINT =
             new DimensionBuilders.AngularLayoutConstraint.Builder(20)
@@ -42,7 +45,9 @@
                     .build();
     private static final DimensionBuilders.DpProp DP_PROP =
             new DimensionBuilders.DpProp.Builder(10)
-                    .setDynamicValue(DynamicBuilders.DynamicFloat.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicFloat.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
     private static final DimensionBuilders.HorizontalLayoutConstraint HORIZONTAL_LAYOUT_CONSTRAINT =
             new DimensionBuilders.HorizontalLayoutConstraint.Builder(20)
@@ -54,7 +59,9 @@
                     .build();
     private static final TypeBuilders.StringProp STRING_PROP =
             new TypeBuilders.StringProp.Builder("string")
-                    .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicString.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
     private static final TypeBuilders.StringLayoutConstraint STRING_LAYOUT_CONSTRAINT =
             new TypeBuilders.StringLayoutConstraint.Builder("pattern")
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
index fec2fb2..8cb5f79 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ModifiersBuildersTest.java
@@ -22,6 +22,7 @@
 import android.graphics.Color;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.ModifiersProto;
 
 import org.junit.Test;
@@ -33,7 +34,9 @@
     private static final String STATE_KEY = "state-key";
     private static final ColorBuilders.ColorProp COLOR =
             new ColorBuilders.ColorProp.Builder(Color.RED)
-                    .setDynamicValue(DynamicBuilders.DynamicColor.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicColor.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
 
     @Test
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
index 2b6348d..5f6c5d87 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/ResourceBuildersTest.java
@@ -21,6 +21,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.ResourceProto;
 
 import org.junit.Test;
@@ -55,7 +56,9 @@
                 new ResourceBuilders.AndroidSeekableAnimatedImageResourceByResId.Builder()
                         .setResourceId(RESOURCE_ID)
                         .setAnimatedImageFormat(FORMAT)
-                        .setProgress(DynamicBuilders.DynamicFloat.fromState(stateKey))
+                        .setProgress(
+                                DynamicBuilders.DynamicFloat.from(
+                                        new AppDataKey<>(stateKey)))
                         .build();
 
         ResourceProto.AndroidSeekableAnimatedImageResourceByResId avdProto = avd.toProto();
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
index 3337f82..86d9ddb 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/StateBuildersTest.java
@@ -18,7 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import androidx.wear.protolayout.expression.StateEntryBuilders;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicBool;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString;
+import androidx.wear.protolayout.expression.DynamicDataBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -35,20 +38,21 @@
 
     @Test
     public void additionalState() {
-        StateEntryBuilders.StateEntryValue boolValue =
-                StateEntryBuilders.StateEntryValue.fromBool(true);
-        StateEntryBuilders.StateEntryValue stringValue =
-                StateEntryBuilders.StateEntryValue.fromString("string");
+        DynamicDataBuilders.DynamicDataValue boolValue =
+                DynamicDataBuilders.DynamicDataValue.fromBool(true);
+        DynamicDataBuilders.DynamicDataValue stringValue =
+                DynamicDataBuilders.DynamicDataValue.fromString("string");
         StateBuilders.State state = new StateBuilders.State.Builder()
-                .addIdToValueMapping("boolValue", boolValue)
-                .addIdToValueMapping("stringValue", stringValue)
+                .addKeyToValueMapping(
+                        new AppDataKey<DynamicBool>("boolValue"), boolValue)
+                .addKeyToValueMapping(
+                        new AppDataKey<DynamicString>("stringValue"), stringValue)
                 .build();
 
         assertThat(state.getIdToValueMapping()).hasSize(2);
-        assertThat(state.getIdToValueMapping().get("boolValue").toStateEntryValueProto()).isEqualTo(
-                boolValue.toStateEntryValueProto());
-        assertThat(
-                state.getIdToValueMapping().get("stringValue").toStateEntryValueProto()).isEqualTo(
-                stringValue.toStateEntryValueProto());
+        assertThat(state.getIdToValueMapping().get("boolValue").toDynamicDataValueProto())
+                .isEqualTo(boolValue.toDynamicDataValueProto());
+        assertThat(state.getIdToValueMapping().get("stringValue").toDynamicDataValueProto())
+                .isEqualTo(stringValue.toDynamicDataValueProto());
     }
 }
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
index 6230a66..7cdffd5 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TriggerBuildersTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -37,7 +38,8 @@
 
     @Test
     public void onConditionTrigger() {
-        DynamicBuilders.DynamicBool condition = DynamicBuilders.DynamicBool.fromState("state");
+        DynamicBuilders.DynamicBool condition =
+                DynamicBuilders.DynamicBool.from(new AppDataKey<>("state"));
 
         TriggerBuilders.Trigger onConditionMetTrigger =
                 TriggerBuilders.createOnConditionMetTrigger(
diff --git a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
index 4de0b0a..3245f32 100644
--- a/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
+++ b/wear/protolayout/protolayout/src/test/java/androidx/wear/protolayout/TypeBuildersTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertThrows;
 
 import androidx.wear.protolayout.expression.DynamicBuilders;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.proto.TypesProto;
 
 import org.junit.Test;
@@ -29,13 +30,17 @@
     private static final String STATE_KEY = "state-key";
     private static final TypeBuilders.StringProp STRING_PROP =
             new TypeBuilders.StringProp.Builder("string")
-                    .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY))
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicString.from(
+                                    new AppDataKey<>(STATE_KEY)))
                     .build();
 
     @SuppressWarnings("deprecation")
     private static final TypeBuilders.StringProp.Builder STRING_PROP_BUILDER_WITHOUT_STATIC_VALUE =
             new TypeBuilders.StringProp.Builder()
-                    .setDynamicValue(DynamicBuilders.DynamicString.fromState(STATE_KEY));
+                    .setDynamicValue(
+                            DynamicBuilders.DynamicString.from(
+                                    new AppDataKey<>(STATE_KEY)));
 
     @Test
     public void stringPropSupportsDynamicString() {
diff --git a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
index 0f105f3..93ea260 100644
--- a/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
+++ b/wear/tiles/tiles/src/test/java/androidx/wear/tiles/RequestBuildersTest.java
@@ -22,9 +22,11 @@
 import androidx.wear.protolayout.DeviceParametersBuilders;
 import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters;
 import androidx.wear.protolayout.StateBuilders.State;
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue;
+import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInt32;
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue;
+import androidx.wear.protolayout.expression.AppDataKey;
 import androidx.wear.protolayout.expression.proto.FixedProto;
-import androidx.wear.protolayout.expression.proto.StateEntryProto;
+import androidx.wear.protolayout.expression.proto.DynamicDataProto;
 import androidx.wear.protolayout.proto.DeviceParametersProto;
 import androidx.wear.protolayout.proto.StateProto;
 import androidx.wear.tiles.RequestBuilders.ResourcesRequest;
@@ -45,8 +47,9 @@
                 new TileRequest.Builder()
                         .setCurrentState(
                                 new State.Builder()
-                                        .addIdToValueMapping(
-                                                "entry_id", StateEntryValue.fromInt(13))
+                                        .addKeyToValueMapping(
+                                                new AppDataKey<DynamicInt32>("entry_id"),
+                                                DynamicDataValue.fromInt(13))
                                         .build())
                         .setDeviceConfiguration(
                                 new DeviceParameters.Builder()
@@ -132,7 +135,7 @@
                         StateProto.State.newBuilder()
                                 .putIdToValue(
                                         "entry_id",
-                                        StateEntryProto.StateEntryValue.newBuilder()
+                                        DynamicDataProto.DynamicDataValue.newBuilder()
                                                 .setInt32Val(
                                                         FixedProto.FixedInt32.newBuilder()
                                                                 .setValue(13))
diff --git a/wear/watchface/watchface-client-guava/build.gradle b/wear/watchface/watchface-client-guava/build.gradle
index 49dba28..45693e3 100644
--- a/wear/watchface/watchface-client-guava/build.gradle
+++ b/wear/watchface/watchface-client-guava/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "Android Wear Watchface Client Guava"
+    name = "Android Wear Watchface Client Guava Integration"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Guava wrappers for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
index ddf43de..ca001fa 100644
--- a/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
+++ b/wear/watchface/watchface-complications-data/src/main/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluator.kt
@@ -23,13 +23,17 @@
 import androidx.annotation.MainThread
 import androidx.annotation.RestrictTo
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
+import androidx.wear.protolayout.expression.PlatformDataKey
+import androidx.wear.protolayout.expression.PlatformHealthSources
 import androidx.wear.protolayout.expression.pipeline.BoundDynamicType
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeBindingRequest
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeEvaluator
 import androidx.wear.protolayout.expression.pipeline.DynamicTypeValueReceiver
+import androidx.wear.protolayout.expression.pipeline.SensorGatewaySingleDataProvider
 import androidx.wear.protolayout.expression.pipeline.StateStore
 import androidx.wear.protolayout.expression.pipeline.TimeGateway
 import androidx.wear.protolayout.expression.pipeline.sensor.SensorGateway
+import java.util.Collections
 import java.util.concurrent.Executor
 import kotlin.coroutines.ContinuationInterceptor
 import kotlin.coroutines.CoroutineContext
@@ -59,6 +63,7 @@
 class ComplicationDataExpressionEvaluator(
     private val stateStore: StateStore? = StateStore(emptyMap()),
     private val timeGateway: TimeGateway? = null,
+    // TODO(b/281664278): remove the SensorGateway usage, implement PlatformDataProvider instead.
     private val sensorGateway: SensorGateway? = null,
     private val keepExpression: Boolean = false,
 ) {
@@ -294,7 +299,22 @@
                     DynamicTypeEvaluator.Config.Builder()
                         .apply { stateStore?.let { setStateStore(it) } }
                         .apply { timeGateway?.let { setTimeGateway(it) } }
-                        .apply { sensorGateway?.let { setSensorGateway(it) } }
+                        .apply { sensorGateway?.let {
+                            addPlatformDataProvider(
+                                SensorGatewaySingleDataProvider(
+                                    sensorGateway, PlatformHealthSources.HEART_RATE_BPM
+                                ),
+                                Collections.singleton(PlatformHealthSources.HEART_RATE_BPM)
+                                    as Set<PlatformDataKey<*>>
+                            )
+                            addPlatformDataProvider(
+                                SensorGatewaySingleDataProvider(
+                                    sensorGateway, PlatformHealthSources.DAILY_STEPS
+                                ),
+                                Collections.singleton(PlatformHealthSources.DAILY_STEPS)
+                                    as Set<PlatformDataKey<*>>
+                            )
+                        } }
                         .build()
                 )
             try {
diff --git a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
index 3a22917..65d472b 100644
--- a/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
+++ b/wear/watchface/watchface-complications-data/src/test/java/androidx/wear/watchface/complications/data/ComplicationDataExpressionEvaluatorTest.kt
@@ -21,10 +21,11 @@
 import android.support.wearable.complications.ComplicationData.Companion.TYPE_SHORT_TEXT
 import android.support.wearable.complications.ComplicationText as WireComplicationText
 import android.util.Log
+import androidx.wear.protolayout.expression.AppDataKey
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicFloat
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicInstant
 import androidx.wear.protolayout.expression.DynamicBuilders.DynamicString
-import androidx.wear.protolayout.expression.StateEntryBuilders.StateEntryValue
+import androidx.wear.protolayout.expression.DynamicDataBuilders.DynamicDataValue
 import androidx.wear.protolayout.expression.pipeline.StateStore
 import androidx.wear.protolayout.expression.pipeline.TimeGateway
 import androidx.wear.watchface.complications.data.ComplicationDataExpressionEvaluator.Companion.INVALID_DATA
@@ -75,7 +76,7 @@
      */
     enum class DataWithExpressionScenario(
         val expressed: WireComplicationData,
-        val states: List<Map<String, StateEntryValue>>,
+        val states: List<Map<AppDataKey<*>, DynamicDataValue>>,
         val evaluated: List<WireComplicationData>,
     ) {
         SET_IMMEDIATELY_WHEN_ALL_DATA_AVAILABLE(
@@ -112,13 +113,19 @@
         SET_ONLY_AFTER_ALL_FIELDS_EVALUATED(
             expressed =
                 WireComplicationData.Builder(TYPE_NO_DATA)
-                    .setRangedValueExpression(DynamicFloat.fromState("ranged_value"))
-                    .setLongText(WireComplicationText(DynamicString.fromState("long_text")))
-                    .setLongTitle(WireComplicationText(DynamicString.fromState("long_title")))
-                    .setShortText(WireComplicationText(DynamicString.fromState("short_text")))
-                    .setShortTitle(WireComplicationText(DynamicString.fromState("short_title")))
+                    .setRangedValueExpression(DynamicFloat.from(AppDataKey("ranged_value")))
+                    .setLongText(WireComplicationText(DynamicString.from(AppDataKey("long_text"))))
+                    .setLongTitle(
+                        WireComplicationText(DynamicString.from(AppDataKey("long_title")))
+                    )
+                    .setShortText(
+                        WireComplicationText(DynamicString.from(AppDataKey("short_text")))
+                    )
+                    .setShortTitle(
+                        WireComplicationText(DynamicString.from(AppDataKey("short_title")))
+                    )
                     .setContentDescription(
-                        WireComplicationText(DynamicString.fromState("description"))
+                        WireComplicationText(DynamicString.from(AppDataKey("description")))
                     )
                     .setPlaceholder(stateData("placeholder"))
                     .setListEntryCollection(listOf(stateData("list")))
@@ -127,15 +134,38 @@
             states =
                 aggregate(
                     // Each map piles on top of the previous ones.
-                    mapOf("ranged_value" to StateEntryValue.fromFloat(1f)),
-                    mapOf("long_text" to StateEntryValue.fromString("Long Text")),
-                    mapOf("long_title" to StateEntryValue.fromString("Long Title")),
-                    mapOf("short_text" to StateEntryValue.fromString("Short Text")),
-                    mapOf("short_title" to StateEntryValue.fromString("Short Title")),
-                    mapOf("description" to StateEntryValue.fromString("Description")),
-                    mapOf("placeholder" to StateEntryValue.fromString("Placeholder")),
-                    mapOf("list" to StateEntryValue.fromString("List")),
-                    mapOf("timeline" to StateEntryValue.fromString("Timeline")),
+                    mapOf(
+                        AppDataKey<DynamicFloat>("ranged_value") to DynamicDataValue.fromFloat(1f)
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("long_text") to
+                            DynamicDataValue.fromString("Long Text")
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("long_title") to
+                            DynamicDataValue.fromString("Long Title")
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("short_text") to
+                            DynamicDataValue.fromString("Short Text")
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("short_title") to
+                            DynamicDataValue.fromString("Short Title")
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("description") to
+                            DynamicDataValue.fromString("Description")
+                    ),
+                    mapOf(
+                        AppDataKey<DynamicString>("placeholder") to
+                            DynamicDataValue.fromString("Placeholder")
+                    ),
+                    mapOf(AppDataKey<DynamicString>("list") to DynamicDataValue.fromString("List")),
+                    mapOf(
+                        AppDataKey<DynamicString>("timeline") to
+                            DynamicDataValue.fromString("Timeline")
+                    ),
                     // Only the last one will trigger an evaluated data.
                 ),
             evaluated =
@@ -164,12 +194,14 @@
         SET_TO_EVALUATED_IF_ALL_FIELDS_VALID(
             expressed =
                 WireComplicationData.Builder(TYPE_SHORT_TEXT)
-                    .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
-                    .setShortText(WireComplicationText(DynamicString.fromState("valid")))
+                    .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+                    .setShortText(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
                     .build(),
             states =
                 listOf(
-                    mapOf("valid" to StateEntryValue.fromString("Valid")),
+                    mapOf(
+                        AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+                    ),
                 ),
             evaluated =
                 listOf(
@@ -183,13 +215,15 @@
         SET_TO_NO_DATA_IF_FIRST_STATE_IS_INVALID(
             expressed =
                 WireComplicationData.Builder(TYPE_SHORT_TEXT)
-                    .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
-                    .setShortText(WireComplicationText(DynamicString.fromState("invalid")))
+                    .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+                    .setShortText(WireComplicationText(DynamicString.from(AppDataKey("invalid"))))
                     .build(),
             states =
                 listOf(
                     mapOf(),
-                    mapOf("valid" to StateEntryValue.fromString("Valid")),
+                    mapOf(
+                        AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+                    ),
                 ),
             evaluated =
                 listOf(
@@ -199,16 +233,19 @@
         SET_TO_NO_DATA_IF_LAST_STATE_IS_INVALID(
             expressed =
                 WireComplicationData.Builder(TYPE_SHORT_TEXT)
-                    .setShortTitle(WireComplicationText(DynamicString.fromState("valid")))
-                    .setShortText(WireComplicationText(DynamicString.fromState("invalid")))
+                    .setShortTitle(WireComplicationText(DynamicString.from(AppDataKey("valid"))))
+                    .setShortText(WireComplicationText(DynamicString.from(AppDataKey("invalid"))))
                     .build(),
             states =
                 listOf(
                     mapOf(
-                        "valid" to StateEntryValue.fromString("Valid"),
-                        "invalid" to StateEntryValue.fromString("Valid"),
+                        AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid"),
+                        AppDataKey<DynamicString>("invalid") to
+                            DynamicDataValue.fromString("Valid"),
                     ),
-                    mapOf("valid" to StateEntryValue.fromString("Valid")),
+                    mapOf(
+                        AppDataKey<DynamicString>("valid") to DynamicDataValue.fromString("Valid")
+                    ),
                 ),
             evaluated =
                 listOf(
@@ -237,18 +274,18 @@
         ),
         SET_TO_EVALUATED_WITHOUT_PLACEHOLDER_EVEN_IF_PLACEHOLDER_INVALID_IF_NOT_NO_DATA(
             expressed =
-            WireComplicationData.Builder(TYPE_SHORT_TEXT)
-                .setShortText(WireComplicationText("Text"))
-                .setPlaceholder(stateData("placeholder"))
-                .build(),
-            states = listOf(), // placeholder state not set.
-            evaluated =
-            listOf(
-                // No placeholder.
                 WireComplicationData.Builder(TYPE_SHORT_TEXT)
                     .setShortText(WireComplicationText("Text"))
+                    .setPlaceholder(stateData("placeholder"))
                     .build(),
-            )
+            states = listOf(), // placeholder state not set.
+            evaluated =
+                listOf(
+                    // No placeholder.
+                    WireComplicationData.Builder(TYPE_SHORT_TEXT)
+                        .setShortText(WireComplicationText("Text"))
+                        .build(),
+                )
         ),
     }
 
@@ -269,7 +306,7 @@
                     )
 
             for (state in scenario.states) {
-                stateStore.setStateEntryValues(state)
+                stateStore.setAppStateEntryValues(state)
             }
 
             expect
@@ -385,7 +422,7 @@
 
         fun stateData(value: String) =
             WireComplicationData.Builder(TYPE_NO_DATA)
-                .setLongText(WireComplicationText(DynamicString.fromState(value)))
+                .setLongText(WireComplicationText(DynamicString.from(AppDataKey(value))))
                 .build()
 
         fun evaluatedData(value: String) =
diff --git a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
index 5342fd8..ecf03eb 100644
--- a/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
+++ b/wear/watchface/watchface-complications-permission-dialogs-sample/build.gradle
@@ -29,7 +29,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Permission Dialog Samples"
+    name = "Wear Watchface Permission Dialog Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains sample code for building Watchface Permission Dialogs"
diff --git a/wear/watchface/watchface-editor-guava/build.gradle b/wear/watchface/watchface-editor-guava/build.gradle
index c8cb24c..933c2fc 100644
--- a/wear/watchface/watchface-editor-guava/build.gradle
+++ b/wear/watchface/watchface-editor-guava/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android Wear Watchface Client Editor"
+    name = "Android Wear Watchface Editor Guava Integration"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Guava wrappers for the Androidx Wear Watchface Editor library"
diff --git a/wear/watchface/watchface-editor/samples/build.gradle b/wear/watchface/watchface-editor/samples/build.gradle
index 85c5449..4fa0e56 100644
--- a/wear/watchface/watchface-editor/samples/build.gradle
+++ b/wear/watchface/watchface-editor/samples/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Editor Samples"
+    name = "Wear Editor Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
     description = "Contains sample code for the Androidx Wear Editor library"
diff --git a/wear/watchface/watchface-guava/build.gradle b/wear/watchface/watchface-guava/build.gradle
index 6571f63..c72486d 100644
--- a/wear/watchface/watchface-guava/build.gradle
+++ b/wear/watchface/watchface-guava/build.gradle
@@ -45,7 +45,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Guava"
+    name = "Android Wear Watchface Guava Integration"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "Guava wrappers for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-complications/build.gradle b/wear/watchface/watchface-samples-minimal-complications/build.gradle
index ce74910..eb6c3db 100644
--- a/wear/watchface/watchface-samples-minimal-complications/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-complications/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Minimal Complications Sample"
+    name = "Wear Watchface Minimal Complications Sample"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-instances/build.gradle b/wear/watchface/watchface-samples-minimal-instances/build.gradle
index 9fd911c..cefa848 100644
--- a/wear/watchface/watchface-samples-minimal-instances/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-instances/build.gradle
@@ -34,7 +34,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Minimal Style Sample"
+    name = "Wear Watchface Minimal Style Sample"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-samples-minimal-style/build.gradle b/wear/watchface/watchface-samples-minimal-style/build.gradle
index 3931645..76d81e8 100644
--- a/wear/watchface/watchface-samples-minimal-style/build.gradle
+++ b/wear/watchface/watchface-samples-minimal-style/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Minimal Style Sample"
+    name = "Wear Watchface Minimal Style Sample"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface-style/old-api-test-service/build.gradle b/wear/watchface/watchface-style/old-api-test-service/build.gradle
index 6d668ff..905cc31 100644
--- a/wear/watchface/watchface-style/old-api-test-service/build.gradle
+++ b/wear/watchface/watchface-style/old-api-test-service/build.gradle
@@ -35,7 +35,7 @@
 }
 
 androidx {
-    name = "AndroidX WatchFace Style Old Api Test Service"
+    name = "WatchFace Style Old Api Test Service"
     type = LibraryType.SAMPLES
     inceptionYear = "2022"
     description = "Test service built with v1.0.0 of the API, used to check for binary AIDL compat"
diff --git a/wear/watchface/watchface-style/old-api-test-stub/build.gradle b/wear/watchface/watchface-style/old-api-test-stub/build.gradle
index ba36ffc..aa784be 100644
--- a/wear/watchface/watchface-style/old-api-test-stub/build.gradle
+++ b/wear/watchface/watchface-style/old-api-test-stub/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "AndroidX WatchFace Style Old Api Test Stub"
+    name = "WatchFace Style Old Api Test Stub"
     type = LibraryType.INTERNAL_TEST_LIBRARY
     inceptionYear = "2022"
     description = "Test stub built with v1.0.0 of the API, used to check for binary AIDL compat"
diff --git a/wear/watchface/watchface/samples/app/build.gradle b/wear/watchface/watchface/samples/app/build.gradle
index 875f848..101b6ba 100644
--- a/wear/watchface/watchface/samples/app/build.gradle
+++ b/wear/watchface/watchface/samples/app/build.gradle
@@ -26,7 +26,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Samples app"
+    name = "Wear Watchface Samples app"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "APK for the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface/samples/build.gradle b/wear/watchface/watchface/samples/build.gradle
index 0e89628..f7b78e9 100644
--- a/wear/watchface/watchface/samples/build.gradle
+++ b/wear/watchface/watchface/samples/build.gradle
@@ -33,7 +33,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Samples"
+    name = "Wear Watchface Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2020"
     description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/watchface/watchface/samples/minimal/build.gradle b/wear/watchface/watchface/samples/minimal/build.gradle
index 38d5ed5..c8e5139 100644
--- a/wear/watchface/watchface/samples/minimal/build.gradle
+++ b/wear/watchface/watchface/samples/minimal/build.gradle
@@ -28,7 +28,7 @@
 }
 
 androidx {
-    name = "AndroidX Wear Watchface Minimal Sample"
+    name = "Wear Watchface Minimal Sample"
     type = LibraryType.SAMPLES
     inceptionYear = "2021"
     description = "Contains the sample code for the Androidx Wear Watchface library"
diff --git a/wear/wear-input-testing/build.gradle b/wear/wear-input-testing/build.gradle
index 6952126..d422e13 100644
--- a/wear/wear-input-testing/build.gradle
+++ b/wear/wear-input-testing/build.gradle
@@ -34,9 +34,9 @@
 }
 
 androidx {
-    name = "Android Wear Support Input Testing Helpers"
+    name = "Android Wear Input Testing Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.WEAR_INPUT_TESTING
     inceptionYear = "2020"
-    description = "Android Wear Support Input  Testing Helpers"
+    description = "Android Wear Support Input Testing Helpers"
 }
diff --git a/wear/wear-input/build.gradle b/wear/wear-input/build.gradle
index 8301f64d..5b5c6d9 100644
--- a/wear/wear-input/build.gradle
+++ b/wear/wear-input/build.gradle
@@ -51,7 +51,7 @@
 }
 
 androidx {
-    name = "Android Wear Support Input"
+    name = "Android Wear Input"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.WEAR_INPUT
     inceptionYear = "2020"
diff --git a/wear/wear-ongoing/build.gradle b/wear/wear-ongoing/build.gradle
index 8baebed..0985190 100644
--- a/wear/wear-ongoing/build.gradle
+++ b/wear/wear-ongoing/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android Wear Ongoing Activities"
+    name = "Android Wear Ongoing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.WEAR_ONGOING
     inceptionYear = "2021"
diff --git a/wear/wear/build.gradle b/wear/wear/build.gradle
index 83bcb50..ea42582 100644
--- a/wear/wear/build.gradle
+++ b/wear/wear/build.gradle
@@ -62,7 +62,7 @@
 }
 
 androidx {
-    name = "Android Wear Support UI"
+    name = "Android Wear"
     publish = Publish.SNAPSHOT_AND_RELEASE
     mavenVersion = LibraryVersions.WEAR
     inceptionYear = "2016"
diff --git a/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt b/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
index 0f24c5b..97204f0 100644
--- a/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
+++ b/wear/wear/src/main/java/androidx/wear/ambient/AmbientLifecycleObserver.kt
@@ -47,6 +47,12 @@
  * }
  * ```
  *
+ * If the observer is registered while the device is in ambient mode, the registered callback
+ * will immediately receive a call to
+ * [AmbientLifecycleObserver.AmbientLifecycleCallback.onEnterAmbient]. If the device is in active
+ * mode, the callbacks will be registered, and `onEnterAmbient` will be called when the device next
+ * enters ambient mode.
+ *
  * @param activity The activity that this observer is being attached to.
  * @param callbackExecutor The executor to run the provided callbacks on.
  * @param callbacks An instance of [AmbientLifecycleObserver.AmbientLifecycleCallback], used to
diff --git a/webkit/webkit/build.gradle b/webkit/webkit/build.gradle
index 0cc7c77..446ce33 100644
--- a/webkit/webkit/build.gradle
+++ b/webkit/webkit/build.gradle
@@ -68,9 +68,9 @@
 }
 
 androidx {
-    name = "WebView Support Library"
+    name = "WebKit"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2017"
-    description = "The WebView Support Library is a static library you can add to your Android application in order to use android.webkit APIs that are not available for older platform versions."
+    description = "The WebKit Support Library is a static library you can add to your Android application in order to use android.webkit APIs that are not available for older platform versions."
     additionalDeviceTestApkKeys.add("chrome")
 }
diff --git a/window/extensions/core/core/build.gradle b/window/extensions/core/core/build.gradle
index 9104d8c..5a895b0 100644
--- a/window/extensions/core/core/build.gradle
+++ b/window/extensions/core/core/build.gradle
@@ -45,7 +45,7 @@
 }
 
 androidx {
-    name = "Jetpack WindowManager library Core Extensions"
+    name = "WindowManager Core Extensions"
     type = LibraryType.PUBLISHED_LIBRARY
     publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
     inceptionYear = "2022"
diff --git a/window/extensions/extensions/build.gradle b/window/extensions/extensions/build.gradle
index 279cbba..4941b4f2 100644
--- a/window/extensions/extensions/build.gradle
+++ b/window/extensions/extensions/build.gradle
@@ -41,7 +41,7 @@
 }
 
 androidx {
-    name = "Jetpack WindowManager library Extensions"
+    name = "WindowManager Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
     runApiTasks = new RunApiTasks.Yes("Need to track API surface before moving to publish")
     inceptionYear = "2020"
diff --git a/window/sidecar/sidecar/build.gradle b/window/sidecar/sidecar/build.gradle
index 742646c..67a5ab4 100644
--- a/window/sidecar/sidecar/build.gradle
+++ b/window/sidecar/sidecar/build.gradle
@@ -27,7 +27,7 @@
 }
 
 androidx {
-    name = "Jetpack WindowManager library Sidecar"
+    name = "WindowManager Sidecar"
     publish = Publish.SNAPSHOT_AND_RELEASE // Only to generate per-project-zips
     runApiTasks = new RunApiTasks.Yes("Need to track API surface but should never publish")
     inceptionYear = "2020"
diff --git a/window/window-core/build.gradle b/window/window-core/build.gradle
index e0e80a3..fbaefda 100644
--- a/window/window-core/build.gradle
+++ b/window/window-core/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "androidx.window:window-core"
+    name = "WindowManager Core"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2022"
     description = "WindowManager Core Library."
diff --git a/window/window-demos/demo/build.gradle b/window/window-demos/demo/build.gradle
index 65adb00..cd3bcf4 100644
--- a/window/window-demos/demo/build.gradle
+++ b/window/window-demos/demo/build.gradle
@@ -82,7 +82,7 @@
 }
 
 androidx {
-    name = "WM Jetpack Samples"
+    name = "WM Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2023"
     description = "Samples for the WM Jetpack Library"
diff --git a/window/window-java/build.gradle b/window/window-java/build.gradle
index ad4a7de..36a1f22 100644
--- a/window/window-java/build.gradle
+++ b/window/window-java/build.gradle
@@ -46,7 +46,7 @@
 }
 
 androidx {
-    name = "WindowManager Java Support"
+    name = "WindowManager Java"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "WindowManager Java Support"
diff --git a/window/window-rxjava2/build.gradle b/window/window-rxjava2/build.gradle
index 97a6430..f3d1277 100644
--- a/window/window-rxjava2/build.gradle
+++ b/window/window-rxjava2/build.gradle
@@ -50,7 +50,7 @@
 }
 
 androidx {
-    name = "WindowManager RxJava 2"
+    name = "WindowManager RxJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
diff --git a/window/window-rxjava3/build.gradle b/window/window-rxjava3/build.gradle
index 2ab8d1a..e4962e8 100644
--- a/window/window-rxjava3/build.gradle
+++ b/window/window-rxjava3/build.gradle
@@ -49,7 +49,7 @@
 }
 
 androidx {
-    name = "WindowManager RxJava 3 Support"
+    name = "WindowManager RxJava3"
     type = LibraryType.PUBLISHED_LIBRARY
     inceptionYear = "2021"
     description = "WindowManager RxJava 3 Support"
diff --git a/window/window-testing/build.gradle b/window/window-testing/build.gradle
index 9ccb288..7996b4b 100644
--- a/window/window-testing/build.gradle
+++ b/window/window-testing/build.gradle
@@ -55,7 +55,7 @@
 }
 
 androidx {
-    name = "WindowManager Test Library"
+    name = "WindowManager Testing Extensions"
     type = LibraryType.PUBLISHED_TEST_LIBRARY
     inceptionYear = "2021"
     description = "WindowManager Test Library"
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 4e4170e..402be78 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -85,7 +85,7 @@
 }
 
 androidx {
-    name = "Jetpack WindowManager Library"
+    name = "WindowManager"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "WindowManager Jetpack library. Currently only provides additional " +
diff --git a/window/window/samples/build.gradle b/window/window/samples/build.gradle
index e44e0ac..7db715c 100644
--- a/window/window/samples/build.gradle
+++ b/window/window/samples/build.gradle
@@ -36,7 +36,7 @@
 }
 
 androidx {
-    name = "Jetpack WindowManager Library Samples"
+    name = "WindowManager Samples"
     type = LibraryType.SAMPLES
     inceptionYear = "2022"
     description = "Code samples for WindowManager Jetpack library."
diff --git a/work/work-benchmark/build.gradle b/work/work-benchmark/build.gradle
index d4a2c31..cd0c8a6 100644
--- a/work/work-benchmark/build.gradle
+++ b/work/work-benchmark/build.gradle
@@ -38,7 +38,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Benchmarks"
+    name = "WorkManager Benchmarks"
      publish = Publish.NONE
     inceptionYear = "2019"
     description = "Android WorkManager Benchmark Library"
diff --git a/work/work-gcm/build.gradle b/work/work-gcm/build.gradle
index 562422b0..98a4351 100644
--- a/work/work-gcm/build.gradle
+++ b/work/work-gcm/build.gradle
@@ -47,7 +47,7 @@
 }
 
 androidx {
-    name = "Android WorkManager GCMNetworkManager Support"
+    name = "WorkManager GCM Integration"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2019"
     description = "Android WorkManager GCMNetworkManager Support"
diff --git a/work/work-inspection/build.gradle b/work/work-inspection/build.gradle
index 5385c55..5cfd833 100644
--- a/work/work-inspection/build.gradle
+++ b/work/work-inspection/build.gradle
@@ -42,7 +42,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Inspector"
+    name = "WorkManager Inspector"
     type = LibraryType.IDE_PLUGIN
     inceptionYear = "2020"
     description = "The implementation of WorkManager Inspector."
diff --git a/work/work-lint/build.gradle b/work/work-lint/build.gradle
index 083e406..fb59083 100644
--- a/work/work-lint/build.gradle
+++ b/work/work-lint/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Runtime Lint Checks"
+    name = "WorkManager Runtime Lint Checks"
     type = LibraryType.LINT
     inceptionYear = "2019"
     description = "Android WorkManager Runtime Lint Checks"
diff --git a/work/work-multiprocess/build.gradle b/work/work-multiprocess/build.gradle
index 7b7697d..94c4112 100644
--- a/work/work-multiprocess/build.gradle
+++ b/work/work-multiprocess/build.gradle
@@ -49,7 +49,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Multiprocess Implementation"
+    name = "WorkManager Multiprocess"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android WorkManager runtime library"
diff --git a/work/work-runtime-ktx/build.gradle b/work/work-runtime-ktx/build.gradle
index f45007c..34051b4 100644
--- a/work/work-runtime-ktx/build.gradle
+++ b/work/work-runtime-ktx/build.gradle
@@ -40,7 +40,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Kotlin Extensions"
+    name = "WorkManager Kotlin Extensions"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android WorkManager Kotlin Extensions"
diff --git a/work/work-runtime/build.gradle b/work/work-runtime/build.gradle
index 5e8d67b..ff562a1 100644
--- a/work/work-runtime/build.gradle
+++ b/work/work-runtime/build.gradle
@@ -96,7 +96,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Runtime"
+    name = "WorkManager Runtime"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android WorkManager runtime library"
diff --git a/work/work-rxjava2/build.gradle b/work/work-rxjava2/build.gradle
index e8e0e7e..9779ab9 100644
--- a/work/work-rxjava2/build.gradle
+++ b/work/work-rxjava2/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android WorkManager RxJava2 Support"
+    name = "WorkManager RxJava2"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android WorkManager RxJava2 interoperatibility library"
diff --git a/work/work-rxjava3/build.gradle b/work/work-rxjava3/build.gradle
index a725099..c6e82b9 100644
--- a/work/work-rxjava3/build.gradle
+++ b/work/work-rxjava3/build.gradle
@@ -32,7 +32,7 @@
 }
 
 androidx {
-    name = "Android WorkManager RxJava3 Support"
+    name = "WorkManager RxJava3"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2020"
     description = "Android WorkManager RxJava3 interoperatibility library"
diff --git a/work/work-testing/build.gradle b/work/work-testing/build.gradle
index 45e33ef..52a3ba4 100644
--- a/work/work-testing/build.gradle
+++ b/work/work-testing/build.gradle
@@ -44,7 +44,7 @@
 }
 
 androidx {
-    name = "Android WorkManager Testing"
+    name = "WorkManager Testing"
     publish = Publish.SNAPSHOT_AND_RELEASE
     inceptionYear = "2018"
     description = "Android WorkManager testing library"