Merge "Make sure generateApi uses android jar for android KMP projects" into androidx-main
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
index 67883b1..bbe2cd8 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/Carousel.kt
@@ -119,7 +119,7 @@
                     density = this,
                     carouselMainAxisSize = availableSpace,
                     preferredItemSize = preferredItemWidth.toPx(),
-                    itemCount = state.itemCountState.value.invoke(),
+                    itemCount = state.pagerState.pageCountState.value.invoke(),
                     itemSpacing = itemSpacingPx,
                     minSmallItemSize = minSmallItemWidth.toPx(),
                     maxSmallItemSize = maxSmallItemWidth.toPx(),
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt
index f288e6c..927ba12 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/carousel/CarouselState.kt
@@ -45,12 +45,10 @@
 class CarouselState(
     currentItem: Int = 0,
     @FloatRange(from = -0.5, to = 0.5) currentItemOffsetFraction: Float = 0f,
-    itemCount: () -> Int
+    itemCount: () -> Int,
 ) : ScrollableState {
-    internal var itemCountState = mutableStateOf(itemCount)
-
-    internal var pagerState: PagerState =
-        PagerState(currentItem, currentItemOffsetFraction, itemCountState.value)
+    internal var pagerState: CarouselPagerState =
+        CarouselPagerState(currentItem, currentItemOffsetFraction, itemCount)
 
     override val isScrollInProgress: Boolean
         get() = pagerState.isScrollInProgress
@@ -108,7 +106,43 @@
                 itemCount = itemCount
             )
         }
