Add special format badge in preview screen
- Add special format badge to the app bar in Preview
- Create separate layouts for special format badge as we have different
icon sizes, and margin between the text and the icon.
- Add Motion Photo badge in photo grid.
Bug: 194281557
Test: atest com.android.providers.media.photopicker.espresso
Change-Id: I1c08491fc8bebbb8aa9a9297098fdc57d934c694
Merged-In: I1c08491fc8bebbb8aa9a9297098fdc57d934c694
(cherry picked from commit b1e0637fe08d498678f05ca4fdce02767ab2965e)
diff --git a/res/drawable/ic_motion_photo.xml b/res/drawable/ic_motion_photo.xml
new file mode 100644
index 0000000..ea8bf73
--- /dev/null
+++ b/res/drawable/ic_motion_photo.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="18dp"
+ android:height="18dp"
+ android:viewportHeight="18"
+ android:viewportWidth="18">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.5 11.375V4.625L11 8L6.5 11.375ZM15.5 8C15.5 12.14 12.14 15.5 8 15.5C3.86 15.5 0.5 12.14 0.5 8C0.5 7.1075 0.665 6.26 0.95 5.465L2.36 5.975C2.1275 6.605 2 7.2875 2 8C2 11.3075 4.6925 14 8 14C11.3075 14 14 11.3075 14 8C14 4.6925 11.3075 2 8 2C7.2875 2 6.6125 2.1275 5.9825 2.36L5.4725 0.9425C6.2675 0.665 7.115 0.5 8 0.5C12.14 0.5 15.5 3.86 15.5 8ZM3.125 2C2.5025 2 2 2.5025 2 3.125C2 3.7475 2.5025 4.25 3.125 4.25C3.7475 4.25 4.25 3.7475 4.25 3.125C4.25 2.5025 3.7475 2 3.125 2Z"/>
+</vector>
diff --git a/res/layout/item_photo_grid.xml b/res/layout/item_photo_grid.xml
index cecf10d..fed1c8b 100644
--- a/res/layout/item_photo_grid.xml
+++ b/res/layout/item_photo_grid.xml
@@ -52,12 +52,21 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
- android:layout_marginEnd="@dimen/picker_item_gif_badge_margin"
- android:layout_marginTop="@dimen/picker_item_gif_badge_margin"
android:scaleType="fitCenter"
android:src="@drawable/ic_gif"
android:contentDescription="@null"/>
+ <ImageView
+ android:id="@+id/icon_motion_photo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end|top"
+ android:layout_marginEnd="@dimen/picker_item_badge_margin"
+ android:layout_marginTop="@dimen/picker_item_badge_margin"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_motion_photo"
+ android:contentDescription="@null"/>
+
<LinearLayout
android:id="@+id/video_container"
android:layout_width="wrap_content"
diff --git a/res/layout/preview_gif.xml b/res/layout/preview_gif.xml
new file mode 100644
index 0000000..1512184
--- /dev/null
+++ b/res/layout/preview_gif.xml
@@ -0,0 +1,30 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingEnd="@dimen/preview_special_format_padding_end" >
+
+ <ImageView
+ android:id="@+id/icon_gif"
+ android:layout_width="@dimen/preview_gif_icon_size"
+ android:layout_height="@dimen/preview_gif_icon_size"
+ android:adjustViewBounds="true"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_gif"
+ android:contentDescription="@null" />
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/preview_motion_photo.xml b/res/layout/preview_motion_photo.xml
new file mode 100644
index 0000000..4d46bc4
--- /dev/null
+++ b/res/layout/preview_motion_photo.xml
@@ -0,0 +1,39 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingEnd="@dimen/preview_special_format_padding_end" >
+
+ <ImageView
+ android:id="@+id/icon_motion_photo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_motion_photo"
+ android:contentDescription="@null" />
+
+ <TextView
+ android:id="@+id/text_motion_photo"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/preview_special_format_text_margin"
+ android:layout_gravity="center_vertical"
+ android:textColor="@color/picker_default_white"
+ android:textSize="@dimen/preview_special_format_text_size"
+ android:text="@string/picker_motion_photo_text" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/menu/picker_preview_menu.xml b/res/menu/picker_preview_menu.xml
new file mode 100644
index 0000000..5381358
--- /dev/null
+++ b/res/menu/picker_preview_menu.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<!-- special format badges and text in preview screen -->
+<menu
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+ <item
+ android:id="@+id/preview_gif"
+ android:title="@null"
+ app:showAsAction="always"
+ app:actionLayout="@layout/preview_gif"/>
+ <item
+ android:id="@+id/preview_motion_photo"
+ android:title="@null"
+ app:showAsAction="always"
+ app:actionLayout="@layout/preview_motion_photo"/>
+</menu>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ff2d197..e85c2ba 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -32,10 +32,9 @@
<dimen name="picker_item_check_size">24dp</dimen>
<dimen name="picker_item_check_margin">6dp</dimen>
- <dimen name="picker_item_badge_margin">5dp</dimen>
+ <dimen name="picker_item_badge_margin">4dp</dimen>
<dimen name="picker_item_badge_text_margin">3dp</dimen>
<dimen name="picker_item_badge_text_size">10dp</dimen>
- <dimen name="picker_item_gif_badge_margin">3dp</dimen>
<dimen name="picker_item_gradient_height">56dp</dimen>
<dimen name="picker_date_header_height">56dp</dimen>
@@ -64,7 +63,11 @@
<dimen name="preview_buttons_padding_horizontal">16dp</dimen>
<dimen name="preview_deselect_padding_start">2dp</dimen>
<dimen name="preview_viewpager_margin">20dp</dimen>
+ <dimen name="preview_gif_icon_size">32dp</dimen>
<!-- PhotoPicker Preview text -->
+ <dimen name="preview_special_format_text_size">12sp</dimen>
+ <dimen name="preview_special_format_text_margin">8dp</dimen>
+ <dimen name="preview_special_format_padding_end">16dp</dimen>
<dimen name="preview_toolbar_scrim_height">96dp</dimen>
<dimen name="preview_deselect_scrim_height">240dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 944c71b..26dbbbb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -146,6 +146,9 @@
<!-- Title for the category in the picker that offers videos. [CHAR LIMIT=24] -->
<string name="picker_category_videos">@string/root_videos</string>
+ <!-- Special format text in preview screen for Motion Photo. [CHAR LIMIT=30] -->
+ <string name="picker_motion_photo_text">Motion Photo</string>
+
<!-- ========================= BEGIN AUTO-GENERATED BY gen_strings.py ========================= -->
<!-- ========================= WRITE STRINGS ========================= -->
diff --git a/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java b/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
index 3f3e2b4..0438865 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
@@ -36,7 +36,7 @@
private final ImageLoader mImageLoader;
private final ImageView mIconThumb;
private final ImageView mIconGif;
- private final ImageView mIconVideo;
+ private final ImageView mIconMotionPhoto;
private final View mVideoBadgeContainer;
private final TextView mVideoDuration;
private final View mOverlayGradient;
@@ -48,8 +48,8 @@
mIconThumb = itemView.findViewById(R.id.icon_thumbnail);
mIconGif = itemView.findViewById(R.id.icon_gif);
+ mIconMotionPhoto = itemView.findViewById(R.id.icon_motion_photo);
mVideoBadgeContainer = itemView.findViewById(R.id.video_container);
- mIconVideo = mVideoBadgeContainer.findViewById(R.id.icon_video);
mVideoDuration = mVideoBadgeContainer.findViewById(R.id.video_duration);
mOverlayGradient = itemView.findViewById(R.id.overlay_gradient);
mImageLoader = imageLoader;
@@ -67,11 +67,8 @@
final Item item = (Item) itemView.getTag();
mImageLoader.loadPhotoThumbnail(item, mIconThumb);
- if (item.isGif()) {
- mIconGif.setVisibility(View.VISIBLE);
- } else {
- mIconGif.setVisibility(View.GONE);
- }
+ mIconGif.setVisibility(item.isGif() ? View.VISIBLE : View.GONE);
+ mIconMotionPhoto.setVisibility(item.isMotionPhoto() ? View.VISIBLE : View.GONE);
if (item.isVideo()) {
mVideoBadgeContainer.setVisibility(View.VISIBLE);
@@ -88,6 +85,6 @@
}
private boolean showShowOverlayGradient(@NonNull Item item) {
- return mCanSelectMultiple || item.isGif() || item.isVideo();
+ return mCanSelectMultiple || item.isGif() || item.isVideo() || item.isMotionPhoto();
}
}
diff --git a/src/com/android/providers/media/photopicker/ui/PreviewFragment.java b/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
index d96942b..118c90b 100644
--- a/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PreviewFragment.java
@@ -23,6 +23,9 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@@ -70,6 +73,31 @@
private ViewPager2 mViewPager;
private PreviewAdapter mAdapter;
private ViewPager2.OnPageChangeCallback mOnPageChangeCallBack;
+ private boolean mShouldShowGifBadge;
+ private boolean mShouldShowMotionPhotoBadge;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Register with the activity to inform the system that the app bar fragment is
+ // participating in the population of the options menu
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+ inflater.inflate(R.menu.picker_preview_menu, menu);
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(@NonNull Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ // All logic to hide/show an item in the menu must be in this method
+ final MenuItem gifItem = menu.findItem(R.id.preview_gif);
+ final MenuItem motionPhotoItem = menu.findItem(R.id.preview_motion_photo);
+ gifItem.setVisible(mShouldShowGifBadge);
+ motionPhotoItem.setVisible(mShouldShowMotionPhotoBadge);
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
@@ -186,6 +214,9 @@
addOrSelectButton.setOnClickListener(
v -> onClickSelect(addOrSelectButton, /* shouldUpdateButtonState */ false));
}
+
+ // Set the appropriate special format icon based on the item in the preview
+ updateSpecialFormatIcon(mAdapter.getItem(0));
}
/**
@@ -276,6 +307,9 @@
// selection list.
updateSelectButtonStateAndText(mSelectButton,
mSelection.isItemSelected(mAdapter.getItem(position)));
+
+ // Set the appropriate special format icon based on the item in the preview
+ updateSpecialFormatIcon(mAdapter.getItem(position));
}
}
@@ -285,6 +319,14 @@
updateSelectButtonText(selectButton, isSelected);
}
+ private void updateSpecialFormatIcon(Item item) {
+ mShouldShowGifBadge = item.isGif();
+ mShouldShowMotionPhotoBadge = item.isMotionPhoto();
+ // Invalidating options menu calls onPrepareOptionsMenu() where the logic for
+ // hiding/showing menu items is placed.
+ requireActivity().invalidateOptionsMenu();
+ }
+
private static void updateSelectButtonText(@NonNull Button selectButton, boolean isSelected) {
selectButton.setText(isSelected ? R.string.deselect : R.string.select);
}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/ActiveProfileButtonTest.java b/tests/src/com/android/providers/media/photopicker/espresso/ActiveProfileButtonTest.java
index ecb1221..63af436 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/ActiveProfileButtonTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/ActiveProfileButtonTest.java
@@ -98,20 +98,20 @@
onView(withId(PROFILE_BUTTON)).check(matches(isDisplayed()));
// Select 1st item thumbnail and verify profile button is not shown
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
onView(withId(PROFILE_BUTTON)).check(matches(not(isDisplayed())));
// Deselect the item to check profile button is shown
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
onView(withId(PROFILE_BUTTON)).check(matches(isDisplayed()));
// Select 1st item thumbnail and verify profile button is not shown
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
onView(withId(PROFILE_BUTTON)).check(matches(not(isDisplayed())));
// Goto Albums page and verify profile button is not shown
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/MaxSelectionTest.java b/tests/src/com/android/providers/media/photopicker/espresso/MaxSelectionTest.java
index b2fee80..c025cc0 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/MaxSelectionTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/MaxSelectionTest.java
@@ -53,13 +53,13 @@
public void testMaxSelection() {
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
- // Select image item thumbnail and verify select icon is selected
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ // Select first image item thumbnail and verify select icon is selected
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
- // Select gif item thumbnail and verify select icon is selected
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_CHECK_ID);
+ // Select second image item thumbnail and verify select icon is selected
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_CHECK_ID);
// Click Video item thumbnail and verify select icon is not selected. Because we set the
// max selection is 2.
@@ -79,9 +79,9 @@
onView(withContentDescription("Navigate up")).perform(click());
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
- // DeSelect Gif item and verify select icon is not selected
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_CHECK_ID);
+ // DeSelect second image item and verify select icon is not selected
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_CHECK_ID);
// Click Video item thumbnail and verify select icon is selected.
clickItem(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/MultiSelectTest.java b/tests/src/com/android/providers/media/photopicker/espresso/MultiSelectTest.java
index 27e1811..afa4594 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/MultiSelectTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/MultiSelectTest.java
@@ -62,29 +62,29 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Check select icon is visible
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, R.id.overlay_gradient);
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, R.id.overlay_gradient);
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Verify that select icon is not selected yet
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Select image item thumbnail and verify select icon is selected
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Deselect the item to check item is marked as not selected.
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Now, click on the select/check icon, verify we can also click on check icon to select or
// deselect an item.
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Click on recyclerView item, this deselects the item. Verify that we can click on any
// region on the recyclerView item to select/deselect the item.
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, /* targetViewId */ -1);
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, /* targetViewId */ -1);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
}
@Test
@@ -99,7 +99,7 @@
onView(withId(bottomBarId)).check(matches(not(isDisplayed())));
// Selecting one item shows view selected and add button
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
onView(withId(bottomBarId)).check(matches(isDisplayed()));
onView(withId(viewSelectedId)).check(matches(isDisplayed()));
@@ -107,7 +107,7 @@
onView(withId(addButtonId)).check(matches(isDisplayed()));
// When the selected item count is 0, ViewSelected and add button should hide
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
onView(withId(bottomBarId)).check(matches(not(isDisplayed())));
onView(withId(viewSelectedId)).check(matches(not(isDisplayed())));
onView(withId(addButtonId)).check(matches(not(isDisplayed())));
@@ -122,18 +122,18 @@
getTargetContext().getResources().getString(R.string.add);
// Selecting one item will enable add button and show "Add (1)" as button text
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
onView(withId(addButtonId)).check(matches(isDisplayed()));
onView(withId(addButtonId)).check(matches(withText(addButtonString + " (1)")));
// When the selected item count is 2, "Add (2)" should be displayed
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
onView(withId(addButtonId)).check(matches(isDisplayed()));
onView(withId(addButtonId)).check(matches(withText(addButtonString + " (2)")));
// When the item is deselected add button resets to selected count
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
onView(withId(addButtonId)).check(matches(isDisplayed()));
onView(withId(addButtonId)).check(matches(withText(addButtonString + " (1)")));
}
@@ -181,8 +181,8 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Select image item thumbnail and verify select icon is selected
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
// Navigate to Albums tab
onView(allOf(withText(PICKER_ALBUMS_STRING_ID), withParent(withId(CHIP_CONTAINER_ID))))
@@ -215,6 +215,6 @@
.perform(click());
// The image item is not selected
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
}
}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
index ad95ac3..bb97c4d 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
@@ -63,16 +63,18 @@
protected static final int VIEW_SELECTED_BUTTON_ID = R.id.button_view_selected;
protected static final int PREVIEW_IMAGE_VIEW_ID = R.id.preview_imageView;
protected static final int DRAG_BAR_ID = R.id.drag_bar;
+ protected static final int PREVIEW_GIF_ID = R.id.preview_gif;
+ protected static final int PREVIEW_MOTION_PHOTO_ID = R.id.preview_motion_photo;
/**
- * The position of the image item in the grid on the Photos tab
+ * The position of the first image item in the grid on the Photos tab
*/
- protected static final int IMAGE_POSITION = 1;
+ protected static final int IMAGE_1_POSITION = 1;
/**
- * The position of the gif item in the grid on the Photos tab
+ * The position of the second item in the grid on the Photos tab
*/
- protected static final int GIF_POSITION = 2;
+ protected static final int IMAGE_2_POSITION = 2;
/**
* The position of the video item in the grid on the Photos tab
@@ -95,11 +97,11 @@
sMultiSelectionIntent.putExtras(extras);
}
- private static final File IMAGE_FILE = new File(Environment.getExternalStorageDirectory(),
+ private static final File IMAGE_1_FILE = new File(Environment.getExternalStorageDirectory(),
Environment.DIRECTORY_DCIM + "/Camera"
+ "/image_" + System.currentTimeMillis() + ".jpeg");
- private static final File GIF_FILE = new File(Environment.getExternalStorageDirectory(),
- Environment.DIRECTORY_DOWNLOADS + "/gif_" + System.currentTimeMillis() + ".gif");
+ private static final File IMAGE_2_FILE = new File(Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_DOWNLOADS + "/image_" + System.currentTimeMillis() + ".jpeg");
private static final File VIDEO_FILE = new File(Environment.getExternalStorageDirectory(),
Environment.DIRECTORY_MOVIES + "/video_" + System.currentTimeMillis() + ".mp4");
@@ -161,8 +163,8 @@
@AfterClass
public static void destroyClass() {
- IMAGE_FILE.delete();
- GIF_FILE.delete();
+ IMAGE_1_FILE.delete();
+ IMAGE_2_FILE.delete();
VIDEO_FILE.delete();
InstrumentationRegistry.getInstrumentation()
@@ -172,10 +174,11 @@
private static void createFiles() throws Exception {
long timeNow = System.currentTimeMillis();
// Create files and change dateModified so that we can predict the recyclerView item
- // position
- createFile(IMAGE_FILE, timeNow + 2000);
- createFile(GIF_FILE, timeNow + 1000);
- createFile(VIDEO_FILE, timeNow);
+ // position. Set modified date ahead of time, so that even if other files are created,
+ // the below files always have positions 1, 2 and 3.
+ createFile(IMAGE_1_FILE, timeNow + 3000);
+ createFile(IMAGE_2_FILE, timeNow + 2000);
+ createFile(VIDEO_FILE, timeNow + 1000);
}
private static void pollForCondition(Supplier<Boolean> condition, String errorMessage)
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotosTabTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotosTabTest.java
index 4f3a896..741f707 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotosTabTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotosTabTest.java
@@ -50,6 +50,7 @@
@RunWith(AndroidJUnit4ClassRunner.class)
public class PhotosTabTest extends PhotoPickerBaseTest {
private static final int ICON_GIF_ID = R.id.icon_gif;
+ private static final int ICON_MOTION_PHOTO_ID = R.id.icon_motion_photo;
private static final int VIDEO_CONTAINER_ID = R.id.video_container;
private static final int OVERLAY_GRADIENT_ID = R.id.overlay_gradient;
@@ -78,29 +79,14 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Verify we have the thumbnail
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
- // Verify check icon, gif icon and video icon are not displayed
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, OVERLAY_GRADIENT_ID);
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_CHECK_ID);
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_GIF_ID);
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, VIDEO_CONTAINER_ID);
- }
-
- @Ignore("Re-enable this test coverage with actual GIF file b/202396821")
- @Test
- public void testPhotoGridLayout_gif() {
- onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
-
- // Verify we have the thumbnail
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
- // Verify gif icon is displayed
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, OVERLAY_GRADIENT_ID);
- assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_GIF_ID);
-
- // Verify check icon and video icon are not displayed
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_CHECK_ID);
- assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, VIDEO_CONTAINER_ID);
+ // Verify check icon, gif icon, motion photo icon and video icon are not displayed
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, OVERLAY_GRADIENT_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_CHECK_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_GIF_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_MOTION_PHOTO_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, VIDEO_CONTAINER_ID);
}
@Test
@@ -119,9 +105,10 @@
.atPositionOnView(VIDEO_POSITION, R.id.video_duration))
.check(matches(withText(containsString("0"))));
- // Verify check icon and gif icon are not displayed
+ // Verify check icon and gif icon and motion photo icon are not displayed
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_CHECK_ID);
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_GIF_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_MOTION_PHOTO_ID);
}
@Test
@@ -153,10 +140,11 @@
// Verify first item is image and has no other icons other than thumbnail
assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, ICON_THUMBNAIL_ID);
- // Verify check icon, gif icon and video icon are not displayed
+ // Verify check icon, gif icon, motion photo icon and video icon are not displayed
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, OVERLAY_GRADIENT_ID);
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, ICON_CHECK_ID);
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, ICON_GIF_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, ICON_MOTION_PHOTO_ID);
assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, photoItemPosition, VIDEO_CONTAINER_ID);
// Verify that toolbar has the title as category name
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectLongPressTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectLongPressTest.java
index c409f9c..7bbf482 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectLongPressTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectLongPressTest.java
@@ -18,6 +18,7 @@
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
@@ -71,6 +72,9 @@
// Verify image is previewed
assertMultiSelectLongPressCommonLayoutMatches();
onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
// Navigate back to Photo grid
onView(withContentDescription("Navigate up")).perform(click());
@@ -95,20 +99,9 @@
// Verify videoView is displayed
assertMultiSelectLongPressCommonLayoutMatches();
onView(withId(R.id.preview_videoView)).check(matches(isDisplayed()));
- }
-
- @Test
- public void testPreview_multiSelect_longPress_gif() {
- onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
-
- // Navigate to preview
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 2, ICON_THUMBNAIL_ID);
-
- registerIdlingResourceAndWaitForIdle();
-
- // Verify imageView is displayed for gif preview
- assertMultiSelectLongPressCommonLayoutMatches();
- onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
}
@Test
@@ -156,38 +149,35 @@
public void testPreview_multiSelect_longPress_showsOnlyOne() {
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
- // Select two items - image and video item
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 1, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 1, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
+ // Select two items - first image and video item
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
- final int position = 2;
- // Long press gif item to preview the item.
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, position, ICON_THUMBNAIL_ID);
+ // Long press second image item to preview the item.
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
registerIdlingResourceAndWaitForIdle();
mRule.getScenario().onActivity(activity -> {
Selection selection
= new ViewModelProvider(activity).get(PickerViewModel.class).getSelection();
- // Verify that we have two items(image and video) as selected items and
- // 1 item (gif) as item for preview
+ // Verify that we have two items(first image and video) as selected items and
+ // 1 item (second image) as item for preview
assertThat(selection.getSelectedItemCount().getValue()).isEqualTo(2);
assertThat(selection.getSelectedItemsForPreview().size()).isEqualTo(1);
});
final int imageViewId = R.id.preview_imageView;
- // TODO(b/194281557): Check Gif badge to confirm this is the preview for gif item
onView(withId(imageViewId)).check(matches(isDisplayed()));
// Verify that only one item is being previewed. Swipe left and right, and verify we still
// have ImageView in preview.
swipeLeftAndWait();
- // TODO(b/194281557): Check Gif badge to confirm this is the preview for gif item
onView(withId(imageViewId)).check(matches(isDisplayed()));
+
swipeRightAndWait();
- // TODO(b/194281557): Check Gif badge to confirm this is the preview for gif item
onView(withId(imageViewId)).check(matches(isDisplayed()));
}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectTest.java
index 27a05ac..d742180 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PreviewMultiSelectTest.java
@@ -19,6 +19,7 @@
import static androidx.test.InstrumentationRegistry.getTargetContext;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
@@ -75,8 +76,8 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Select two items and Navigate to preview
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
onView(withId(VIEW_SELECTED_BUTTON_ID)).perform(click());
registerIdlingResourceAndWaitForIdle();
@@ -100,9 +101,9 @@
public void testPreview_multiSelect_deselect() {
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
- // Select image and gif
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ // Select first and second image
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
// Navigate to preview
onView(withId(VIEW_SELECTED_BUTTON_ID)).perform(click());
@@ -157,8 +158,8 @@
// Select items
clickItem(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
// Navigate to preview
onView(withId(VIEW_SELECTED_BUTTON_ID)).perform(click());
@@ -166,20 +167,25 @@
// Preview Order
// 1 - Image
- // 2 - Gif
+ // 2 - Image
// 3 - Video
- // Navigate from Image -> Gif -> Video -> Gif -> Image -> Gif and verify the layout matches
+ // Navigate from Image -> Image -> Video -> Image -> Image -> Image and verify the layout
+ // matches
// 1. Image
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, PREVIEW_IMAGE_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
swipeLeftAndWait();
- // 2. Gif
+ // 2. Image
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, PREVIEW_IMAGE_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
swipeLeftAndWait();
// Since there is no video in the video file, we get an error.
@@ -188,24 +194,32 @@
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, VIDEO_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
swipeRightAndWait();
- // 2. Gif
+ // 2. Image
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, PREVIEW_IMAGE_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
swipeRightAndWait();
// 1. Image
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, PREVIEW_IMAGE_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
swipeLeftAndWait();
- // 2. Gif
+ // 2. Image
assertMultiSelectPreviewCommonLayoutDisplayed();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, PREVIEW_IMAGE_VIEW_ID))
.check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ assertSpecialFormatBadgeDoesNotExist();
}
@Test
@@ -213,9 +227,9 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Select 1 item in Photos tab
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
final int iconCheckId = R.id.icon_check;
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, iconCheckId);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, iconCheckId);
// Navigate to Albums tab
onView(allOf(withText(PICKER_ALBUMS_STRING_ID), withParent(withId(CHIP_CONTAINER_ID))))
@@ -250,12 +264,11 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Select video item
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
- final int position = 2;
- // Preview gif item using preview on long press
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, position, ICON_THUMBNAIL_ID);
+ // Preview second image item using preview on long press
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
registerIdlingResourceAndWaitForIdle();
@@ -281,12 +294,12 @@
onView(withText(android.R.string.ok)).perform(click());
assertMultiSelectPreviewCommonLayoutDisplayed();
- // Verify that "View Selected" shows the video item, not the gif item that was previewed
+ // Verify that "View Selected" shows the video item, not the image item that was previewed
// earlier with preview on long press
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, VIDEO_VIEW_ID))
.check(matches(isDisplayed()));
- // Swipe and verify we don't preview the gif item
+ // Swipe and verify we don't preview the image item
swipeLeftAndWait();
onView(ViewPagerMatcher(PREVIEW_VIEW_PAGER_ID, VIDEO_VIEW_ID))
.check(matches(isDisplayed()));
@@ -299,11 +312,11 @@
public void testPreview_multiSelect_acrossAlbums() {
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
- // Select gif and video item from Photos tab
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 2, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 2, ICON_THUMBNAIL_ID);
- clickItem(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
- assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 3, ICON_THUMBNAIL_ID);
+ // Select second image and video item from Photos tab
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
+ assertItemSelected(PICKER_TAB_RECYCLERVIEW_ID, VIDEO_POSITION, ICON_THUMBNAIL_ID);
// Navigate to albums
onView(allOf(withText(PICKER_ALBUMS_STRING_ID), withParent(withId(CHIP_CONTAINER_ID))))
@@ -341,12 +354,17 @@
onView(withId(VIEW_SELECTED_BUTTON_ID)).perform(click());
registerIdlingResourceAndWaitForIdle();
- // Deselect the Gif item
+ // Deselect the second image item
onView(withId(previewSelectButtonId)).perform(click());
- // Go back to Photos tab and verify that Gif item is deselected
+ // Go back to Photos tab and verify that second image item is deselected
onView(withContentDescription("Navigate up")).perform(click());
- assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, /* position */ 2, ICON_THUMBNAIL_ID);
+ assertItemNotSelected(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_2_POSITION, ICON_THUMBNAIL_ID);
+ }
+
+ private void assertSpecialFormatBadgeDoesNotExist() {
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
}
private void assertMultiSelectPreviewCommonLayoutDisplayed() {
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PreviewSingleSelectTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PreviewSingleSelectTest.java
index 819b6d6..e19032e 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PreviewSingleSelectTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PreviewSingleSelectTest.java
@@ -20,6 +20,7 @@
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
@@ -65,7 +66,7 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Navigate to preview
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
registerIdlingResourceAndWaitForIdle();
@@ -75,6 +76,9 @@
// Verify image is previewed
assertSingleSelectCommonLayoutMatches();
onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
// Navigate back to Photo grid
onView(withContentDescription("Navigate up")).perform(click());
@@ -99,20 +103,9 @@
// Verify videoView is displayed
assertSingleSelectCommonLayoutMatches();
onView(withId(R.id.preview_videoView)).check(matches(isDisplayed()));
- }
-
- @Test
- public void testPreview_singleSelect_gif() {
- onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
-
- // Navigate to preview
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
-
- registerIdlingResourceAndWaitForIdle();
-
- // Verify imageView is displayed for gif preview
- assertSingleSelectCommonLayoutMatches();
- onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ // Verify no special format icon is previewed
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
}
@Test
@@ -156,7 +149,7 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Navigate to preview
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
registerIdlingResourceAndWaitForIdle();
@@ -182,7 +175,7 @@
onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
// Navigate to preview
- longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_POSITION, ICON_THUMBNAIL_ID);
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
registerIdlingResourceAndWaitForIdle();
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatMultiSelectTest.java b/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatMultiSelectTest.java
new file mode 100644
index 0000000..8ad7de2
--- /dev/null
+++ b/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatMultiSelectTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2021 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.providers.media.photopicker.espresso;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
+import static com.android.providers.media.photopicker.espresso.CustomSwipeAction.swipeLeftAndWait;
+import static com.android.providers.media.photopicker.espresso.CustomSwipeAction.swipeRightAndWait;
+import static com.android.providers.media.scan.MediaScannerTest.stage;
+import static com.google.common.truth.Truth.assertThat;
+
+import static com.android.providers.media.photopicker.espresso.RecyclerViewTestUtils.clickItem;
+import static com.android.providers.media.photopicker.espresso.RecyclerViewTestUtils.longClickItem;
+
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+
+import androidx.test.espresso.Espresso;
+import androidx.test.espresso.IdlingRegistry;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import com.android.providers.media.R;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+public class SpecialFormatMultiSelectTest extends PhotoPickerBaseTest {
+
+ private static final File MOTION_PHOTO_FILE =
+ new File(Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_PICTURES + "/" + Environment.DIRECTORY_SCREENSHOTS
+ + "/motionphoto_" + System.currentTimeMillis() + ".jpeg");
+ private static final File GIF_FILE = new File(Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_DOWNLOADS + "/gif_" + System.currentTimeMillis() + ".gif");
+
+ /**
+ * The position of the gif item in the grid on the Photos tab
+ */
+ private static final int GIF_POSITION = 4;
+
+ /**
+ * The position of the video item in the grid on the Photos tab
+ */
+ private static final int MOTION_PHOTO_POSITION = 5;
+
+ @Rule
+ public ActivityScenarioRule<PhotoPickerTestActivity> mRule
+ = new ActivityScenarioRule<>(PhotoPickerBaseTest.getMultiSelectionIntent());
+
+ @BeforeClass
+ public static void setupClass() throws Exception {
+ PhotoPickerBaseTest.setupClass();
+ createSpecialFormatFiles();
+ }
+
+ @AfterClass
+ public static void destroyClass() {
+ PhotoPickerBaseTest.destroyClass();
+ MOTION_PHOTO_FILE.delete();
+ GIF_FILE.delete();
+ }
+
+ protected static void createSpecialFormatFiles() throws Exception {
+ createFile(MOTION_PHOTO_FILE, R.raw.test_motion_photo);
+ createFile(GIF_FILE, R.raw.test_gif);
+ }
+
+ @Test
+ public void testPreview_multiSelect_longPress_gif() {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Navigate to preview
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+
+ registerIdlingResourceAndWaitForIdle();
+
+ // Verify imageView is displayed for gif preview
+ onView(withId(PREVIEW_GIF_ID)).check(matches(isDisplayed()));
+ onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ }
+
+ @Test
+ public void testPreview_multiSelect_longPress_motionPhoto() {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Navigate to preview
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_THUMBNAIL_ID);
+
+ registerIdlingResourceAndWaitForIdle();
+
+ // Verify imageView is displayed for motion photo preview
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(matches(isDisplayed()));
+ onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
+ }
+
+ @Test
+ public void testPreview_multiSelect_navigation() {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Select items
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, IMAGE_1_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ clickItem(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_THUMBNAIL_ID);
+ // Navigate to preview
+ onView(withId(VIEW_SELECTED_BUTTON_ID)).perform(click());
+
+ registerIdlingResourceAndWaitForIdle();
+
+ // Preview Order
+ // 1 - Image
+ // 2 - Gif
+ // 3 - MotionPhoto
+ // Navigate from Image -> Gif -> Motion Photo -> Gif -> Image and verify the layout
+ // matches. This test does not check for common layout as that is already covered in
+ // other tests.
+
+ // 1. Image
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
+
+ swipeLeftAndWait();
+ // 2. Gif
+ onView(withId(PREVIEW_GIF_ID)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+
+ swipeLeftAndWait();
+ // 3. Motion Photo
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
+
+ swipeRightAndWait();
+ // 2. Gif
+ onView(withId(PREVIEW_GIF_ID)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+
+ swipeRightAndWait();
+ // 1. Image
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
+ }
+
+ private void registerIdlingResourceAndWaitForIdle() {
+ mRule.getScenario().onActivity((activity -> IdlingRegistry.getInstance().register(
+ new ViewPager2IdlingResource(activity.findViewById(R.id.preview_viewPager)))));
+ Espresso.onIdle();
+ }
+
+ private static void createFile(File file, int resId) throws IOException {
+ File parentFile = file.getParentFile();
+ parentFile.mkdirs();
+
+ assertThat(parentFile.exists()).isTrue();
+ file = stage(resId, file);
+ assertThat(file.exists()).isTrue();
+
+ final Uri uri = MediaStore.scanFile(getIsolatedContext().getContentResolver(), file);
+ MediaStore.waitForIdle(getIsolatedContext().getContentResolver());
+ assertThat(uri).isNotNull();
+ }
+}
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatSingleSelectTest.java b/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatSingleSelectTest.java
new file mode 100644
index 0000000..6d7e219
--- /dev/null
+++ b/tests/src/com/android/providers/media/photopicker/espresso/SpecialFormatSingleSelectTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2021 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.providers.media.photopicker.espresso;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static com.android.providers.media.photopicker.espresso.RecyclerViewTestUtils.assertItemDisplayed;
+import static com.android.providers.media.photopicker.espresso.RecyclerViewTestUtils.assertItemNotDisplayed;
+import static com.android.providers.media.photopicker.espresso.RecyclerViewTestUtils.longClickItem;
+import static com.android.providers.media.scan.MediaScannerTest.stage;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.hamcrest.Matchers.not;
+
+import android.net.Uri;
+import android.os.Environment;
+import android.provider.MediaStore;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.espresso.Espresso;
+import androidx.test.espresso.IdlingRegistry;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import com.android.providers.media.R;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+public class SpecialFormatSingleSelectTest extends PhotoPickerBaseTest {
+ private static final int ICON_GIF_ID = R.id.icon_gif;
+ private static final int ICON_MOTION_PHOTO_ID = R.id.icon_motion_photo;
+ private static final int VIDEO_CONTAINER_ID = R.id.video_container;
+ private static final int OVERLAY_GRADIENT_ID = R.id.overlay_gradient;
+ private static final int PREVIEW_GIF_ID = R.id.preview_gif;
+ private static final int PREVIEW_MOTION_PHOTO_ID = R.id.preview_motion_photo;
+
+ private static final File MOTION_PHOTO_FILE =
+ new File(Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_PICTURES
+ + "/motionphoto_" + System.currentTimeMillis() + ".jpeg");
+ private static final File GIF_FILE = new File(Environment.getExternalStorageDirectory(),
+ Environment.DIRECTORY_DOWNLOADS + "/gif_" + System.currentTimeMillis() + ".gif");
+
+ /**
+ * The position of the gif item in the grid on the Photos tab
+ */
+ private static final int GIF_POSITION = 4;
+
+ /**
+ * The position of the video item in the grid on the Photos tab
+ */
+ private static final int MOTION_PHOTO_POSITION = 5;
+
+ @Rule
+ public ActivityScenarioRule<PhotoPickerTestActivity> mRule
+ = new ActivityScenarioRule<>(PhotoPickerBaseTest.getSingleSelectionIntent());
+
+ @BeforeClass
+ public static void setupClass() throws Exception {
+ PhotoPickerBaseTest.setupClass();
+ createSpecialFormatFiles();
+ }
+
+ @AfterClass
+ public static void destroyClass() {
+ PhotoPickerBaseTest.destroyClass();
+ MOTION_PHOTO_FILE.delete();
+ GIF_FILE.delete();
+ }
+
+ protected static void createSpecialFormatFiles() throws Exception {
+ createFile(MOTION_PHOTO_FILE, R.raw.test_motion_photo);
+ createFile(GIF_FILE, R.raw.test_gif);
+ }
+
+ @Test
+ public void testPhotoGridLayout_motionPhoto() throws Exception {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Verify we have the thumbnail
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_THUMBNAIL_ID);
+ // Verify motion photo icon is displayed
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, OVERLAY_GRADIENT_ID);
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION,
+ ICON_MOTION_PHOTO_ID);
+
+ // Verify check icon, video icon and gif icon are not displayed
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_CHECK_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION,
+ VIDEO_CONTAINER_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_GIF_ID);
+ }
+
+ @Test
+ public void testPhotoGridLayout_gif() throws Exception {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Verify we have the thumbnail
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+ // Verify gif icon is displayed
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, OVERLAY_GRADIENT_ID);
+ assertItemDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_GIF_ID);
+
+ // Verify check icon, video icon and motion photo icon are not displayed
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_CHECK_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, VIDEO_CONTAINER_ID);
+ assertItemNotDisplayed(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_MOTION_PHOTO_ID);
+ }
+
+ @Test
+ public void testPreview_singleSelect_gif() throws Exception {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Navigate to preview
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, GIF_POSITION, ICON_THUMBNAIL_ID);
+
+ registerIdlingResourceAndWaitForIdle();
+
+ // Verify gif icon is displayed for gif preview
+ assertSingleSelectCommonLayoutMatches();
+ onView(withId(PREVIEW_GIF_ID)).check(matches(isDisplayed()));
+ onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(doesNotExist());
+ }
+
+ @Test
+ public void testPreview_singleSelect_motionPhoto() throws Exception {
+ onView(withId(PICKER_TAB_RECYCLERVIEW_ID)).check(matches(isDisplayed()));
+
+ // Navigate to preview
+ longClickItem(PICKER_TAB_RECYCLERVIEW_ID, MOTION_PHOTO_POSITION, ICON_THUMBNAIL_ID);
+
+ registerIdlingResourceAndWaitForIdle();
+
+ // Verify motion photo icon is displayed for motion photo preview
+ assertSingleSelectCommonLayoutMatches();
+ onView(withId(PREVIEW_MOTION_PHOTO_ID)).check(matches(isDisplayed()));
+ onView(withId(R.id.preview_imageView)).check(matches(isDisplayed()));
+ onView(withId(PREVIEW_GIF_ID)).check(doesNotExist());
+ }
+
+ private static void createFile(File file, int resId) throws IOException {
+ File parentFile = file.getParentFile();
+ parentFile.mkdirs();
+
+ assertThat(parentFile.exists()).isTrue();
+ file = stage(resId, file);
+ assertThat(file.exists()).isTrue();
+
+ final Uri uri = MediaStore.scanFile(getIsolatedContext().getContentResolver(), file);
+ MediaStore.waitForIdle(getIsolatedContext().getContentResolver());
+ assertThat(uri).isNotNull();
+ }
+
+ private void registerIdlingResourceAndWaitForIdle() {
+ mRule.getScenario().onActivity((activity -> IdlingRegistry.getInstance().register(
+ new ViewPager2IdlingResource(activity.findViewById(R.id.preview_viewPager)))));
+ Espresso.onIdle();
+ }
+
+ private void assertSingleSelectCommonLayoutMatches() {
+ onView(withId(R.id.preview_viewPager)).check(matches(isDisplayed()));
+ onView(withId(R.id.preview_select_check_button)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.preview_add_or_select_button)).check(matches(isDisplayed()));
+ // Verify that the text in Add button
+ onView(withId(R.id.preview_add_or_select_button)).check(matches(withText(R.string.add)));
+ }
+}