summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Android Build Coastguard Worker <android-build-coastguard-worker@google.com> 2025-03-21 20:22:02 -0700
committer Android Build Coastguard Worker <android-build-coastguard-worker@google.com> 2025-03-21 20:22:02 -0700
commitc6ce906051ea48069314975374a33e92fce3163a (patch)
tree5c1b3b3b5f6bb28b92fa5cb9425dc86f2f1f1a70
parenteb3508c8701c0b69ddc0b879624d0a14f88db109 (diff)
parent343bf4b4eafc3c91e82afc6f5ff0847e2ba97b2f (diff)
Snap for 13256841 from 343bf4b4eafc3c91e82afc6f5ff0847e2ba97b2f to 25Q2-release
Change-Id: Icc91d11c3dce5b6a95e7aa0c1a41068f71f032de
-rw-r--r--proguard.flags1
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/color/grid_item_ripple_color.xml28
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_item_mask.xml21
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_nameplate_background.xml214
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/drawer_layout.xml8
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/fixed_layout.xml7
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/item_doc_grid.xml295
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/job_progress_panel.xml43
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml8
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/layout/peek_layout.xml22
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/colors.xml4
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml12
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml7
-rw-r--r--res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml4
-rw-r--r--res/values/strings.xml1
-rw-r--r--src/com/android/documentsui/BaseActivity.java8
-rw-r--r--src/com/android/documentsui/JobPanelController.kt26
-rw-r--r--src/com/android/documentsui/dirlist/AnimationView.java43
-rw-r--r--src/com/android/documentsui/dirlist/DirectoryFragment.java24
-rw-r--r--src/com/android/documentsui/files/ActionHandler.java14
-rw-r--r--src/com/android/documentsui/files/FilesActivity.java4
-rw-r--r--src/com/android/documentsui/peek/PeekFragment.kt32
-rw-r--r--src/com/android/documentsui/peek/PeekViewManager.kt83
-rw-r--r--src/com/android/documentsui/util/FlagUtils.kt2
-rw-r--r--tests/Android.bp3
-rw-r--r--tests/common/com/android/documentsui/bots/Bots.java4
-rw-r--r--tests/common/com/android/documentsui/bots/PeekBot.kt50
-rw-r--r--tests/common/com/android/documentsui/testing/MutableJobProgress.kt32
-rw-r--r--tests/common/com/android/documentsui/testing/TestPeekViewManager.kt34
-rw-r--r--tests/functional/com/android/documentsui/JobPanelUiTest.kt93
-rw-r--r--tests/functional/com/android/documentsui/peek/PeekUiTest.kt68
-rw-r--r--tests/unit/com/android/documentsui/JobPanelControllerTest.kt14
-rw-r--r--tests/unit/com/android/documentsui/files/ActionHandlerTest.java7
33 files changed, 939 insertions, 277 deletions
diff --git a/proguard.flags b/proguard.flags
index 76449d4e9..34071fa6d 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -106,6 +106,7 @@
int dir_menu_view_in_owner;
int drawer_layout;
int inspector_details_view;
+ int job_progress_panel_title;
int option_menu_create_dir;
int option_menu_debug;
int option_menu_extract_all;
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/color/grid_item_ripple_color.xml b/res/flag(com.android.documentsui.flags.use_material3)/color/grid_item_ripple_color.xml
new file mode 100644
index 000000000..85e5b46ce
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/color/grid_item_ripple_color.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:color="@android:color/transparent" />
+ <!-- By default <ripple> introduces a gray-ish layer for the focused state which we don't
+ want, hence explicitly setting focused ripple color to transparent to get rid of that.
+ -->
+ <item android:state_focused="true" android:color="@android:color/transparent" />
+ <item android:state_selected="true" android:alpha="@dimen/ripple_overlay_alpha"
+ android:color="?attr/colorOnPrimaryContainer" />
+ <item android:alpha="@dimen/ripple_overlay_alpha"
+ android:color="?attr/colorOnSurface" />
+</selector>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_item_mask.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_item_mask.xml
new file mode 100644
index 000000000..98473059c
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_item_mask.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <!-- The color here doesn't matter, it's just being used as a mask. -->
+ <solid android:color="@android:color/white" />
+</shape> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_nameplate_background.xml b/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_nameplate_background.xml
index 502efaede..087fc1c15 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_nameplate_background.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/drawable/grid_nameplate_background.xml
@@ -14,56 +14,124 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- selected -->
- <item
- android:state_focused="true"
- android:state_hovered="true"
- android:state_selected="true">
- <layer-list>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="@color/grid_item_ripple_color">
+
+ <!-- The mask below only works for the ripple itself, doesn't work for other <item>s, we
+ need to explicitly apply the drawable if the other items also need this mask. -->
+ <item android:id="@android:id/mask" android:drawable="@drawable/grid_item_mask"/>
+
+ <item>
+ <selector>
+ <!-- selected -->
<item
- android:bottom="@dimen/focus_ring_gap"
- android:left="@dimen/focus_ring_gap"
- android:right="@dimen/focus_ring_gap"
- android:top="@dimen/focus_ring_gap">
- <shape>
- <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
- <solid android:color="?attr/colorPrimaryContainer" />
- </shape>
+ android:state_focused="true"
+ android:state_hovered="true"
+ android:state_selected="true">
+ <layer-list>
+ <item
+ android:bottom="@dimen/focus_ring_gap"
+ android:left="@dimen/focus_ring_gap"
+ android:right="@dimen/focus_ring_gap"
+ android:top="@dimen/focus_ring_gap">
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
+ <solid android:color="?attr/colorPrimaryContainer" />
+ </shape>
+ </item>
+ <item
+ android:bottom="@dimen/focus_ring_gap"
+ android:left="@dimen/focus_ring_gap"
+ android:right="@dimen/focus_ring_gap"
+ android:top="@dimen/focus_ring_gap">
+ <shape android:tint="?attr/colorOnPrimaryContainer">
+ <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
+ <solid android:color="@color/overlay_hover_color_percentage" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ </layer-list>
+ </item>
+ <item android:state_selected="true" android:state_focused="true">
+ <layer-list>
+ <item
+ android:bottom="@dimen/focus_ring_gap"
+ android:left="@dimen/focus_ring_gap"
+ android:right="@dimen/focus_ring_gap"
+ android:top="@dimen/focus_ring_gap">
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
+ <solid android:color="?attr/colorPrimaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ </layer-list>
</item>
<item
- android:bottom="@dimen/focus_ring_gap"
- android:left="@dimen/focus_ring_gap"
- android:right="@dimen/focus_ring_gap"
- android:top="@dimen/focus_ring_gap">
- <shape android:tint="?attr/colorOnPrimaryContainer">
- <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
- <solid android:color="@color/overlay_hover_color_percentage" />
- </shape>
+ android:state_hovered="true"
+ android:state_selected="true">
+ <layer-list>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <solid android:color="?attr/colorPrimaryContainer" />
+ </shape>
+ </item>
+ <item>
+ <shape android:tint="?attr/colorOnPrimaryContainer">
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <solid android:color="@color/overlay_hover_color_percentage" />
+ </shape>
+ </item>
+ </layer-list>
</item>
- <item>
+ <item android:state_selected="true">
<shape>
<corners android:radius="@dimen/grid_item_nameplate_radius" />
- <stroke
- android:width="@dimen/focus_ring_width"
- android:color="?attr/colorSecondary" />
+ <solid android:color="?attr/colorPrimaryContainer" />
</shape>
</item>
- </layer-list>
- </item>
- <item android:state_selected="true" android:state_focused="true">
- <layer-list>
+
+ <!-- unselected -->
<item
- android:bottom="@dimen/focus_ring_gap"
- android:left="@dimen/focus_ring_gap"
- android:right="@dimen/focus_ring_gap"
- android:top="@dimen/focus_ring_gap">
- <shape>
- <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
- <solid android:color="?attr/colorPrimaryContainer" />
- </shape>
+ android:state_focused="true"
+ android:state_hovered="true">
+ <layer-list>
+ <item
+ android:bottom="@dimen/focus_ring_gap"
+ android:left="@dimen/focus_ring_gap"
+ android:right="@dimen/focus_ring_gap"
+ android:top="@dimen/focus_ring_gap">
+ <shape android:tint="?attr/colorOnSurface">
+ <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
+ <solid android:color="@color/overlay_hover_color_percentage" />
+ </shape>
+ </item>
+ <item>
+ <shape>
+ <corners android:radius="@dimen/grid_item_nameplate_radius" />
+ <stroke
+ android:width="@dimen/focus_ring_width"
+ android:color="?attr/colorSecondary" />
+ </shape>
+ </item>
+ </layer-list>
</item>
- <item>
+ <item android:state_focused="true">
<shape>
<corners android:radius="@dimen/grid_item_nameplate_radius" />
<stroke
@@ -71,70 +139,12 @@
android:color="?attr/colorSecondary" />
</shape>
</item>
- </layer-list>
- </item>
- <item
- android:state_hovered="true"
- android:state_selected="true">
- <layer-list>
- <item>
- <shape>
- <corners android:radius="@dimen/grid_item_nameplate_radius" />
- <solid android:color="?attr/colorPrimaryContainer" />
- </shape>
- </item>
- <item>
- <shape android:tint="?attr/colorOnPrimaryContainer">
- <corners android:radius="@dimen/grid_item_nameplate_radius" />
- <solid android:color="@color/overlay_hover_color_percentage" />
- </shape>
- </item>
- </layer-list>
- </item>
- <item android:state_selected="true">
- <shape>
- <corners android:radius="@dimen/grid_item_nameplate_radius" />
- <solid android:color="?attr/colorPrimaryContainer" />
- </shape>
- </item>
-
- <!-- unselected -->
- <item
- android:state_focused="true"
- android:state_hovered="true">
- <layer-list>
- <item
- android:bottom="@dimen/focus_ring_gap"
- android:left="@dimen/focus_ring_gap"
- android:right="@dimen/focus_ring_gap"
- android:top="@dimen/focus_ring_gap">
+ <item android:state_hovered="true">
<shape android:tint="?attr/colorOnSurface">
- <corners android:radius="@dimen/grid_item_nameplate_inner_radius" />
- <solid android:color="@color/overlay_hover_color_percentage" />
- </shape>
- </item>
- <item>
- <shape>
<corners android:radius="@dimen/grid_item_nameplate_radius" />
- <stroke
- android:width="@dimen/focus_ring_width"
- android:color="?attr/colorSecondary" />
+ <solid android:color="@color/overlay_hover_color_percentage" />
</shape>
</item>
- </layer-list>
- </item>
- <item android:state_focused="true">
- <shape>
- <corners android:radius="@dimen/grid_item_nameplate_radius" />
- <stroke
- android:width="@dimen/focus_ring_width"
- android:color="?attr/colorSecondary" />
- </shape>
- </item>
- <item android:state_hovered="true">
- <shape android:tint="?attr/colorOnSurface">
- <corners android:radius="@dimen/grid_item_nameplate_radius" />
- <solid android:color="@color/overlay_hover_color_percentage" />
- </shape>
+ </selector>
</item>
-</selector> \ No newline at end of file
+</ripple> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/drawer_layout.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/drawer_layout.xml
index aeb85442f..0fe74fe64 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout/drawer_layout.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/drawer_layout.xml
@@ -116,4 +116,12 @@
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
+
+ <!-- Peek overlay -->
+ <FrameLayout
+ android:id="@+id/peek_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/fixed_layout.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/fixed_layout.xml
index c2a06122a..4445dd1a6 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout/fixed_layout.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/fixed_layout.xml
@@ -131,4 +131,11 @@
</LinearLayout>
+ <!-- Peek overlay -->
+ <FrameLayout
+ android:id="@+id/peek_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/item_doc_grid.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/item_doc_grid.xml
index f854cf5f8..a8e3148b4 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout/item_doc_grid.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/item_doc_grid.xml
@@ -13,163 +13,170 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/item_root"
- android:layout_width="@dimen/grid_item_width"
- android:layout_height="@dimen/grid_item_height"
- android:layout_margin="@dimen/grid_item_layout_margin"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:clickable="true"
android:defaultFocusHighlightEnabled="false"
- android:focusable="true"
- android:paddingEnd="@dimen/grid_item_padding_end"
- android:paddingStart="@dimen/grid_item_padding_start"
- android:paddingTop="@dimen/grid_item_padding_top">
-
-<!-- Main item thumbnail. Comprised of two overlapping images, the
- visibility of which is controlled by code in
- DirectoryFragment.java. -->
-
- <FrameLayout
- android:id="@+id/thumbnail"
- android:layout_width="@dimen/grid_item_thumbnail_width"
- android:layout_height="@dimen/grid_item_thumbnail_height"
- android:layout_centerHorizontal="true"
- android:background="@drawable/grid_thumbnail_background">
-
- <!-- stroke width will be controlled dynamically in the code. -->
- <com.google.android.material.card.MaterialCardView
- android:id="@+id/icon_wrapper"
- android:layout_width="@dimen/grid_item_icon_width"
- android:layout_height="@dimen/grid_item_icon_height"
- android:layout_gravity="center"
- app:cardBackgroundColor="?attr/colorSurfaceContainerLowest"
- app:cardElevation="0dp"
- app:strokeColor="?attr/colorSecondaryContainer"
- app:strokeWidth="0dp">
-
- <com.android.documentsui.GridItemThumbnail
- android:id="@+id/icon_thumb"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:contentDescription="@null"
- android:scaleType="centerCrop"
- android:tint="?attr/gridItemTint"
- android:tintMode="src_over" />
-
- <com.android.documentsui.GridItemThumbnail
- android:id="@+id/icon_mime_lg"
- android:layout_width="@dimen/icon_size"
- android:layout_height="@dimen/icon_size"
+ android:focusable="true">
+
+ <RelativeLayout
+ android:layout_width="@dimen/grid_width"
+ android:layout_height="@dimen/grid_height"
+ android:layout_margin="@dimen/grid_item_margin"
+ android:layout_gravity="center_horizontal"
+ android:paddingEnd="@dimen/grid_item_padding_end"
+ android:paddingStart="@dimen/grid_item_padding_start"
+ android:paddingTop="@dimen/grid_item_padding_top"
+ android:duplicateParentState="true">
+
+ <!-- Main item thumbnail. Comprised of two overlapping images, the
+ visibility of which is controlled by code in
+ DirectoryFragment.java. -->
+
+ <FrameLayout
+ android:id="@+id/thumbnail"
+ android:layout_width="@dimen/grid_item_thumbnail_width"
+ android:layout_height="@dimen/grid_item_thumbnail_height"
+ android:layout_centerHorizontal="true"
+ android:background="@drawable/grid_thumbnail_background">
+
+ <!-- stroke width will be controlled dynamically in the code. -->
+ <com.google.android.material.card.MaterialCardView
+ android:id="@+id/icon_wrapper"
+ android:layout_width="@dimen/grid_item_icon_width"
+ android:layout_height="@dimen/grid_item_icon_height"
android:layout_gravity="center"
- android:contentDescription="@null"
- android:scaleType="fitCenter" />
-
- </com.google.android.material.card.MaterialCardView>
-
- </FrameLayout>
-
- <FrameLayout
- android:id="@+id/preview_icon"
- android:layout_width="@dimen/button_touch_size"
- android:layout_height="@dimen/button_touch_size"
- android:layout_alignParentEnd="true"
- android:layout_alignParentTop="true"
- android:clickable="true"
- android:focusable="true"
- android:pointerIcon="hand">
-
- <ImageView
- android:layout_width="@dimen/zoom_icon_size"
- android:layout_height="@dimen/zoom_icon_size"
- android:layout_gravity="center"
- android:background="@drawable/circle_button_background"
- android:padding="2dp"
- android:scaleType="fitCenter"
- android:src="@drawable/ic_zoom_out" />
-
- </FrameLayout>
-
- <!-- Item nameplate. Has some text fields (title, size, mod-time, etc). -->
-
- <LinearLayout
- android:id="@+id/nameplate"
- android:layout_width="@dimen/grid_item_nameplate_width"
- android:layout_height="@dimen/grid_item_nameplate_height"
- android:layout_below="@id/thumbnail"
- android:layout_marginTop="@dimen/grid_item_nameplate_marginTop"
- android:background="@drawable/grid_nameplate_background"
- android:orientation="vertical"
- android:duplicateParentState="true"
- android:padding="@dimen/grid_item_nameplate_padding">
-
- <!-- Top row. -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal">
+ app:cardBackgroundColor="?attr/colorSurfaceContainerLowest"
+ app:cardElevation="0dp"
+ app:strokeColor="?attr/colorSecondaryContainer"
+ app:strokeWidth="0dp">
+
+ <com.android.documentsui.GridItemThumbnail
+ android:id="@+id/icon_thumb"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:contentDescription="@null"
+ android:scaleType="centerCrop"
+ android:tint="?attr/gridItemTint"
+ android:tintMode="src_over" />
+
+ <com.android.documentsui.GridItemThumbnail
+ android:id="@+id/icon_mime_lg"
+ android:layout_width="@dimen/icon_size"
+ android:layout_height="@dimen/icon_size"
+ android:layout_gravity="center"
+ android:contentDescription="@null"
+ android:scaleType="fitCenter" />
+
+ </com.google.android.material.card.MaterialCardView>
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/preview_icon"
+ android:layout_width="@dimen/button_touch_size"
+ android:layout_height="@dimen/button_touch_size"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentTop="true"
+ android:clickable="true"
+ android:focusable="true"
+ android:pointerIcon="hand">
<ImageView
- android:id="@+id/icon_profile_badge"
- android:layout_width="@dimen/briefcase_icon_size"
- android:layout_height="@dimen/briefcase_icon_size"
- android:layout_marginEnd="@dimen/briefcase_icon_margin"
- android:contentDescription="@string/a11y_work"
- android:gravity="center_vertical"
- android:src="@drawable/ic_briefcase"
- android:tint="?android:attr/colorAccent" />
-
- <TextView
- android:id="@android:id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:ellipsize="end"
- android:singleLine="true"
- android:textAlignment="center"
- android:textAppearance="@style/FileItemLabelText" />
+ android:layout_width="@dimen/zoom_icon_size"
+ android:layout_height="@dimen/zoom_icon_size"
+ android:layout_gravity="center"
+ android:background="@drawable/circle_button_background"
+ android:padding="2dp"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_zoom_out" />
- </LinearLayout>
+ </FrameLayout>
+
+ <!-- Item nameplate. Has some text fields (title, size, mod-time, etc). -->
- <!-- Bottom row. -->
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal">
-
- <TextView
- android:id="@+id/details"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="4dp"
- android:ellipsize="end"
- android:singleLine="true"
- android:textAlignment="viewStart"
- android:textAppearance="@style/ItemCaptionText" />
-
- <TextView
- android:id="@+id/bullet"
- android:layout_width="wrap_content"
+ android:id="@+id/nameplate"
+ android:layout_width="@dimen/grid_item_nameplate_width"
+ android:layout_height="@dimen/grid_item_nameplate_height"
+ android:layout_below="@id/thumbnail"
+ android:layout_marginTop="@dimen/grid_item_nameplate_marginTop"
+ android:background="@drawable/grid_nameplate_background"
+ android:orientation="vertical"
+ android:duplicateParentState="true"
+ android:padding="@dimen/grid_item_nameplate_padding">
+
+ <!-- Top row. -->
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginEnd="4dp"
- android:singleLine="true"
- android:text="@string/bullet"
- android:textAlignment="viewStart"
- android:textAppearance="@style/ItemCaptionText" />
-
- <TextView
- android:id="@+id/date"
- android:layout_width="wrap_content"
+ android:gravity="center"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/icon_profile_badge"
+ android:layout_width="@dimen/briefcase_icon_size"
+ android:layout_height="@dimen/briefcase_icon_size"
+ android:layout_marginEnd="@dimen/briefcase_icon_margin"
+ android:contentDescription="@string/a11y_work"
+ android:gravity="center_vertical"
+ android:src="@drawable/ic_briefcase"
+ android:tint="?android:attr/colorAccent" />
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAlignment="center"
+ android:textAppearance="@style/FileItemLabelText" />
+
+ </LinearLayout>
+
+ <!-- Bottom row. -->
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:ellipsize="end"
- android:singleLine="true"
- android:textAlignment="viewStart"
- android:textAppearance="@style/ItemCaptionText" />
+ android:gravity="center"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/details"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="4dp"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAlignment="viewStart"
+ android:textAppearance="@style/ItemCaptionText" />
+
+ <TextView
+ android:id="@+id/bullet"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="4dp"
+ android:singleLine="true"
+ android:text="@string/bullet"
+ android:textAlignment="viewStart"
+ android:textAppearance="@style/ItemCaptionText" />
+
+ <TextView
+ android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAlignment="viewStart"
+ android:textAppearance="@style/ItemCaptionText" />
+
+ </LinearLayout>
</LinearLayout>
- </LinearLayout>
+ </RelativeLayout>
-</RelativeLayout> \ No newline at end of file
+</FrameLayout> \ No newline at end of file
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/job_progress_panel.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/job_progress_panel.xml
new file mode 100644
index 000000000..17f6aa6fc
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/job_progress_panel.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2025 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="match_parent"
+ android:layout_height="wrap_content">
+ <com.google.android.material.card.MaterialCardView
+ style="@style/JobProgressPanelStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/job_progress_panel_title"
+ android:text="@string/job_progress_panel_title"
+ android:textAppearance="@style/JobProgressPanelHeaderText"
+ android:layout_margin="@dimen/job_progress_panel_header_margin" />
+ <androidx.recyclerview.widget.RecyclerView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/job_progress_list" />
+ </LinearLayout>
+ </com.google.android.material.card.MaterialCardView>
+</FrameLayout>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml
index bfbb83c17..091444155 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/nav_rail_layout.xml
@@ -179,4 +179,12 @@
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
+
+ <!-- Peek overlay -->
+ <FrameLayout
+ android:id="@+id/peek_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/layout/peek_layout.xml b/res/flag(com.android.documentsui.flags.use_material3)/layout/peek_layout.xml
new file mode 100644
index 000000000..50102d622
--- /dev/null
+++ b/res/flag(com.android.documentsui.flags.use_material3)/layout/peek_layout.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/peek_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/peek_overlay_background"
+ android:focusable="false" />
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/colors.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/colors.xml
index fe98c92b5..5696288e6 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/colors.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/colors.xml
@@ -91,4 +91,8 @@
</shape>
-->
<color name="overlay_hover_color_percentage">#14000000</color> <!-- 8% -->
+
+ <!-- Peek overlay static color. Makes the background dimmer with an 80% opacity. This color is not
+ intended to be dynamic, and is defined specifically for Peek. -->
+ <color name="peek_overlay_background">#CC000000</color> <!-- 80% -->
</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
index 8c1fb7440..fa9e436ab 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/dimens.xml
@@ -43,9 +43,10 @@
<dimen name="progress_bar_height">4dp</dimen>
<fraction name="grid_scale_min">85%</fraction>
<fraction name="grid_scale_max">200%</fraction>
- <dimen name="grid_width">152dp</dimen>
+ <dimen name="grid_width">150dp</dimen>
+ <dimen name="grid_height">132dp</dimen>
<dimen name="grid_section_separator_height">0dp</dimen>
- <dimen name="grid_item_margin">6dp</dimen>
+ <dimen name="grid_item_margin">@dimen/space_small_1</dimen>
<dimen name="grid_padding_horiz">4dp</dimen>
<dimen name="grid_padding_vert">4dp</dimen>
<dimen name="list_item_height">56dp</dimen>
@@ -71,8 +72,6 @@
<dimen name="breadcrumb_item_arrow_size">16dp</dimen>
<dimen name="dir_elevation">8dp</dimen>
<dimen name="drag_shadow_size">120dp</dimen>
- <dimen name="grid_item_width">150dp</dimen>
- <dimen name="grid_item_height">132dp</dimen>
<dimen name="grid_item_padding_start">@dimen/space_extra_small_2</dimen>
<dimen name="grid_item_padding_end">@dimen/space_extra_small_2</dimen>
<dimen name="grid_item_padding_top">@dimen/space_extra_small_2</dimen>
@@ -81,7 +80,6 @@
<dimen name="grid_item_thumbnail_radius">12dp</dimen>
<dimen name="grid_item_icon_width">64dp</dimen>
<dimen name="grid_item_icon_height">64dp</dimen>
- <dimen name="grid_item_layout_margin">@dimen/space_small_1</dimen>
<dimen name="grid_item_nameplate_width">142dp</dimen>
<dimen name="grid_item_nameplate_height">44dp</dimen>
<dimen name="grid_item_nameplate_padding">4dp</dimen>
@@ -250,4 +248,8 @@
<dimen name="focus_ring_gap">5dp</dimen>
<dimen name="hover_overlay_alpha">0.08</dimen>
<dimen name="ripple_overlay_alpha">0.10</dimen>
+
+ <dimen name="job_progress_panel_width">360dp</dimen>
+ <dimen name="job_progress_panel_margin">@dimen/space_small_1</dimen>
+ <dimen name="job_progress_panel_header_margin">@dimen/space_small_1</dimen>
</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
index 6819c12a3..481cd0be8 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/styles.xml
@@ -190,4 +190,11 @@
<item name="android:textColor">@color/nav_rail_item_text_color</item>
<item name="android:textAppearance">@style/NavRailItemTextAppearance</item>
</style>
+
+ <style name="JobProgressPanelStyle" parent="@style/Widget.Material3.CardView.Elevated">
+ <item name="android:layout_marginStart">@dimen/job_progress_panel_margin</item>
+ <item name="android:layout_marginBottom">@dimen/job_progress_panel_margin</item>
+ <item name="cardElevation">1dp</item>
+ <item name="cardBackgroundColor">?attr/colorSurfaceDim</item>
+ </style>
</resources>
diff --git a/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml b/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
index 2f400ea24..57dbb1212 100644
--- a/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
+++ b/res/flag(com.android.documentsui.flags.use_material3)/values/styles_text.xml
@@ -159,4 +159,8 @@
<item name="fontFamily">@string/config_fontFamily</item>
</style>
+ <style name="JobProgressPanelHeaderText" parent="@style/TextAppearance.Material3.TitleMedium">
+ <item name="fontFamily">@string/config_fontFamilyMedium</item>
+ </style>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f8ade4c47..c3f11bab4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -429,6 +429,7 @@
=1 {Zipping <xliff:g id="filename" example="foobar.txt">{filename}</xliff:g>}
other {Zipping # files}
}</string>
+ <string name="job_progress_panel_title" translatable="false">File Progress</string>
<!-- Text in an alert dialog asking user to grant app access to a given directory in an external storage volume -->
<string name="open_external_dialog_request">Grant <xliff:g id="appName" example="System Settings"><b>^1</b></xliff:g>
diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 790feeac4..8a5779a69 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -20,6 +20,7 @@ import static com.android.documentsui.base.Shared.EXTRA_BENCHMARK;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.State.MODE_GRID;
import static com.android.documentsui.util.FlagUtils.isUseMaterial3FlagEnabled;
+import static com.android.documentsui.util.FlagUtils.isUsePeekPreviewFlagEnabled;
import android.content.Context;
import android.content.Intent;
@@ -65,6 +66,7 @@ import com.android.documentsui.base.UserId;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.AppsRowManager;
import com.android.documentsui.dirlist.DirectoryFragment;
+import com.android.documentsui.peek.PeekViewManager;
import com.android.documentsui.prefs.LocalPreferences;
import com.android.documentsui.prefs.PreferencesMonitor;
import com.android.documentsui.queries.CommandInterceptor;
@@ -96,6 +98,7 @@ public abstract class BaseActivity
protected SearchViewManager mSearchManager;
protected AppsRowManager mAppsRowManager;
+ protected @Nullable PeekViewManager mPeekViewManager;
protected UserIdManager mUserIdManager;
protected UserManagerState mUserManagerState;
protected State mState;
@@ -414,6 +417,11 @@ public abstract class BaseActivity
// Base classes must update result in their onCreate.
setResult(AppCompatActivity.RESULT_CANCELED);
updateRecentsSetting();
+
+ if (isUsePeekPreviewFlagEnabled()) {
+ mPeekViewManager = new PeekViewManager(this);
+ mPeekViewManager.initFragment(getSupportFragmentManager());
+ }
}
private NavigationViewManager getNavigationViewManager(Breadcrumb breadcrumb,
diff --git a/src/com/android/documentsui/JobPanelController.kt b/src/com/android/documentsui/JobPanelController.kt
index b3b5f1cfd..a8ab8b0a4 100644
--- a/src/com/android/documentsui/JobPanelController.kt
+++ b/src/com/android/documentsui/JobPanelController.kt
@@ -20,7 +20,10 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.util.Log
+import android.view.LayoutInflater
import android.view.MenuItem
+import android.view.ViewGroup
+import android.widget.PopupWindow
import android.widget.ProgressBar
import com.android.documentsui.base.Menus
import com.android.documentsui.services.FileOperationService
@@ -77,8 +80,29 @@ class JobPanelController(private val mContext: Context) : BroadcastReceiver() {
/**
* Sets the menu item controlled by this class. The item's actionView must be a [ProgressBar].
*/
+ @Suppress("ktlint:standard:comment-wrapping")
fun setMenuItem(menuItem: MenuItem) {
- (menuItem.actionView as ProgressBar).max = MAX_PROGRESS
+ val progressIcon = menuItem.actionView as ProgressBar
+ progressIcon.max = MAX_PROGRESS
+ progressIcon.setOnClickListener { view ->
+ val panel = LayoutInflater.from(mContext).inflate(
+ R.layout.job_progress_panel,
+ /* root= */ null
+ )
+ val popupWidth = mContext.resources.getDimension(R.dimen.job_progress_panel_width) +
+ mContext.resources.getDimension(R.dimen.job_progress_panel_margin)
+ val popup = PopupWindow(
+ /* contentView= */ panel,
+ /* width= */ popupWidth.toInt(),
+ /* height= */ ViewGroup.LayoutParams.WRAP_CONTENT,
+ /* focusable= */ true
+ )
+ popup.showAsDropDown(
+ /* anchor= */ view,
+ /* xoff= */ view.width - popupWidth.toInt(),
+ /* yoff= */ 0
+ )
+ }
mMenuItem = menuItem
updateMenuItem(animate = false)
}
diff --git a/src/com/android/documentsui/dirlist/AnimationView.java b/src/com/android/documentsui/dirlist/AnimationView.java
index d17bddf98..5813085b3 100644
--- a/src/com/android/documentsui/dirlist/AnimationView.java
+++ b/src/com/android/documentsui/dirlist/AnimationView.java
@@ -16,19 +16,22 @@
package com.android.documentsui.dirlist;
-import androidx.annotation.IntDef;
-import androidx.fragment.app.FragmentTransaction;
+import static com.android.documentsui.util.FlagUtils.isUseMaterial3FlagEnabled;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.widget.LinearLayout;
+import androidx.annotation.IntDef;
+import androidx.fragment.app.FragmentTransaction;
+
import com.android.documentsui.R;
import com.android.documentsui.base.Shared;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
/**
* This class exists solely to support animated transition of our directory fragment.
@@ -51,6 +54,8 @@ public class AnimationView extends LinearLayout {
public static final int ANIM_LEAVE = 3;
public static final int ANIM_ENTER = 4;
+ private final ArrayList<OnSizeChangedListener> mOnSizeChangedListeners = new ArrayList<>();
+
private float mPosition = 0f;
// The distance the animation will cover...currently matches the height of the
@@ -65,11 +70,45 @@ public class AnimationView extends LinearLayout {
super(context, attrs);
}
+ /**
+ * A listener of the onSizeChanged method.
+ */
+ public interface OnSizeChangedListener {
+ /**
+ * Called on the View's onSizeChanged.
+ */
+ void onSizeChanged();
+ }
+
+ /**
+ * Adds a listener of the onSizeChanged method.
+ */
+ public void addOnSizeChangedListener(OnSizeChangedListener listener) {
+ if (isUseMaterial3FlagEnabled()) {
+ mOnSizeChangedListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a listener of the onSizeChanged method.
+ */
+ public void removeOnSizeChangedListener(OnSizeChangedListener listener) {
+ if (isUseMaterial3FlagEnabled()) {
+ mOnSizeChangedListeners.remove(listener);
+ }
+ }
+
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mSpan = h;
setPosition(mPosition);
+ if (isUseMaterial3FlagEnabled()) {
+ for (int i = mOnSizeChangedListeners.size() - 1; i >= 0; --i) {
+ mOnSizeChangedListeners.get(i).onSizeChanged();
+ }
+ }
}
public float getPosition() {
diff --git a/src/com/android/documentsui/dirlist/DirectoryFragment.java b/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 2ea906a60..2911d04e9 100644
--- a/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -108,6 +108,7 @@ import com.android.documentsui.clipping.ClipStore;
import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.dirlist.AnimationView.AnimationType;
+import com.android.documentsui.dirlist.AnimationView.OnSizeChangedListener;
import com.android.documentsui.picker.PickActivity;
import com.android.documentsui.services.FileOperation;
import com.android.documentsui.services.FileOperationService;
@@ -188,7 +189,7 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
private SelectionMetadata mSelectionMetadata;
private KeyInputHandler mKeyListener;
private @Nullable DragHoverListener mDragHoverListener;
- private View mRootView;
+ private AnimationView mRootView;
private IconHelper mIconHelper;
private SwipeRefreshLayout mRefreshLayout;
private RecyclerView mRecView;
@@ -416,13 +417,27 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
|| Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action);
}
+ private OnSizeChangedListener mOnSizeChangedListener =
+ new AnimationView.OnSizeChangedListener() {
+ @Override
+ public void onSizeChanged() {
+ if (isUseMaterial3FlagEnabled() && mState.derivedMode != MODE_LIST) {
+ // Update the grid layout when the window size changes.
+ updateLayout(mState.derivedMode);
+ }
+ }
+ };
+
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mHandler = new Handler(Looper.getMainLooper());
mActivity = (BaseActivity) getActivity();
- mRootView = inflater.inflate(R.layout.fragment_directory, container, false);
+ mRootView = (AnimationView) inflater.inflate(R.layout.fragment_directory, container, false);
+ if (isUseMaterial3FlagEnabled()) {
+ mRootView.addOnSizeChangedListener(mOnSizeChangedListener);
+ }
mProgressBar = mRootView.findViewById(R.id.progressbar);
assert mProgressBar != null;
@@ -497,6 +512,10 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
mModel.removeUpdateListener(mAdapter.getModelUpdateListener());
setPreDrawListenerEnabled(false);
+ if (isUseMaterial3FlagEnabled()) {
+ mRootView.removeOnSizeChangedListener(mOnSizeChangedListener);
+ }
+
super.onDestroyView();
}
@@ -809,7 +828,6 @@ public class DirectoryFragment extends Fragment implements SwipeRefreshLayout.On
if (mLayout != null) {
mLayout.setSpanCount(mColumnCount);
}
-
int pad = getDirectoryPadding(mode);
mAppBarHeight = getAppBarLayoutHeight();
mSaveLayoutHeight = getSaveLayoutHeight();
diff --git a/src/com/android/documentsui/files/ActionHandler.java b/src/com/android/documentsui/files/ActionHandler.java
index 86f7a1a14..cbe02dc25 100644
--- a/src/com/android/documentsui/files/ActionHandler.java
+++ b/src/com/android/documentsui/files/ActionHandler.java
@@ -71,6 +71,7 @@ import com.android.documentsui.clipping.DocumentClipper;
import com.android.documentsui.clipping.UrisSupplier;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.inspector.InspectorActivity;
+import com.android.documentsui.peek.PeekViewManager;
import com.android.documentsui.queries.SearchViewManager;
import com.android.documentsui.roots.ProvidersAccess;
import com.android.documentsui.services.FileOperation;
@@ -101,6 +102,7 @@ public class ActionHandler<T extends FragmentActivity & AbstractActionHandler.Co
private final ClipStore mClipStore;
private final DragAndDropManager mDragAndDropManager;
private final Runnable mCloseSelectionBar;
+ private final @Nullable PeekViewManager mPeekViewManager;
ActionHandler(
T activity,
@@ -114,6 +116,7 @@ public class ActionHandler<T extends FragmentActivity & AbstractActionHandler.Co
DocumentClipper clipper,
ClipStore clipStore,
DragAndDropManager dragAndDropManager,
+ @Nullable PeekViewManager peekViewManager,
Injector injector) {
super(activity, state, providers, docs, searchMgr, executors, injector);
@@ -125,6 +128,7 @@ public class ActionHandler<T extends FragmentActivity & AbstractActionHandler.Co
mClipper = clipper;
mClipStore = clipStore;
mDragAndDropManager = dragAndDropManager;
+ mPeekViewManager = peekViewManager;
}
@Override
@@ -609,14 +613,16 @@ public class ActionHandler<T extends FragmentActivity & AbstractActionHandler.Co
mActivity.startActivity(intent);
}
- private void showPeek() {
- Log.d(TAG, "Peek not implemented");
+ private void showPeek(DocumentInfo doc) {
+ if (mPeekViewManager != null) {
+ mPeekViewManager.peekDocument(doc);
+ }
}
@Override
public void showPreview(DocumentInfo doc) {
- if (isUseMaterial3FlagEnabled() && isUsePeekPreviewFlagEnabled()) {
- showPeek();
+ if (isUsePeekPreviewFlagEnabled()) {
+ showPeek(doc);
} else {
showInspector(doc);
}
diff --git a/src/com/android/documentsui/files/FilesActivity.java b/src/com/android/documentsui/files/FilesActivity.java
index cb8708f0b..b254ce525 100644
--- a/src/com/android/documentsui/files/FilesActivity.java
+++ b/src/com/android/documentsui/files/FilesActivity.java
@@ -19,6 +19,7 @@ package com.android.documentsui.files;
import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.util.FlagUtils.isUseMaterial3FlagEnabled;
+import static com.android.documentsui.util.FlagUtils.isVisualSignalsFlagEnabled;
import static com.android.documentsui.util.FlagUtils.isZipNgFlagEnabled;
import android.app.ActivityManager.TaskDescription;
@@ -134,7 +135,7 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler
return clipper.hasItemsToPaste();
}
},
- getApplicationContext(),
+ isVisualSignalsFlagEnabled() ? this : getApplicationContext(),
mInjector.selectionMgr,
mProviders::getApplicationName,
mInjector.getModel()::getItemUri,
@@ -163,6 +164,7 @@ public class FilesActivity extends BaseActivity implements AbstractActionHandler
clipper,
DocumentsApplication.getClipStore(this),
DocumentsApplication.getDragAndDropManager(this),
+ mPeekViewManager,
mInjector);
mInjector.searchManager = mSearchManager;
diff --git a/src/com/android/documentsui/peek/PeekFragment.kt b/src/com/android/documentsui/peek/PeekFragment.kt
new file mode 100644
index 000000000..50ee64efc
--- /dev/null
+++ b/src/com/android/documentsui/peek/PeekFragment.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2025 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.documentsui.peek
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+
+import com.android.documentsui.R
+
+class PeekFragment : Fragment() {
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.peek_layout, container, /* attachToRoot= */ false)
+ }
+}
diff --git a/src/com/android/documentsui/peek/PeekViewManager.kt b/src/com/android/documentsui/peek/PeekViewManager.kt
new file mode 100644
index 000000000..9bbeba3bf
--- /dev/null
+++ b/src/com/android/documentsui/peek/PeekViewManager.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2025 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.documentsui.peek
+
+import android.app.Activity
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.widget.FrameLayout
+import androidx.annotation.IdRes
+import androidx.fragment.app.FragmentManager
+import com.android.documentsui.R
+import androidx.fragment.app.FragmentTransaction
+import com.android.documentsui.base.DocumentInfo
+import com.android.documentsui.util.FlagUtils.Companion.isUsePeekPreviewFlagEnabled
+
+/**
+ * Manager that controls the Peek UI.
+ */
+open class PeekViewManager(
+ private val mActivity: Activity
+) {
+ companion object {
+ const val TAG = "PeekViewManager"
+ }
+
+ private var mPeekFragment: PeekFragment? = null
+
+ open fun initFragment(
+ fm: FragmentManager
+ ) {
+ if (!isUsePeekPreviewFlagEnabled()) {
+ Log.e(TAG, "Attempting to create PeekViewManager while Peek disabled")
+ return
+ }
+
+ if (getOverlayContainer() == null) {
+ Log.e(TAG, "Unable to find Peek container")
+ return
+ }
+
+ // Load the Peek fragment into its container.
+ val peekFragment = PeekFragment()
+ mPeekFragment = peekFragment
+ val ft: FragmentTransaction = fm.beginTransaction()
+ ft.replace(getOverlayId(), peekFragment)
+ ft.commitAllowingStateLoss()
+ }
+
+ open fun peekDocument(doc: DocumentInfo) {
+ if (mPeekFragment == null) {
+ Log.e(TAG, "Peek fragment not initialized")
+ return
+ }
+ show()
+ }
+
+ @IdRes
+ private fun getOverlayId(): Int {
+ return R.id.peek_overlay
+ }
+
+ private fun getOverlayContainer(): FrameLayout? {
+ return mActivity.findViewById(getOverlayId())
+ }
+
+ private fun show() {
+ getOverlayContainer()?.visibility = View.VISIBLE
+ }
+} \ No newline at end of file
diff --git a/src/com/android/documentsui/util/FlagUtils.kt b/src/com/android/documentsui/util/FlagUtils.kt
index a041dde44..cf81d5966 100644
--- a/src/com/android/documentsui/util/FlagUtils.kt
+++ b/src/com/android/documentsui/util/FlagUtils.kt
@@ -56,7 +56,7 @@ class FlagUtils {
@JvmStatic
fun isUsePeekPreviewFlagEnabled(): Boolean {
- return Flags.usePeekPreviewRo()
+ return Flags.usePeekPreviewRo() && isUseMaterial3FlagEnabled()
}
}
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 41ccc1ab1..65e3f259f 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -42,6 +42,7 @@ android_library {
name: "DocumentsUIPerfTests-lib",
srcs: [
"common/com/android/documentsui/**/*.java",
+ "common/com/android/documentsui/**/*.kt",
"functional/com/android/documentsui/ActivityTest.java",
],
resource_dirs: [],
@@ -70,6 +71,7 @@ android_library {
srcs: [
"common/**/*.java",
+ "common/**/*.kt",
"unit/**/*.java",
"unit/**/*.kt",
],
@@ -94,6 +96,7 @@ android_library {
srcs: [
"common/**/*.java",
+ "common/**/*.kt",
"functional/**/*.java",
"functional/**/*.kt",
"unit/**/*.java",
diff --git a/tests/common/com/android/documentsui/bots/Bots.java b/tests/common/com/android/documentsui/bots/Bots.java
index 8cc00ac7a..f0f69b9cf 100644
--- a/tests/common/com/android/documentsui/bots/Bots.java
+++ b/tests/common/com/android/documentsui/bots/Bots.java
@@ -48,6 +48,7 @@ public final class Bots {
public final UiBot main;
public final InspectorBot inspector;
public final NotificationsBot notifications;
+ public final PeekBot peek;
public Bots(UiDevice device, UiAutomation automation, Context context, int timeout) {
main = new UiBot(device, context, TIMEOUT);
@@ -61,13 +62,14 @@ public final class Bots {
menu = new MenuBot(device, context, TIMEOUT);
inspector = new InspectorBot(device, context, TIMEOUT);
notifications = new NotificationsBot(device, context, TIMEOUT);
+ peek = new PeekBot(device, context, TIMEOUT);
}
/**
* A test helper class that provides support for controlling directory list
* and making assertions against the state of it.
*/
- static abstract class BaseBot {
+ public static abstract class BaseBot {
public final UiDevice mDevice;
final Context mContext;
final int mTimeout;
diff --git a/tests/common/com/android/documentsui/bots/PeekBot.kt b/tests/common/com/android/documentsui/bots/PeekBot.kt
new file mode 100644
index 000000000..6906d5a1a
--- /dev/null
+++ b/tests/common/com/android/documentsui/bots/PeekBot.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2025 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.documentsui.bots
+
+import android.content.Context
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.UiObject
+import junit.framework.Assert.assertFalse
+import junit.framework.Assert.assertTrue
+
+/**
+ * A test helper class that provides support for controlling the peek overlay
+ * and making assertions against the state of it.
+ */
+class PeekBot(
+ device: UiDevice,
+ context: Context,
+ timeout: Int
+) : Bots.BaseBot(device, context, timeout) {
+
+ private val mOverlayId: String = "$mTargetPackage:id/peek_overlay"
+ private val mContainerId: String = "$mTargetPackage:id/peek_container"
+
+ fun assertPeekActive() {
+ val peekContainer = findPeekContainer()
+ assertTrue(peekContainer.exists())
+ }
+
+ fun assertPeekHidden() {
+ val peekContainer = findPeekContainer()
+ assertFalse(peekContainer.exists())
+ }
+
+ fun findPeekContainer(): UiObject {
+ return findObject(mOverlayId, mContainerId)
+ }
+}
diff --git a/tests/common/com/android/documentsui/testing/MutableJobProgress.kt b/tests/common/com/android/documentsui/testing/MutableJobProgress.kt
new file mode 100644
index 000000000..b2dd595f9
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/MutableJobProgress.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2025 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.documentsui.testing
+
+import com.android.documentsui.services.Job
+import com.android.documentsui.services.JobProgress
+
+data class MutableJobProgress(
+ var id: String,
+ @Job.State var state: Int,
+ var msg: String?,
+ var hasFailures: Boolean,
+ var currentBytes: Long = -1,
+ var requiredBytes: Long = -1,
+ var msRemaining: Long = -1,
+) {
+ fun toJobProgress() =
+ JobProgress(id, state, msg, hasFailures, currentBytes, requiredBytes, msRemaining)
+}
diff --git a/tests/common/com/android/documentsui/testing/TestPeekViewManager.kt b/tests/common/com/android/documentsui/testing/TestPeekViewManager.kt
new file mode 100644
index 000000000..e3ad6033c
--- /dev/null
+++ b/tests/common/com/android/documentsui/testing/TestPeekViewManager.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 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.documentsui.testing
+
+import android.app.Activity
+import androidx.fragment.app.FragmentManager
+import com.android.documentsui.base.DocumentInfo
+import com.android.documentsui.peek.PeekViewManager
+
+class TestPeekViewManager(mActivity: Activity) : PeekViewManager(mActivity) {
+
+ val peekDocument = TestEventListener<DocumentInfo>()
+
+ override fun initFragment(fm: FragmentManager) {
+ throw UnsupportedOperationException()
+ }
+
+ override fun peekDocument(doc: DocumentInfo) {
+ peekDocument.accept(doc)
+ }
+} \ No newline at end of file
diff --git a/tests/functional/com/android/documentsui/JobPanelUiTest.kt b/tests/functional/com/android/documentsui/JobPanelUiTest.kt
new file mode 100644
index 000000000..5b28b1f5d
--- /dev/null
+++ b/tests/functional/com/android/documentsui/JobPanelUiTest.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2025 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.documentsui
+
+import android.content.Intent
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.action.ViewActions.click
+import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
+import androidx.test.espresso.assertion.ViewAssertions.matches
+import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
+import androidx.test.espresso.matcher.ViewMatchers.withId
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.documentsui.files.FilesActivity
+import com.android.documentsui.flags.Flags.FLAG_USE_MATERIAL3
+import com.android.documentsui.flags.Flags.FLAG_VISUAL_SIGNALS_RO
+import com.android.documentsui.services.FileOperationService.ACTION_PROGRESS
+import com.android.documentsui.services.FileOperationService.EXTRA_PROGRESS
+import com.android.documentsui.services.Job
+import com.android.documentsui.services.JobProgress
+import com.android.documentsui.testing.MutableJobProgress
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RequiresFlagsEnabled(FLAG_USE_MATERIAL3, FLAG_VISUAL_SIGNALS_RO)
+@RunWith(AndroidJUnit4::class)
+class JobPanelUiTest : ActivityTestJunit4<FilesActivity>() {
+ @get:Rule
+ val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+ private var mLastId = 0L
+
+ private fun sendProgress(progresses: ArrayList<JobProgress>, id: Long = mLastId++) {
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ var intent = Intent(ACTION_PROGRESS).apply {
+ `package` = context.packageName
+ putExtra("id", id)
+ putParcelableArrayListExtra(EXTRA_PROGRESS, progresses)
+ }
+ context.sendBroadcast(intent)
+ }
+
+ @Before
+ override fun setUp() {
+ super.setUp()
+ }
+
+ @After
+ override fun tearDown() {
+ super.tearDown()
+ }
+
+ @Test
+ fun testJobPanelAppearsOnClick() {
+ onView(withId(R.id.option_menu_job_progress)).check(doesNotExist())
+ onView(withId(R.id.job_progress_panel_title)).check(doesNotExist())
+
+ val progress = MutableJobProgress(
+ id = "jobId1",
+ state = Job.STATE_SET_UP,
+ msg = "Job started",
+ hasFailures = false,
+ currentBytes = 4,
+ requiredBytes = 10,
+ msRemaining = -1
+ )
+ sendProgress(arrayListOf(progress.toJobProgress()))
+
+ onView(withId(R.id.option_menu_job_progress))
+ .check(matches(isDisplayed()))
+ .perform(click())
+ onView(withId(R.id.job_progress_panel_title)).check(matches(isDisplayed()))
+ }
+}
diff --git a/tests/functional/com/android/documentsui/peek/PeekUiTest.kt b/tests/functional/com/android/documentsui/peek/PeekUiTest.kt
new file mode 100644
index 000000000..a7624df2f
--- /dev/null
+++ b/tests/functional/com/android/documentsui/peek/PeekUiTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2025 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.documentsui.peek
+
+import android.os.RemoteException
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import com.android.documentsui.ActivityTestJunit4
+import com.android.documentsui.files.FilesActivity
+import com.android.documentsui.flags.Flags
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@RequiresFlagsEnabled(Flags.FLAG_USE_MATERIAL3, Flags.FLAG_USE_PEEK_PREVIEW_RO)
+class PeekUiTest : ActivityTestJunit4<FilesActivity?>() {
+ @get:Rule
+ val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+ @Before
+ @Throws(Exception::class)
+ override fun setUp() {
+ super.setUp()
+ initTestFiles()
+ }
+
+ @After
+ @Throws(Exception::class)
+ override fun tearDown() {
+ super.tearDown()
+ }
+
+ @Throws(RemoteException::class)
+ override fun initTestFiles() {
+ mDocsHelper!!.createDocument(rootDir0, "image/png", "image.png")
+ }
+
+ @Test
+ @Throws(
+ Exception::class
+ )
+ fun testShowPeek() {
+ bots!!.peek.assertPeekHidden()
+ bots!!.directory.selectDocument("image.png")
+ bots!!.main.clickActionItem("Get info")
+ bots!!.peek.assertPeekActive()
+ }
+}
diff --git a/tests/unit/com/android/documentsui/JobPanelControllerTest.kt b/tests/unit/com/android/documentsui/JobPanelControllerTest.kt
index be0c9adbd..3e510edd9 100644
--- a/tests/unit/com/android/documentsui/JobPanelControllerTest.kt
+++ b/tests/unit/com/android/documentsui/JobPanelControllerTest.kt
@@ -30,6 +30,7 @@ import com.android.documentsui.services.FileOperationService.ACTION_PROGRESS
import com.android.documentsui.services.FileOperationService.EXTRA_PROGRESS
import com.android.documentsui.services.Job
import com.android.documentsui.services.JobProgress
+import com.android.documentsui.testing.MutableJobProgress
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
@@ -38,19 +39,6 @@ import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
-private data class MutableJobProgress(
- var id: String,
- @Job.State var state: Int,
- var msg: String?,
- var hasFailures: Boolean,
- var currentBytes: Long = -1,
- var requiredBytes: Long = -1,
- var msRemaining: Long = -1,
-) {
- fun toJobProgress() =
- JobProgress(id, state, msg, hasFailures, currentBytes, requiredBytes, msRemaining)
-}
-
@SmallTest
@RequiresFlagsEnabled(FLAG_USE_MATERIAL3, FLAG_VISUAL_SIGNALS_RO)
@RunWith(AndroidJUnit4::class)
diff --git a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
index 1d6ef1fd6..5b19fcdc2 100644
--- a/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
+++ b/tests/unit/com/android/documentsui/files/ActionHandlerTest.java
@@ -76,6 +76,7 @@ import com.android.documentsui.testing.TestDocumentClipper;
import com.android.documentsui.testing.TestDragAndDropManager;
import com.android.documentsui.testing.TestEnv;
import com.android.documentsui.testing.TestFeatures;
+import com.android.documentsui.testing.TestPeekViewManager;
import com.android.documentsui.testing.TestProvidersAccess;
import com.android.documentsui.testing.UserManagers;
import com.android.documentsui.ui.TestDialogController;
@@ -110,6 +111,7 @@ public class ActionHandlerTest {
private ActionHandler<TestActivity> mHandler;
private TestDocumentClipper mClipper;
private TestDragAndDropManager mDragAndDropManager;
+ private TestPeekViewManager mPeekViewManager;
private TestFeatures mFeatures;
private TestConfigStore mTestConfigStore;
private boolean refreshAnswer = false;
@@ -141,6 +143,7 @@ public class ActionHandlerTest {
mDialogs = new TestDialogController();
mClipper = new TestDocumentClipper();
mDragAndDropManager = new TestDragAndDropManager();
+ mPeekViewManager = new TestPeekViewManager(mActivity);
mTestConfigStore = new TestConfigStore();
mEnv.state.configStore = mTestConfigStore;
@@ -744,6 +747,8 @@ public class ActionHandlerTest {
mHandler.showPreview(TestEnv.FILE_GIF);
// The inspector activity is not called.
mActivity.startActivity.assertNotCalled();
+ mPeekViewManager.getPeekDocument().assertCalled();
+ mPeekViewManager.getPeekDocument().assertLastArgument(TestEnv.FILE_GIF);
}
@Test
@@ -751,6 +756,7 @@ public class ActionHandlerTest {
public void testShowInspector() throws Exception {
mHandler.showPreview(TestEnv.FILE_GIF);
+ mPeekViewManager.getPeekDocument().assertNotCalled();
mActivity.startActivity.assertCalled();
Intent intent = mActivity.startActivity.getLastValue();
assertTargetsComponent(intent, InspectorActivity.class);
@@ -864,6 +870,7 @@ public class ActionHandlerTest {
mClipper,
null, // clip storage, not utilized unless we venture into *jumbo* clip territory.
mDragAndDropManager,
+ mPeekViewManager,
mEnv.injector);
}
}