Merge "Add Text team as OWNERS for Text tests" into androidx-main
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/Release.kt b/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
index ec02d35..4d2aec4 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/Release.kt
@@ -121,20 +121,17 @@
 object Release {
     @Suppress("MemberVisibilityCanBePrivate")
     const val PROJECT_ARCHIVE_ZIP_TASK_NAME = "createProjectZip"
-    const val DIFF_TASK_PREFIX = "createDiffArchive"
     const val FULL_ARCHIVE_TASK_NAME = "createArchive"
     const val ALL_ARCHIVES_TASK_NAME = "createAllArchives"
     const val DEFAULT_PUBLISH_CONFIG = "release"
-    const val GROUP_ZIPS_FOLDER = "per-group-zips"
     const val PROJECT_ZIPS_FOLDER = "per-project-zips"
-    const val GROUP_ZIP_PREFIX = "gmaven"
     const val GLOBAL_ZIP_PREFIX = "top-of-tree-m2repository"
 
     // lazily created config action params so that we don't keep re-creating them
     private var configActionParams: GMavenZipTask.ConfigAction.Params? = null
 
     /**
-     * Registers the project to be included in its group's zip file as well as the global zip files.
+     * Registers the project to be included in the global zip file.
      */
     fun register(project: Project, extension: AndroidXExtension) {
         if (!extension.shouldPublish()) {
@@ -159,11 +156,11 @@
             return
         }
 
-        val mavenGroup =
-            extension.mavenGroup?.group
-                ?: throw IllegalArgumentException(
-                    "Cannot register a project to release if it does not have a mavenGroup set up"
-                )
+        if (extension.mavenGroup?.group == null) {
+            throw IllegalArgumentException(
+                "Cannot register a project to release if it does not have a mavenGroup set up"
+            )
+        }
         if (!extension.isVersionSet()) {
             throw IllegalArgumentException(
                 "Cannot register a project to release if it does not have a mavenVersion set up"
@@ -175,7 +172,6 @@
         val zipTasks =
             listOf(
                 projectZipTask,
-                getGroupReleaseZipTask(project, mavenGroup),
                 getGlobalFullZipTask(project)
             )
 
@@ -295,28 +291,6 @@
         )
     }
 
-    /** Creates and returns the zip task that includes artifacts only in the given maven group. */
-    private fun getGroupReleaseZipTask(
-        project: Project,
-        group: String
-    ): TaskProvider<GMavenZipTask> {
-        return project.rootProject.maybeRegister(
-            name = "${DIFF_TASK_PREFIX}For${groupToTaskNameSuffix(group)}",
-            onConfigure = { task: GMavenZipTask ->
-                GMavenZipTask.ConfigAction(
-                        getParams(
-                            project = project,
-                            distDir = File(project.getDistributionDirectory(), GROUP_ZIPS_FOLDER),
-                            fileNamePrefix = GROUP_ZIP_PREFIX,
-                            group = group
-                        )
-                    )
-                    .execute(task)
-            },
-            onRegister = { taskProvider -> project.addToAnchorTask(taskProvider) }
-        )
-    }
-
     private fun getProjectZipTask(project: Project): TaskProvider<GMavenZipTask> {
         val taskProvider =
             project.tasks.register(PROJECT_ARCHIVE_ZIP_TASK_NAME, GMavenZipTask::class.java) {
@@ -510,13 +484,6 @@
         "-${project.version}.zip"
 }
 
-fun Project.getGroupZipPath(): String {
-    return Release.GROUP_ZIPS_FOLDER +
-        "/" +
-        getZipName(Release.GROUP_ZIP_PREFIX, project.group.toString()) +
-        ".zip"
-}
-
 fun Project.getGlobalZipFile(): File {
     return File(
         project.getDistributionDirectory(),
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTask.kt b/buildSrc/private/src/main/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTask.kt
index 94757ef..fb83246 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTask.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/buildInfo/CreateLibraryBuildInfoFileTask.kt
@@ -19,7 +19,6 @@
 import androidx.build.AndroidXExtension
 import androidx.build.LibraryGroup
 import androidx.build.getBuildInfoDirectory
-import androidx.build.getGroupZipPath
 import androidx.build.getProjectZipPath
 import androidx.build.getSupportRootFolder
 import androidx.build.gitclient.getHeadShaProvider
@@ -90,8 +89,6 @@
 
     @get:Input abstract val groupIdRequiresSameVersion: Property<Boolean>
 
-    @get:Input abstract val groupZipPath: Property<String>
-
     @get:Input abstract val projectZipPath: Property<String>
 
     @get:[Input Optional]
@@ -131,7 +128,6 @@
         libraryBuildInfoFile.path = projectDir.get()
         libraryBuildInfoFile.sha = commit.get()
         libraryBuildInfoFile.groupIdRequiresSameVersion = groupIdRequiresSameVersion.get()
-        libraryBuildInfoFile.groupZipPath = groupZipPath.get()
         libraryBuildInfoFile.projectZipPath = projectZipPath.get()
         libraryBuildInfoFile.kotlinVersion = kotlinVersion.orNull
         libraryBuildInfoFile.checks = ArrayList()
@@ -184,7 +180,6 @@
                 )
                 task.commit.set(shaProvider)
                 task.groupIdRequiresSameVersion.set(mavenGroup?.requireSameVersion ?: false)
-                task.groupZipPath.set(project.getGroupZipPath())
                 task.projectZipPath.set(project.getProjectZipPath())
 
                 // Note:
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
index 38a96aa..1971592 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldCursorTest.kt
@@ -575,6 +575,7 @@
             )
     }
 
+    @Ignore("b/308895081")
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun cursorNotBlinking_whenWindowLostFocus() {
@@ -617,6 +618,7 @@
             .assertDoesNotContainColor(cursorColor)
     }
 
+    @Ignore("b/308895081")
     @Test
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     fun focusedTextField_resumeBlinking_whenWindowRegainsFocus() {
diff --git a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldSelectionTest.kt b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldSelectionTest.kt
index 68ec6e1..356477b 100644
--- a/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldSelectionTest.kt
+++ b/compose/foundation/foundation/src/androidInstrumentedTest/kotlin/androidx/compose/foundation/textfield/TextFieldSelectionTest.kt
@@ -204,6 +204,7 @@
         )
     }
 
+    @Ignore("b/308895081")
     @Test
     fun textField_noSelectionHandles_whenWindowLosesFocus() {
         val textFieldValue = mutableStateOf(TextFieldValue("texttexttext"))
@@ -246,6 +247,7 @@
         assertHandlesNotExist()
     }
 
+    @Ignore("b/308895081")
     @Test
     fun textField_redisplaysSelectionHandlesAndToolbar_whenWindowRegainsFocus() {
         val textFieldValue = mutableStateOf(TextFieldValue("texttexttext"))
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
index d7c2838..b56c733 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/CoreTextField.kt
@@ -86,6 +86,7 @@
 import androidx.compose.ui.platform.LocalTextToolbar
 import androidx.compose.ui.platform.LocalWindowInfo
 import androidx.compose.ui.platform.SoftwareKeyboardController
+import androidx.compose.ui.platform.WindowInfo
 import androidx.compose.ui.semantics.copyText
 import androidx.compose.ui.semantics.cutText
 import androidx.compose.ui.semantics.disabled
@@ -416,7 +417,7 @@
         state.layoutResult?.innerTextFieldCoordinates = it
         if (enabled) {
             if (state.handleState == HandleState.Selection) {
-                if (state.showFloatingToolbar && windowInfo.isWindowFocused) {
+                if (state.showFloatingToolbar && isWindowFocusedBehindFlag(windowInfo)) {
                     manager.showSelectionToolbar()
                 } else {
                     manager.hideSelectionToolbar()
@@ -582,7 +583,7 @@
         }
     }
 
-    val showCursor = enabled && !readOnly && windowInfo.isWindowFocused
+    val showCursor = enabled && !readOnly && isWindowFocusedBehindFlag(windowInfo)
     val cursorModifier = Modifier.cursor(state, value, offsetMapping, cursorBrush, showCursor)
 
     DisposableEffect(manager) {
@@ -631,7 +632,7 @@
         }
 
     val showHandleAndMagnifier =
-        enabled && state.hasFocus && state.isInTouchMode && windowInfo.isWindowFocused
+        enabled && state.hasFocus && state.isInTouchMode && isWindowFocusedBehindFlag(windowInfo)
     val magnifierModifier = if (showHandleAndMagnifier) {
         Modifier.textFieldMagnifier(manager)
     } else {
@@ -1185,3 +1186,8 @@
         )
     }
 }
+
+// (b/308895081) Temporary disable use of Window Focus for cursor blinking state
+internal const val USE_WINDOW_FOCUS_ENABLED = false
+internal fun isWindowFocusedBehindFlag(windowInfo: WindowInfo) =
+    if (USE_WINDOW_FOCUS_ENABLED) windowInfo.isWindowFocused else true
diff --git a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.android.kt b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.android.kt
index e810b09..15a7bf7 100644
--- a/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.android.kt
+++ b/compose/material/material/src/androidMain/kotlin/androidx/compose/material/internal/ExposedDropdownMenuPopup.android.kt
@@ -28,6 +28,7 @@
 import android.view.ViewOutlineProvider
 import android.view.ViewTreeObserver
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionContext
 import androidx.compose.runtime.DisposableEffect
@@ -44,12 +45,13 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.R
 import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.toComposeIntRect
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.layout.positionInWindow
 import androidx.compose.ui.platform.AbstractComposeView
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.LocalView
@@ -86,17 +88,22 @@
     val density = LocalDensity.current
     val testTag = LocalPopupTestTag.current
     val layoutDirection = LocalLayoutDirection.current
+    val context = LocalContext.current
+    val a11yManager =
+        context.getSystemService(Context.ACCESSIBILITY_SERVICE) as? AccessibilityManager
+
     val parentComposition = rememberCompositionContext()
     val currentContent by rememberUpdatedState(content)
     val popupId = rememberSaveable { UUID.randomUUID() }
-    val popupLayout = remember {
+    val popupLayout = remember(a11yManager) {
         PopupLayout(
             onDismissRequest = onDismissRequest,
             testTag = testTag,
             composeView = view,
+            focusable = a11yManager?.isTouchExplorationEnabled == true,
             density = density,
             initialPositionProvider = popupPositionProvider,
-            popupId = popupId
+            popupId = popupId,
         ).apply {
             setContent(parentComposition) {
                 SimpleStack(
@@ -215,6 +222,7 @@
     private var onDismissRequest: (() -> Unit)?,
     var testTag: String,
     private val composeView: View,
+    private val focusable: Boolean,
     density: Density,
     initialPositionProvider: PopupPositionProvider,
     popupId: UUID
@@ -246,15 +254,6 @@
 
     override val subCompositionView: AbstractComposeView get() = this
 
-    // Specific to exposed dropdown menus.
-    private val dismissOnOutsideClick = { offset: Offset?, bounds: IntRect ->
-        if (offset == null) false
-        else {
-            offset.x < bounds.left || offset.x > bounds.right ||
-                offset.y < bounds.top || offset.y > bounds.bottom
-        }
-    }
-
     init {
         id = android.R.id.content
         setViewTreeLifecycleOwner(composeView.findViewTreeLifecycleOwner())
@@ -343,10 +342,10 @@
         val parentBounds = parentBounds ?: return
         val popupContentSize = popupContentSize ?: return
 
-        val windowSize = previousWindowVisibleFrame.let {
-            composeView.getWindowVisibleDisplayFrame(it)
-            val bounds = it.toIntBounds()
-            IntSize(width = bounds.width, height = bounds.height)
+        val windowSize = previousWindowVisibleFrame.let { rect ->
+            composeView.getWindowVisibleDisplayFrame(rect)
+            val bounds = rect.toComposeIntRect()
+            bounds.size
         }
 
         val popupPosition = positionProvider.calculatePosition(
@@ -386,13 +385,11 @@
                 (event.x < 0 || event.x >= width || event.y < 0 || event.y >= height)) ||
             event.action == MotionEvent.ACTION_OUTSIDE
         ) {
-            val parentBounds = parentBounds
-            val shouldDismiss = parentBounds == null || dismissOnOutsideClick(
-                // Keep menu open if ACTION_OUTSIDE event is reported as raw coordinates of (0, 0).
-                // This means it belongs to another owner, e.g., the soft keyboard or other window.
-                if (event.rawX != 0f && event.rawY != 0f) Offset(event.rawX, event.rawY) else null,
-                parentBounds
-            )
+            // If an event has raw coordinates of (0, 0), it means it belongs to another owner,
+            // e.g., the soft keyboard or other window, so we want to keep the menu open.
+            val isOutsideClickOnKeyboard = event.rawX == 0f && event.rawY == 0f
+
+            val shouldDismiss = parentBounds == null || !isOutsideClickOnKeyboard
             if (shouldDismiss) {
                 onDismissRequest?.invoke()
                 return true
@@ -424,9 +421,15 @@
             gravity = Gravity.START or Gravity.TOP
 
             // Flags specific to exposed dropdown menu.
-            flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
-                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
+            flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH and
+                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL.inv() or
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+            flags = if (focusable) {
+                flags and WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv()
+            } else {
+                flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+            }
+
             softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
 
             type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
@@ -446,13 +449,6 @@
         }
     }
 
-    private fun Rect.toIntBounds() = IntRect(
-        left = left,
-        top = top,
-        right = right,
-        bottom = bottom
-    )
-
     override fun onGlobalLayout() {
         // Update the position of the popup, in case getWindowVisibleDisplayFrame has changed.
         composeView.getWindowVisibleDisplayFrame(tmpWindowVisibleFrame)
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SegmentedButtonTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SegmentedButtonTest.kt
index d141417..92f8b4f 100644
--- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SegmentedButtonTest.kt
+++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SegmentedButtonTest.kt
@@ -243,4 +243,22 @@
         assertThat((border.brush as SolidColor).value).isEqualTo(specColor)
         assertThat(border.width).isEqualTo(OutlinedSegmentedButtonTokens.OutlineWidth)
     }
+
+    @Test
+    fun segmentedButtonBorderColor_customColors_resolvesCorrectly() {
+        lateinit var colors: SegmentedButtonColors
+        rule.setMaterialContent(lightColorScheme()) {
+            colors = SegmentedButtonDefaults.colors(
+                activeBorderColor = Color.Magenta,
+                inactiveBorderColor = Color.Cyan,
+                disabledActiveBorderColor = Color.Yellow,
+                disabledInactiveBorderColor = Color.Green,
+            )
+        }
+
+        assertThat(colors.borderColor(active = true, enabled = true)).isEqualTo(Color.Magenta)
+        assertThat(colors.borderColor(active = false, enabled = true)).isEqualTo(Color.Cyan)
+        assertThat(colors.borderColor(active = true, enabled = false)).isEqualTo(Color.Yellow)
+        assertThat(colors.borderColor(active = false, enabled = false)).isEqualTo(Color.Green)
+    }
 }
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.android.kt
index 67a996d..9089e62 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.android.kt
@@ -28,6 +28,7 @@
 import android.view.ViewOutlineProvider
 import android.view.ViewTreeObserver
 import android.view.WindowManager
+import android.view.accessibility.AccessibilityManager
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionContext
 import androidx.compose.runtime.DisposableEffect
@@ -43,12 +44,13 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.R
 import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.toComposeIntRect
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.layout.positionInWindow
 import androidx.compose.ui.platform.AbstractComposeView
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.platform.LocalView
@@ -85,16 +87,21 @@
     val view = LocalView.current
     val density = LocalDensity.current
     val layoutDirection = LocalLayoutDirection.current
+    val context = LocalContext.current
+    val a11yManager =
+        context.getSystemService(Context.ACCESSIBILITY_SERVICE) as? AccessibilityManager
+
     val parentComposition = rememberCompositionContext()
     val currentContent by rememberUpdatedState(content)
     val popupId = rememberSaveable { UUID.randomUUID() }
-    val popupLayout = remember {
+    val popupLayout = remember(a11yManager) {
         PopupLayout(
             onDismissRequest = onDismissRequest,
             composeView = view,
             positionProvider = popupPositionProvider,
+            focusable = a11yManager?.isTouchExplorationEnabled == true,
             density = density,
-            popupId = popupId
+            popupId = popupId,
         ).apply {
             setContent(parentComposition) {
                 SimpleStack(
@@ -200,6 +207,7 @@
     private var onDismissRequest: (() -> Unit)?,
     private val composeView: View,
     private val positionProvider: PopupPositionProvider,
+    private val focusable: Boolean,
     density: Density,
     popupId: UUID
 ) : AbstractComposeView(composeView.context),
@@ -312,10 +320,9 @@
         val parentBounds = parentBounds ?: return
         val popupContentSize = popupContentSize ?: return
 
-        val windowSize = previousWindowVisibleFrame.let {
-            composeView.getWindowVisibleDisplayFrame(it)
-            val bounds = it.toIntBounds()
-            IntSize(width = bounds.width, height = bounds.height)
+        val windowSize = previousWindowVisibleFrame.let { rect ->
+            composeView.getWindowVisibleDisplayFrame(rect)
+            rect.toComposeIntRect().size
         }
 
         val popupPosition = positionProvider.calculatePosition(
@@ -355,14 +362,11 @@
             (event.action == MotionEvent.ACTION_DOWN &&
                 (event.x < 0 || event.x >= width || event.y < 0 || event.y >= height))
         ) {
-            val parentBounds = parentBounds
-            val shouldDismiss = parentBounds == null || dismissOnOutsideClick(
-                // Keep menu open if ACTION_OUTSIDE event is reported as raw coordinates of (0, 0).
-                // This means it belongs to another owner, e.g., the soft keyboard or other window.
-                if (event.rawX != 0f && event.rawY != 0f) Offset(event.rawX, event.rawY) else null,
-                parentBounds
-            )
+            // If an event has raw coordinates of (0, 0), it means it belongs to another owner,
+            // e.g., the soft keyboard or other window, so we want to keep the menu open.
+            val isOutsideClickOnKeyboard = event.rawX == 0f && event.rawY == 0f
 
+            val shouldDismiss = parentBounds == null || !isOutsideClickOnKeyboard
             if (shouldDismiss) {
                 onDismissRequest?.invoke()
                 return true
@@ -385,15 +389,6 @@
         super.setLayoutDirection(direction)
     }
 
-    // Specific to exposed dropdown menus.
-    private fun dismissOnOutsideClick(offset: Offset?, bounds: IntRect): Boolean =
-        if (offset == null) {
-            false
-        } else {
-            offset.x < bounds.left || offset.x > bounds.right ||
-                offset.y < bounds.top || offset.y > bounds.bottom
-        }
-
     /**
      * Initialize the LayoutParams specific to [android.widget.PopupWindow].
      */
@@ -403,9 +398,15 @@
             gravity = Gravity.START or Gravity.TOP
 
             // Flags specific to exposed dropdown menu.
-            flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
-                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
+            flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH and
+                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL.inv() or
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+            flags = if (focusable) {
+                flags and WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE.inv()
+            } else {
+                flags or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+            }
+
             softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
 
             type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
@@ -425,13 +426,6 @@
         }
     }
 
-    private fun Rect.toIntBounds() = IntRect(
-        left = left,
-        top = top,
-        right = right,
-        bottom = bottom
-    )
-
     override fun onGlobalLayout() {
         // Update the position of the popup, in case getWindowVisibleDisplayFrame has changed.
         composeView.getWindowVisibleDisplayFrame(tmpWindowVisibleFrame)
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
index 6cea7dd..643d21e 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SegmentedButton.kt
@@ -625,8 +625,8 @@
         return when {
             enabled && active -> activeBorderColor
             enabled && !active -> inactiveBorderColor
-            !enabled && active -> disabledActiveContentColor
-            else -> disabledInactiveContentColor
+            !enabled && active -> disabledActiveBorderColor
+            else -> disabledInactiveBorderColor
         }
     }
 
diff --git a/docs-public/build.gradle b/docs-public/build.gradle
index d3a7dd4..2f783a9 100644
--- a/docs-public/build.gradle
+++ b/docs-public/build.gradle
@@ -339,9 +339,9 @@
     docs("androidx.startup:startup-runtime:1.2.0-alpha02")
     docs("androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01")
     // androidx.test is not hosted in androidx\
-    docsWithoutApiSince("androidx.test:core:1.6.0-alpha01")
-    docsWithoutApiSince("androidx.test:core-ktx:1.6.0-alpha01")
-    docsWithoutApiSince("androidx.test:monitor:1.7.0-alpha01")
+    docsWithoutApiSince("androidx.test:core:1.6.0-alpha02")
+    docsWithoutApiSince("androidx.test:core-ktx:1.6.0-alpha02")
+    docsWithoutApiSince("androidx.test:monitor:1.7.0-alpha02")
     docsWithoutApiSince("androidx.test:rules:1.6.0-alpha01")
     docsWithoutApiSince("androidx.test:runner:1.6.0-alpha01")
     docsWithoutApiSince("androidx.test.espresso:espresso-accessibility:3.6.0-alpha01")
diff --git a/docs/lint_guide.md b/docs/lint_guide.md
index a08a143..cf62088 100644
--- a/docs/lint_guide.md
+++ b/docs/lint_guide.md
@@ -456,19 +456,18 @@
 
 ```kotlin
 override fun visitElement(context: XmlContext, element: Element) {
-    val lintFix = fix().replace()
+    val fix = LintFix.create()
+        .replace()
         .text(ELEMENT)
-        .with(REPLACEMENT TEXT)
+        .with(REPLACEMENT_TEXT)
         .build()
 
-    val incident = Incident(context)
-        .fix(lintFix)
-        .issue(ISSUE)
-        .location(context.getLocation(element))
-        .message("My issue message")
-        .scope(context.getNameLocation(element))
-
-    context.report(incident)
+    context.report(
+        issue = ISSUE,
+        location = context.getNameLocation(element),
+        message = "My issue message",
+        quickFixData = fix
+    )
 }
 ```
 
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 6cfc48b..913cc67 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -16,8 +16,8 @@
 androidLintMinCompose = "30.0.0"
 androidxTestRunner = "1.6.0-alpha01"
 androidxTestRules = "1.6.0-alpha01"
-androidxTestMonitor = "1.7.0-alpha01"
-androidxTestCore = "1.6.0-alpha01"
+androidxTestMonitor = "1.7.0-alpha02"
+androidxTestCore = "1.6.0-alpha02"
 androidxTestExtJunit = "1.2.0-alpha01"
 androidxTestExtTruth = "1.6.0-alpha01"
 annotationVersion = "1.7.0"
diff --git a/libraryversions.toml b/libraryversions.toml
index 7ee4ab8..79b378a 100644
--- a/libraryversions.toml
+++ b/libraryversions.toml
@@ -45,7 +45,7 @@
 CORE_SPLASHSCREEN = "1.1.0-alpha02"
 CORE_TELECOM = "1.0.0-alpha02"
 CORE_UWB = "1.0.0-alpha08"
-CREDENTIALS = "1.2.0"
+CREDENTIALS = "1.3.0-alpha01"
 CREDENTIALS_FIDO_QUARANTINE = "1.0.0-alpha01"
 CURSORADAPTER = "1.1.0-alpha01"
 CUSTOMVIEW = "1.2.0-alpha03"
@@ -89,7 +89,7 @@
 LEANBACK_TAB = "1.1.0-beta01"
 LEGACY = "1.1.0-alpha01"
 LIBYUV = "0.1.0-dev01"
-LIFECYCLE = "2.7.0-beta01"
+LIFECYCLE = "2.7.0-rc01"
 LIFECYCLE_EXTENSIONS = "2.2.0"
 LOADER = "1.2.0-alpha01"
 MEDIA = "1.7.0-rc01"
@@ -105,7 +105,7 @@
 PRIVACYSANDBOX_ACTIVITY = "1.0.0-alpha01"
 PRIVACYSANDBOX_ADS = "1.1.0-beta02"
 PRIVACYSANDBOX_PLUGINS = "1.0.0-alpha03"
-PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha10"
+PRIVACYSANDBOX_SDKRUNTIME = "1.0.0-alpha11"
 PRIVACYSANDBOX_TOOLS = "1.0.0-alpha06"
 PRIVACYSANDBOX_UI = "1.0.0-alpha07"
 PROFILEINSTALLER = "1.4.0-alpha01"
diff --git a/tracing/tracing/lint-baseline.xml b/tracing/tracing/lint-baseline.xml
deleted file mode 100644
index 0391a7b..0000000
--- a/tracing/tracing/lint-baseline.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 8.3.0-alpha04" type="baseline" client="gradle" dependencies="false" name="AGP (8.3.0-alpha04)" variant="all" version="8.3.0-alpha04">
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18 &amp;&amp; Build.VERSION.SDK_INT &lt; 31) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 19"
-        errorLine1="        if (Build.VERSION.SDK_INT >= 18) {"
-        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/Trace.java"/>
-    </issue>
-
-    <issue
-        id="ObsoleteSdkInt"
-        message="Unnecessary; SDK_INT is always >= 18"
-        errorLine1="@RequiresApi(18)"
-        errorLine2="~~~~~~~~~~~~~~~~">
-        <location
-            file="src/main/java/androidx/tracing/TraceApi18Impl.java"/>
-    </issue>
-
-</issues>
diff --git a/tracing/tracing/src/main/java/androidx/tracing/Trace.java b/tracing/tracing/src/main/java/androidx/tracing/Trace.java
index 9a7dcba..d2eef10 100644
--- a/tracing/tracing/src/main/java/androidx/tracing/Trace.java
+++ b/tracing/tracing/src/main/java/androidx/tracing/Trace.java
@@ -96,7 +96,7 @@
      * API 31.
      */
     public static void forceEnableAppTracing() {
-        if (Build.VERSION.SDK_INT >= 18 && Build.VERSION.SDK_INT < 31) {
+        if (Build.VERSION.SDK_INT < 31) {
             try {
                 if (!sHasAppTracingEnabled) {
                     sHasAppTracingEnabled = true; // only attempt once
@@ -126,9 +126,7 @@
      * @param label The name of the code section to appear in the trace.
      */
     public static void beginSection(@NonNull String label) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            TraceApi18Impl.beginSection(truncatedTraceSectionLabel(label));
-        }
+        android.os.Trace.beginSection(truncatedTraceSectionLabel(label));
     }
 
     /**
@@ -140,9 +138,7 @@
      * called from the same thread.
      */
     public static void endSection() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            TraceApi18Impl.endSection();
-        }
+        android.os.Trace.endSection();
     }
 
     /**
@@ -215,77 +211,69 @@
         }
     }
 
-    @SuppressWarnings({"JavaReflectionMemberAccess", "ConstantConditions"})
+    @SuppressWarnings({"JavaReflectionMemberAccess", "BanUncheckedReflection"})
     private static boolean isEnabledFallback() {
-        if (Build.VERSION.SDK_INT >= 18) {
-            try {
-                if (sIsTagEnabledMethod == null) {
-                    Field traceTagAppField = android.os.Trace.class.getField("TRACE_TAG_APP");
-                    sTraceTagApp = traceTagAppField.getLong(null);
-                    sIsTagEnabledMethod =
-                            android.os.Trace.class.getMethod("isTagEnabled", long.class);
-                }
-                return (boolean) sIsTagEnabledMethod.invoke(null, sTraceTagApp);
-            } catch (Exception exception) {
-                handleException("isTagEnabled", exception);
+        try {
+            if (sIsTagEnabledMethod == null) {
+                Field traceTagAppField = android.os.Trace.class.getField("TRACE_TAG_APP");
+                sTraceTagApp = traceTagAppField.getLong(null);
+                sIsTagEnabledMethod =
+                        android.os.Trace.class.getMethod("isTagEnabled", long.class);
             }
+            return (boolean) sIsTagEnabledMethod.invoke(null, sTraceTagApp);
+        } catch (Exception exception) {
+            handleException("isTagEnabled", exception);
         }
         // Never enabled on < API 18
         return false;
     }
 
-    @SuppressWarnings("JavaReflectionMemberAccess")
+    @SuppressWarnings({"JavaReflectionMemberAccess", "BanUncheckedReflection"})
     private static void beginAsyncSectionFallback(@NonNull String methodName, int cookie) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            try {
-                if (sAsyncTraceBeginMethod == null) {
-                    sAsyncTraceBeginMethod = android.os.Trace.class.getMethod(
-                            "asyncTraceBegin",
-                            long.class,
-                            String.class, int.class
-                    );
-                }
-                sAsyncTraceBeginMethod.invoke(null, sTraceTagApp, methodName, cookie);
-            } catch (Exception exception) {
-                handleException("asyncTraceBegin", exception);
+        try {
+            if (sAsyncTraceBeginMethod == null) {
+                sAsyncTraceBeginMethod = android.os.Trace.class.getMethod(
+                        "asyncTraceBegin",
+                        long.class,
+                        String.class, int.class
+                );
             }
+            sAsyncTraceBeginMethod.invoke(null, sTraceTagApp, methodName, cookie);
+        } catch (Exception exception) {
+            handleException("asyncTraceBegin", exception);
         }
     }
 
-    @SuppressWarnings("JavaReflectionMemberAccess")
+    @SuppressWarnings({"JavaReflectionMemberAccess", "BanUncheckedReflection"})
     private static void endAsyncSectionFallback(@NonNull String methodName, int cookie) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            try {
-                if (sAsyncTraceEndMethod == null) {
-                    sAsyncTraceEndMethod = android.os.Trace.class.getMethod(
-                            "asyncTraceEnd",
-                            long.class,
-                            String.class, int.class
-                    );
-                }
-                sAsyncTraceEndMethod.invoke(null, sTraceTagApp, methodName, cookie);
-            } catch (Exception exception) {
-                handleException("asyncTraceEnd", exception);
+        try {
+            if (sAsyncTraceEndMethod == null) {
+                sAsyncTraceEndMethod = android.os.Trace.class.getMethod(
+                        "asyncTraceEnd",
+                        long.class,
+                        String.class, int.class
+                );
             }
+            sAsyncTraceEndMethod.invoke(null, sTraceTagApp, methodName, cookie);
+        } catch (Exception exception) {
+            handleException("asyncTraceEnd", exception);
         }
     }
 
-    @SuppressWarnings("JavaReflectionMemberAccess")
+    @SuppressWarnings({"JavaReflectionMemberAccess", "BanUncheckedReflection"})
     private static void setCounterFallback(@NonNull String counterName, int counterValue) {
-        if (Build.VERSION.SDK_INT >= 18) {
-            try {
-                if (sTraceCounterMethod == null) {
-                    sTraceCounterMethod = android.os.Trace.class.getMethod(
-                            "traceCounter",
-                            long.class,
-                            String.class,
-                            int.class
-                    );
-                }
-                sTraceCounterMethod.invoke(null, sTraceTagApp, counterName, counterValue);
-            } catch (Exception exception) {
-                handleException("traceCounter", exception);
+        try {
+            if (sTraceCounterMethod == null) {
+                sTraceCounterMethod = android.os.Trace.class.getMethod(
+                        "traceCounter",
+                        long.class,
+                        String.class,
+                        int.class
+                );
             }
+            sTraceCounterMethod.invoke(null, sTraceTagApp, counterName, counterValue);
+        } catch (Exception exception) {
+            handleException("traceCounter", exception);
         }
     }
 
diff --git a/tracing/tracing/src/main/java/androidx/tracing/TraceApi18Impl.java b/tracing/tracing/src/main/java/androidx/tracing/TraceApi18Impl.java
deleted file mode 100644
index f70646e..0000000
--- a/tracing/tracing/src/main/java/androidx/tracing/TraceApi18Impl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.tracing;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
-
-/**
- * This is a helper class that handles {@link android.os.Trace} functionality in API >= 18.
- * <p>
- * This class is being defined separately to avoid class verification failures.
- * For more information read https://chromium.googlesource
- * .com/chromium/src/build/+/refs/heads/master/android/docs/class_verification_failures
- * .md#understanding-the-reason-for-the-failure
- */
-@RequiresApi(18)
-final class TraceApi18Impl {
-
-    private TraceApi18Impl() {
-        // Does nothing
-    }
-
-    /**
-     * Writes a trace message to indicate that a given section of code has begun. This call must
-     * be followed by a corresponding call to {@link #endSection()} on the same thread.
-     *
-     * <p class="note"> At this time the vertical bar character '|', newline character '\n', and
-     * null character '\0' are used internally by the tracing mechanism.  If sectionName contains
-     * these characters they will be replaced with a space character in the trace.
-     *
-     * @param label The name of the code section to appear in the trace.  This may be at
-     *              most 127 Unicode code units long.
-     */
-    public static void beginSection(@NonNull String label) {
-        android.os.Trace.beginSection(label);
-    }
-
-    /**
-     * Writes a trace message to indicate that a given section of code has ended. This call must
-     * be preceded by a corresponding call to {@link #beginSection(String)}. Calling this method
-     * will mark the end of the most recently begun section of code, so care must be taken to
-     * ensure that beginSection / endSection pairs are properly nested and called from the same
-     * thread.
-     */
-    public static void endSection() {
-        android.os.Trace.endSection();
-    }
-}
diff --git a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
index 654dae7..423ff64 100644
--- a/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
+++ b/wear/compose/compose-material/src/main/java/androidx/wear/compose/material/PositionIndicator.kt
@@ -223,8 +223,8 @@
 @Deprecated(
     "This overload is provided for backwards compatibility with " +
         "Compose for Wear OS 1.2." +
-        "A newer overload is available with additional showFadeInAnimation, " +
-        "showFadeOutAnimation and showPositionAnimation parameters.",
+        "A newer overload is available with additional fadeInAnimationSpec, " +
+        "fadeOutAnimationSpec and positionAnimationSpec parameters.",
     level = DeprecationLevel.HIDDEN
 )
 @Composable
@@ -305,8 +305,8 @@
 @Deprecated(
     "This overload is provided for backwards compatibility with " +
         "Compose for Wear OS 1.2." +
-        "A newer overload is available with additional showFadeInAnimation, " +
-        "showFadeOutAnimation and showPositionAnimation parameters.",
+        "A newer overload is available with additional fadeInAnimationSpec, " +
+        "fadeOutAnimationSpec and positionAnimationSpec parameters.",
     level = DeprecationLevel.HIDDEN
 )
 @Composable
@@ -422,8 +422,8 @@
 @Deprecated(
     "This overload is provided for backwards compatibility with " +
         "Compose for Wear OS 1.2." +
-        "A newer overload is available with additional showFadeInAnimation, " +
-        "showFadeOutAnimation and showPositionAnimation parameters.",
+        "A newer overload is available with additional fadeInAnimationSpec, " +
+        "fadeOutAnimationSpec and positionAnimationSpec parameters.",
     level = DeprecationLevel.HIDDEN
 )
 @Composable
@@ -566,8 +566,8 @@
 @Deprecated(
     "This overload is provided for backwards compatibility with " +
         "Compose for Wear OS 1.2." +
-        "A newer overload is available with additional showFadeInAnimation, " +
-        "showFadeOutAnimation and showPositionAnimation parameters.",
+        "A newer overload is available with additional fadeInAnimationSpec, " +
+        "fadeOutAnimationSpec and positionAnimationSpec parameters.",
     level = DeprecationLevel.HIDDEN
 )
 @Composable
@@ -602,16 +602,21 @@
  * dimensions [indicatorHeight] and [indicatorWidth], and position with respect to the edge of the
  * screen according to [paddingHorizontal]
  *
- * This [PositionIndicator] has 3 separate flags to control different animations.
- * - [showFadeInAnimation] - controls fade-in animation.
- * - [showFadeOutAnimation] - controls fade-out animation.
- * - [showPositionAnimation] - controls position change animation.
+ * This [PositionIndicator] has 3 separate animation specs to control different animations.
+ * - [fadeInAnimationSpec] - controls fade-in animation.
+ * - [fadeOutAnimationSpec] - controls fade-out animation.
+ * - [positionAnimationSpec] - controls position change animation.
  *
  * For performance reasons and for UX consistency, when [PositionIndicator] is used with scrollable
- * list, we recommend to switch off [showFadeInAnimation] and [showPositionAnimation] flags.
+ * list, we recommend to switch off fade-in and position animations by passing [snap] spec into
+ * [fadeInAnimationSpec] and [positionAnimationSpec] parameters.
  * If [PositionIndicator] is used as a standalone indicator, for example as volume control,
  * then we recommend to have all 3 animations turned on.
  *
+ * If color of [PositionIndicator] is not white and position animation is enabled - a short
+ * highlight animation will be triggered on any position change.
+ * This is a short animation accenting [PositionIndicator] with white color with 33% opacity.
+ *
  * For more information, see the
  * [Scroll indicators](https://developer.android.com/training/wearables/components/scroll)
  * guide.
@@ -952,8 +957,8 @@
 @Deprecated(
     "This overload is provided for backwards compatibility with " +
         "Compose for Wear OS 1.2." +
-        "A newer overload is available with additional showFadeInAnimation, " +
-        "showFadeOutAnimation and showPositionAnimation parameters.",
+        "A newer overload is available with additional fadeInAnimationSpec, " +
+        "fadeOutAnimationSpec and positionAnimationSpec parameters.",
     level = DeprecationLevel.HIDDEN
 )
 @Composable
diff --git a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
index b7de201..1a91267 100644
--- a/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
+++ b/wear/compose/compose-material3/src/main/java/androidx/wear/compose/material3/Button.kt
@@ -17,25 +17,41 @@
 package androidx.wear.compose.material3
 
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.border
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.Interaction
 import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.IntrinsicSize
 import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.defaultMinSize
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.ripple.rememberRipple
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.State
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.draw.paint
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.painter.ColorPainter
 import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.unit.Dp
@@ -1188,18 +1204,29 @@
     interactionSource: MutableInteractionSource,
     content: @Composable RowScope.() -> Unit
 ) {
-    androidx.wear.compose.materialcore.Chip(
-        modifier = modifier
+    val borderModifier = if (border != null)
+        modifier.border(
+            border = border,
+            shape = shape
+        ) else modifier
+    Row(
+        modifier = borderModifier
             .defaultMinSize(minHeight = ButtonDefaults.Height)
-            .height(IntrinsicSize.Min),
-        onClick = onClick,
-        background = { colors.containerPainter(enabled = it) },
-        border = { rememberUpdatedState(border) },
-        enabled = enabled,
-        contentPadding = contentPadding,
-        shape = shape,
-        interactionSource = interactionSource,
-        role = Role.Button,
+            .height(IntrinsicSize.Min)
+            .clip(shape = shape)
+            .width(intrinsicSize = IntrinsicSize.Max)
+            .paint(
+                painter = colors.containerPainter(enabled = enabled).value,
+                contentScale = ContentScale.Crop
+            )
+            .clickable(
+                enabled = enabled,
+                onClick = onClick,
+                role = Role.Button,
+                indication = rememberRipple(),
+                interactionSource = interactionSource,
+            )
+            .padding(contentPadding),
         content = provideScopeContent(
             colors.contentColor(enabled = enabled),
             labelFont,
@@ -1228,31 +1255,48 @@
     interactionSource: MutableInteractionSource,
     label: @Composable RowScope.() -> Unit
 ) {
-    androidx.wear.compose.materialcore.Chip(
-        modifier = modifier
-            .defaultMinSize(minHeight = ButtonDefaults.Height)
-            .height(IntrinsicSize.Min),
+    Button(
         onClick = onClick,
-        background = { colors.containerPainter(enabled = it) },
-        border = { rememberUpdatedState(border) },
+        modifier = modifier,
         enabled = enabled,
-        interactionSource = interactionSource,
         shape = shape,
+        labelFont = labelFont,
+        colors = colors,
+        border = border,
         contentPadding = contentPadding,
-        label = provideScopeContent(
-            colors.contentColor(enabled),
-            labelFont,
-            label
-        ),
-        secondaryLabel = secondaryLabel?.let { provideScopeContent(
-            colors.secondaryContentColor(enabled),
-            secondaryLabelFont,
-            secondaryLabel
-        ) },
-        icon = icon?.let {
-            provideScopeContent(colors.iconColor(enabled), icon)
-        },
-        defaultIconSpacing = ButtonDefaults.IconSpacing,
-        role = Role.Button
-    )
+        interactionSource = interactionSource,
+    ) {
+        Row(
+            verticalAlignment = Alignment.CenterVertically,
+            // Fill the container height but not its width as chips have fixed size height but we
+            // want them to be able to fit their content
+            modifier = Modifier.fillMaxHeight()
+        ) {
+            if (icon != null) {
+                Box(
+                    modifier = Modifier.wrapContentSize(align = Alignment.Center),
+                    content = provideScopeContent(colors.iconColor(enabled), icon)
+                )
+                Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing))
+            }
+            Column {
+                Row(
+                    content = provideScopeContent(
+                        colors.contentColor(enabled),
+                        labelFont,
+                        label
+                    )
+                )
+                secondaryLabel?.let {
+                    Row(
+                        content = provideScopeContent(
+                            colors.secondaryContentColor(enabled),
+                            secondaryLabelFont,
+                            secondaryLabel
+                        )
+                    )
+                }
+            }
+        }
+    }
 }