-        .apply { itemCountState.value = itemCount }
+        .apply { pagerState.pageCountState.value = itemCount }
+}
+
+internal const val MinPageOffset = -0.5f
+internal const val MaxPageOffset = 0.5f
+
+internal class CarouselPagerState(
+    currentPage: Int,
+    currentPageOffsetFraction: Float,
+    updatedPageCount: () -> Int,
+) : PagerState(currentPage, currentPageOffsetFraction) {
+    var pageCountState = mutableStateOf(updatedPageCount)
+
+    // Observe changes to the lambda within the MutableState
+    override val pageCount: Int
+        get() = pageCountState.value.invoke()
+
+    companion object {
+        /** To keep current page and current page offset saved */
+        val Saver: Saver<CarouselPagerState, *> =
+            listSaver(
+                save = {
+                    listOf(
+                        it.currentPage,
+                        (it.currentPageOffsetFraction).coerceIn(MinPageOffset, MaxPageOffset),
+                        it.pageCountState.value
+                    )
+                },
+                restore = {
+                    CarouselPagerState(
+                        currentPage = it[0] as Int,
+                        currentPageOffsetFraction = it[1] as Float,
+                        updatedPageCount = { it[2] as Int },
+                    )
+                }
+            )
+    }
 }
 
 /**
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillManagerTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillManagerTest.kt
index 8500c36..8c06ff3 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillManagerTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/autofill/AndroidAutofillManagerTest.kt
@@ -20,6 +20,7 @@
 import androidx.annotation.RequiresApi
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.clickable
+import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -39,19 +40,23 @@
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.focus.FocusManager
+import androidx.compose.ui.focus.focusProperties
 import androidx.compose.ui.platform.LocalAutofillManager
+import androidx.compose.ui.platform.LocalFocusManager
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.contentDataType
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.contentType
 import androidx.compose.ui.semantics.editableText
-import androidx.compose.ui.semantics.focused
 import androidx.compose.ui.semantics.onAutofillText
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.testTag
 import androidx.compose.ui.test.TestActivity
 import androidx.compose.ui.test.junit4.createAndroidComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.performClick
+import androidx.compose.ui.test.requestFocus
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.unit.dp
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -67,11 +72,13 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.verifyNoMoreInteractions
+import org.mockito.kotlin.verifyZeroInteractions
 
 @SdkSuppress(minSdkVersion = 26)
 @RequiresApi(Build.VERSION_CODES.O)
@@ -135,30 +142,31 @@
         rule.runOnIdle { isVisible = true }
 
         // `commit` should not be called when an autofillable component appears onscreen.
-        rule.runOnIdle { verify(am, times(0)).commit() }
+        rule.runOnIdle { verify(am, never()).commit() }
     }
 
     @Test
     @SmallTest
     fun autofillManager_doNotCallCommit_autofillTagsAdded() {
         val am: PlatformAutofillManager = mock()
-        var isRelatedToAutofill by mutableStateOf(false)
+        var hasContentType by mutableStateOf(false)
 
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (isRelatedToAutofill)
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
+                    Modifier.then(
+                            if (hasContentType) {
+                                Modifier.semantics { contentType = ContentType.Username }
+                            } else {
+                                Modifier
                             }
-                            .size(height, width)
-                    else Modifier.size(height, width)
+                        )
+                        .size(height, width)
             )
         }
 
-        rule.runOnIdle { isRelatedToAutofill = true }
+        rule.runOnIdle { hasContentType = true }
 
         // `commit` should not be called a component becomes relevant to autofill.
         rule.runOnIdle { verify(am, times(0)).commit() }
@@ -179,7 +187,7 @@
 
         rule.runOnIdle { revealFirstUsername = false }
 
-        // `commit` should be called when an autofillable component leaves the screen.
+        // `commit` should be called when an autofill-able component leaves the screen.
         rule.runOnIdle { verify(am, times(1)).commit() }
     }
 
@@ -203,8 +211,8 @@
         rule.runOnIdle { revealFirstUsername = false }
         rule.runOnIdle { revealSecondUsername = true }
 
-        // `commit` should be called when an autofillable component leaves onscreen, even when
-        // another, different autofillable component is added.
+        // `commit` should be called when an autofill-able component leaves onscreen, even when
+        // another, different autofill-able component is added.
         rule.runOnIdle { verify(am, times(1)).commit() }
     }
 
@@ -221,10 +229,13 @@
                 Box(
                     modifier =
                         Modifier.then(
-                            if (semanticsExist)
-                                Modifier.semantics { contentDescription = "contentDescription" }
-                            else Modifier.size(height, width)
-                        )
+                                if (semanticsExist) {
+                                    Modifier.semantics { contentDescription = "contentDescription" }
+                                } else {
+                                    Modifier
+                                }
+                            )
+                            .size(height, width)
                 )
             }
         }
@@ -241,25 +252,26 @@
     fun autofillManager_callCommit_nodesBecomeAutofillRelatedAndDisappear() {
         val am: PlatformAutofillManager = mock()
         var isVisible by mutableStateOf(true)
-        var isRelatedToAutofill by mutableStateOf(false)
+        var hasContentType by mutableStateOf(false)
 
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             if (isVisible) {
                 Box(
                     modifier =
-                        if (isRelatedToAutofill)
-                            Modifier.semantics {
-                                    contentType = ContentType.Username
-                                    contentDataType = ContentDataType.Text
+                        Modifier.then(
+                                if (hasContentType) {
+                                    Modifier.semantics { contentType = ContentType.Username }
+                                } else {
+                                    Modifier
                                 }
-                                .size(height, width)
-                        else Modifier.size(height, width)
+                            )
+                            .size(height, width)
                 )
             }
         }
 
-        rule.runOnIdle { isRelatedToAutofill = true }
+        rule.runOnIdle { hasContentType = true }
         rule.runOnIdle { isVisible = false }
 
         // `commit` should be called when component becomes autofillable, then leaves the screen.
@@ -445,22 +457,19 @@
     @SdkSuppress(minSdkVersion = 26)
     fun autofillManager_notifyViewEntered_previousFocusFalse() {
         val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(false)
-
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 Modifier.semantics {
-                        contentType = ContentType.Username
-                        contentDataType = ContentDataType.Text
-                        focused = hasFocus
+                        testTag = "username"
                         onAutofillText { true }
                     }
                     .size(height, width)
+                    .focusable()
             )
         }
 
-        rule.runOnIdle { hasFocus = true }
+        rule.onNodeWithTag("username").requestFocus()
 
         rule.runOnIdle { verify(am).notifyViewEntered(any(), any(), any()) }
     }
@@ -470,21 +479,20 @@
     @SdkSuppress(minSdkVersion = 26)
     fun autofillManager_notAutofillable_notifyViewEntered_previousFocusFalse() {
         val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(false)
-
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 Modifier.semantics {
+                        testTag = "username"
                         contentType = ContentType.Username
                         contentDataType = ContentDataType.Text
-                        focused = hasFocus
                     }
                     .size(height, width)
+                    .focusable()
             )
         }
 
-        rule.runOnIdle { hasFocus = true }
+        rule.onNodeWithTag("username").requestFocus()
 
         rule.runOnIdle { verifyNoMoreInteractions(am) }
     }
@@ -494,25 +502,20 @@
     @SdkSuppress(minSdkVersion = 26)
     fun autofillManager_notifyViewEntered_previousFocusNull() {
         val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(false)
-
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (hasFocus)
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                                focused = hasFocus
-                                onAutofillText { true }
-                            }
-                            .size(height, width)
-                    else plainVisibleModifier("usernameTag")
+                    Modifier.semantics {
+                            testTag = "username"
+                            onAutofillText { true }
+                        }
+                        .size(height, width)
+                        .focusable()
             )
         }
 
-        rule.runOnIdle { hasFocus = true }
+        rule.onNodeWithTag("username").requestFocus()
 
         rule.runOnIdle { verify(am).notifyViewEntered(any(), any(), any()) }
     }
@@ -520,51 +523,25 @@
     @Test
     @SmallTest
     @SdkSuppress(minSdkVersion = 26)
-    fun autofillManager_notifyViewEntered_itemNotAutofillable() {
-        val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(false)
-
-        rule.setContent {
-            (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
-            Box(
-                modifier =
-                    if (hasFocus)
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                                focused = hasFocus
-                            }
-                            .size(height, width)
-                    else plainVisibleModifier("usernameTag")
-            )
-        }
-
-        rule.runOnIdle { hasFocus = true }
-
-        rule.runOnIdle { verifyNoMoreInteractions(am) }
-    }
-
-    @Test
-    @SmallTest
-    @SdkSuppress(minSdkVersion = 26)
     fun autofillManager_notifyViewExited_previousFocusTrue() {
         val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(true)
-
+        lateinit var focusManager: FocusManager
         rule.setContent {
+            focusManager = LocalFocusManager.current
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 Modifier.semantics {
-                        contentType = ContentType.Username
-                        contentDataType = ContentDataType.Text
-                        focused = hasFocus
+                        testTag = "username"
                         onAutofillText { true }
                     }
                     .size(height, width)
+                    .focusable()
             )
         }
+        rule.onNodeWithTag("username").requestFocus()
+        rule.runOnIdle { clearInvocations(am) }
 
-        rule.runOnIdle { hasFocus = false }
+        rule.runOnIdle { focusManager.clearFocus() }
 
         rule.runOnIdle { verify(am).notifyViewExited(any(), any()) }
     }
@@ -574,23 +551,17 @@
     @SdkSuppress(minSdkVersion = 26)
     fun autofillManager_notifyViewExited_previouslyFocusedItemNotAutofillable() {
         val am: PlatformAutofillManager = mock()
-        var hasFocus by mutableStateOf(true)
-
+        lateinit var focusManager: FocusManager
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
-            Box(
-                Modifier.semantics {
-                        contentType = ContentType.Username
-                        contentDataType = ContentDataType.Text
-                        focused = hasFocus
-                    }
-                    .size(height, width)
-            )
+            focusManager = LocalFocusManager.current
+            Box(Modifier.semantics { testTag = "username" }.size(height, width).focusable())
         }
 
-        rule.runOnIdle { hasFocus = false }
+        rule.onNodeWithTag("username").requestFocus()
+        rule.runOnIdle { focusManager.clearFocus() }
 
-        rule.runOnIdle { verifyNoMoreInteractions(am) }
+        rule.runOnIdle { verifyZeroInteractions(am) }
     }
 
     @Ignore // TODO(b/383198004): Add support for notifyVisibilityChanged.
@@ -599,15 +570,16 @@
     @SdkSuppress(minSdkVersion = 27)
     fun autofillManager_notifyVisibilityChanged_disappeared() {
         val am: PlatformAutofillManager = mock()
-        val usernameTag = "usernameTag"
         var isVisible by mutableStateOf(true)
 
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (isVisible) plainVisibleModifier(usernameTag)
-                    else invisibleModifier(usernameTag)
+                    Modifier.then(if (isVisible) Modifier else Modifier.alpha(0f))
+                        .semantics { onAutofillText { true } }
+                        .size(width, height)
+                        .focusable()
             )
         }
 
@@ -622,15 +594,16 @@
     @SdkSuppress(minSdkVersion = 27)
     fun autofillManager_notifyVisibilityChanged_appeared() {
         val am: PlatformAutofillManager = mock()
-        val usernameTag = "username_tag"
         var isVisible by mutableStateOf(false)
 
         rule.setContent {
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (isVisible) plainVisibleModifier(usernameTag)
-                    else invisibleModifier(usernameTag)
+                    Modifier.then(if (isVisible) Modifier else Modifier.alpha(0f))
+                        .semantics { onAutofillText { true } }
+                        .size(width, height)
+                        .focusable()
             )
         }
 
@@ -693,29 +666,24 @@
         val am: PlatformAutofillManager = mock()
         val contextMenuTag = "menu_tag"
         var autofillManager: AutofillManager?
-        var hasFocus by mutableStateOf(false)
 
         rule.setContent {
             autofillManager = LocalAutofillManager.current
             (autofillManager as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (hasFocus)
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                                focused = hasFocus
-                                onAutofillText { true }
-                            }
-                            .clickable { autofillManager?.requestAutofillForActiveElement() }
-                            .size(height, width)
-                            .testTag(contextMenuTag)
-                    else plainVisibleModifier(contextMenuTag)
+                    Modifier.semantics {
+                            testTag = contextMenuTag
+                            onAutofillText { true }
+                        }
+                        .focusProperties { canFocus = true }
+                        .clickable { autofillManager?.requestAutofillForActiveElement() }
+                        .size(height, width)
             )
         }
 
         // `requestAutofill` is always called after an element is focused
-        rule.runOnIdle { hasFocus = true }
+        rule.onNodeWithTag(contextMenuTag).requestFocus()
         rule.runOnIdle { verify(am).notifyViewEntered(any(), any(), any()) }
 
         // then `requestAutofill` is called on that same previously focused element
@@ -730,28 +698,25 @@
         val am: PlatformAutofillManager = mock()
         val contextMenuTag = "menu_tag"
         var autofillManager: AutofillManager?
-        var hasFocus by mutableStateOf(false)
 
         rule.setContent {
             autofillManager = LocalAutofillManager.current
             (autofillManager as AndroidAutofillManager).platformAutofillManager = am
             Box(
                 modifier =
-                    if (hasFocus)
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                                focused = hasFocus
-                            }
-                            .clickable { autofillManager?.requestAutofillForActiveElement() }
-                            .size(height, width)
-                            .testTag(contextMenuTag)
-                    else plainVisibleModifier(contextMenuTag)
+                    Modifier.semantics { testTag = contextMenuTag }
+                        .focusProperties { canFocus = true }
+                        .clickable { autofillManager?.requestAutofillForActiveElement() }
+                        .size(height, width)
             )
         }
 
         // `requestAutofill` is always called after an element is focused
-        rule.runOnIdle { hasFocus = true }
+        rule.onNodeWithTag(contextMenuTag).requestFocus()
+        rule.runOnIdle { verifyZeroInteractions(am) }
+
+        // then `requestAutofill` is called on that same previously focused element
+        rule.onNodeWithTag(contextMenuTag).performClick()
         rule.runOnIdle { verifyNoMoreInteractions(am) }
     }
 
@@ -769,15 +734,7 @@
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
 
             LazyColumn(Modifier.fillMaxWidth().height(50.dp), state) {
-                item {
-                    Box(
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                            }
-                            .size(10.dp)
-                    )
-                }
+                item { Box(Modifier.semantics { contentType = ContentType.Username }.size(10.dp)) }
                 items(count) { Box(Modifier.size(10.dp)) }
             }
         }
@@ -800,15 +757,7 @@
             (LocalAutofillManager.current as AndroidAutofillManager).platformAutofillManager = am
 
             Column(Modifier.fillMaxWidth().height(50.dp).verticalScroll(scrollState)) {
-                Row {
-                    Box(
-                        Modifier.semantics {
-                                contentType = ContentType.Username
-                                contentDataType = ContentDataType.Text
-                            }
-                            .size(10.dp)
-                    )
-                }
+                Row { Box(Modifier.semantics { contentType = ContentType.Username }.size(10.dp)) }
                 repeat(50) { Box(Modifier.size(10.dp)) }
             }
         }
@@ -833,13 +782,7 @@
             Column(Modifier.fillMaxWidth().height(50.dp).verticalScroll(scrollState)) {
                 if (autofillComponentsVisible) {
                     Row {
-                        Box(
-                            Modifier.semantics {
-                                    contentType = ContentType.Username
-                                    contentDataType = ContentDataType.Text
-                                }
-                                .size(10.dp)
-                        )
+                        Box(Modifier.semantics { contentType = ContentType.Username }.size(10.dp))
                     }
                 }
                 repeat(50) { Box(Modifier.size(10.dp)) }
@@ -851,27 +794,4 @@
         // A column disappearing will call commit
         rule.runOnIdle { verify(am).commit() }
     }
-
-    // ============================================================================================
-    // Helper functions
-    // ============================================================================================
-
-    private fun plainVisibleModifier(testTag: String): Modifier {
-        return Modifier.semantics {
-                contentType = ContentType.Username
-                contentDataType = ContentDataType.Text
-            }
-            .size(width, height)
-            .testTag(testTag)
-    }
-
-    private fun invisibleModifier(testTag: String): Modifier {
-        return Modifier.alpha(0f) // this will make the component invisible
-            .semantics {
-                contentType = ContentType.Username
-                contentDataType = ContentDataType.Text
-            }
-            .size(width, height)
-            .testTag(testTag)
-    }
 }
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofillManager.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofillManager.android.kt
index d3fed6e..e4ee1a8 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofillManager.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/autofill/AndroidAutofillManager.android.kt
@@ -113,8 +113,7 @@
         //  so that this could be more efficient.
         val previousFocus = prevConfig?.getOrNull(SemanticsProperties.Focused)
         val currFocus = config?.getOrNull(SemanticsProperties.Focused)
-        val supportsAutofill = config?.getOrNull(SemanticsActions.OnAutofillText) != null
-        if (previousFocus != true && currFocus == true && supportsAutofill) {
+        if (previousFocus != true && currFocus == true && config.isAutofillable()) {
             previouslyFocusedId = semanticsId
             rectManager.rects.withRect(semanticsId) { left, top, right, bottom ->
                 platformAutofillManager.notifyViewEntered(
@@ -124,16 +123,15 @@
                 )
             }
         }
-        val previouslySupportedAutofill = config?.getOrNull(SemanticsActions.OnAutofillText) != null
-        if (previousFocus == true && currFocus != true && previouslySupportedAutofill) {
+        if (previousFocus == true && currFocus != true && prevConfig.isAutofillable()) {
             platformAutofillManager.notifyViewExited(view, semanticsId)
         }
 
-        // Update currentlyDisplayedIDs if relevance to Autofill has changed.
-        val prevRelatedToAutofill = prevConfig?.isRelatedToAutofill() ?: false
-        val currRelatedToAutofill = config?.isRelatedToAutofill() ?: false
-        if (prevRelatedToAutofill != currRelatedToAutofill) {
-            if (currRelatedToAutofill) {
+        // Update currentlyDisplayedIDs if relevance to Autocommit has changed.
+        val prevRelatedToAutoCommit = prevConfig?.isRelatedToAutoCommit() == true
+        val currRelatedToAutoCommit = config?.isRelatedToAutoCommit() == true
+        if (prevRelatedToAutoCommit != currRelatedToAutoCommit) {
+            if (currRelatedToAutoCommit) {
                 currentlyDisplayedIDs.add(semanticsId)
             } else {
                 currentlyDisplayedIDs.remove(semanticsId)
@@ -166,8 +164,8 @@
                     return@fastForEach
                 }
 
-                // TODO(b/378160001): For now we only populate autofill-able nodes. Populate the
-                //  structure for all nodes in the future.
+                // TODO(b/378160001): For now we only populate nodes that are relevant for autofill.
+                //  Populate the structure for all nodes in the future.
                 val semanticsConfigurationChild = childInfo.semanticsConfiguration
                 if (semanticsConfigurationChild?.isRelatedToAutofill() != true) {
                     populateChildren.add(childInfo)
@@ -218,7 +216,7 @@
     private var pendingChangesToDisplayedIds = false
 
     internal fun onPostAttach(semanticsInfo: SemanticsInfo) {
-        if (semanticsInfo.semanticsConfiguration?.isRelatedToAutofill() == true) {
+        if (semanticsInfo.semanticsConfiguration?.isRelatedToAutoCommit() == true) {
             currentlyDisplayedIDs.add(semanticsInfo.semanticsId)
             pendingChangesToDisplayedIds = true
             // TODO(MNUZEN): Notify autofill manager that a node has been added.
@@ -231,7 +229,7 @@
         if (currentlyDisplayedIDs.remove(previousSemanticsId)) {
             pendingChangesToDisplayedIds = true
         }
-        if (semanticsInfo.semanticsConfiguration?.isRelatedToAutofill() == true) {
+        if (semanticsInfo.semanticsConfiguration?.isRelatedToAutoCommit() == true) {
             currentlyDisplayedIDs.add(semanticsInfo.semanticsId)
             pendingChangesToDisplayedIds = true
         }
@@ -275,6 +273,15 @@
     }
 }
 
+private fun SemanticsConfiguration.isAutofillable(): Boolean {
+    // TODO add more actions once we add support for Toggle, List, Date etc.
+    return props.contains(SemanticsActions.OnAutofillText)
+}
+
+private fun SemanticsConfiguration.isRelatedToAutoCommit(): Boolean {
+    return props.contains(SemanticsProperties.ContentType)
+}
+
 private fun SemanticsConfiguration.isRelatedToAutofill(): Boolean {
     return props.contains(SemanticsActions.OnAutofillText) ||
         props.contains(SemanticsProperties.ContentType) ||