Merge "Update SqlParser to correctly detect top level star projection with a prefix." into androidx-main
diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml
index a0c4ba9..6a0bcc3 100644
--- a/.github/workflows/integration_tests.yml
+++ b/.github/workflows/integration_tests.yml
@@ -7,7 +7,7 @@
 jobs:
   run_integration_tests:
     runs-on: ubuntu-latest
-    if: ${{ github.event.workflow_run.conclusion == 'success' }}
+    if: ${{ !github.event.repository.fork && github.event.workflow_run.conclusion == 'success' }}
     name: Run integration tests on FTL
     steps:
       - name: Set up JDK 11
@@ -33,7 +33,7 @@
   teardown:
     runs-on: ubuntu-latest
     needs: [run_integration_tests]
-    if: always()
+    if: ${{ !github.event.repository.fork && always() }} # always() is required so that this job will run irrespective of status of upstream 'run_integration_test' job.
     steps:
       - name: Parse workflow status
         id: workflow-status
diff --git a/.github/workflows/register_workflow_start.yml b/.github/workflows/register_workflow_start.yml
index 8a66d98..ec447a7 100644
--- a/.github/workflows/register_workflow_start.yml
+++ b/.github/workflows/register_workflow_start.yml
@@ -6,6 +6,7 @@
 
 jobs:
   ping_androidx_dev:
+    if: ${{ !github.event.repository.fork }}
     runs-on: ubuntu-latest
     name: "Start webhook"
     steps:
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ShareActionProvider.java b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ShareActionProvider.java
index e9903ea..2e034d2 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ShareActionProvider.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/widget/ShareActionProvider.java
@@ -40,7 +40,7 @@
  * overflow menu, it creates a submenu with the appropriate sharing
  * actions.
  *
- * <h3 id="add-share-action">Adding a share action</h3>
+ * ### Adding a share action
  *
  * <p>To add a "share" action to your activity, put a
  * <code>ShareActionProvider</code> in the app bar's menu resource. For
@@ -101,7 +101,7 @@
  * myShareActionProvider.setShareIntent(myShareIntent);</pre></li>
  * </ol>
  *
- * <h3 id="rankings">Share target rankings</h3>
+ * ### Share target rankings
  *
  * <p>The share action provider retains a ranking for each share target,
  * based on how often the user chooses each one. The more often a user
diff --git a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
index f987118..8905e0e0 100644
--- a/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
+++ b/appsearch/appsearch/src/androidTest/java/androidx/appsearch/cts/app/AppSearchSessionLocalCtsTest.java
@@ -41,6 +41,7 @@
 import androidx.appsearch.testutil.AppSearchEmail;
 import androidx.appsearch.testutil.SimpleTestLogger;
 import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.FlakyTest;
 
 import com.google.common.util.concurrent.ListenableFuture;
 
@@ -347,6 +348,7 @@
 
     // TODO(b/194207451) This test can be moved to CtsTestBase if customized logger is
     //  supported for platform backend.
