Revert "Revert "Add hasText in ClipboardManager""

This reverts commit e192760bd86b8cdd261dbbc776eab2cba69f31c6.

Reason for revert: <We have bumped to 1.4.0-alpha>

Bug: b/249506376
Change-Id: I55aab65faeec908e2883e0dff3c9ceb3d2a2d7f6
diff --git a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
index 8e9881a..1e972ee 100644
--- a/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
+++ b/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManager.kt
@@ -645,7 +645,7 @@
             }
         } else null
 
-        val paste: (() -> Unit)? = if (editable && clipboardManager?.getText() != null) {
+        val paste: (() -> Unit)? = if (editable && clipboardManager?.hasText() == true) {
             {
                 paste()
                 hideSelectionToolbar()
diff --git a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
index f4926c9..5bdc120 100644
--- a/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
+++ b/compose/foundation/foundation/src/test/kotlin/androidx/compose/foundation/text/selection/TextFieldSelectionManagerTest.kt
@@ -510,7 +510,8 @@
     }
 
     @Test
-    fun showSelectionToolbar_trigger_textToolbar_showMenu_Clipboard_empty_not_show_paste() {
+    fun showSelectionToolbar_trigger_textToolbar_showMenu_noText_inClipboard_not_show_paste() {
+        whenever(clipboardManager.hasText()).thenReturn(false)
         manager.value = TextFieldValue(
             text = text + text,
             selection = TextRange("Hello".length, text.length)
@@ -522,8 +523,23 @@
     }
 
     @Test
+    fun showSelectionToolbar_trigger_textToolbar_showMenu_hasText_inClipboard_show_paste() {
+        whenever(clipboardManager.hasText()).thenReturn(true)
+        manager.value = TextFieldValue(
+            text = text + text,
+            selection = TextRange("Hello".length, text.length)
+        )
+
+        manager.showSelectionToolbar()
+
+        verify(textToolbar, times(1))
+            .showMenu(anyOrNull(), anyOrNull(), any(), anyOrNull(), anyOrNull())
+    }
+
+    @Test
     fun showSelectionToolbar_trigger_textToolbar_showMenu_selection_collapse_not_show_copy_cut() {
         whenever(clipboardManager.getText()).thenReturn(AnnotatedString(text))
+        whenever(clipboardManager.hasText()).thenReturn(true)
         manager.value = TextFieldValue(
             text = text + text,
             selection = TextRange(0, 0)
@@ -536,7 +552,7 @@
 
     @Test
     fun showSelectionToolbar_trigger_textToolbar_showMenu_no_text_show_paste_only() {
-        whenever(clipboardManager.getText()).thenReturn(AnnotatedString(text))
+        whenever(clipboardManager.hasText()).thenReturn(true)
         manager.value = TextFieldValue()
 
         manager.showSelectionToolbar()
@@ -547,6 +563,7 @@
     @Test
     fun showSelectionToolbar_trigger_textToolbar_no_menu() {
         whenever(clipboardManager.getText()).thenReturn(null)
+        whenever(clipboardManager.hasText()).thenReturn(false)
         manager.value = TextFieldValue()
 
         manager.showSelectionToolbar()
@@ -558,6 +575,7 @@
     fun showSelectionToolbar_passwordTextField_not_show_copy_cut() {
         manager.visualTransformation = PasswordVisualTransformation()
         whenever(clipboardManager.getText()).thenReturn(AnnotatedString(text))
+        whenever(clipboardManager.hasText()).thenReturn(true)
         manager.value = TextFieldValue(text, TextRange(0, 5))
 
         manager.showSelectionToolbar()
diff --git a/compose/ui/ui/api/current.txt b/compose/ui/ui/api/current.txt
index 4e271a5..afad798 100644
--- a/compose/ui/ui/api/current.txt
+++ b/compose/ui/ui/api/current.txt
@@ -2359,6 +2359,7 @@
 
   public interface ClipboardManager {
     method public androidx.compose.ui.text.AnnotatedString? getText();
+    method public default boolean hasText();
     method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
   }
 
diff --git a/compose/ui/ui/api/public_plus_experimental_current.txt b/compose/ui/ui/api/public_plus_experimental_current.txt
index 018383f..9d06549 100644
--- a/compose/ui/ui/api/public_plus_experimental_current.txt
+++ b/compose/ui/ui/api/public_plus_experimental_current.txt
@@ -2652,6 +2652,7 @@
 
   public interface ClipboardManager {
     method public androidx.compose.ui.text.AnnotatedString? getText();
+    method public default boolean hasText();
     method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
   }
 
diff --git a/compose/ui/ui/api/restricted_current.txt b/compose/ui/ui/api/restricted_current.txt
index 8fdcef9..4e7508e 100644
--- a/compose/ui/ui/api/restricted_current.txt
+++ b/compose/ui/ui/api/restricted_current.txt
@@ -2398,6 +2398,7 @@
 
   public interface ClipboardManager {
     method public androidx.compose.ui.text.AnnotatedString? getText();
+    method public default boolean hasText();
     method public void setText(androidx.compose.ui.text.AnnotatedString annotatedString);
   }
 
diff --git a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
index f2df005..1411e53 100644
--- a/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
+++ b/compose/ui/ui/src/androidAndroidTest/kotlin/androidx/compose/ui/platform/AndroidClipboardManagerTest.kt
@@ -16,6 +16,7 @@
 
 package androidx.compose.ui.platform
 
+import android.content.ClipDescription
 import android.content.ClipboardManager
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
@@ -212,8 +213,38 @@
         whenever(clipboardManager.primaryClip).thenReturn(null)
         val subject = AndroidClipboardManager(clipboardManager)
 
-        val actual = subject.getText()
-        assertThat(actual).isNull()
+        assertThat(subject.getText()).isNull()
+    }
+
+    @Test
+    fun hasText_whenHasPrimaryClipDescription_Text_returnsTrue() {
+        val clipboardManager = mock<ClipboardManager>()
+        val clipDescription = mock<ClipDescription>()
+        whenever(clipboardManager.primaryClipDescription).thenReturn(clipDescription)
+        whenever(clipDescription.hasMimeType("text/*")).thenReturn(true)
+        val subject = AndroidClipboardManager(clipboardManager)
+
+        assertThat(subject.hasText()).isTrue()
+    }
+
+    @Test
+    fun hasText_whenHasPrimaryClipDescription_notText_returnsFalse() {
+        val clipboardManager = mock<ClipboardManager>()
+        val clipDescription = mock<ClipDescription>()
+        whenever(clipboardManager.primaryClipDescription).thenReturn(clipDescription)
+        whenever(clipDescription.hasMimeType("text/*")).thenReturn(false)
+        val subject = AndroidClipboardManager(clipboardManager)
+
+        assertThat(subject.hasText()).isFalse()
+    }
+
+    @Test
+    fun hasText_whenNoPrimaryClipDescription_returnsFalse() {
+        val clipboardManager = mock<ClipboardManager>()
+        whenever(clipboardManager.primaryClipDescription).thenReturn(null)
+        val subject = AndroidClipboardManager(clipboardManager)
+
+        assertThat(subject.hasText()).isFalse()
     }
 
     private fun assertEncodeAndDecode(spanStyle: SpanStyle) {
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
index d6bd8de..445b00b 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidClipboardManager.android.kt
@@ -17,7 +17,6 @@
 package androidx.compose.ui.platform
 
 import android.content.ClipData
-import android.content.ClipDescription.MIMETYPE_TEXT_PLAIN
 import android.content.Context
 import android.os.Parcel
 import android.text.Annotation
@@ -75,8 +74,8 @@
         }
     }
 
-    fun hasText() =
-        clipboardManager.primaryClipDescription?.hasMimeType(MIMETYPE_TEXT_PLAIN) ?: false
+    override fun hasText() =
+        clipboardManager.primaryClipDescription?.hasMimeType("text/*") ?: false
 }
 
 internal fun CharSequence?.convertToAnnotatedString(): AnnotatedString? {
diff --git a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
index 470daf2..71ccac7 100644
--- a/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
+++ b/compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/ClipboardManager.kt
@@ -27,6 +27,7 @@
      *
      * @param annotatedString The [AnnotatedString] to be put into Clipboard.
      */
+    @Suppress("GetterSetterNames")
     fun setText(annotatedString: AnnotatedString)
 
     /**
@@ -37,4 +38,9 @@
      * [CharSequence] text in Clipboard to [AnnotatedString].
      */
     fun getText(): AnnotatedString?
+
+    /**
+     * This method returns true if there is a text in the Clipboard, false otherwise.
+     */
+    fun hasText(): Boolean = getText()?.isNotEmpty() == true
 }
diff --git a/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
new file mode 100644
index 0000000..48c769f
--- /dev/null
+++ b/compose/ui/ui/src/test/kotlin/androidx/compose/ui/platform/ClipboardManagerTest.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.ui.platform
+
+import androidx.compose.ui.text.AnnotatedString
+import org.junit.Test
+import com.google.common.truth.Truth.assertThat
+
+class ClipboardManagerTest {
+
+    @Test
+    fun clipboardManagerWithoutHasText_returnsTrue_withNonEmptyGetText() {
+        val clipboardManager = object : ClipboardManager {
+            override fun setText(annotatedString: AnnotatedString) { }
+            override fun getText() = AnnotatedString("Something")
+        }
+        assertThat(clipboardManager.hasText()).isTrue()
+    }
+
+    @Test
+    fun clipboardManagerWithoutHasText_returnsFalse_withNullGetText() {
+        val clipboardManager = object : ClipboardManager {
+            override fun setText(annotatedString: AnnotatedString) { }
+            override fun getText() = null
+        }
+        assertThat(clipboardManager.hasText()).isFalse()
+    }
+
+    @Test
+    fun clipboardManagerWithoutHasText_returnsFalse_withEmptyGetText() {
+        val clipboardManager = object : ClipboardManager {
+            override fun setText(annotatedString: AnnotatedString) { }
+            override fun getText() = AnnotatedString("")
+        }
+        assertThat(clipboardManager.hasText()).isFalse()
+    }
+}
\ No newline at end of file