summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2023-04-27 20:49:49 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2023-04-27 20:49:49 +0000
commitbe75ef548c4da02c8404aec17b628a3ae8021179 (patch)
tree6d8772bd44e2811327ca5519c03e2c83896d2e08 /java
parente53e9ba00842781ba6d52254e11f051ec79de1c0 (diff)
parentf680044e68571da056b823f2078836656a96ac78 (diff)
Merge "Preview UI: specify metadata columns, change metada reading order" into udc-dev am: f680044e68
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/IntentResolver/+/22902958 Change-Id: I0f3364e2f5fdb60886c2baca99f464ed99e4047e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java21
-rw-r--r--java/tests/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUiTest.kt72
2 files changed, 77 insertions, 16 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
index 69d8c49f..8173d542 100644
--- a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
@@ -37,6 +37,7 @@ import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.intentresolver.widget.ActionRow;
import com.android.intentresolver.widget.ImagePreviewView.TransitionElementStatusCallback;
@@ -52,6 +53,18 @@ import java.util.function.Consumer;
* A content preview façade.
*/
public final class ChooserContentPreviewUi {
+
+ /**
+ * A set of metadata columns we read for a content URI (see [readFileMetadata] method).
+ */
+ @VisibleForTesting
+ static final String[] METADATA_COLUMNS = new String[] {
+ DocumentsContract.Document.COLUMN_FLAGS,
+ MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI,
+ OpenableColumns.DISPLAY_NAME,
+ Downloads.Impl.COLUMN_TITLE
+ };
+
/**
* Delegate to build the default system action buttons to display in the preview layout, if/when
* they're determined to be appropriate for the particular preview we display.
@@ -209,9 +222,9 @@ public final class ChooserContentPreviewUi {
if (typeClassifier.isImageType(mimeType)) {
return builder.withPreviewUri(uri).build();
}
- readFileMetadata(resolver, uri, builder);
+ readOtherFileTypes(resolver, uri, typeClassifier, builder);
if (builder.getPreviewUri() == null) {
- readOtherFileTypes(resolver, uri, typeClassifier, builder);
+ readFileMetadata(resolver, uri, builder);
}
return builder.build();
}
@@ -329,7 +342,7 @@ public final class ChooserContentPreviewUi {
} catch (SecurityException e) {
logProviderPermissionWarning(uri, "mime type");
} catch (Throwable t) {
- Log.e(ContentPreviewUi.TAG, "Failed to read content type, uri: " + uri, t);
+ Log.e(ContentPreviewUi.TAG, "Failed to read content type, uri: " + uri, t);
}
return null;
}
@@ -337,7 +350,7 @@ public final class ChooserContentPreviewUi {
@Nullable
private static Cursor query(ContentInterface resolver, Uri uri) {
try {
- return resolver.query(uri, null, null, null);
+ return resolver.query(uri, METADATA_COLUMNS, null, null);
} catch (SecurityException e) {
logProviderPermissionWarning(uri, "metadata");
} catch (Throwable t) {
diff --git a/java/tests/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUiTest.kt b/java/tests/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUiTest.kt
index f29fac84..63fa8766 100644
--- a/java/tests/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUiTest.kt
+++ b/java/tests/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUiTest.kt
@@ -19,11 +19,15 @@ package com.android.intentresolver.contentpreview
import android.content.ClipDescription
import android.content.ContentInterface
import android.content.Intent
+import android.database.MatrixCursor
import android.graphics.Bitmap
+import android.media.MediaMetadata
import android.net.Uri
+import android.provider.DocumentsContract
import com.android.intentresolver.any
import com.android.intentresolver.anyOrNull
import com.android.intentresolver.contentpreview.ChooserContentPreviewUi.ActionFactory
+import com.android.intentresolver.contentpreview.ChooserContentPreviewUi.METADATA_COLUMNS
import com.android.intentresolver.mock
import com.android.intentresolver.whenever
import com.android.intentresolver.widget.ActionRow
@@ -59,7 +63,7 @@ class ChooserContentPreviewUiTest {
private val transitionCallback = mock<ImagePreviewView.TransitionElementStatusCallback>()
@Test
- fun test_ChooserContentPreview_non_send_intent_action_to_text_preview() {
+ fun test_nonSendIntentAction_useTextPreviewUi() {
val targetIntent = Intent(Intent.ACTION_VIEW)
val testSubject = ChooserContentPreviewUi(
targetIntent,
@@ -76,7 +80,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_text_mime_type_to_text_preview() {
+ fun test_textMimeType_useTextPreviewUi() {
val targetIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Text Extra")
@@ -96,7 +100,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_single_image_uri_to_image_preview() {
+ fun test_singleImageUri_useImagePreviewUi() {
val uri = Uri.parse("content://$PROVIDER_NAME/test.png")
val targetIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
@@ -117,7 +121,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_single_uri_without_preview_to_file_preview() {
+ fun test_singleNonImageUriWithoutPreview_useFilePreviewUi() {
val uri = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
@@ -138,7 +142,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_single_uri_crashing_getType_to_file_preview() {
+ fun test_singleUriWithFailingGetType_useFilePreviewUi() {
val uri = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
@@ -160,7 +164,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_single_uri_crashing_metadata_to_file_preview() {
+ fun test_singleNonImageUriWithFailingMetadata_useFilePreviewUi() {
val uri = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
@@ -185,7 +189,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_single_uri_with_preview_to_image_preview() {
+ fun test_SingleNonImageUriWithImageTypeInGetStreamTypes_useImagePreviewUi() {
val uri = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, uri)
@@ -208,7 +212,52 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_multiple_image_uri_to_image_preview() {
+ fun test_SingleNonImageUriWithThumbnailFlag_useImagePreviewUi() {
+ testMetadataToImagePreview(
+ columns = arrayOf(DocumentsContract.Document.COLUMN_FLAGS),
+ values = arrayOf(
+ DocumentsContract.Document.FLAG_SUPPORTS_THUMBNAIL or
+ DocumentsContract.Document.FLAG_SUPPORTS_METADATA
+ )
+ )
+ }
+
+ @Test
+ fun test_SingleNonImageUriWithMetadataIconUri_useImagePreviewUi() {
+ testMetadataToImagePreview(
+ columns = arrayOf(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI),
+ values = arrayOf("content://$PROVIDER_NAME/test.pdf?thumbnail"),
+ )
+ }
+
+ private fun testMetadataToImagePreview(columns: Array<String>, values: Array<Any>) {
+ val uri = Uri.parse("content://$PROVIDER_NAME/test.pdf")
+ val targetIntent = Intent(Intent.ACTION_SEND).apply {
+ putExtra(Intent.EXTRA_STREAM, uri)
+ }
+ whenever(contentResolver.getType(uri)).thenReturn("application/pdf")
+ whenever(contentResolver.query(uri, METADATA_COLUMNS, null, null))
+ .thenReturn(
+ MatrixCursor(columns).apply {
+ addRow(values)
+ }
+ )
+ val testSubject = ChooserContentPreviewUi(
+ targetIntent,
+ contentResolver,
+ imageClassifier,
+ imageLoader,
+ actionFactory,
+ transitionCallback,
+ headlineGenerator
+ )
+ assertThat(testSubject.preferredContentPreview)
+ .isEqualTo(ContentPreviewType.CONTENT_PREVIEW_IMAGE)
+ verify(transitionCallback, never()).onAllTransitionElementsReady()
+ }
+
+ @Test
+ fun test_multipleImageUri_useImagePreviewUi() {
val uri1 = Uri.parse("content://$PROVIDER_NAME/test.png")
val uri2 = Uri.parse("content://$PROVIDER_NAME/test.jpg")
val targetIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
@@ -237,7 +286,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_some_non_image_uri_to_image_preview() {
+ fun test_SomeImageUri_useImagePreviewUi() {
val uri1 = Uri.parse("content://$PROVIDER_NAME/test.png")
val uri2 = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
@@ -266,7 +315,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_some_non_image_uri_with_preview_to_image_preview() {
+ fun test_someNonImageUriWithPreview_useImagePreviewUi() {
val uri1 = Uri.parse("content://$PROVIDER_NAME/test.mp4")
val uri2 = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
@@ -297,7 +346,7 @@ class ChooserContentPreviewUiTest {
}
@Test
- fun test_ChooserContentPreview_all_non_image_uris_without_preview_to_file_preview() {
+ fun test_allNonImageUrisWithoutPreview_useFilePreviewUi() {
val uri1 = Uri.parse("content://$PROVIDER_NAME/test.html")
val uri2 = Uri.parse("content://$PROVIDER_NAME/test.pdf")
val targetIntent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
@@ -324,5 +373,4 @@ class ChooserContentPreviewUiTest {
.isEqualTo(ContentPreviewType.CONTENT_PREVIEW_FILE)
verify(transitionCallback, times(1)).onAllTransitionElementsReady()
}
-
}