+    @FlakyTest(bugId = 204478878)
     @Test
     public void testSetSchemaStats_withSchemaMigration() throws Exception {
         SimpleTestLogger logger = new SimpleTestLogger();
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
index 66ddef2..2dd0f5f 100644
--- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
+++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/perfetto/PerfettoConfig.kt
@@ -36,10 +36,6 @@
         name = "linux.ftrace",
         target_buffer = 0,
         ftrace_config = FtraceConfig(
-            // These parameters affect only the kernel trace buffer size and how
-            // frequently it gets moved into the userspace buffer defined above.
-            buffer_size_kb = 16384,
-            drain_period_ms = 250,
             ftrace_events = listOf(
                 // We need to do process tracking to ensure kernel ftrace events targeted at short-lived
                 // threads are associated correctly
@@ -146,8 +142,8 @@
     atraceApps: List<String>
 ) = TraceConfig(
     buffers = listOf(
-        BufferConfig(size_kb = 16384, FillPolicy.RING_BUFFER),
-        BufferConfig(size_kb = 16384, FillPolicy.RING_BUFFER)
+        BufferConfig(size_kb = 32768, FillPolicy.RING_BUFFER),
+        BufferConfig(size_kb = 4096, FillPolicy.RING_BUFFER)
     ),
     data_sources = listOf(
         ftraceDataSource(atraceApps),
@@ -155,6 +151,13 @@
         LINUX_SYS_STATS_DATASOURCE,
         TraceConfig.DataSource(DataSourceConfig("android.surfaceflinger.frametimeline"))
     ),
+    // periodically dump to file, so we don't overrun our ring buffer
+    // buffers are expected to be big enough for 5 seconds, so conservatively set 2.5 dump
+    write_into_file = true,
+    file_write_period_ms = 2500,
+
+    // multiple of file_write_period_ms, enables trace processor to work in batches
+    flush_period_ms = 5000
 )
 
 @RequiresApi(21) // needed for shell access
diff --git a/benchmark/integration-tests/macrobenchmark-target/build.gradle b/benchmark/integration-tests/macrobenchmark-target/build.gradle
index 7ad8481..0661058 100644
--- a/benchmark/integration-tests/macrobenchmark-target/build.gradle
+++ b/benchmark/integration-tests/macrobenchmark-target/build.gradle
@@ -33,8 +33,8 @@
 dependencies {
     implementation(libs.kotlinStdlib)
     implementation(libs.constraintLayout)
-    implementation("androidx.appcompat:appcompat:1.2.0")
-    implementation("androidx.activity:activity:1.3.0")
-    implementation("androidx.recyclerview:recyclerview:1.1.0")
+    implementation(project(":appcompat:appcompat"))
+    implementation(project(":activity:activity"))
+    implementation(project(":recyclerview:recyclerview"))
     implementation(libs.material)
 }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
index a106f01..87a4d07 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -534,10 +534,9 @@
         packageApplicationProvider.get().let { packageTask ->
             AffectedModuleDetector.configureTaskGuard(packageTask)
             // Skip copying AndroidTest apks if they have no source code (no tests to run).
-            if (testApk && !project.hasAndroidTestSourceCode()) {
-                return
+            if (!testApk || project.hasAndroidTestSourceCode()) {
+                addToTestZips(project, packageTask)
             }
-            addToTestZips(project, packageTask)
         }
         project.tasks.withType(ListingFileRedirectTask::class.java).forEach {
             AffectedModuleDetector.configureTaskGuard(it)
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
index d559e19..c7090c2 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/metalava/MetalavaRunner.kt
@@ -17,7 +17,6 @@
 package androidx.build.metalava
 
 import androidx.build.checkapi.ApiLocation
-import androidx.build.dependencies.getDependencyAsString
 import androidx.build.java.JavaCompileInputs
 import androidx.build.logging.TERMINAL_RED
 import androidx.build.logging.TERMINAL_RESET
@@ -98,7 +97,7 @@
             VersionCatalogsExtension::class.java
         ).find("libs").get()
         val dependency = dependencies.create(
-            getDependencyAsString(libs.findDependency("metalava").get())
+            libs.findDependency("metalava").get().get()
         )
         it.dependencies.add(dependency)
     }
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt
index e51c320..0fb1a3a 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/studio/StudioTask.kt
@@ -16,10 +16,7 @@
 
 package androidx.build.studio
 
-import androidx.build.OperatingSystem
 import androidx.build.StudioType
-import androidx.build.getOperatingSystem
-import androidx.build.getSdkPath
 import androidx.build.getSupportRootFolder
 import androidx.build.studioType
 import com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
@@ -34,7 +31,6 @@
 import org.gradle.internal.service.ServiceRegistry
 import org.gradle.process.ExecOperations
 import java.io.File
-import java.nio.file.Files
 import javax.inject.Inject
 
 /**
@@ -172,33 +168,6 @@
     }
 
     /**
-     * Attempts to symlink the system-images and emulator SDK directories to a canonical SDK.
-     */
-    private fun setupSymlinksIfNeeded() {
-        val paths = listOf("system-images", "emulator")
-
-        val localSdkPath = project.getSdkPath()
-        val canonicalSdkPath = when (getOperatingSystem()) {
-            OperatingSystem.MAC -> File(System.getProperty("user.home"), "Library/Android/sdk")
-            OperatingSystem.LINUX -> File(System.getProperty("user.home"), "Android/Sdk")
-            else -> null
-        } ?: return
-
-        if (!canonicalSdkPath.exists()) {
-            // In the future, we might want to try a little harder to locate a canonical SDK path.
-            return
-        }
-
-        paths.forEach { path ->
-            val link = File(localSdkPath, path)
-            val target = File(canonicalSdkPath, path)
-            if (target.exists() && !link.exists()) {
-                Files.createSymbolicLink(link.toPath(), target.toPath())
-            }
-        }
-    }
-
-    /**
      * Launches Studio if the user accepts / has accepted the license agreement.
      */
     private fun launch() {
@@ -213,10 +182,6 @@
                     """.trimIndent()
                 )
             }
-
-            // This seems like as good a time as any to set up SDK symlinks...
-            setupSymlinksIfNeeded()
-
             println("Launching studio...")
             launchStudio()
         } else {
diff --git a/buildSrc/public/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/public/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index 6371113..b55ed1a 100644
--- a/buildSrc/public/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/public/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -16,9 +16,6 @@
 
 package androidx.build.dependencies
 
-import org.gradle.api.artifacts.MinimalExternalModuleDependency
-import org.gradle.api.provider.Provider
-
 internal lateinit var guavaVersion: String
 val GUAVA_VERSION get() = guavaVersion
 
@@ -31,9 +28,3 @@
 
 internal lateinit var agpVersion: String
 val AGP_LATEST get() = "com.android.tools.build:gradle:$agpVersion"
-
-@Suppress("UnstableApiUsage")
-fun getDependencyAsString(dependencyProvider: Provider<MinimalExternalModuleDependency>): String {
-    val dependency = dependencyProvider.get()
-    return dependency.module.toString() + ":" + dependency.versionConstraint.toString()
-}
\ No newline at end of file
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CaptureProcessorPipeline.java b/camera/camera-core/src/main/java/androidx/camera/core/CaptureProcessorPipeline.java
index f614281..20dd85a 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CaptureProcessorPipeline.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CaptureProcessorPipeline.java
@@ -27,6 +27,7 @@
 import androidx.camera.core.impl.ImageProxyBundle;
 import androidx.camera.core.impl.ImageReaderProxy;
 import androidx.camera.core.impl.TagBundle;
+import androidx.camera.core.impl.utils.executor.CameraXExecutors;
 import androidx.core.util.Preconditions;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -35,15 +36,17 @@
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
 
 /**
  * A CaptureProcessor which can link two CaptureProcessors.
  */
 @RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
 class CaptureProcessorPipeline implements CaptureProcessor {
+    private static final String TAG = "CaptureProcessorPipeline";
     private final CaptureProcessor mPreCaptureProcessor;
     private final CaptureProcessor mPostCaptureProcessor;
-    private final Executor mExecutor;
+    final Executor mExecutor;
     private final int mMaxImages;
     private ImageReaderProxy mIntermediateImageReader = null;
     private ImageInfo mSourceImageInfo = null;
@@ -120,12 +123,17 @@
         // Register the ImageAvailableListener to receive the processed image from the
         // pre-processing CaptureProcessor.
         mIntermediateImageReader.setOnImageAvailableListener(
-                new ImageReaderProxy.OnImageAvailableListener() {
-                    @Override
-                    public void onImageAvailable(@NonNull ImageReaderProxy imageReader) {
-                        postProcess(imageReader.acquireNextImage());
+                imageReader -> {
+                    ImageProxy image = imageReader.acquireNextImage();
+                    try {
+                        mExecutor.execute(() -> postProcess(image));
+                    } catch (RejectedExecutionException e) {
+                        Logger.e(TAG, "The executor for post-processing might have been "
+                                + "shutting down or terminated!");
+                        image.close();
                     }
-                }, mExecutor);
+                },
+                CameraXExecutors.directExecutor());
     }
 
     void postProcess(ImageProxy imageProxy) {
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/Logger.java b/camera/camera-core/src/main/java/androidx/camera/core/Logger.java
index 1d4aa96..56bebf3 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/Logger.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/Logger.java
@@ -21,7 +21,6 @@
 
 import androidx.annotation.IntRange;
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.annotation.RestrictTo;
 
@@ -70,6 +69,14 @@
     }
 
     /**
+     * Returns {@code true} if logging with the truncated tag {@code truncatedTag} is
+     * enabled at the {@code logLevel} level.
+     */
+    private static boolean isLogLevelEnabled(@NonNull String truncatedTag, int logLevel) {
+        return sMinLogLevel <= logLevel || Log.isLoggable(truncatedTag, logLevel);
+    }
+
+    /**
      * Sets the minimum logging level to use in {@link Logger}. After calling this method, only logs
      * at the level {@code logLevel} and above are output.
      */
@@ -99,7 +106,7 @@
      * {@link Log#DEBUG} at least.
      */
     public static boolean isDebugEnabled(@NonNull String tag) {
-        return sMinLogLevel <= Log.DEBUG || Log.isLoggable(truncateTag(tag), Log.DEBUG);
+        return isLogLevelEnabled(truncateTag(tag), Log.DEBUG);
     }
 
     /**
@@ -109,7 +116,7 @@
      * {@link Log#INFO} at least.
      */
     public static boolean isInfoEnabled(@NonNull String tag) {
-        return sMinLogLevel <= Log.INFO || Log.isLoggable(truncateTag(tag), Log.INFO);
+        return isLogLevelEnabled(truncateTag(tag), Log.INFO);
     }
 
     /**
@@ -119,7 +126,7 @@
      * {@link Log#WARN} at least.
      */
     public static boolean isWarnEnabled(@NonNull String tag) {
-        return sMinLogLevel <= Log.WARN || Log.isLoggable(truncateTag(tag), Log.WARN);
+        return isLogLevelEnabled(truncateTag(tag), Log.WARN);
     }
 
     /**
@@ -129,7 +136,7 @@
      * {@link Log#ERROR} at least.
      */
     public static boolean isErrorEnabled(@NonNull String tag) {
-        return sMinLogLevel <= Log.ERROR || Log.isLoggable(truncateTag(tag), Log.ERROR);
+        return isLogLevelEnabled(truncateTag(tag), Log.ERROR);
     }
 
     /**
@@ -137,7 +144,10 @@
      * {@linkplain #isDebugEnabled(String) loggable}.
      */
     public static void d(@NonNull String tag, @NonNull String message) {
-        d(tag, message, null);
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.DEBUG)) {
+            Log.d(truncatedTag, message);
+        }
     }
 
     /**
@@ -145,9 +155,10 @@
      * {@linkplain #isDebugEnabled(String) loggable}.
      */
     public static void d(@NonNull String tag, @NonNull String message,
-            @Nullable final Throwable throwable) {
-        if (isDebugEnabled(tag)) {
-            Log.d(truncateTag(tag), message, throwable);
+            @NonNull final Throwable throwable) {
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.DEBUG)) {
+            Log.d(truncatedTag, message, throwable);
         }
     }
 
@@ -156,7 +167,10 @@
      * {@linkplain #isInfoEnabled(String) loggable}.
      */
     public static void i(@NonNull String tag, @NonNull String message) {
-        i(tag, message, null);
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.INFO)) {
+            Log.i(truncatedTag, message);
+        }
     }
 
     /**
@@ -164,9 +178,10 @@
      * {@linkplain #isInfoEnabled(String) loggable}.
      */
     public static void i(@NonNull String tag, @NonNull String message,
-            @Nullable final Throwable throwable) {
-        if (isInfoEnabled(tag)) {
-            Log.i(truncateTag(tag), message, throwable);
+            @NonNull final Throwable throwable) {
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.INFO)) {
+            Log.i(truncatedTag, message, throwable);
         }
     }
 
@@ -175,7 +190,10 @@
      * {@linkplain #isWarnEnabled(String) loggable}.
      */
     public static void w(@NonNull String tag, @NonNull String message) {
-        w(tag, message, null);
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.WARN)) {
+            Log.w(truncatedTag, message);
+        }
     }
 
     /**
@@ -183,9 +201,10 @@
      * {@linkplain #isWarnEnabled(String) loggable}.
      */
     public static void w(@NonNull String tag, @NonNull String message,
-            @Nullable final Throwable throwable) {
-        if (isWarnEnabled(tag)) {
-            Log.w(truncateTag(tag), message, throwable);
+            @NonNull final Throwable throwable) {
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.WARN)) {
+            Log.w(truncatedTag, message, throwable);
         }
     }
 
@@ -194,7 +213,10 @@
      * {@linkplain #isErrorEnabled(String) loggable}.
      */
     public static void e(@NonNull String tag, @NonNull String message) {
-        e(tag, message, null);
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.ERROR)) {
+            Log.e(truncatedTag, message);
+        }
     }
 
     /**
@@ -202,9 +224,10 @@
      * {@linkplain #isErrorEnabled(String) loggable}.
      */
     public static void e(@NonNull String tag, @NonNull String message,
-            @Nullable final Throwable throwable) {
-        if (isErrorEnabled(tag)) {
-            Log.e(truncateTag(tag), message, throwable);
+            @NonNull final Throwable throwable) {
+        final String truncatedTag = truncateTag(tag);
+        if (isLogLevelEnabled(truncatedTag, Log.ERROR)) {
+            Log.e(truncatedTag, message, throwable);
         }
     }
 
@@ -215,7 +238,7 @@
      */
     @NonNull
     private static String truncateTag(@NonNull String tag) {
-        if (MAX_TAG_LENGTH < tag.length() && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && MAX_TAG_LENGTH < tag.length()) {
             return tag.substring(0, MAX_TAG_LENGTH);
         }
         return tag;
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
index 5b9ec7f..65626a4 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/VideoCapabilities.java
@@ -26,6 +26,8 @@
 import androidx.camera.core.impl.CamcorderProfileProvider;
 import androidx.camera.core.impl.CamcorderProfileProxy;
 import androidx.camera.core.impl.CameraInfoInternal;
+import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
+import androidx.camera.video.internal.compat.quirk.VideoQualityNotSupportQuirk;
 import androidx.core.util.Preconditions;
 
 import java.util.ArrayDeque;
@@ -71,7 +73,7 @@
             // SortedQualities is from size large to small
 
             // Get CamcorderProfile
-            if (!camcorderProfileProvider.hasProfile(quality)) {
+            if (!camcorderProfileProvider.hasProfile(quality) || !isDeviceValidQuality(quality)) {
                 continue;
             }
             CamcorderProfileProxy profile = camcorderProfileProvider.get(quality);
@@ -151,4 +153,10 @@
         Preconditions.checkArgument(QualitySelector.containsQuality(quality),
                 "Unknown quality: " + quality);
     }
+
+    private boolean isDeviceValidQuality(@QualitySelector.VideoQuality int quality) {
+        VideoQualityNotSupportQuirk quirk = DeviceQuirks.get(VideoQualityNotSupportQuirk.class);
+        return quirk == null || !quirk.isProblematicVideoQuality(quality);
+    }
+
 }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
index 09543f98..92846e72 100644
--- a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/DeviceQuirksLoader.java
@@ -53,6 +53,9 @@
         if (CameraUseInconsistentTimebaseQuirk.load()) {
             quirks.add(new CameraUseInconsistentTimebaseQuirk());
         }
+        if (VideoQualityNotSupportQuirk.load()) {
+            quirks.add(new VideoQualityNotSupportQuirk());
+        }
 
         return quirks;
     }
diff --git a/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/VideoQualityNotSupportQuirk.java b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/VideoQualityNotSupportQuirk.java
new file mode 100644
index 0000000..5d461ba
--- /dev/null
+++ b/camera/camera-video/src/main/java/androidx/camera/video/internal/compat/quirk/VideoQualityNotSupportQuirk.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.camera.video.internal.compat.quirk;
+
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder.VideoEncoder;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+import androidx.camera.core.impl.CamcorderProfileProvider;
+import androidx.camera.core.impl.Quirk;
+import androidx.camera.video.QualitySelector;
+import androidx.camera.video.VideoCapabilities;
+
+/**
+ * Quirk denotes that quality {@link VideoCapabilities} queried by {@link CamcorderProfileProvider}
+ * does not work on video recording on device, and need to exclude it.
+ *
+ * <p>On Huawei Mate20 and Mate20 Pro, {@link CamcorderProfile} indicates it can support
+ * resolutions 3840x2160 for {@link VideoEncoder#H264}, and it can create the video
+ * encoder by the corresponding format. However, there is not any video frame output from Camera
+ * . The CaptureSession is opened and configured, but something error in the HAL of these devices
+ * . Hence use a quirk to exclude the problematic resolution quality. See b/202080832#comment8.
+ *
+ */
+@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
+public class VideoQualityNotSupportQuirk implements Quirk {
+    static boolean load() {
+        return isHuaweiMate20() || isHuaweiMate20Pro();
+    }
+
+    private static boolean isHuaweiMate20() {
+        return "Huawei".equalsIgnoreCase(Build.BRAND) && "HMA-L29".equalsIgnoreCase(Build.MODEL);
+    }
+
+    private static boolean isHuaweiMate20Pro() {
+        return "Huawei".equalsIgnoreCase(Build.BRAND) && "LYA-AL00".equalsIgnoreCase(Build.MODEL);
+    }
+
+    /** Checks if the given mime type is a problematic quality. */
+    public boolean isProblematicVideoQuality(@QualitySelector.VideoQuality int quality) {
+        return quality == QualitySelector.QUALITY_UHD;
+    }
+}
diff --git a/car/app/app/api/current.txt b/car/app/app/api/current.txt
index 47ba617..9353a32 100644
--- a/car/app/app/api/current.txt
+++ b/car/app/app/api/current.txt
@@ -221,6 +221,7 @@
 package androidx.car.app.hardware.common {
 
   @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.RequiresCarApi(3) public final class CarUnit {
+    method public static String toString(int);
     field public static final int IMPERIAL_GALLON = 204; // 0xcc
     field public static final int KILOMETER = 3; // 0x3
     field public static final int KILOMETERS_PER_HOUR = 102; // 0x66
diff --git a/car/app/app/api/public_plus_experimental_current.txt b/car/app/app/api/public_plus_experimental_current.txt
index 4eaeb9c..42a1550 100644
--- a/car/app/app/api/public_plus_experimental_current.txt
+++ b/car/app/app/api/public_plus_experimental_current.txt
@@ -224,6 +224,7 @@
 package androidx.car.app.hardware.common {
 
   @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.RequiresCarApi(3) public final class CarUnit {
+    method public static String toString(int);
     field public static final int IMPERIAL_GALLON = 204; // 0xcc
     field public static final int KILOMETER = 3; // 0x3
     field public static final int KILOMETERS_PER_HOUR = 102; // 0x66
diff --git a/car/app/app/api/restricted_current.txt b/car/app/app/api/restricted_current.txt
index 47ba617..9353a32 100644
--- a/car/app/app/api/restricted_current.txt
+++ b/car/app/app/api/restricted_current.txt
@@ -221,6 +221,7 @@
 package androidx.car.app.hardware.common {
 
   @androidx.car.app.annotations.CarProtocol @androidx.car.app.annotations.RequiresCarApi(3) public final class CarUnit {
+    method public static String toString(int);
     field public static final int IMPERIAL_GALLON = 204; // 0xcc
     field public static final int KILOMETER = 3; // 0x3
     field public static final int KILOMETERS_PER_HOUR = 102; // 0x66
diff --git a/car/app/app/src/main/java/androidx/car/app/hardware/common/CarUnit.java b/car/app/app/src/main/java/androidx/car/app/hardware/common/CarUnit.java
index e92e551..adde31a 100644
--- a/car/app/app/src/main/java/androidx/car/app/hardware/common/CarUnit.java
+++ b/car/app/app/src/main/java/androidx/car/app/hardware/common/CarUnit.java
@@ -19,6 +19,7 @@
 import static androidx.annotation.RestrictTo.Scope.LIBRARY;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
 import androidx.annotation.RestrictTo;
 import androidx.car.app.annotations.CarProtocol;
 import androidx.car.app.annotations.RequiresCarApi;
@@ -127,4 +128,35 @@
     public static final int MILES_PER_HOUR = 103;
 
     private CarUnit() {}
+
+    /** Get a user friendly representation of the unit. */
+    @NonNull
+    public static String toString(int unit) {
+        switch (unit) {
+            case MILLIMETER:
+                return "MILLIMETER";
+            case METER:
+                return "METER";
+            case KILOMETER:
+                return "KILOMETER";
+            case MILE:
+                return "MILE";
+            case MILLILITER:
+                return "MILLILITER";
+            case LITER:
+                return "LITER";
+            case US_GALLON :
+                return "US_GALLON ";
+            case IMPERIAL_GALLON:
+                return "IMPERIAL_GALLON";
+            case METERS_PER_SEC:
+                return "METERS_PER_SEC";
+            case KILOMETERS_PER_HOUR:
+                return "KILOMETERS_PER_HOUR";
+            case MILES_PER_HOUR :
+                return "MILES_PER_HOUR ";
+            default:
+                return "UNKNOWN";
+        }
+    }
 }
diff --git a/car/app/app/src/main/java/androidx/car/app/model/PlaceMarker.java b/car/app/app/src/main/java/androidx/car/app/model/PlaceMarker.java
index 30ea12b..b21f963 100644
--- a/car/app/app/src/main/java/androidx/car/app/model/PlaceMarker.java
+++ b/car/app/app/src/main/java/androidx/car/app/model/PlaceMarker.java
@@ -63,7 +63,7 @@
      * Represents a marker image.
      *
      * <p>To minimize scaling artifacts across a wide range of car screens, apps should provide
-     * images targeting a 72 x 72 dp bounding box. If necessary, the icon will be scaled down while
+     * images targeting a 72 x 72 dp bounding box. If necessary, the image will be scaled down while
      * preserving its aspect ratio.
      */
     public static final int TYPE_IMAGE = 1;
diff --git a/compose/integration-tests/macrobenchmark-target/build.gradle b/compose/integration-tests/macrobenchmark-target/build.gradle
index 3ff9864..623a666a 100644
--- a/compose/integration-tests/macrobenchmark-target/build.gradle
+++ b/compose/integration-tests/macrobenchmark-target/build.gradle
@@ -19,12 +19,12 @@
     kotlinPlugin(project(":compose:compiler:compiler"))
 
     implementation(libs.kotlinStdlib)
+    implementation(project(":activity:activity-compose"))
     implementation(project(":compose:foundation:foundation-layout"))
     implementation(project(":compose:material:material"))
     implementation(project(":compose:runtime:runtime"))
     implementation(project(":compose:ui:ui"))
     implementation(project(":compose:ui:ui-tooling"))
-    implementation("androidx.activity:activity-compose:1.3.1")
 }
 
 android.defaultConfig.minSdkVersion 21
diff --git a/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java b/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
index a059eac..3a881a6c 100644
--- a/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
+++ b/core/core/src/main/java/androidx/core/app/TaskStackBuilder.java
@@ -60,7 +60,7 @@
  * task.</p>
  *
  * <div class="special reference">
- * <h3>About Navigation</h3>
+ * ### About Navigation
  * For more detailed information about tasks, the back stack, and navigation design guidelines,
  * please read
  * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
diff --git a/core/core/src/main/java/androidx/core/content/FileProvider.java b/core/core/src/main/java/androidx/core/content/FileProvider.java
index b8e5c80..e5995d6 100644
--- a/core/core/src/main/java/androidx/core/content/FileProvider.java
+++ b/core/core/src/main/java/androidx/core/content/FileProvider.java
@@ -80,7 +80,7 @@
  *     <li><a href="#Permissions">Granting Temporary Permissions to a URI</a></li>
  *     <li><a href="#ServeUri">Serving a Content URI to Another App</a></li>
  * </ol>
- * <h3 id="ProviderDefinition">Defining a FileProvider</h3>
+ * ### Defining a FileProvider
  * <p>
  * Since the default functionality of FileProvider includes content URI generation for files, you
  * don't need to define a subclass in code. Instead, you can include a FileProvider in your app
@@ -114,7 +114,7 @@
  * If you want to override any of the default behavior of FileProvider methods, extend
  * the FileProvider class and use the fully-qualified class name in the <code>android:name</code>
  * attribute of the <code>&lt;provider&gt;</code> element.
- * <h3 id="SpecifyFiles">Specifying Available Files</h3>
+ * ### Specifying Available Files
  * A FileProvider can only generate a content URI for files in directories that you specify
  * beforehand. To specify a directory, specify its storage area and path in XML, using child
  * elements of the <code>&lt;paths&gt;</code> element.
@@ -245,7 +245,7 @@
  *        android:resource="&#64;xml/file_paths" /&gt;
  *&lt;/provider&gt;
  *</pre>
- * <h3 id="GetUri">Generating the Content URI for a File</h3>
+ * ### Generating the Content URI for a File
  * <p>
  * To share a file with another app using a content URI, your app has to generate the content URI.
  * To generate the content URI, create a new {@link File} for the file, then pass the {@link File}
@@ -268,7 +268,7 @@
  * As a result of the previous snippet,
  * {@link #getUriForFile(Context, String, File) getUriForFile()} returns the content URI
  * <code>content://com.mydomain.fileprovider/my_images/default_image.jpg</code>.
- * <h3 id="Permissions">Granting Temporary Permissions to a URI</h3>
+ * ### Granting Temporary Permissions to a URI
  * To grant an access permission to a content URI returned from
  * {@link #getUriForFile(Context, String, File) getUriForFile()}, you can either grant the
  * permission to a specific package or include the permission in an intent, as shown in the
@@ -324,7 +324,7 @@
  * automatically removed. Permissions granted to one {@link android.app.Activity} in a client
  * app are automatically extended to other components of that app.
  * </p>
- * <h3 id="ServeUri">Serving a Content URI to Another App</h3>
+ * ### Serving a Content URI to Another App
  * <p>
  * There are a variety of ways to serve the content URI for a file to a client app. One common way
  * is for the client app to start your app by calling
@@ -351,7 +351,7 @@
  *  {@link Intent}. Set the action to {@link Intent#ACTION_SEND} and put the URI in data by calling
  *  {@link Intent#setData setData()}.
  * </p>
- * <h3 id="">More Information</h3>
+ * ### More Information
  * <p>
  *    To learn more about FileProvider, see the Android training class
  *    <a href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files Securely with URIs</a>.
diff --git a/core/core/src/main/java/androidx/core/view/ActionProvider.java b/core/core/src/main/java/androidx/core/view/ActionProvider.java
index 14c710d..468e67f 100644
--- a/core/core/src/main/java/androidx/core/view/ActionProvider.java
+++ b/core/core/src/main/java/androidx/core/view/ActionProvider.java
@@ -58,7 +58,7 @@
  * </code></pre>
  * </li></ul></p>
  *
- * <h3>Creating a custom action provider</h3>
+ * ### Creating a custom action provider
  *
  * <p>To create a custom action provider, extend ActionProvider and implement
  * its callback methods as necessary. In particular, implement the following
diff --git a/datastore/datastore-preferences-proto/build.gradle b/datastore/datastore-preferences-proto/build.gradle
index d643f9d..33d33fa 100644
--- a/datastore/datastore-preferences-proto/build.gradle
+++ b/datastore/datastore-preferences-proto/build.gradle
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-import androidx.build.dependencies.DependenciesKt
 import androidx.build.LibraryGroups
 import androidx.build.Publish
 
@@ -31,7 +30,7 @@
 
 protobuf {
     protoc {
-        artifact = DependenciesKt.getDependencyAsString(libs.protobufCompiler)
+        artifact = libs.protobufCompiler.get()
     }
 
     // Generates the java proto-lite code for the protos in this project. See
diff --git a/datastore/datastore-proto/build.gradle b/datastore/datastore-proto/build.gradle
index 5acd326..f16a115 100644
--- a/datastore/datastore-proto/build.gradle
+++ b/datastore/datastore-proto/build.gradle
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-import androidx.build.dependencies.DependenciesKt
 import androidx.build.LibraryGroups
 import androidx.build.Publish
 import androidx.build.RunApiTasks
@@ -40,7 +39,7 @@
 
 protobuf {
     protoc {
-        artifact = DependenciesKt.getDependencyAsString(libs.protobufCompiler)
+        artifact = libs.protobufCompiler.get()
     }
     // Generates the java proto-lite code for the protos in this project. See
     // https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation
diff --git a/datastore/datastore-sampleapp/build.gradle b/datastore/datastore-sampleapp/build.gradle
index 9d7572c..2059f64 100644
--- a/datastore/datastore-sampleapp/build.gradle
+++ b/datastore/datastore-sampleapp/build.gradle
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-
-import androidx.build.dependencies.DependenciesKt
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
@@ -52,7 +50,7 @@
 
 protobuf {
     protoc {
-        artifact = DependenciesKt.getDependencyAsString(libs.protobufCompiler)
+        artifact = libs.protobufCompiler.get()
     }
 
     // Generates the java proto-lite code for the protos in this project. See
diff --git a/playground-common/gradle/wrapper/gradle-wrapper.properties b/playground-common/gradle/wrapper/gradle-wrapper.properties
index a0f7639..38b2653 100644
--- a/playground-common/gradle/wrapper/gradle-wrapper.properties
+++ b/playground-common/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-rc-1-all.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotated.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotated.kt
index 18b7559..9ad903b 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotated.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XAnnotated.kt
@@ -105,6 +105,18 @@
     fun hasAnyAnnotation(vararg annotations: KClass<out Annotation>) =
         annotations.any(this::hasAnnotation)
 
+    /**
+     * Returns `true` if this element has all the [annotations].
+     */
+    fun hasAllAnnotations(vararg annotations: ClassName): Boolean =
+        annotations.all(this::hasAnnotation)
+
+    /**
+     * Returns `true` if this element has all the [annotations].
+     */
+    fun hasAllAnnotations(vararg annotations: KClass<out Annotation>): Boolean =
+        annotations.all(this::hasAnnotation)
+
     @Deprecated(
         replaceWith = ReplaceWith("getAnnotation(annotation)"),
         message = "Use getAnnotation(not repeatable) or getAnnotations (repeatable)"
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
index aeaed8f..b231e22 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
@@ -31,6 +31,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import kotlin.reflect.KClass
 
 @RunWith(JUnit4::class)
 class XElementTest {
@@ -271,6 +272,53 @@
     }
 
     @Test
+    fun hasAllAnnotations() {
+        val source = Source.java(
+            "foo.bar.Baz",
+            """
+            package foo.bar;
+            import org.junit.*;
+            import org.junit.runner.*;
+            import org.junit.runners.*;
+            import androidx.room.compiler.processing.testcode.OtherAnnotation;
+
+            @RunWith(JUnit4.class)
+            class Baz {
+                @OtherAnnotation(value="xx")
+                String testField;
+
+                @org.junit.Test
+                @OtherAnnotation(value="yy")
+                void testMethod() {}
+            }
+            """.trimIndent()
+        )
+        runProcessorTest(
+            listOf(source)
+        ) {
+            val element = it.processingEnv.requireTypeElement("foo.bar.Baz")
+            assertThat(element.hasAllAnnotations(*arrayOf<KClass<Annotation>>())).isTrue()
+            assertThat(element.hasAllAnnotations(RunWith::class)).isTrue()
+            assertThat(element.hasAllAnnotations(RunWith::class, Test::class)).isFalse()
+
+            element.getMethod("testMethod").let { method ->
+                assertThat(method.hasAllAnnotations(*arrayOf<KClass<Annotation>>())).isTrue()
+                assertThat(method.hasAllAnnotations(Test::class)).isTrue()
+                assertThat(method.hasAllAnnotations(Test::class, OtherAnnotation::class)).isTrue()
+                assertThat(method.hasAllAnnotations(Test::class, OtherAnnotation::class,
+                    RunWith::class)).isFalse()
+            }
+            element.getField("testField").let { field ->
+                assertThat(field.hasAllAnnotations(*arrayOf<KClass<Annotation>>())).isTrue()
+                assertThat(field.hasAllAnnotations(OtherAnnotation::class)).isTrue()
+                assertThat(field.hasAllAnnotations(OtherAnnotation::class, Test::class)).isFalse()
+                assertThat(field.hasAllAnnotations(OtherAnnotation::class, OtherAnnotation::class))
+                    .isTrue()
+            }
+        }
+    }
+
+    @Test
     fun nonType() {
         val source = Source.java(
             "foo.bar.Baz",
diff --git a/settings.gradle b/settings.gradle
index b6fcfd3..5de4f86 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -245,8 +245,8 @@
 includeProject(":benchmark:benchmark-macro", "benchmark/benchmark-macro", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":benchmark:benchmark-macro-junit4", "benchmark/benchmark-macro-junit4", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":benchmark:integration-tests:dry-run-benchmark", "benchmark/integration-tests/dry-run-benchmark", [BuildType.MAIN])
-includeProject(":benchmark:integration-tests:macrobenchmark", "benchmark/integration-tests/macrobenchmark", [BuildType.MAIN, BuildType.COMPOSE])
-includeProject(":benchmark:integration-tests:macrobenchmark-target", "benchmark/integration-tests/macrobenchmark-target", [BuildType.MAIN, BuildType.COMPOSE])
+includeProject(":benchmark:integration-tests:macrobenchmark", "benchmark/integration-tests/macrobenchmark", [BuildType.MAIN])
+includeProject(":benchmark:integration-tests:macrobenchmark-target", "benchmark/integration-tests/macrobenchmark-target", [BuildType.MAIN])
 includeProject(":benchmark:integration-tests:test-module-sample", "benchmark/integration-tests/test-module-sample", [BuildType.MAIN, BuildType.COMPOSE])
 includeProject(":benchmark:integration-tests:startup-benchmark", "benchmark/integration-tests/startup-benchmark", [BuildType.MAIN])
 includeProject(":biometric:biometric", "biometric/biometric", [BuildType.MAIN])
diff --git a/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/ViewPagerWithTitleStripTest.java b/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/ViewPagerWithTitleStripTest.java
index ae5c889..87412ed 100644
--- a/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/ViewPagerWithTitleStripTest.java
+++ b/viewpager/viewpager/src/androidTest/java/androidx/viewpager/widget/ViewPagerWithTitleStripTest.java
@@ -30,6 +30,7 @@
 /**
  * Provides assertions that depend on the non-interactive nature of <code>PagerTabStrip</code>.
  */
+@FlakyTest(bugId = 179887413)
 public class ViewPagerWithTitleStripTest
         extends BaseViewPagerTest<ViewPagerWithTitleStripActivity> {
     public ViewPagerWithTitleStripTest() {
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderScreenshotTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderScreenshotTest.kt
new file mode 100644
index 0000000..66062fe
--- /dev/null
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderScreenshotTest.kt
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.wear.compose.material
+
+import android.os.Build
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Star
+import androidx.compose.material.icons.filled.ThumbUp
+import androidx.compose.testutils.assertAgainstGolden
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.captureToImage
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.filters.SdkSuppress
+import androidx.test.screenshot.AndroidXScreenshotTestRule
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+class InlineSliderScreenshotTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    @get:Rule
+    val screenshotRule = AndroidXScreenshotTestRule(SCREENSHOT_GOLDEN_PATH)
+
+    @get:Rule
+    val testName = TestName()
+
+    @Test
+    fun inlineslider_not_segmented() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                segmented = false,
+                onValueChange = { },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+
+    @Test
+    fun inlineslider_segmented() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                segmented = true,
+                onValueChange = { },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+
+    @Test
+    fun inlineslider_segmented_with_custom_colors() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                segmented = true,
+                colors = InlineSliderDefaults.colors(
+                    backgroundColor = Color.Green,
+                    spacerColor = Color.Yellow,
+                    selectedBarColor = Color.Magenta,
+                    unselectedBarColor = Color.White,
+                    disabledBackgroundColor = Color.DarkGray,
+                    disabledSpacerColor = Color.LightGray,
+                    disabledSelectedBarColor = Color.Red,
+                    disabledUnselectedBarColor = Color.Blue
+                ),
+                onValueChange = { },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+
+    @Test
+    fun inlineslider_custom_icons() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                onValueChange = { },
+                valueRange = 1f..4f,
+                decreaseIcon = {
+                    Icon(
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                },
+                increaseIcon = {
+                    Icon(
+                        imageVector = Icons.Filled.ThumbUp,
+                        contentDescription = ""
+                    )
+                },
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+
+    @Test
+    fun inlineslider_segmented_with_custom_colors_disabled() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                enabled = false,
+                segmented = true,
+                colors = InlineSliderDefaults.colors(
+                    backgroundColor = Color.Green,
+                    spacerColor = Color.Yellow,
+                    selectedBarColor = Color.Magenta,
+                    unselectedBarColor = Color.White,
+                    disabledBackgroundColor = Color.DarkGray,
+                    disabledSpacerColor = Color.LightGray,
+                    disabledSelectedBarColor = Color.Red,
+                    disabledUnselectedBarColor = Color.Blue
+                ),
+                onValueChange = { },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+
+    @Test
+    fun inlineslider_custom_icons_disabled() {
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 2f,
+                enabled = false,
+                onValueChange = { },
+                valueRange = 1f..4f,
+                decreaseIcon = {
+                    Icon(
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                },
+                increaseIcon = {
+                    Icon(
+                        imageVector = Icons.Filled.ThumbUp,
+                        contentDescription = ""
+                    )
+                },
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG)
+            .captureToImage()
+            .assertAgainstGolden(screenshotRule, testName.methodName)
+    }
+}
\ No newline at end of file
diff --git a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderTest.kt b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderTest.kt
index 156e9f1..54dce95 100644
--- a/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderTest.kt
+++ b/wear/compose/compose-material/src/androidAndroidTest/kotlin/androidx/wear/compose/material/InlineSliderTest.kt
@@ -16,13 +16,24 @@
 
 package androidx.wear.compose.material
 
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Star
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
+import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertRangeInfoEquals
+import androidx.compose.ui.test.click
+import androidx.compose.ui.test.getUnclippedBoundsInRoot
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.onRoot
+import androidx.compose.ui.test.performTouchInput
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.width
+import com.google.common.truth.Truth
 import org.junit.Rule
 import org.junit.Test
 
@@ -160,4 +171,179 @@
         rule.onNodeWithTag(TEST_TAG)
             .assertRangeInfoEquals(ProgressBarRangeInfo(0.6f, range, 4))
     }
+
+    @Test
+    fun decreases_value_by_clicking_left() {
+        val state = mutableStateOf(2f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(1f)
+        }
+    }
+
+    @Test
+    fun increases_value_by_clicking_right() {
+        val state = mutableStateOf(2f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width - 15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(3f)
+        }
+    }
+
+    @Test
+    fun ignores_left_click_when_disabled() {
+        val state = mutableStateOf(2f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                enabled = false,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(2f)
+        }
+    }
+
+    @Test
+    fun ignores_right_click_when_disabled() {
+        val state = mutableStateOf(2f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                enabled = false,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width - 15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(2f)
+        }
+    }
+
+    @Test
+    fun reaches_min_clicking_left() {
+        val state = mutableStateOf(1f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(1f)
+        }
+    }
+
+    @Test
+    fun reaches_max_clicking_right() {
+        val state = mutableStateOf(4f)
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = state.value,
+                onValueChange = { state.value = it },
+                valueRange = 1f..4f,
+                steps = 2
+            )
+        }
+
+        rule.onNodeWithTag(TEST_TAG).performTouchInput { click(Offset(width - 15f, height / 2f)) }
+        rule.runOnIdle {
+            Truth.assertThat(state.value).isWithin(0.001f).of(4f)
+        }
+    }
+
+    @Test
+    fun sets_custom_decrease_icon() {
+        val iconTag = "iconTag_test"
+
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                onValueChange = { },
+                decreaseIcon = {
+                    Icon(
+                        modifier = Modifier.testTag(iconTag),
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                }
+            )
+        }
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(iconTag, true)
+            .assertExists()
+            .assertLeftPositionInRootIsEqualTo(IconsOuterHorizontalMargin)
+    }
+
+    @Test
+    fun sets_custom_increase_icon() {
+        val iconTag = "iconTag_test"
+
+        rule.setContentWithTheme {
+            InlineSlider(
+                modifier = Modifier.testTag(TEST_TAG),
+                value = 0f,
+                steps = 5,
+                onValueChange = { },
+                increaseIcon = {
+                    Icon(
+                        modifier = Modifier.testTag(iconTag),
+                        imageVector = Icons.Default.Star,
+                        contentDescription = ""
+                    )
+                }
+            )
+        }
+        val unclippedBoundsInRoot = rule.onRoot().getUnclippedBoundsInRoot()
+
+        rule.waitForIdle()
+        rule.onNodeWithTag(iconTag, true)
+            .assertExists()
+            .assertLeftPositionInRootIsEqualTo(
+                unclippedBoundsInRoot.width -
+                    IconsOuterHorizontalMargin - DefaultIconWidth
+            )
+    }
+
+    private val IconsOuterHorizontalMargin = 8.dp
+    private val DefaultIconWidth = 24.dp
 }
diff --git a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Slider.kt b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Slider.kt
index 4db4d33..3877a46 100644
--- a/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Slider.kt
+++ b/wear/compose/compose-material/src/commonMain/kotlin/androidx/wear/compose/material/Slider.kt
@@ -276,7 +276,7 @@
         selectedBarColor: Color = MaterialTheme.colors.secondary,
         unselectedBarColor: Color = MaterialTheme.colors.onSurface.copy(0.1f),
         disabledBackgroundColor: Color = backgroundColor.copy(alpha = ContentAlpha.disabled),
-        disabledSpacerColor: Color = spacerColor,
+        disabledSpacerColor: Color = spacerColor.copy(alpha = ContentAlpha.disabled),
         disabledSelectedBarColor: Color = selectedBarColor.copy(alpha = ContentAlpha.disabled),
         disabledUnselectedBarColor: Color = unselectedBarColor.copy(alpha = 0.05f),
     ): InlineSliderColors = DefaultInlineSliderColors(
diff --git a/wear/tiles/tiles-proto/build.gradle b/wear/tiles/tiles-proto/build.gradle
index 90014de..6d9735e 100644
--- a/wear/tiles/tiles-proto/build.gradle
+++ b/wear/tiles/tiles-proto/build.gradle
@@ -15,10 +15,8 @@
  */
 
 import androidx.build.LibraryGroups
-import androidx.build.LibraryVersions
 import androidx.build.Publish
 import androidx.build.RunApiTasks
-import androidx.build.dependencies.DependenciesKt
 import com.github.jengelman.gradle.plugins.shadow.transformers.DontIncludeResourceTransformer
 
 plugins {
@@ -80,7 +78,7 @@
 
 protobuf {
     protoc {
-        artifact = DependenciesKt.getDependencyAsString(libs.protobufCompiler)
+        artifact = libs.protobufCompiler.get()
     }
 
     // Generates the java proto-lite code for the protos in this project. See
diff --git a/webkit/OWNERS b/webkit/OWNERS
index 4a97867..8ced73f 100644
--- a/webkit/OWNERS
+++ b/webkit/OWNERS
@@ -1,6 +1,3 @@
 # Bug component: 460423
-changwan@google.com
-laisminchillo@google.com
 ntfschr@google.com
-tobiasjs@google.com
 torne@google.com