diff options
| author | 2023-02-04 00:19:55 +0000 | |
|---|---|---|
| committer | 2023-02-04 00:19:55 +0000 | |
| commit | 3d094b80389b2386b9f724217ef593dc64a3ca8b (patch) | |
| tree | d5bd64546039ae0c3cbcb49ad55307b998aec41f /java | |
| parent | 3fd3c66efa00ed9da270e85753defa666bb9af62 (diff) | |
| parent | 150f8b476d622b592ce9192aed2e106076f2f67e (diff) | |
Merge "Enable scrollable image preview view" into tm-qpr-dev
Diffstat (limited to 'java')
| -rw-r--r-- | java/res/layout/chooser_grid_preview_image.xml | 6 | ||||
| -rw-r--r-- | java/res/layout/chooser_image_preview_view.xml | 24 | ||||
| -rw-r--r-- | java/res/layout/chooser_image_preview_view_internals.xml (renamed from java/res/layout/image_preview_view.xml) | 0 | ||||
| -rw-r--r-- | java/res/layout/scrollable_image_preview_view.xml | 24 | ||||
| -rw-r--r-- | java/src/com/android/intentresolver/ChooserContentPreviewUi.java | 17 | ||||
| -rw-r--r-- | java/src/com/android/intentresolver/flags/Flags.kt | 6 | ||||
| -rw-r--r-- | java/src/com/android/intentresolver/widget/ChooserImagePreviewView.kt | 3 | ||||
| -rw-r--r-- | java/tests/Android.bp | 7 | ||||
| -rw-r--r-- | java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt | 30 | ||||
| -rw-r--r-- | java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java | 134 |
10 files changed, 194 insertions, 57 deletions
diff --git a/java/res/layout/chooser_grid_preview_image.xml b/java/res/layout/chooser_grid_preview_image.xml index d43a26de..6af0af11 100644 --- a/java/res/layout/chooser_grid_preview_image.xml +++ b/java/res/layout/chooser_grid_preview_image.xml @@ -16,7 +16,6 @@ * limitations under the License. */ --> -<!-- Layout Option: Supporting up to 3 images for preview --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" @@ -32,8 +31,9 @@ android:gravity="center_horizontal" android:layout_marginBottom="@dimen/chooser_view_spacing"> - <com.android.intentresolver.widget.ChooserImagePreviewView - android:id="@androidprv:id/content_preview_image_area" + <ViewStub + android:id="@+id/image_preview_stub" + android:inflatedId="@androidprv:id/content_preview_image_area" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingStart="@dimen/chooser_edge_margin_normal" diff --git a/java/res/layout/chooser_image_preview_view.xml b/java/res/layout/chooser_image_preview_view.xml new file mode 100644 index 00000000..a111b923 --- /dev/null +++ b/java/res/layout/chooser_image_preview_view.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<com.android.intentresolver.widget.ChooserImagePreviewView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:paddingBottom="@dimen/chooser_view_spacing" + android:background="?android:attr/colorBackground" /> diff --git a/java/res/layout/image_preview_view.xml b/java/res/layout/chooser_image_preview_view_internals.xml index 8730fc30..8730fc30 100644 --- a/java/res/layout/image_preview_view.xml +++ b/java/res/layout/chooser_image_preview_view_internals.xml diff --git a/java/res/layout/scrollable_image_preview_view.xml b/java/res/layout/scrollable_image_preview_view.xml new file mode 100644 index 00000000..ff2f273f --- /dev/null +++ b/java/res/layout/scrollable_image_preview_view.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!-- + ~ Copyright (C) 2023 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. + --> + +<com.android.intentresolver.widget.ScrollableImagePreviewView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:paddingBottom="@dimen/chooser_view_spacing" + android:background="?android:attr/colorBackground" /> diff --git a/java/src/com/android/intentresolver/ChooserContentPreviewUi.java b/java/src/com/android/intentresolver/ChooserContentPreviewUi.java index 553a36c6..9bef3553 100644 --- a/java/src/com/android/intentresolver/ChooserContentPreviewUi.java +++ b/java/src/com/android/intentresolver/ChooserContentPreviewUi.java @@ -363,8 +363,7 @@ public final class ChooserContentPreviewUi { @LayoutRes int actionRowLayout) { ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate( R.layout.chooser_grid_preview_image, parent, false); - ImagePreviewView imagePreview = contentPreviewLayout.findViewById( - com.android.internal.R.id.content_preview_image_area); + ImagePreviewView imagePreview = inflateImagePreviewView(contentPreviewLayout); final ActionRow actionRow = inflateActionRow(contentPreviewLayout, actionRowLayout); if (actionRow != null) { @@ -431,6 +430,20 @@ public final class ChooserContentPreviewUi { return actions; } + private ImagePreviewView inflateImagePreviewView(ViewGroup previewLayout) { + ViewStub stub = previewLayout.findViewById(R.id.image_preview_stub); + if (stub != null) { + int layoutId = + mFeatureFlagRepository.isEnabled(Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW) + ? R.layout.scrollable_image_preview_view + : R.layout.chooser_image_preview_view; + stub.setLayoutResource(layoutId); + stub.inflate(); + } + return previewLayout.findViewById( + com.android.internal.R.id.content_preview_image_area); + } + private static ViewGroup displayFileContentPreview( Intent targetIntent, Resources resources, diff --git a/java/src/com/android/intentresolver/flags/Flags.kt b/java/src/com/android/intentresolver/flags/Flags.kt index db00a751..9c206265 100644 --- a/java/src/com/android/intentresolver/flags/Flags.kt +++ b/java/src/com/android/intentresolver/flags/Flags.kt @@ -35,6 +35,12 @@ object Flags { id = 1503, name = "sharesheet_image_text_preview", teamfood = true ) + // TODO(b/267355521) Tracking Bug + @JvmField + val SHARESHEET_SCROLLABLE_IMAGE_PREVIEW = unreleasedFlag( + 1504, "sharesheet_scrollable_image_preview" + ) + private fun unreleasedFlag(id: Int, name: String, teamfood: Boolean = false) = UnreleasedFlag(id, name, "systemui", teamfood) } diff --git a/java/src/com/android/intentresolver/widget/ChooserImagePreviewView.kt b/java/src/com/android/intentresolver/widget/ChooserImagePreviewView.kt index bf10bfaa..ca94a95d 100644 --- a/java/src/com/android/intentresolver/widget/ChooserImagePreviewView.kt +++ b/java/src/com/android/intentresolver/widget/ChooserImagePreviewView.kt @@ -57,7 +57,8 @@ class ChooserImagePreviewView : RelativeLayout, ImagePreviewView { private var transitionStatusElementCallback: TransitionElementStatusCallback? = null override fun onFinishInflate() { - LayoutInflater.from(context).inflate(R.layout.image_preview_view, this, true) + LayoutInflater.from(context) + .inflate(R.layout.chooser_image_preview_view_internals, this, true) mainImage = requireViewById(IntR.id.content_preview_image_1_large) secondLargeImage = requireViewById(IntR.id.content_preview_image_2_large) secondSmallImage = requireViewById(IntR.id.content_preview_image_2_small) diff --git a/java/tests/Android.bp b/java/tests/Android.bp index a62c52e6..4e835ec8 100644 --- a/java/tests/Android.bp +++ b/java/tests/Android.bp @@ -21,11 +21,12 @@ android_test { "IntentResolver-core", "androidx.test.rules", "androidx.test.ext.junit", + "androidx.test.espresso.contrib", "mockito-target-minus-junit4", "androidx.test.espresso.core", - "androidx.lifecycle_lifecycle-common-java8", - "androidx.lifecycle_lifecycle-extensions", - "androidx.lifecycle_lifecycle-runtime-ktx", + "androidx.lifecycle_lifecycle-common-java8", + "androidx.lifecycle_lifecycle-extensions", + "androidx.lifecycle_lifecycle-runtime-ktx", "truth-prebuilt", "testables", "testng", diff --git a/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt b/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt new file mode 100644 index 00000000..abc24efb --- /dev/null +++ b/java/tests/src/com/android/intentresolver/TestFeatureFlagRepository.kt @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 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 com.android.intentresolver + +import com.android.intentresolver.flags.FeatureFlagRepository +import com.android.systemui.flags.ReleasedFlag +import com.android.systemui.flags.UnreleasedFlag + +internal class TestFeatureFlagRepository( + private val overrides: Map<UnreleasedFlag, Boolean> +) : FeatureFlagRepository { + override fun isEnabled(flag: UnreleasedFlag): Boolean = + overrides.getOrDefault(flag, flag.default) + + override fun isEnabled(flag: ReleasedFlag): Boolean = flag.default +} diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index 2d8a74b9..249dca62 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -90,24 +90,23 @@ import android.util.HashedStringCache; import android.util.Pair; import android.util.SparseArray; import android.view.View; +import android.view.ViewGroup; import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.test.espresso.contrib.RecyclerViewActions; import androidx.test.espresso.matcher.BoundedDiagnosingMatcher; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; import com.android.intentresolver.ResolverActivity.ResolvedComponentInfo; import com.android.intentresolver.chooser.DisplayResolveInfo; -import com.android.intentresolver.flags.FeatureFlagRepository; import com.android.intentresolver.flags.Flags; import com.android.intentresolver.shortcuts.ShortcutLoader; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.systemui.flags.ReleasedFlag; -import com.android.systemui.flags.UnreleasedFlag; import org.hamcrest.Description; import org.hamcrest.Matcher; @@ -124,6 +123,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; @@ -859,7 +859,7 @@ public class UnbundledChooserActivityTest { @Test - public void oneVisibleImagePreview() throws InterruptedException { + public void oneVisibleImagePreview() { Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -884,18 +884,31 @@ public class UnbundledChooserActivityTest { .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); - onView(withId(com.android.internal.R.id.content_preview_image_1_large)) - .check(matches(isDisplayed())); - onView(withId(com.android.internal.R.id.content_preview_image_2_large)) - .check(matches(not(isDisplayed()))); - onView(withId(com.android.internal.R.id.content_preview_image_2_small)) - .check(matches(not(isDisplayed()))); - onView(withId(com.android.internal.R.id.content_preview_image_3_small)) - .check(matches(not(isDisplayed()))); + onView(withId(com.android.internal.R.id.content_preview_image_area)) + .check((view, exception) -> { + if (exception != null) { + throw exception; + } + ViewGroup parent = (ViewGroup) view; + ArrayList<View> visibleViews = new ArrayList<>(); + for (int i = 0, count = parent.getChildCount(); i < count; i++) { + View child = parent.getChildAt(i); + if (child.getVisibility() == View.VISIBLE) { + visibleViews.add(child); + } + } + assertThat(visibleViews.size(), is(1)); + assertThat( + "image preview view is fully visible", + isDisplayed().matches(visibleViews.get(0))); + }); } @Test - public void twoVisibleImagePreview() throws InterruptedException { + public void twoVisibleImagePreview() { + ChooserActivityOverrideData.getInstance().featureFlagRepository = + new TestFeatureFlagRepository( + Collections.singletonMap(Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, false)); Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -932,7 +945,11 @@ public class UnbundledChooserActivityTest { } @Test - public void threeOrMoreVisibleImagePreview() throws InterruptedException { + public void threeOrMoreVisibleImagePreview() { + ChooserActivityOverrideData.getInstance().featureFlagRepository = + new TestFeatureFlagRepository( + Collections.singletonMap( + Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, false)); Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); @@ -972,20 +989,60 @@ public class UnbundledChooserActivityTest { } @Test - public void testImageAndTextPreview() { + public void testManyVisibleImagePreview_ScrollableImagePreview() { ChooserActivityOverrideData.getInstance().featureFlagRepository = - new FeatureFlagRepository() { - @Override - public boolean isEnabled(@NonNull UnreleasedFlag flag) { - return Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW.equals(flag) - || flag.getDefault(); - } + new TestFeatureFlagRepository( + Collections.singletonMap( + Flags.SHARESHEET_SCROLLABLE_IMAGE_PREVIEW, true)); + Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + + R.drawable.test320x240); + + ArrayList<Uri> uris = new ArrayList<>(); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + uris.add(uri); + + Intent sendIntent = createSendUriIntentWithPreview(uris); + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; + + List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); - @Override - public boolean isEnabled(@NonNull ReleasedFlag flag) { - return false; + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + waitForIdle(); + onView(withId(com.android.internal.R.id.content_preview_image_area)) + .perform(RecyclerViewActions.scrollToLastPosition()) + .check((view, exception) -> { + if (exception != null) { + throw exception; } - }; + RecyclerView recyclerView = (RecyclerView) view; + assertThat(recyclerView.getAdapter().getItemCount(), is(uris.size())); + }); + } + + @Test + public void testImageAndTextPreview() { + ChooserActivityOverrideData.getInstance().featureFlagRepository = + new TestFeatureFlagRepository( + Collections.singletonMap(Flags.SHARESHEET_IMAGE_AND_TEXT_PREVIEW, true)); final Uri uri = Uri.parse("android.resource://com.android.frameworks.coretests/" + R.drawable.test320x240); final String sharedText = "text-" + System.currentTimeMillis(); @@ -1723,17 +1780,8 @@ public class UnbundledChooserActivityTest { @Test public void testLaunchWithCustomAction() throws InterruptedException { ChooserActivityOverrideData.getInstance().featureFlagRepository = - new FeatureFlagRepository() { - @Override - public boolean isEnabled(@NonNull UnreleasedFlag flag) { - return Flags.SHARESHEET_CUSTOM_ACTIONS.equals(flag) || flag.getDefault(); - } - - @Override - public boolean isEnabled(@NonNull ReleasedFlag flag) { - return false; - } - }; + new TestFeatureFlagRepository( + Collections.singletonMap(Flags.SHARESHEET_CUSTOM_ACTIONS, true)); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); when( ChooserActivityOverrideData @@ -1787,18 +1835,8 @@ public class UnbundledChooserActivityTest { @Test public void testLaunchWithPayloadReselection() throws InterruptedException { ChooserActivityOverrideData.getInstance().featureFlagRepository = - new FeatureFlagRepository() { - @Override - public boolean isEnabled(@NonNull UnreleasedFlag flag) { - return Flags.SHARESHEET_RESELECTION_ACTION.equals(flag) - || flag.getDefault(); - } - - @Override - public boolean isEnabled(@NonNull ReleasedFlag flag) { - return false; - } - }; + new TestFeatureFlagRepository( + Collections.singletonMap(Flags.SHARESHEET_RESELECTION_ACTION, true)); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2); when( ChooserActivityOverrideData |