Read clipboard item mimetype from description
Currently we construct the clipboard model by calling
contentResolver.getType on the main thread, which can cause problems
because that call can hang.
This change switches to reading the mimeType set in the clip description
instead (which should be set correctly per-item).
Bug: 357197236
Flag: com.android.systemui.clipboard_use_description_mimetype
Test: manual with flag on/off, atest ClipboardModelTest
Change-Id: I78550105f9c4f9b3ee1cf69a732b075397cdf4ac
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 02e8cd6..47ddae7 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -582,6 +582,16 @@
}
flag {
+ name: "clipboard_use_description_mimetype"
+ namespace: "systemui"
+ description: "Read item mimetype from description rather than checking URI"
+ bug: "357197236"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "screenshot_action_dismiss_system_windows"
namespace: "systemui"
description: "Dismiss existing system windows when starting action from screenshot UI"
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
index 12597a7..99c026c 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardModel.kt
@@ -24,6 +24,7 @@
import android.util.Log
import android.util.Size
import android.view.textclassifier.TextLinks
+import com.android.systemui.Flags.clipboardUseDescriptionMimetype
import com.android.systemui.res.R
import java.io.IOException
@@ -70,11 +71,11 @@
context: Context,
utils: ClipboardOverlayUtils,
clipData: ClipData,
- source: String
+ source: String,
): ClipboardModel {
val sensitive = clipData.description?.extras?.getBoolean(EXTRA_IS_SENSITIVE) ?: false
val item = clipData.getItemAt(0)!!
- val type = getType(context, item)
+ val type = getType(context, item, clipData.description.getMimeType(0))
val remote = utils.isRemoteCopy(context, clipData, source)
return ClipboardModel(
clipData,
@@ -84,18 +85,26 @@
item.textLinks,
item.uri,
sensitive,
- remote
+ remote,
)
}
- private fun getType(context: Context, item: ClipData.Item): Type {
+ private fun getType(context: Context, item: ClipData.Item, mimeType: String): Type {
return if (!TextUtils.isEmpty(item.text)) {
Type.TEXT
} else if (item.uri != null) {
- if (context.contentResolver.getType(item.uri)?.startsWith("image") == true) {
- Type.IMAGE
+ if (clipboardUseDescriptionMimetype()) {
+ if (mimeType.startsWith("image")) {
+ Type.IMAGE
+ } else {
+ Type.URI
+ }
} else {
- Type.URI
+ if (context.contentResolver.getType(item.uri)?.startsWith("image") == true) {
+ Type.IMAGE
+ } else {
+ Type.URI
+ }
}
} else {
Type.OTHER
@@ -107,6 +116,6 @@
TEXT,
IMAGE,
URI,
- OTHER
+ OTHER,
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
index 5d76e32..85e8ab4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardModelTest.kt
@@ -22,10 +22,12 @@
import android.graphics.Bitmap
import android.net.Uri
import android.os.PersistableBundle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_CLIPBOARD_USE_DESCRIPTION_MIMETYPE
import com.android.systemui.SysuiTestCase
-import com.android.systemui.util.mockito.whenever
import java.io.IOException
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
@@ -37,6 +39,7 @@
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.whenever
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -88,7 +91,8 @@
@Test
@Throws(IOException::class)
- fun test_imageClipData() {
+ @DisableFlags(FLAG_CLIPBOARD_USE_DESCRIPTION_MIMETYPE)
+ fun test_imageClipData_legacy() {
val testBitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888)
whenever(mMockContext.contentResolver).thenReturn(mMockContentResolver)
whenever(mMockContext.resources).thenReturn(mContext.resources)
@@ -103,6 +107,21 @@
@Test
@Throws(IOException::class)
+ @EnableFlags(FLAG_CLIPBOARD_USE_DESCRIPTION_MIMETYPE)
+ fun test_imageClipData() {
+ val testBitmap = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888)
+ whenever(mMockContext.contentResolver).thenReturn(mMockContentResolver)
+ whenever(mMockContext.resources).thenReturn(mContext.resources)
+ whenever(mMockContentResolver.loadThumbnail(any(), any(), any())).thenReturn(testBitmap)
+ whenever(mMockContentResolver.getType(any())).thenReturn("text")
+ val imageClipData = ClipData("Test", arrayOf("image/png"), ClipData.Item(Uri.parse("test")))
+ val model = ClipboardModel.fromClipData(mMockContext, mClipboardUtils, imageClipData, "")
+ assertEquals(ClipboardModel.Type.IMAGE, model.type)
+ assertEquals(testBitmap, model.loadThumbnail(mMockContext))
+ }
+
+ @Test
+ @Throws(IOException::class)
fun test_imageClipData_loadFailure() {
whenever(mMockContext.contentResolver).thenReturn(mMockContentResolver)
whenever(mMockContext.resources).thenReturn(mContext.resources)