summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2023-04-11 17:21:22 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-04-11 17:21:22 +0000
commit11b9cf84dc1c3a8bf1add401423e48cb44293a10 (patch)
tree9820a39d7de64f4c17eca4bfd96c2155161ed31d /java
parentfc7ddd61dd62105dae67594517b9344afca163ff (diff)
parent8ae8c4a3f25cc5c0da3196fa0a3f0f07dfe87066 (diff)
Merge "Hide thumbnail prview if no preview has loaded" into udc-dev
Diffstat (limited to 'java')
-rw-r--r--java/res/layout/chooser_grid_preview_image.xml9
-rw-r--r--java/res/values/dimens.xml1
-rw-r--r--java/src/com/android/intentresolver/contentpreview/UnifiedContentPreviewUi.java15
-rw-r--r--java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt15
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java5
-rw-r--r--java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java6
-rw-r--r--java/tests/src/com/android/intentresolver/TestPreviewImageLoader.kt12
-rw-r--r--java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java131
8 files changed, 145 insertions, 49 deletions
diff --git a/java/res/layout/chooser_grid_preview_image.xml b/java/res/layout/chooser_grid_preview_image.xml
index 43f6f4d1..2cfab2a8 100644
--- a/java/res/layout/chooser_grid_preview_image.xml
+++ b/java/res/layout/chooser_grid_preview_image.xml
@@ -32,7 +32,9 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal"
- android:layout_marginBottom="@dimen/chooser_view_spacing">
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
+ android:paddingStart="@dimen/chooser_edge_margin_normal_half"
+ android:paddingEnd="@dimen/chooser_edge_margin_normal_half">
<com.android.intentresolver.widget.ScrollableImagePreviewView
android:id="@+id/scrollable_image_preview"
@@ -42,7 +44,7 @@
android:layout_marginBottom="@dimen/chooser_view_spacing"
android:background="?android:attr/colorBackground"
app:itemInnerSpacing="3dp"
- app:itemOuterSpacing="@dimen/chooser_edge_margin_normal"
+ app:itemOuterSpacing="@dimen/chooser_edge_margin_normal_half"
app:maxWidthHint="@dimen/chooser_width" />
<TextView
@@ -51,7 +53,8 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
- android:paddingEnd="@dimen/chooser_edge_margin_normal"
+ android:layout_marginStart="@dimen/chooser_edge_margin_normal_half"
+ android:layout_marginEnd="@dimen/chooser_edge_margin_normal_half"
android:maxLines="6"
android:ellipsize="end"
android:linksClickable="false"
diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml
index 44fc3c38..8636f742 100644
--- a/java/res/values/dimens.xml
+++ b/java/res/values/dimens.xml
@@ -24,6 +24,7 @@
<dimen name="chooser_view_spacing">18dp</dimen>
<dimen name="chooser_edge_margin_thin">8dp</dimen>
<dimen name="chooser_edge_margin_normal">24dp</dimen>
+ <dimen name="chooser_edge_margin_normal_half">12dp</dimen>
<dimen name="chooser_preview_image_font_size">20sp</dimen>
<dimen name="chooser_preview_image_border">1dp</dimen>
<dimen name="chooser_preview_image_width">120dp</dimen>
diff --git a/java/src/com/android/intentresolver/contentpreview/UnifiedContentPreviewUi.java b/java/src/com/android/intentresolver/contentpreview/UnifiedContentPreviewUi.java
index 748f7421..2e6ecb0e 100644
--- a/java/src/com/android/intentresolver/contentpreview/UnifiedContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/contentpreview/UnifiedContentPreviewUi.java
@@ -91,6 +91,7 @@ class UnifiedContentPreviewUi extends ContentPreviewUi {
R.layout.chooser_grid_preview_image, parent, false);
ScrollableImagePreviewView imagePreview =
contentPreviewLayout.findViewById(R.id.scrollable_image_preview);
+ imagePreview.setOnNoPreviewCallback(() -> imagePreview.setVisibility(View.GONE));
final ActionRow actionRow =
contentPreviewLayout.findViewById(com.android.internal.R.id.chooser_action_row);
@@ -132,7 +133,7 @@ class UnifiedContentPreviewUi extends ContentPreviewUi {
mImageLoader);
if (!TextUtils.isEmpty(mText) && mFiles.size() == 1 && allImages) {
- setTextInImagePreviewVisibility(contentPreviewLayout, mActionFactory);
+ setTextInImagePreviewVisibility(contentPreviewLayout, imagePreview, mActionFactory);
updateTextWithImageHeadline(contentPreviewLayout);
} else {
if (allImages) {
@@ -175,7 +176,9 @@ class UnifiedContentPreviewUi extends ContentPreviewUi {
}
private void setTextInImagePreviewVisibility(
- ViewGroup contentPreview, ChooserContentPreviewUi.ActionFactory actionFactory) {
+ ViewGroup contentPreview,
+ ScrollableImagePreviewView imagePreview,
+ ChooserContentPreviewUi.ActionFactory actionFactory) {
final TextView textView = contentPreview
.requireViewById(com.android.internal.R.id.content_preview_text);
CheckBox actionView = contentPreview
@@ -194,8 +197,12 @@ class UnifiedContentPreviewUi extends ContentPreviewUi {
shareTextAction.accept(false);
actionView.setOnCheckedChangeListener((view, isChecked) -> {
view.setText(actionLabels[isChecked ? 1 : 0]);
- TransitionManager.beginDelayedTransition((ViewGroup) textView.getParent());
- textView.setVisibility(isChecked ? View.VISIBLE : View.GONE);
+ textView.setEnabled(isChecked);
+ if (imagePreview.getVisibility() == View.VISIBLE) {
+ // animate only only if we have preview
+ TransitionManager.beginDelayedTransition((ViewGroup) textView.getParent());
+ textView.setVisibility(isChecked ? View.VISIBLE : View.GONE);
+ }
shareTextAction.accept(!isChecked);
updateTextWithImageHeadline(contentPreview);
});
diff --git a/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt b/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt
index d1b0f5b4..8dcaacb8 100644
--- a/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt
+++ b/java/src/com/android/intentresolver/widget/ScrollableImagePreviewView.kt
@@ -40,6 +40,7 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
@@ -129,13 +130,18 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView {
imageLoader,
previews,
otherItemCount,
- ).apply {
+ ) {
+ onNoPreviewCallback?.run()
+ }
+ .apply {
if (isMeasured) {
loadAspectRatios(getMaxWidth(), this@ScrollableImagePreviewView::calcPreviewWidth)
}
}
}
+ var onNoPreviewCallback: Runnable? = null
+
private fun getMaxWidth(): Int =
when {
maxWidthHint > 0 -> maxWidthHint
@@ -187,6 +193,7 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView {
private var totalItemCount: Int = 0
private val hasOtherItem get() = previews.size < totalItemCount
+ val hasPreviews: Boolean get() = previews.isNotEmpty()
var transitionStatusElementCallback: TransitionElementStatusCallback? = null
@@ -369,6 +376,7 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView {
private val imageLoader: ImageLoader,
previews: List<Preview>,
otherItemCount: Int,
+ private val onNoPreviewCallback: (() -> Unit)
) {
private val pendingPreviews = ArrayDeque<Preview>(previews)
private val totalItemCount = previews.size + otherItemCount
@@ -393,6 +401,11 @@ class ScrollableImagePreviewView : RecyclerView, ImagePreviewView {
reportFlow
.takeWhile { it !== completedEvent }
.throttle(ADAPTER_UPDATE_INTERVAL_MS)
+ .onCompletion { cause ->
+ if (cause == null && !adapter.hasPreviews) {
+ onNoPreviewCallback()
+ }
+ }
.collect {
if (isFirstUpdate) {
isFirstUpdate = false
diff --git a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
index f9093b8f..2a4d654a 100644
--- a/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
+++ b/java/tests/src/com/android/intentresolver/ChooserActivityOverrideData.java
@@ -24,7 +24,6 @@ import static org.mockito.Mockito.when;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.os.UserHandle;
import com.android.intentresolver.AbstractMultiProfilePagerAdapter.CrossProfileIntentsChecker;
@@ -64,7 +63,7 @@ public class ChooserActivityOverrideData {
public boolean isImageType;
public Cursor resolverCursor;
public boolean resolverForceException;
- public Bitmap previewThumbnail;
+ public ImageLoader imageLoader;
public ChooserActivityLogger chooserActivityLogger;
public int alternateProfileSetting;
public Resources resources;
@@ -83,7 +82,7 @@ public class ChooserActivityOverrideData {
onSafelyStartInternalCallback = null;
isVoiceInteraction = null;
createPackageManager = null;
- previewThumbnail = null;
+ imageLoader = null;
isImageType = false;
resolverCursor = null;
resolverForceException = false;
diff --git a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
index 8886892f..dc9baade 100644
--- a/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
+++ b/java/tests/src/com/android/intentresolver/ChooserWrapperActivity.java
@@ -194,9 +194,9 @@ public class ChooserWrapperActivity
@Override
protected ImageLoader createPreviewImageLoader() {
- return new TestPreviewImageLoader(
- super.createPreviewImageLoader(),
- () -> sOverrides.previewThumbnail);
+ return sOverrides.imageLoader == null
+ ? super.createPreviewImageLoader()
+ : sOverrides.imageLoader;
}
@Override
diff --git a/java/tests/src/com/android/intentresolver/TestPreviewImageLoader.kt b/java/tests/src/com/android/intentresolver/TestPreviewImageLoader.kt
index cfe041dd..2f240d58 100644
--- a/java/tests/src/com/android/intentresolver/TestPreviewImageLoader.kt
+++ b/java/tests/src/com/android/intentresolver/TestPreviewImageLoader.kt
@@ -21,18 +21,12 @@ import android.net.Uri
import java.util.function.Consumer
internal class TestPreviewImageLoader(
- private val imageLoader: ImageLoader,
- private val imageOverride: () -> Bitmap?
+ private val bitmaps: Map<Uri, Bitmap>
) : ImageLoader {
override fun loadImage(uri: Uri, callback: Consumer<Bitmap?>) {
- val override = imageOverride()
- if (override != null) {
- callback.accept(override)
- } else {
- imageLoader.loadImage(uri, callback)
- }
+ callback.accept(bitmaps[uri])
}
- override suspend fun invoke(uri: Uri): Bitmap? = imageOverride() ?: imageLoader(uri)
+ override suspend fun invoke(uri: Uri): Bitmap? = bitmaps[uri]
override fun prePopulate(uris: List<Uri>) = Unit
}
diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
index 39357a4d..0a60b8c7 100644
--- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
+++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java
@@ -26,6 +26,7 @@ import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasSibling;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
@@ -125,6 +126,7 @@ import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -422,10 +424,12 @@ public class UnbundledChooserActivityTest {
@Test
public void visiblePreviewTitleAndThumbnail() throws InterruptedException {
String previewTitle = "My Content Preview Title";
- Intent sendIntent = createSendTextIntentWithPreview(previewTitle,
- Uri.parse("android.resource://com.android.frameworks.coretests/"
- + R.drawable.test320x240));
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendTextIntentWithPreview(previewTitle, uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
setupResolverControllers(resolvedComponentInfos);
@@ -688,10 +692,12 @@ public class UnbundledChooserActivityTest {
@Test
public void testImagePlusTextSharing_ExcludeText() {
- Intent sendIntent = createSendImageIntent(
- Uri.parse("android.resource://com.android.frameworks.coretests/"
- + R.drawable.test320x240));
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendImageIntent(uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://google.com/search?q=google");
@@ -728,10 +734,12 @@ public class UnbundledChooserActivityTest {
@Test
public void testImagePlusTextSharing_RemoveAndAddBackText() {
- Intent sendIntent = createSendImageIntent(
- Uri.parse("android.resource://com.android.frameworks.coretests/"
- + R.drawable.test320x240));
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendImageIntent(uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
final String text = "https://google.com/search?q=google";
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
@@ -772,10 +780,12 @@ public class UnbundledChooserActivityTest {
@Test
public void testImagePlusTextSharing_TextExclusionDoesNotAffectAlternativeIntent() {
- Intent sendIntent = createSendImageIntent(
- Uri.parse("android.resource://com.android.frameworks.coretests/"
- + R.drawable.test320x240));
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendImageIntent(uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
sendIntent.putExtra(Intent.EXTRA_TEXT, "https://google.com/search?q=google");
@@ -815,6 +825,42 @@ public class UnbundledChooserActivityTest {
}
@Test
+ public void testImagePlusTextSharing_failedThumbnailAndExcludedText_textRemainsVisible() {
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendImageIntent(uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ new TestPreviewImageLoader(Collections.emptyMap());
+ ChooserActivityOverrideData.getInstance().isImageType = true;
+ sendIntent.putExtra(Intent.EXTRA_TEXT, "https://google.com/search?q=google");
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = Arrays.asList(
+ ResolverDataProvider.createResolvedComponentInfo(
+ new ComponentName("org.imageviewer", "ImageTarget"),
+ sendIntent, PERSONAL_USER_HANDLE),
+ ResolverDataProvider.createResolvedComponentInfo(
+ new ComponentName("org.textviewer", "UriTarget"),
+ new Intent("VIEW_TEXT"), PERSONAL_USER_HANDLE)
+ );
+
+ setupResolverControllers(resolvedComponentInfos);
+
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+
+ onView(withId(R.id.include_text_action))
+ .check(matches(isDisplayed()))
+ .perform(click());
+ waitForIdle();
+
+ onView(withId(R.id.scrollable_image_preview))
+ .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
+ onView(withId(com.android.internal.R.id.content_preview_text))
+ .check(matches(allOf(isDisplayed(), not(isEnabled()))));
+ }
+
+ @Test
public void copyTextToClipboard() throws Exception {
Intent sendIntent = createSendTextIntent();
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -879,11 +925,12 @@ public class UnbundledChooserActivityTest {
@Test @Ignore
public void testEditImageLogs() throws Exception {
- Intent sendIntent = createSendImageIntent(
- Uri.parse("android.resource://com.android.frameworks.coretests/"
- + R.drawable.test320x240));
-
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ Uri uri = Uri.parse(
+ "android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+ Intent sendIntent = createSendImageIntent(uri);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -910,7 +957,8 @@ public class UnbundledChooserActivityTest {
uris.add(uri);
Intent sendIntent = createSendUriIntentWithPreview(uris);
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -933,6 +981,29 @@ public class UnbundledChooserActivityTest {
}
@Test
+ public void allThumbnailsFailedToLoad_hidePreview() {
+ Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ + R.drawable.test320x240);
+
+ ArrayList<Uri> uris = new ArrayList<>();
+ uris.add(uri);
+ uris.add(uri);
+
+ Intent sendIntent = createSendUriIntentWithPreview(uris);
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ new TestPreviewImageLoader(Collections.emptyMap());
+ ChooserActivityOverrideData.getInstance().isImageType = true;
+
+ List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+ setupResolverControllers(resolvedComponentInfos);
+ mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
+ waitForIdle();
+ onView(withId(R.id.scrollable_image_preview))
+ .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
+ }
+
+ @Test
public void testManyVisibleImagePreview_ScrollableImagePreview() {
Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/"
+ R.drawable.test320x240);
@@ -950,7 +1021,8 @@ public class UnbundledChooserActivityTest {
uris.add(uri);
Intent sendIntent = createSendUriIntentWithPreview(uris);
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -980,7 +1052,8 @@ public class UnbundledChooserActivityTest {
Intent sendIntent = createSendUriIntentWithPreview(uris);
sendIntent.putExtra(Intent.EXTRA_TEXT, sharedText);
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -1004,7 +1077,8 @@ public class UnbundledChooserActivityTest {
Intent sendIntent = createSendUriIntentWithPreview(uris);
sendIntent.putExtra(Intent.EXTRA_TEXT, sharedText);
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -1093,7 +1167,8 @@ public class UnbundledChooserActivityTest {
uris.add(uri);
Intent sendIntent = createSendUriIntentWithPreview(uris);
- ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap();
+ ChooserActivityOverrideData.getInstance().imageLoader =
+ createImageLoader(uri, createBitmap());
ChooserActivityOverrideData.getInstance().isImageType = true;
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -2866,4 +2941,8 @@ public class UnbundledChooserActivityTest {
};
return shortcutLoaders;
}
+
+ private static ImageLoader createImageLoader(Uri uri, Bitmap bitmap) {
+ return new TestPreviewImageLoader(Collections.singletonMap(uri, bitmap));
+ }
}