Don't do special handling for clearFocus on API 27 and below

Bug: 318968220
Fixes: 350534714

This reverts aosp/2928744 because it is causing problems when
focus first arrives into the ComposeView.

When the IME has a NEXT action from an external View, it
can arrive into the ComposeView's requestFocus() with
isInTouchMode = true. We can't distinguish this behavior
from the clearFocus() behavior that aosp/2928744 was
trying to fix.

Test: new test

Change-Id: I99d9d63c6007823dd7be203ce968496e6c0feb9e
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
index 7fda49e..08b702e 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusManagerCompositionLocalTest.kt
@@ -18,7 +18,6 @@
 
 import android.view.View
 import androidx.compose.foundation.layout.Box
-import androidx.compose.material.TextField
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusStateImpl.Active
@@ -30,13 +29,8 @@
 import androidx.compose.ui.platform.LocalFocusManager
 import androidx.compose.ui.platform.LocalInputModeManager
 import androidx.compose.ui.platform.LocalView
-import androidx.compose.ui.platform.testTag
-import androidx.compose.ui.test.assertIsFocused
-import androidx.compose.ui.test.assertIsNotFocused
 import androidx.compose.ui.test.junit4.ComposeContentTestRule
 import androidx.compose.ui.test.junit4.createComposeRule
-import androidx.compose.ui.test.onNodeWithTag
-import androidx.compose.ui.test.requestFocus
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
 import com.google.common.truth.Truth.assertThat
@@ -345,25 +339,6 @@
         }
     }
 
-    @Test
-    fun clearFocus_textFieldLosesFocus() {
-        // Arrange.
-        val textField = "textField"
-        rule.setTestContent(extraItemForInitialFocus = false) {
-            TextField(value = "", onValueChange = {}, modifier = Modifier.testTag(textField))
-        }
-        rule.onNodeWithTag(textField).requestFocus()
-
-        // Act.
-        rule.runOnIdle { focusManager.clearFocus() }
-
-        // Assert.
-        when (inputModeManager.inputMode) {
-            Keyboard -> rule.onNodeWithTag(textField).assertIsFocused()
-            Touch -> rule.onNodeWithTag(textField).assertIsNotFocused()
-        }
-    }
-
     private val FocusManager.rootFocusState: FocusState
         get() = (this as FocusOwnerImpl).rootFocusNode.focusState
 
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
index d4aebb8..6569265 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/focus/FocusTransactionsTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.focus
 
+import android.os.Build
 import android.view.View
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.size
@@ -163,8 +164,15 @@
                     assertThat(view.isFocused).isTrue()
                 }
                 Touch -> {
-                    assertThat(root.focusOwner.rootState).isEqualTo(Inactive)
-                    assertThat(view.isFocused).isFalse()
+                    // On devices pre-P, clearFocus() will cause a subsequent requestFocus()
+                    // the causes another request for focus on the ComposeView.
+                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+                        assertThat(root.focusOwner.rootState).isEqualTo(ActiveParent)
+                        assertThat(view.isFocused).isTrue()
+                    } else {
+                        assertThat(root.focusOwner.rootState).isEqualTo(Inactive)
+                        assertThat(view.isFocused).isFalse()
+                    }
                 }
                 else -> error("invalid input mode")
             }
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/viewinterop/FocusSearchForwardInteropTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/viewinterop/FocusSearchForwardInteropTest.kt
index a599981..c34238f 100644
--- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/viewinterop/FocusSearchForwardInteropTest.kt
+++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/viewinterop/FocusSearchForwardInteropTest.kt
@@ -20,11 +20,16 @@
 import android.view.KeyEvent as AndroidKeyEvent
 import android.view.KeyEvent.ACTION_DOWN
 import android.view.View
+import android.view.inputmethod.EditorInfo
+import android.widget.EditText
 import android.widget.LinearLayout
 import androidx.compose.foundation.focusable
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.safeContentPadding
 import androidx.compose.foundation.layout.size
+import androidx.compose.material.TextField
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusDirection
@@ -631,6 +636,46 @@
         rule.onNodeWithTag(composable).assertIsNotFocused()
     }
 
+    @Test
+    fun focusableInTouchMode() {
+        val tag = "tag"
+        lateinit var editText: EditText
+        lateinit var composeView: ComposeView
+        setContent {
+            AndroidView(
+                {
+                    LinearLayout(it).also { linearLayout ->
+                        linearLayout.orientation = LinearLayout.VERTICAL
+                        linearLayout.addView(EditText(linearLayout.context))
+                        editText = EditText(linearLayout.context)
+                        editText.setSingleLine()
+                        editText.setText("1")
+                        editText.inputType = EditorInfo.TYPE_NUMBER_VARIATION_NORMAL
+                        editText.imeOptions = EditorInfo.IME_FLAG_NAVIGATE_NEXT
+                        linearLayout.addView(editText)
+                        composeView =
+                            ComposeView(linearLayout.context).apply {
+                                setContent {
+                                    Column { TextField("Hello World", {}, Modifier.testTag(tag)) }
+                                }
+                            }
+                        linearLayout.addView(composeView)
+                    }
+                },
+                Modifier.safeContentPadding()
+            )
+        }
+        rule.runOnIdle {
+            val instrumentation = InstrumentationRegistry.getInstrumentation()
+            instrumentation.setInTouchMode(true)
+            editText.requestFocusFromTouch()
+        }
+        rule.waitUntil { rule.runOnUiThread { editText.isFocused } }
+        rule.waitForIdle()
+        rule.runOnIdle { editText.onEditorAction(EditorInfo.IME_ACTION_NEXT) }
+        rule.onNodeWithTag(tag).assertIsFocused()
+    }
+
     private fun ComposeContentTestRule.focusSearchForward(waitForIdle: Boolean = true) {
         if (waitForIdle) waitForIdle()
         if (moveFocusProgrammatically) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
index 9961afd..5a2b22d 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidComposeView.android.kt
@@ -916,11 +916,6 @@
             return super.requestFocus(direction, previouslyFocusedRect)
         }
 
-        // When we clear focus on Pre P devices, request focus is called even when we are
-        // in touch mode. We fix this by assigning initial focus only in non-touch mode.
-        // https://developer.android.com/about/versions/pie/android-9.0-changes-28#focus
-        if (isInTouchMode) return false
-
         val focusDirection = toFocusDirection(direction) ?: Enter
         return focusOwner.focusSearch(
             focusDirection = focusDirection,