[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 6749343f10 -s ours
am skip reason: contains skip directive
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/WallpaperPicker2/+/26974199
Change-Id: I36efcf2a181c3d8733d73b0867b74d879b59c37d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index b973cf4..1c6d0d2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,7 +35,7 @@
"androidx.lifecycle_lifecycle-runtime-ktx",
"androidx.recyclerview_recyclerview",
"androidx.slice_slice-view",
- "androidx.transition_transition-ktx-nodeps",
+ "androidx.transition_transition-ktx",
"androidx.viewpager2_viewpager2",
"androidx.navigation_navigation-ui-ktx",
"androidx.navigation_navigation-fragment-ktx",
@@ -56,6 +56,7 @@
"SettingsLibActivityEmbedding",
"monet",
"hilt_android",
+ "accessibility_settings_flags_lib",
],
resource_dirs: ["res"],
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 281ae78..5c6b55d 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -1,7 +1,7 @@
aconfig_declarations {
name: "com_android_wallpaper_flags",
package: "com.android.wallpaper",
- container: "system",
+ container: "system_ext",
srcs: ["customization_picker.aconfig"],
}
diff --git a/aconfig/customization_picker.aconfig b/aconfig/customization_picker.aconfig
index bf1d760..80fa274 100644
--- a/aconfig/customization_picker.aconfig
+++ b/aconfig/customization_picker.aconfig
@@ -1,12 +1,5 @@
package: "com.android.wallpaper"
-container: "system"
-
-flag {
- name: "multi_crop_preview_ui_flag"
- namespace: "customization_picker"
- description: "Enables new preview UI if both the SysUI multi crop flag and this flag are true."
- bug: "291761856"
-}
+container: "system_ext"
flag {
name: "wallpaper_restorer_flag"
diff --git a/res/drawable/ic_file_download.xml b/res/drawable/ic_file_download.xml
index 78ecd17..1c34024 100644
--- a/res/drawable/ic_file_download.xml
+++ b/res/drawable/ic_file_download.xml
@@ -18,7 +18,7 @@
android:height="@dimen/wallpaper_control_icon_size"
android:viewportHeight="@dimen/wallpaper_control_icon_viewport_size"
android:viewportWidth="@dimen/wallpaper_control_icon_viewport_size"
- android:tint="@color/wallpaper_control_button_ic_color_tint"
+ android:tint="?android:textColorPrimary"
android:tintMode="multiply">
<path
android:fillColor="@android:color/white"
diff --git a/res/drawable/wallpaper_control_button_download.xml b/res/drawable/wallpaper_control_button_download.xml
index 343a0cb..0f330b9 100644
--- a/res/drawable/wallpaper_control_button_download.xml
+++ b/res/drawable/wallpaper_control_button_download.xml
@@ -15,6 +15,6 @@
limitations under the License.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/wallpaper_control_button_background" />
+ <item android:drawable="@drawable/wallpaper_control_button_off_background" />
<item android:drawable="@drawable/ic_file_download" />
</layer-list>
\ No newline at end of file
diff --git a/res/layout/activity_wallpaper_preview.xml b/res/layout/activity_wallpaper_preview.xml
index 72f1ca3..ad33cd3 100644
--- a/res/layout/activity_wallpaper_preview.xml
+++ b/res/layout/activity_wallpaper_preview.xml
@@ -20,5 +20,4 @@
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:defaultNavHost="true"
- app:navGraph="@navigation/wallpaper_preview_nav_graph" />
\ No newline at end of file
+ app:defaultNavHost="true"/>
\ No newline at end of file
diff --git a/res/layout/floating_sheet2.xml b/res/layout/floating_sheet2.xml
index c0637f1..64fcf06 100644
--- a/res/layout/floating_sheet2.xml
+++ b/res/layout/floating_sheet2.xml
@@ -35,7 +35,7 @@
android:layout_width="match_parent"
android:padding="@dimen/wallpaper_info_pane_padding"
android:layout_marginHorizontal="@dimen/floating_sheet_margin"
- android:layout_marginBottom="120dp"
+ android:layout_marginBottom="@dimen/floating_sheet_bottom_margin"
android:background="@drawable/floating_sheet_background" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_full_preview.xml b/res/layout/fragment_full_preview.xml
index c32b050..092ac71 100644
--- a/res/layout/fragment_full_preview.xml
+++ b/res/layout/fragment_full_preview.xml
@@ -50,7 +50,7 @@
android:background="@drawable/check_circle_full_preview"
android:elevation="@dimen/wallpaper_preview_buttons_elevation"
android:layout_marginEnd="@dimen/set_wallpaper_button_margin_end"
- android:contentDescription="@string/show_preview_controls_action"
+ android:contentDescription="@string/full_preview_check_button_description"
android:textColor="@color/system_on_primary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/toolbar_container"
diff --git a/res/layout/fragment_small_preview_foldable.xml b/res/layout/fragment_small_preview_foldable.xml
index 2ea100b..2ca96a0 100644
--- a/res/layout/fragment_small_preview_foldable.xml
+++ b/res/layout/fragment_small_preview_foldable.xml
@@ -21,51 +21,67 @@
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:transitionGroup="true">
<include
android:id="@+id/toolbar_container"
layout="@layout/section_header_content"
- android:layout_width="match_parent"
- android:layout_height="0dp"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
+ app:layout_constraintEnd_toStartOf="@id/button_set_wallpaper"
+ app:layout_constraintBottom_toTopOf="@+id/pager_group"
+ app:layout_constraintVertical_chainStyle="spread_inside" />
<Button
android:id="@+id/button_set_wallpaper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:elevation="@dimen/wallpaper_preview_buttons_elevation"
android:layout_marginEnd="@dimen/set_wallpaper_button_margin_end"
android:background="@drawable/set_wallpaper_button_background_variant"
+ android:elevation="@dimen/wallpaper_preview_buttons_elevation"
+ android:gravity="center"
+ android:minHeight="@dimen/touch_target_min_height"
android:text="@string/set_wallpaper_button_text"
android:textColor="@color/system_on_primary"
android:textAppearance="@style/WallpaperPicker.Preview.TextAppearance.NoAllCaps"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="@id/toolbar_container"
+ app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/toolbar_container"/>
- <com.android.wallpaper.picker.preview.ui.fragment.smallpreview.DualPreviewViewPager
- android:id="@+id/dual_preview_pager"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingHorizontal="@dimen/small_dual_preview_edge_space"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
-
- <com.android.wallpaper.picker.preview.ui.fragment.smallpreview.views.TabsPagerContainer
- android:id="@+id/pager_container"
+ <LinearLayout
+ android:id="@+id/pager_group"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:layout_marginTop="@dimen/spacing_10dp"
- app:layout_constraintTop_toBottomOf="@id/dual_preview_pager"
+ android:paddingBottom="@dimen/wallpaper_control_button_size"
+ android:gravity="center"
+ android:importantForAccessibility="no"
+ android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/toolbar_container"
+ app:layout_constraintBottom_toBottomOf="parent">
+
+ <com.android.wallpaper.picker.preview.ui.fragment.smallpreview.DualPreviewViewPager
+ android:id="@+id/dual_preview_pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="bottom"
+ android:paddingHorizontal="@dimen/small_dual_preview_edge_space"
+ android:importantForAccessibility="no" />
+
+ <com.android.wallpaper.picker.preview.ui.fragment.smallpreview.views.TabsPagerContainer
+ android:id="@+id/pager_container"
+ android:importantForAccessibility="no"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:layout_marginTop="@dimen/spacing_10dp"
+ android:layout_marginBottom="@dimen/spacing_10dp" />
+ </LinearLayout>
<com.android.wallpaper.picker.preview.ui.view.PreviewActionFloatingSheet
android:id="@+id/floating_sheet"
@@ -77,8 +93,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/wallpaper_control_button_group_margin_end"
+ android:layout_marginTop="@dimen/wallpaper_control_button_group_margin_top"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"/>
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_small_preview_handheld.xml b/res/layout/fragment_small_preview_handheld.xml
index a255ace..7596c22 100644
--- a/res/layout/fragment_small_preview_handheld.xml
+++ b/res/layout/fragment_small_preview_handheld.xml
@@ -22,7 +22,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:transitionGroup="true">
<include
android:id="@+id/toolbar_container"
@@ -37,9 +38,11 @@
android:id="@+id/button_set_wallpaper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:elevation="@dimen/wallpaper_preview_buttons_elevation"
android:layout_marginEnd="@dimen/set_wallpaper_button_margin_end"
android:background="@drawable/set_wallpaper_button_background_variant"
+ android:elevation="@dimen/wallpaper_preview_buttons_elevation"
+ android:gravity="center"
+ android:minHeight="@dimen/touch_target_min_height"
android:text="@string/set_wallpaper_button_text"
android:textColor="@color/system_on_primary"
android:textAppearance="@style/WallpaperPicker.Preview.TextAppearance.NoAllCaps"
diff --git a/res/layout/full_wallpaper_preview_card.xml b/res/layout/full_wallpaper_preview_card.xml
index 624de83..1112830 100644
--- a/res/layout/full_wallpaper_preview_card.xml
+++ b/res/layout/full_wallpaper_preview_card.xml
@@ -17,8 +17,7 @@
<com.android.wallpaper.picker.preview.ui.view.FullPreviewFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wallpaper_preview_crop"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center">
+ android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="@+id/preview_card"
@@ -26,9 +25,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="true"
- android:contentDescription="@string/wallpaper_preview_card_content_description">
+ android:contentDescription="@string/wallpaper_preview_card_content_description"
+ android:layout_gravity="center">
- <com.android.wallpaper.picker.preview.ui.view.SystemScaledWallpaperPreviewSurfaceView
+ <SurfaceView
android:id="@+id/wallpaper_surface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
@@ -38,6 +38,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="noHideDescendants" />
+
+ <View
+ android:id="@+id/preview_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/gradient_black_scrim"
+ android:importantForAccessibility="noHideDescendants"
+ android:visibility="gone" />
</androidx.cardview.widget.CardView>
+
</com.android.wallpaper.picker.preview.ui.view.FullPreviewFrameLayout>
diff --git a/res/layout/fullscreen_wallpaper_preview_old.xml b/res/layout/fullscreen_wallpaper_preview_old.xml
new file mode 100644
index 0000000..40f7193
--- /dev/null
+++ b/res/layout/fullscreen_wallpaper_preview_old.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 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">
+
+ <ImageView
+ android:id="@+id/low_res_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerCrop"
+ android:background="?android:colorBackground" />
+
+ <com.android.wallpaper.picker.preview.ui.view.SystemScaledSubsamplingScaleImageView
+ android:id="@+id/full_res_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</FrameLayout>
\ No newline at end of file
diff --git a/res/layout/grid_item_category.xml b/res/layout/grid_item_category.xml
index 04cb5f1..60f63e4 100755
--- a/res/layout/grid_item_category.xml
+++ b/res/layout/grid_item_category.xml
@@ -17,6 +17,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tile"
+ android:importantForAccessibility="no"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@@ -25,6 +26,7 @@
android:id="@+id/category"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:importantForAccessibility="no"
android:foreground="?attr/selectableItemBackground"
app:cardCornerRadius="?android:dialogCornerRadius"
app:cardElevation="0dp">
diff --git a/res/layout/my_photos.xml b/res/layout/my_photos.xml
index 52b5b97..441c8cc 100644
--- a/res/layout/my_photos.xml
+++ b/res/layout/my_photos.xml
@@ -20,22 +20,26 @@
android:id="@+id/tile_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:focusable="false"
android:orientation="vertical"
android:layout_marginTop="10dp"
- android:importantForAccessibility="no">
+ android:importantForAccessibility="yes">
<TextView
android:id="@+id/tile_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:contentDescription="@string/choose_a_wallpaper_section_title"
android:text="@string/choose_a_wallpaper_section_title"
android:textAppearance="@style/CategorySectionTitleTextAppearance"
+ android:focusable="false"
android:layout_gravity="bottom" />
<include android:id="@+id/tile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
+ android:focusable="true"
layout="@layout/grid_item_category">
</include>
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/preview_customize_settings2.xml b/res/layout/preview_customize_settings2.xml
new file mode 100644
index 0000000..eeae7bf
--- /dev/null
+++ b/res/layout/preview_customize_settings2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2024 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="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/floating_sheet_customize_content_min_height"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <!-- TODO(b/179127651): Figure out where these slices are generated to update them -->
+ <androidx.slice.widget.SliceView
+ android:id="@+id/settings_slice"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+</LinearLayout>
diff --git a/res/layout/set_wallpaper_dialog.xml b/res/layout/set_wallpaper_dialog.xml
index 41917c2..8105e6c 100644
--- a/res/layout/set_wallpaper_dialog.xml
+++ b/res/layout/set_wallpaper_dialog.xml
@@ -14,70 +14,77 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingStart="@dimen/spacing_8dp"
- android:paddingEnd="@dimen/spacing_8dp"
- android:paddingBottom="@dimen/set_wallpaper_dialog_bottom_padding">
-
- <TextView
- android:id="@+id/title"
- style="@style/TextAppearance.SetWallpaperDialog.Title"
+ android:overScrollMode="never">
+ <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/set_wallpaper_button_text"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
+ android:paddingStart="@dimen/spacing_8dp"
+ android:paddingEnd="@dimen/spacing_8dp"
+ android:paddingBottom="@dimen/set_wallpaper_dialog_bottom_padding"
+ android:layout_gravity="center_horizontal">
- <FrameLayout
- android:id="@+id/preview_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintTop_toBottomOf="@+id/title"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
- <include layout="@layout/set_wallpaper_dialog_foldable_preview"
- android:id="@+id/foldable_previews"
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.SetWallpaperDialog.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="@dimen/abc_dialog_title_divider_material"
- android:paddingBottom="@dimen/abc_dialog_title_divider_material"
- android:visibility="gone">
- </include>
- <include layout="@layout/set_wallpaper_dialog_handheld_preview"
- android:id="@+id/handheld_previews"
- android:layout_width="@dimen/set_wallpaper_dialog_handheld_width"
+ android:text="@string/set_wallpaper_button_text"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ <FrameLayout
+ android:id="@+id/preview_container"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingTop="@dimen/abc_dialog_title_divider_material"
- android:paddingBottom="@dimen/abc_dialog_title_divider_material"
- android:visibility="gone">
- </include>
- </FrameLayout>
+ app:layout_constraintTop_toBottomOf="@+id/title"
+ app:layout_constraintBottom_toTopOf="@+id/button_set"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+ <include layout="@layout/set_wallpaper_dialog_foldable_preview"
+ android:id="@+id/foldable_previews"
+ android:layout_width="@dimen/set_wallpaper_dialog_foldable_content_width"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/abc_dialog_title_divider_material"
+ android:paddingBottom="@dimen/abc_dialog_title_divider_material"
+ android:visibility="gone"/>
+ <include layout="@layout/set_wallpaper_dialog_handheld_preview"
+ android:id="@+id/handheld_previews"
+ android:layout_width="@dimen/set_wallpaper_dialog_handheld_content_width"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/abc_dialog_title_divider_material"
+ android:paddingBottom="@dimen/abc_dialog_title_divider_material"
+ android:visibility="gone"/>
+ </FrameLayout>
- <Button
- android:id="@+id/button_set"
- style="@style/SetWallpaperDialog.Button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/set_wallpaper_dialog_set_button"
- android:layout_marginVertical="@dimen/set_wallpaper_dialog_button_margin_vertical"
- app:layout_constraintTop_toBottomOf="@id/preview_container"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
+ <Button
+ android:id="@+id/button_set"
+ style="@style/SetWallpaperDialog.Button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginVertical="@dimen/set_wallpaper_dialog_button_margin_vertical"
+ android:gravity="center"
+ android:minHeight="@dimen/touch_target_min_height"
+ android:text="@string/set_wallpaper_dialog_set_button"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
- <Button
- android:id="@+id/button_cancel"
- style="@style/SetWallpaperDialog.Button.OutlinedButton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/cancel"
- android:layout_marginEnd="@dimen/spacing_8dp"
- android:layout_marginVertical="@dimen/set_wallpaper_dialog_button_margin_vertical"
- app:layout_constraintTop_toBottomOf="@id/preview_container"
- app:layout_constraintEnd_toStartOf="@+id/button_set"/>
+ <Button
+ android:id="@+id/button_cancel"
+ style="@style/SetWallpaperDialog.Button.OutlinedButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/spacing_8dp"
+ android:layout_marginVertical="@dimen/set_wallpaper_dialog_button_margin_vertical"
+ android:gravity="center"
+ android:minHeight="@dimen/touch_target_min_height"
+ android:text="@string/cancel"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/button_set"/>
-</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
+ </androidx.constraintlayout.widget.ConstraintLayout>
+</ScrollView>
diff --git a/res/layout/set_wallpaper_dialog_foldable_preview.xml b/res/layout/set_wallpaper_dialog_foldable_preview.xml
index 71471ec..65cc955 100644
--- a/res/layout/set_wallpaper_dialog_foldable_preview.xml
+++ b/res/layout/set_wallpaper_dialog_foldable_preview.xml
@@ -22,13 +22,16 @@
<include layout="@layout/small_preview_foldable_card_view_selector"
android:id="@+id/lock_preview_selector"
android:layout_width="@dimen/set_wallpaper_dialog_foldable_preview_width"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"/>
<TextView
style="@style/TextAppearance.SetWallpaperDialog.Subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:labelFor="@+id/lock_preview_selector"
android:layout_gravity="center_horizontal"
- android:text="@string/set_wallpaper_lock_screen_destination"/>
+ android:text="@string/set_wallpaper_lock_screen_destination"
+ android:maxWidth="@dimen/set_wallpaper_dialog_foldable_preview_width"/>
<android.widget.Space
android:layout_width="match_parent"
@@ -37,12 +40,15 @@
<include layout="@layout/small_preview_foldable_card_view_selector"
android:id="@+id/home_preview_selector"
android:layout_width="@dimen/set_wallpaper_dialog_foldable_preview_width"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"/>
<TextView
style="@style/TextAppearance.SetWallpaperDialog.Subtitle"
android:layout_width="wrap_content"
+ android:labelFor="@+id/home_preview_selector"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:text="@string/set_wallpaper_home_screen_destination"/>
+ android:text="@string/set_wallpaper_home_screen_destination"
+ android:maxWidth="@dimen/set_wallpaper_dialog_foldable_preview_width"/>
</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/set_wallpaper_dialog_handheld_preview.xml b/res/layout/set_wallpaper_dialog_handheld_preview.xml
index d82e438..b79642f 100644
--- a/res/layout/set_wallpaper_dialog_handheld_preview.xml
+++ b/res/layout/set_wallpaper_dialog_handheld_preview.xml
@@ -34,7 +34,9 @@
style="@style/TextAppearance.SetWallpaperDialog.Subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:labelFor="@+id/lock_preview_selector"
android:text="@string/set_wallpaper_lock_screen_destination"
+ android:maxWidth="@dimen/set_wallpaper_dialog_handheld_preview_width"
app:layout_constraintTop_toBottomOf="@id/lock_preview_selector"
app:layout_constraintStart_toStartOf="@+id/lock_preview_selector"
app:layout_constraintEnd_toEndOf="@+id/lock_preview_selector"/>
@@ -53,7 +55,9 @@
style="@style/TextAppearance.SetWallpaperDialog.Subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:labelFor="@+id/home_preview_selector"
android:text="@string/set_wallpaper_home_screen_destination"
+ android:maxWidth="@dimen/set_wallpaper_dialog_handheld_preview_width"
app:layout_constraintTop_toBottomOf="@id/home_preview_selector"
app:layout_constraintStart_toStartOf="@+id/home_preview_selector"
app:layout_constraintEnd_toEndOf="@+id/home_preview_selector"/>
diff --git a/res/layout/set_wallpaper_progress_dialog_view.xml b/res/layout/set_wallpaper_progress_dialog_view.xml
new file mode 100644
index 0000000..80df67e
--- /dev/null
+++ b/res/layout/set_wallpaper_progress_dialog_view.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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"
+ style="@style/LightDialogTheme"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/set_wallpaper_progress_dialog_padding">
+
+ <ProgressBar
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="@dimen/set_wallpaper_progress_dialog_progress_bar_margin_end"/>
+
+ <TextView
+ android:id="@+id/set_wallpaper_progress_dialog_text"
+ android:textAppearance="?android:textAppearance"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/set_wallpaper_progress_message" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/small_preview_foldable_card_view_selector.xml b/res/layout/small_preview_foldable_card_view_selector.xml
index c5e295e..0793c1d 100644
--- a/res/layout/small_preview_foldable_card_view_selector.xml
+++ b/res/layout/small_preview_foldable_card_view_selector.xml
@@ -26,7 +26,8 @@
<FrameLayout
android:layout_width="wrap_content"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:importantForAccessibility="noHideDescendants">
<include
android:id="@+id/small_preview_folded_preview"
layout="@layout/small_wallpaper_preview_card"
@@ -65,7 +66,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/set_wallpaper_dialog_preview_selector"/>
-
</FrameLayout>
</com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout>
diff --git a/res/layout/wallpaper_info_view2.xml b/res/layout/wallpaper_info_view2.xml
index 737a822..ca41219 100644
--- a/res/layout/wallpaper_info_view2.xml
+++ b/res/layout/wallpaper_info_view2.xml
@@ -19,6 +19,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@drawable/horizontal_divider_8dp"
+ android:textDirection="locale"
android:orientation="vertical">
<TextView
@@ -51,5 +52,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/explore"
+ android:minHeight="@dimen/touch_target_min_height"
android:visibility="gone" />
</LinearLayout>
diff --git a/res/navigation/wallpaper_preview_nav_graph.xml b/res/navigation/wallpaper_preview_nav_graph.xml
index a6bb666..298d8f8 100644
--- a/res/navigation/wallpaper_preview_nav_graph.xml
+++ b/res/navigation/wallpaper_preview_nav_graph.xml
@@ -16,7 +16,7 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/wallpaper_preview_nav_graph"
- app:startDestination="@id/smallPreviewFragment">
+ app:startDestination="@+id/smallPreviewFragment">
<fragment
android:id="@+id/smallPreviewFragment"
@@ -26,13 +26,16 @@
app:destination="@+id/fullPreviewFragment" />
<action
android:id="@+id/action_smallPreviewFragment_to_setWallpaperDialog"
- app:destination="@id/setWallpaperDialog" />
+ app:destination="@+id/setWallpaperDialog" />
+ <action
+ android:id="@+id/action_smallPreviewFragment_to_creativeEditPreviewFragment"
+ app:destination="@+id/creativeEditPreviewFragment" />
</fragment>
<fragment
- android:id="@+id/creativeNewPreviewFragment"
- android:name="com.android.wallpaper.picker.preview.ui.fragment.CreativeNewPreviewFragment">
+ android:id="@+id/creativeEditPreviewFragment"
+ android:name="com.android.wallpaper.picker.preview.ui.fragment.CreativeEditPreviewFragment">
<action
- android:id="@+id/action_creativeNewPreviewFragment_to_smallPreviewFragment"
+ android:id="@+id/action_creativeEditPreviewFragment_to_smallPreviewFragment"
app:destination="@+id/smallPreviewFragment" />
</fragment>
<fragment
@@ -42,5 +45,8 @@
<dialog
android:id="@+id/setWallpaperDialog"
android:name="com.android.wallpaper.picker.preview.ui.fragment.SetWallpaperDialogFragment">
+ <action
+ android:id="@+id/action_setWallpaperDialog_self"
+ app:destination="@+id/setWallpaperDialog" />
</dialog>
</navigation>
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 8a1324c..06d9fec 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Herlaai daaglikse tuisskermmuurpapier"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Herlaai daaglikse muurpapier"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Muurpapiervoorskouskerm"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Klaar muurpapier geredigeer"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Herlaai tans daaglikse muurpapier …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Kon nie daaglikse muurpapier herlaai nie. Gaan jou netwerkverbinding na en probeer weer."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Muurpapiere op toestel"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 4d0e868..fed9820 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"የዕለታዊ መነሻ ማያ ገፅ ልጣፍን ያድሱ"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ዕለታዊ ልጣፍን ያድሱ"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"የልጣፍ ቅድመ ዕይታ ማያ ገጽ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"የልጣፍ አርትዖት ተከናውኗል"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"ዕለታዊ ልጣፍን በማደስ ላይ…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ዕለታዊ ልጣፍን ማደስ አልተሳካም። እባክዎ የእርስዎን የአውታረ መረብ ግንኙነት ይፈትሹ እና እንደገና ይሞክሩ።"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"የመሣሪያ ላይ ልጣፎች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 21586fa..948ba2f 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"إعادة تحميل خلفية الشاشة الرئيسية اليومية"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"إعادة تحميل الخلفية اليومية"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"شاشة معاينة الخلفية"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"تم تعديل الخلفية"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"تجري إعادة تحميل الخلفية اليومية…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"تعذّرت إعادة تحميل الخلفية اليومية. يُرجى التحقق من اتصالك بالشبكة وإعادة المحاولة."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"خلفيات على الجهاز"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index f8497f3..aab9cfd 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"গৃহ স্ক্ৰীনৰ দৈনিক ৱালপেপাৰ ৰিফ্ৰেশ্ব কৰক"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"দৈনিক ৱালপেপাৰ ৰিফ্ৰেশ্ব কৰক"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ৱালপেপাৰৰ পূৰ্বদৰ্শনৰ স্ক্ৰীন"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ৱালপেপাৰ সম্পাদনা কৰি হ’ল"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"দৈনিক ৱালপেপাৰ ৰিফ্ৰেশ্ব কৰি থকা হৈছে …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"দৈনিক ৱালপেপাৰ ৰিফ্ৰেশ্ব কৰিব পৰা নগ\'ল। অনুগ্ৰহ কৰি আপোনাৰ নেটৱর্ক সংযোগ পৰীক্ষা কৰক আৰু আকৌ চেষ্টা কৰক।"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ডিভাইচত থকা ৱালপেপাৰ"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index d206b65..7ba8b60 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Əsas ekranın divar kağızını gündəlik yeniləyin"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Divar kağızını gündəlik yeniləyin"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Divar kağızını önizləmə ekranı"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Divar kağızı redaktə edildi"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Günlük divar kağızı yenilənir..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Gündəlik divar kağızını yeniləmək olmadı. Şəbəkəni yoxlayın və yenidən cəhd edin."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Cihazdakı divar kağızları"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 847506f..212dcf0 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Osveži dnevnu pozadinu za početni ekran"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Osveži dnevnu pozadinu"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ekran prikaza pozadine"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Izmene pozadine su završene"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Dnevna pozadina se osvežava…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Osvežavanje dnevne pozadine nije uspelo. Proverite mrežnu vezu i probajte ponovo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Pozadine na uređaju"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index e4e7d04..132b975 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Абнавіць шпалеры галоўнага экрана на кожны дзень"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Абнавіць шпалеры на кожны дзень"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Экран перадпрагляду шпалер"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Рэдагаванне шпалер завершана"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Абнаўленне шпалер на кожны дзень…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Не атрымалася абнавіць шпалеры на кожны дзень. Спраўдзіце падключэнне да сеткі і паўтарыце спробу."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Шпалеры на прыладзе"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index df706e3..c3c722a 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Опресняване на тапета за деня на началния екран"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Опресняване на тапета за деня"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Екран за визуализация на тапета"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Край на редактирането на тапета"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Тапетът за деня се опреснява…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Опресняването на тапета за деня не бе успешно. Моля, проверете връзката си с мрежата и опитайте отново."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Тапети, съхранявани на у-вото"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 707487c..01d3fcf 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"প্রতিদিনের হোম স্ক্রিন ওয়ালপেপার রিফ্রেশ করুন"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"প্রতিদিনের ওয়ালপেপার রিফ্রেশ করুন"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ওয়ালপেপার প্রিভিউ স্ক্রিন"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ওয়ালপেপার এডিট করা হয়ে গেছে"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"প্রতিদিনের ওয়ালপেপার রিফ্রশ করা হচ্ছে…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"প্রতিদিনের ওয়ালপেপার রিফ্রেশ করা গেল না। অনুগ্রহ করে আপনার কানেকশন যাচাই করে আবার চেষ্টা করুন।"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ডিভাইসে থাকা ওয়ালপেপার"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 38e2d6e..d1550a0 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Osvježite dnevnu pozadinsku sliku na početnom ekranu"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Osvježite dnevnu pozadinsku sliku"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ekran pregleda pozadinske slike"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Gotovo je uređivanje pozadinske slike"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Osvježavanje dnevne pozadinske slike…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Osvježavanje dnevne pozadinske slike nije uspjelo. Provjerite vezu s mrežom i pokušajte ponovo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Pozadinske slike na uređaju"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index e03efb4..50e9bff 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualitza el fons de pantalla diari de la pantalla d\'inici"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualitza el fons de pantalla diari"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Pantalla de previsualització del fons de pantalla"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"He acabat d\'editar el fons de pantalla"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"S\'està actualitzant el fons de pantalla diari…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"No s\'ha pogut actualitzar el fons de pantalla diari. Comprova la connexió a la xarxa i torna-ho a provar."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fons de pantalla del dispositiu"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 0285c47..1bf3819 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Obnovit denní tapetu plochy"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Obnovit denní tapetu"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Obrazovka náhledu tapety"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Úprava tapety je dokončena"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Obnovování denní tapety…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Denní tapetu se nepodařilo obnovit. Zkontrolujte připojení k síti a zkuste to znovu."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Tapety v zařízení"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 3f503e4..c36b973 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Opdater daglig baggrund på startskærmen"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Opdater daglig baggrund"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Skærm til forhåndsvisning af baggrund"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Redigering af baggrund er udført"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Opdaterer daglig baggrund…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Opdateringen af din daglige baggrund mislykkedes. Tjek din netværksforbindelse, og prøv igen."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Baggrunde på enheden"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 8501057..8d788b1 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Täglichen Hintergrund des Startbildschirms aktualisieren"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Täglichen Hintergrund aktualisieren"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Vorschau für Bildschirmhintergrund"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Bearbeitung des Hintergrunds abgeschlossen"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Täglicher Hintergrund wird aktualisiert…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Aktualisierung des täglichen Hintergrunds fehlgeschlagen. Prüfe die Netzwerkverbindung und versuche es noch einmal."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Hintergründe auf dem Gerät"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index afcb36a..ced134f 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Ανανέωση ημερήσιας ταπετσαρίας αρχικής οθόνης"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Ανανέωση ημερήσιας ταπετσαρίας"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Οθόνη προεπισκόπησης ταπετσαρίας"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Η επεξεργασία της ταπετσαρίας ολοκληρώθηκε"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Ανανέωση ημερήσιας ταπετσαρίας…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Αποτυχία ανανέωσης ημερήσιας ταπετσαρίας. Ελέγξτε τη σύνδεση δικτύου σας και δοκιμάστε ξανά."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Ταπετσαρίες στη συσκευή"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index f3dca5e..e637345 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Refresh daily home screen wallpaper"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Refresh daily wallpaper"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Wallpaper preview screen"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Done editing wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Refreshing daily wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Failed to refresh daily wallpaper. Please check your network connection and try again."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"On-device wallpapers"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index e9bec55..c658dfe 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -71,6 +71,12 @@
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Refresh daily wallpaper"</string>
<!-- no translation found for preview_screen_description (3386387053327775919) -->
<skip />
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <!-- no translation found for full_preview_check_button_description (700484353763952975) -->
+ <skip />
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Refreshing daily wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Failed to refresh daily wallpaper. Please check your network connection and try again."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"On-device wallpapers"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f3dca5e..e637345 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Refresh daily home screen wallpaper"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Refresh daily wallpaper"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Wallpaper preview screen"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Done editing wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Refreshing daily wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Failed to refresh daily wallpaper. Please check your network connection and try again."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"On-device wallpapers"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index f3dca5e..e637345 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Refresh daily home screen wallpaper"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Refresh daily wallpaper"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Wallpaper preview screen"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Done editing wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Refreshing daily wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Failed to refresh daily wallpaper. Please check your network connection and try again."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"On-device wallpapers"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index bfefc9d..4f45c14 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -67,6 +67,9 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Refresh daily home screen wallpaper"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Refresh daily wallpaper"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Wallpaper preview screen"</string>
+ <string name="folded_device_state_description" msgid="4972608448265616264">"Folded"</string>
+ <string name="unfolded_device_state_description" msgid="3071975681472460627">"Unfolded"</string>
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Done editing wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Refreshing daily wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Failed to refresh daily wallpaper. Please check your network connection and try again."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"On-device wallpapers"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 5308783..54ef733 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualiza el fondo diario de la pantalla principal"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualiza el fondo de pantalla diario"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Pantalla de vista previa del fondo de pantalla"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Dejar de editar el fondo de pantalla"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Actualizando fondo de pantalla diario…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"No se pudo actualizar el fondo de pantalla diario. Comprueba tu conexión de red y vuelve a intentarlo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fondos del dispositivo"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index d3a6bce..da11fe7 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualizar el fondo de la pantalla de inicio diario"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualizar el fondo de pantalla diario"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Pantalla de vista previa del fondo de pantalla"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Dejar de editar fondo de pantalla"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Actualizando el fondo de pantalla diario…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"No se ha podido actualizar el fondo de pantalla diario. Comprueba tu conexión a Internet y vuelve a intentarlo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fondos pantalla en dispositivo"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 5ab6284..b8df98b 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Avaekraani päeva taustapildi värskendamine"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Päeva taustapildi värskendamine"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Taustapildi eelvaatekuva"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Olen taustapildi muutmisega valmis"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Päeva taustapildi värskendamine …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Päeva taustapildi värskendamine ebaõnnestus. Kontrollige võrguühendust ja proovige uuesti."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Seadmes olevad taustapildid"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index a0797e9..7c0857d 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Freskatu orri nagusiaren eguneko horma-papera"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Freskatu eguneko horma-papera"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Horma-paperaren aurrebistaren pantaila"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Amaitu da horma-papera editatzeko prozesua"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Eguneko horma-papera freskatzen…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Ezin izan da freskatu eguneko horma-papera. Egiaztatu sarera konektatuta zaudela eta saiatu berriro."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Gailuko horma-paperak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 22b1547..e2b2722 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"بازآوری کاغذدیواری روزانه در صفحه اصلی"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"بازآوری کاغذدیواری روزانه"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"صفحه پیشنمای کاغذدیواری"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"پایان ویرایش کاغذدیواری"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"درحال بازآوری کاغذدیواری روزانه…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"کاغذدیواری روزانه بازآوری نشد. لطفاً اتصال شبکهتان را بررسی و دوباره امتحان کنید."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"کاغذدیواریهای موجود در دستگاه"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 2cf1c7f..2e9933e 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Päivitä etusivun päivittäinen taustakuva."</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Siirry seuraavaan taustakuvaan"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Taustakuvan esikatselunäkymä"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Taustakuvan muokkaus valmis"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Päivitetään päivän taustakuvaa…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Päivän taustakuvan päivittäminen epäonnistui. Tarkista verkkoasetukset ja yritä uudelleen."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Laitteella olevat taustakuvat"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index cf4a84e..3d4c445 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualiser le fond d\'écran quotidien de l\'écran d\'accueil"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualiser le fond d\'écran quotidien"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Écran d\'aperçu du fond d\'écran"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Terminer la modification du fond d\'écran"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Actualisation du fond d\'écran quotidien en cours…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Échec de l\'actualisation du fond d\'écran quotidien. Veuillez vérifier votre connexion réseau, puis réessayer."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fonds d\'écran sur l\'appareil"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index ad665fe..6acf8b7 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualiser le fond d\'écran quotidien de l\'écran d\'accueil"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualiser le fond d\'écran quotidien"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Écran d\'aperçu des fonds d\'écran"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Modification du fond d\'écran terminée"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Actualisation du fond d\'écran quotidien…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Échec de l\'actualisation du fond d\'écran quotidien. Veuillez vérifier votre connexion réseau, puis réessayer."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fonds d\'écran sur l\'appareil"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index ce8f5da..310d13a 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualiza o fondo de pantalla diario para a pantalla de inicio"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualiza o fondo de pantalla diario"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Pantalla de vista previa do fondo de pantalla"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Acabouse de editar o fondo de pantalla"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Actualizando fondo de pantalla diario…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Produciuse un erro ao actualizar o fondo de pantalla diario. Comproba a conexión de rede e téntao de novo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fondos no dispositivo"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index d6e27de..a00a406 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"દૈનિક હોમ સ્ક્રીન વૉલપેપર રિફ્રેશ કરો"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"દૈનિક વૉલપેપર રિફ્રેશ કરો"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"વૉલપેપરનો પ્રીવ્યૂ બતાવતી સ્ક્રીન"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"વૉલપેપરમાં ફેરફાર કરવાનું કામ પૂરું થયું"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"દૈનિક વૉલપેપર રિફ્રેશ કરી રહ્યાં છીએ…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"દૈનિક વૉલપેપર રિફ્રેશ કરવામાં નિષ્ફળ રહ્યાં. કૃપા કરીને તમારું નેટવર્ક કનેક્શન ચેક કરો અને ફરી પ્રયાસ કરો."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ઉપકરણ પરના વૉલપેપર"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index a824c90..4d559ea 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"होम स्क्रीन का रोज़ बदलने वाला वॉलपेपर रीफ़्रेश करें"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"रोज़ बदलने वाला वॉलपेपर रीफ़्रेश करें"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"स्क्रीन पर दिखने वाले वॉलपेपर की झलक"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"वॉलपेपर में बदलाव हो गया"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"रोज़ बदलने वाला वॉलपेपर रीफ़्रेश हो रहा है…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"रोज़ बदलने वाला वॉलपेपर रीफ़्रेश नहीं हो पा रहा है. कृपया अपना इंटरनेट कनेक्शन जाँचें और फिर से कोशिश करें."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"डिवाइस पर पहले से मौजूद वॉलपेपर"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 0f8057b..3abe68f 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Osvježi dnevnu pozadinu početnog zaslona"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Osvježi dnevnu pozadinu"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Zaslon pregleda pozadine"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Dovršeno je uređivanje pozadine"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Osvježavanje dnevne pozadine…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Osvježavanje dnevne pozadine nije uspjelo. Provjerite mrežnu vezu i pokušajte ponovo."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Pozadine na uređaju"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index fe8312c..c3ec937 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"A kezdőképernyő napi háttérképének frissítése"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Napi háttérkép frissítése"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Háttérkép előnézeti képernyője"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Háttérkép szerkesztésének befejezése"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Napi háttérkép frissítése…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Nem sikerült frissíteni a napi háttérképet. Ellenőrizze hálózati kapcsolatát, majd próbálkozzon újra."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Eszközön lévő háttérképek"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 4115b2e..5386e1b 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Թարմացնել հիմնական էկրանի օրվա պաստառը"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Թարմացնել օրվա պաստառը"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Պաստառի նախադիտման էկրան"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Ավարտել պաստառի խմբագրումը"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Օրվա պաստառը թարմացվում է…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Չհաջողվեց թարմացնել օրվա պաստառը: Ստուգեք ինտերնետ կապը և նորից փորձեք:"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Սարքում պահված պաստառներ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 8d5caa9..7e731a3 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Muat ulang wallpaper layar utama harian"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Muat ulang wallpaper harian"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Layar pratinjau wallpaper"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Selesai mengedit wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Memuat ulang wallpaper harian…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Gagal memuat ulang wallpaper harian. Harap periksa koneksi jaringan Anda dan coba lagi."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Wallpaper di perangkat"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 2c88685..75ba708 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Uppfæra daglegt veggfóður á heimaskjá"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Uppfæra daglegt veggfóður"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Forskoðunarskjár veggfóðurs"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Búið að breyta veggfóðri"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Uppfærir daglegt veggfóður…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Ekki tókst að endurnýja daglegt veggfóður. Athugaðu nettenginguna og reyndu aftur."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Veggfóður í tækinu"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index c29404b..49b31f3 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Aggiorna lo sfondo giornaliero della schermata Home"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Aggiorna lo sfondo giornaliero"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Schermata di anteprima sfondo"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Modifica sfondo completata"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Aggiornamento dello sfondo giornaliero…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Impossibile aggiornare lo sfondo giornaliero. Controlla la connessione di rete e riprova."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Sfondi sul dispositivo"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 681af26..2e1b9f8 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"רענון הטפט היומי של מסך הבית"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"רענון הטפט היומי"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"מסך התצוגה המקדימה של הטפט"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"סיימתי לערוך את הטפט"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"מרענן את הטפט היומי..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"רענון הטפט היומי נכשל. יש לבדוק את החיבור לרשת ולנסות שוב."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"טפטים במכשיר"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index e4a5606..b8f31b2 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ホーム画面の日替り壁紙を更新"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"毎日の壁紙を更新"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"壁紙のプレビュー画面"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"壁紙の編集を終了します"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"日替り壁紙を更新しています…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"日替り壁紙を更新できませんでした。ネットワーク接続を確認してからもう一度お試しください。"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"デバイスに保存されている壁紙"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 14377c3..319b90f 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"მთავარი ეკრანის ყოველდღიური ფონის განახლება"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ყოველდღიური ფონის განახლება"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ფონის გადახედვის ეკრანი"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ფონის რედაქტირება დასრულდა"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"მიმდინარეობს ყოველდღიური ფონის განახლება…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ყოველდღიური ფონი ვერ განახლდა. გთხოვთ, შეამოწმოთ ქსელის კავშირი და ხელახლა ცადოთ."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"მოწყობილობაზე შენახული ფონები"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 8132694..69b2034 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Негізгі экрандағы күнделікті тұсқағазды ауыстыру"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Күнделікті тұсқағазды ауыстыру"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Тұсқағазды алдын ала көру экраны"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Тұсқағазды өзгерту аяқталды."</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Күнделікті тұсқағаз ауыстырылуда…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Күнделікті тұсқағаз ауыстырылмады. Желі байланысын тексеріп, әрекетті қайталаңыз."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Құрылғыдағы тұсқағаздар"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index fcd775f..c615865 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ផ្ទុកផ្ទាំងរូបភាពអេក្រង់ដើមប្រចាំថ្ងៃឡើងវិញ"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ផ្ទុកផ្ទាំងរូបភាពប្រចាំថ្ងៃឡើងវិញ"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"អេក្រង់មើលផ្ទាំងរូបភាពសាកល្បង"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"រួចរាល់ក្នុងការកែផ្ទាំងរូបភាព"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"កំពុងផ្ទុកផ្ទាំងរូបភាពប្រចាំថ្ងៃឡើងវិញ…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"បានបរាជ័យក្នុងការផ្ទុកផ្ទាំងរូបភាពប្រចាំថ្ងៃឡើងវិញ។ សូមពិនិត្យការតភ្ជាប់បណ្តាញរបស់អ្នក ហើយព្យាយាមម្តងទៀត។"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ផ្ទាំងរូបភាពនៅលើឧបករណ៍"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 12e51fb..e16618f 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ದೈನಂದಿನ ಮುಖಪುಟ ಪರದೆಯ ವಾಲ್ಪೇಪರ್ ರಿಫ್ರೆಶ್ ಮಾಡಿ"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ದಿನನಿತ್ಯದ ವಾಲ್ಪೇಪರ್ ಅನ್ನು ರಿಫ್ರೆಶ್ ಮಾಡಿ"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ವಾಲ್ಪೇಪರ್ ಪೂರ್ವವೀಕ್ಷಣೆಯ ಪರದೆ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ವಾಲ್ಪೇಪರ್ ಎಡಿಟಿಂಗ್ ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"ದೈನಂದಿನ ವಾಲ್ಪೇಪರ್ ಅನ್ನು ರಿಫ್ರೆಶ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ಪ್ರತಿದಿನದ ವಾಲ್ಪೇಪರ್ ರಿಫ್ರೆಶ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ. ನಿಮ್ಮ ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ಸಾಧನದಲ್ಲಿನ ವಾಲ್ಪೇಪರ್ಗಳು"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index cf5c88a..ebf6ce3 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -67,6 +67,9 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"일일 홈 화면 배경화면 새로고침"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"일일 배경화면 새로고침"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"배경화면 미리보기 화면"</string>
+ <string name="folded_device_state_description" msgid="4972608448265616264">"접힌 상태"</string>
+ <string name="unfolded_device_state_description" msgid="3071975681472460627">"펼친 상태"</string>
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"배경화면 편집 완료"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"일일 배경화면 새로고침 중..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"일일 배경화면을 새로고침할 수 없습니다. 네트워크 연결을 확인한 후 다시 시도해 주세요."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"기기 배경화면"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 3611b13..565dd45 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Башкы экрандын күнүмдүк тушкагазын жаңыртуу"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Күнүмдүк тушкагазды жаңыртуу"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Тушкагазды карап көрүү экраны"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Тушкагаз түзөтүлүп бүттү"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Күнүмдүк тушкагаз жаңыртылууда…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Күнүмдүк тушкагаз жаңыртылбай калды. Интернетке туташууңузду текшерип, дагы бир жолу аракет кылыңыз."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Түзмөктөгү тушкагаздар"</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 438d4b2..3ab06eb 100755
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -25,4 +25,10 @@
<dimen name="preview_page_gap">60dp</dimen>
<dimen name="preview_page_horizontal_margin">92dp</dimen>
<dimen name="preview_card_padding">8dp</dimen>
+
+ <!-- Dimensions for wallpaper effects dialog -->
+ <dimen name="set_wallpaper_dialog_handheld_width">900dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_content_width">840dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_width">416dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_height">260dp</dimen>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 267cc10..11fa89e 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ໂຫຼດຂໍ້ມູນຮູບພື້ນຫຼັງໜ້າຈໍຫຼັກຄືນໃໝ່ທຸກມື້"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ໂຫຼດຮູບພື້ນຫຼັງຄືນໃໝ່ທຸກມື້"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ໜ້າຈໍຕົວຢ່າງຮູບພື້ນຫຼັງ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ການແກ້ໄຂຮູບພື້ນຫຼັງແລ້ວໆ"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"ກຳລັງໂຫຼດຂໍ້ມູນຮູບພື້ນຫຼັງປະຈຳວັນຄືນໃໝ່…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ໂຫຼດຮູບພື້ນຫຼັງຄືນໃໝ່ທຸກມື້ບໍ່ສຳເລັດ. ກະລຸນາກວດສອບການເຊື່ອມຕໍ່ອິນເຕີເນັດຂອງທ່ານແລ້ວລອງໃໝ່ອີກຄັ້ງ."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ຮູບພື້ນຫຼັງໃນເຄື່ອງ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 24772a3..0d7e3ed 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Atnaujinti dienos pagrindinio ekrano foną"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Atnaujinti dienos ekrano foną"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ekrano fono peržiūra"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Ekrano fonas baigtas redaguoti"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Atnaujinamas dienos ekrano fonas…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Nepavyko atnaujinti dienos ekrano fono. Patikrinkite tinklo ryšį ir bandykite dar kartą."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Ekrano fonai įrenginyje"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 59e5fb4..6845731 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Atsvaidzināt dienas fona tapeti sākuma ekrānā"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Atsvaidzināt dienas fona tapeti"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Fona tapetes priekšskatījuma ekrāns"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Pabeigt fona tapetes rediģēšanu"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Notiek dienas fona tapetes atsvaidzināšana…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Neizdevās atsvaidzināt dienas fona tapeti. Lūdzu, pārbaudiet tīkla savienojumu un mēģiniet vēlreiz."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Fona tapetes ierīcē"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index c00b32c..4bcd102 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Освежи го дневниот тапет за почетниот екран"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Освежи го дневниот тапет"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Екран за преглед на тапет"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Изменувањето на тапетот е завршено"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Се освежува дневниот тапет…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Освежувањето на дневниот тапет не успеа. Проверете ја мрежната врска и обидете се повторно."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Тапети на уредот"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index d40bdb9..9154a28 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"പ്രതിദിന ഹോം സ്ക്രീൻ വാൾപേപ്പർ പുതുക്കുക"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"പ്രതിദിന വാൾപേപ്പർ പുതുക്കുക"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"വാൾപേപ്പർ പ്രിവ്യൂ സ്ക്രീൻ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"വാൾപേപ്പർ എഡിറ്റിംഗ് പൂർത്തിയായി"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"പ്രതിദിന വാൾപേപ്പർ പുതുക്കുന്നു…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"പ്രതിദിന വാൾപേപ്പർ പുതുക്കിയെടുക്കുന്നത് പരാജയപ്പെട്ടു. നിങ്ങളുടെ നെറ്റ്വർക്ക് കണക്ഷൻ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ഉപകരണത്തിലെ വാൾപേപ്പറുകൾ"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 18f052f..518471a 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Үндсэн нүүрийн өдөр тутмын дэлгэцийн зургийг сэргээх"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Өдөр тутмын дэлгэцийн зургийг сэргээх"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Дэлгэцийн зургийг урьдчилан үзэх дэлгэц"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Дэлгэцийн зургийг засаж дууслаа"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Өдөр тутмын дэлгэцийн зургийг сэргээж байна…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Өдөр тутмын дэлгэцийн зургийг сэргээж чадсангүй. Сүлжээний холболтоо шалгаад дахин оролдоно уу."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Төхөөрөмжийн дэлгэцийн зураг"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 4b03f12..e98d3fb 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"दैनिक होम स्क्रीन वॉलपेपर रिफ्रेश करा"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"दैनिक वॉलपेपर रिफ्रेश करा"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"वॉलपेपर पूर्वावलोकन स्क्रीन"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"वॉलपेपर संपादित करणे पूर्ण झाले आहे"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"दैनिक वॉलपेपर रिफ्रेश करत आहे…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"दैनिक वॉलपेपर रिफ्रेश करता आला नाही. कृपया तुमचे नेटवर्क कनेक्शन तपासा आणि पुन्हा प्रयत्न करा."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"डिव्हाइसवरील वॉलपेपर"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 268cdb0..b2c4c77 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Muat semula kertas dinding skrin utama harian"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Muat semula kertas dinding harian"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Skrin pratonton hiasan latar"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Selesai mengedit hiasan latar"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Memuat semula kertas dinding harian…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Gagal memuat semula kertas dinding harian. Sila semak sambungan rangkaian anda dan cuba lagi."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Kertas dinding pada peranti"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 79e927f..1d84009 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"နေ့စဉ်ပင်မစာမျက်နှာနောက်ခံကို ပြန်လည်စတင်ရန်"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"နေ့စဉ်နောက်ခံကို ပြန်လည် စတင်ရန်"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"နောက်ခံ အစမ်းကြည့်ရှုခြင်း ဖန်သားပြင်"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"နောက်ခံ တည်းဖြတ်ခြင်း ပြီးပါပြီ"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"နေ့စဉ်နောက်ခံကို ပြန်လည်စတင်နေသည်…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"နေ့စဉ် နောက်ခံကို ပြန်လည် စတင်ခြင်း မအောင်မြင်ပါ။ ကွန်ရက်ချိတ်ဆက်မှုကို စစ်ဆေးပြီး ထပ်စမ်းကြည့်ပါ။"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"စက်ပေါ်ရှိ နောက်ခံများ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 7617997..6c2fe8c 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Oppdater den daglige bakgrunnen på startskjermen"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Oppdater daglig bakgrunn"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Skjerm for forhåndsvisning av bakgrunn"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Ferdig med å endre bakgrunnen"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Oppdaterer daglig bakgrunn …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Kunne ikke oppdatere den daglige bakgrunnen. Sjekk nettverkstilkoblingen din, og prøv igjen."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Bakgrunner på enheten"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 55179f7..bf45984 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"गृहपृष्ठको दैनिक वालपेपर पुनः ताजा गर्नुहोस्"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"दैनिक वालपेपर पुनः ताजा गर्नुहोस्"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"वालपेपरको प्रिभ्यू स्क्रिन"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"वालपेपर सम्पादन गर्ने कार्य पूरा भयो"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"दैनिक वालपेपर पुनः ताजा गर्दै…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"दैनिक वालपेपर पुनः ताजा गर्न सकिएन। कृपया आफ्नो नेटवर्कको जडान जाँच गरी फेरि प्रयास गर्नुहोस्।"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"यन्त्रमा रहेका वालपेपरहरू"</string>
diff --git a/res/transition/shared_view.xml b/res/values-night/bools.xml
similarity index 75%
rename from res/transition/shared_view.xml
rename to res/values-night/bools.xml
index 184d918..f47f4d7 100644
--- a/res/transition/shared_view.xml
+++ b/res/values-night/bools.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2023 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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.
@@ -15,7 +14,6 @@
~ limitations under the License.
-->
-<transitionSet>
- <changeTransform />
- <changeBounds />
-</transitionSet>
\ No newline at end of file
+<resources>
+ <bool name="isFragmentStatusBarLightText">true</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 200a153..d91aeb3 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Dagelijkse startschermachtergrond vernieuwen"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Dagelijkse achtergrond vernieuwen"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Voorbeeldscherm achtergrond"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Klaar met bewerken van achtergrond"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Dagelijkse achtergrond vernieuwen…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Dagelijkse achtergrond kan niet worden vernieuwd. Controleer je netwerkverbinding en probeer het opnieuw."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Achtergronden op apparaat"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index cf94efb..7bec191 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ଦୈନିକ ହୋମ ସ୍କ୍ରିନ ୱାଲପେପର୍କୁ ରିଫ୍ରେସ କରନ୍ତୁ"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ଦୈନିକ ୱାଲପେପର୍କୁ ରିଫ୍ରେଶ୍ କରନ୍ତୁ"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ୱାଲପେପରର ପ୍ରିଭ୍ୟୁ ସ୍କ୍ରିନ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ୱାଲପେପର ଏଡିଟିଂ ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"ଦୈନିକ ୱାଲପେପର୍ ରିଫ୍ରେଶ୍ ହେଉଛି…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ଦୈନିକ ୱାଲପେପର୍କୁ ରିଫ୍ରେଶ କରିବାରେ ବିଫଳ ହୋଇଛି। ଦୟାକରି ଆପଣଙ୍କର ନେଟୱର୍କ କନେକ୍ସନ୍କୁ ଯାଞ୍ଚ କରିବା ସହିତ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ଅନ୍-ଡିଭାଇସ୍ ୱାଲପେପର୍"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 66dd503..d377825 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"ਰੋਜ਼ਾਨਾ ਹੋਮ ਸਕ੍ਰੀਨ ਵਾਲਪੇਪਰ ਨੂੰ ਰਿਫ੍ਰੈਸ਼ ਕਰੋ"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"ਰੋਜ਼ਾਨਾ ਵਾਲਪੇਪਰ ਰਿਫ੍ਰੈਸ਼ ਕਰੋ"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"ਵਾਲਪੇਪਰ ਦੀ ਪੂਰਵ-ਝਲਕ ਸਕ੍ਰੀਨ"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"ਵਾਲਪੇਪਰ ਦਾ ਸੰਪਾਦਨ ਕਰਨ ਦੀ ਪ੍ਰਕਿਰਿਆ ਪੂਰੀ ਹੋਈ"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"ਰੋਜ਼ਾਨਾ ਵਾਲਪੇਪਰ ਰਿਫ੍ਰੈਸ਼ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"ਰੋਜ਼ਾਨਾ ਵਾਲਪੇਪਰ ਰਿਫ੍ਰੈਸ਼ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ। ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"ਡੀਵਾਈਸ ਵਿੱਚ ਮੌਜੂਦ ਵਾਲਪੇਪਰ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index e044da0..8d23252 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Odśwież codzienną tapetę na ekranie głównym"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Odśwież codzienną tapetę"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ekran podglądu tapety"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Zakończono edytowanie tapety"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Odświeżam codzienną tapetę…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Nie udało się odświeżyć codziennej tapety. Sprawdź połączenie sieciowe i spróbuj ponownie."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Tapety na urządzeniu"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 0c6eb1e..c97a26a 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Atualizar a imagem de fundo do ecrã principal diária"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Atualizar a imagem de fundo diária"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ecrã de pré-visualização da imagem de fundo"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Concluir edição da imagem de fundo"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"A atualizar a imagem de fundo diária…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Falha ao atualizar a imagem de fundo diária. Verifique a sua ligação de rede e tente novamente."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Imagens de fundo no disposit."</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index ccc5463..2078ae9 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Atualizar o plano de fundo diário da tela inicial"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Atualizar o plano de fundo diário"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Tela de prévia do plano de fundo"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Edição do plano de fundo concluída"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Atualizando plano de fundo diário…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Falha na atualização do plano de fundo diário. Verifique sua conexão de rede e tente novamente."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Planos de fundo no dispositivo"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index ac5d350..4e83f41 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Actualizează imaginea de fundal zilnică a ecranului de pornire"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Actualizează imaginea de fundal zilnică"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ecranul de previzualizare a imaginii de fundal"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Editarea imaginii de fundal s-a încheiat"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Se actualizează imaginea de fundal zilnică…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Nu s-a putut actualiza imaginea de fundal zilnică. Verifică-ți conexiunea la rețea și încearcă din nou."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Imagini fundal pe dispozitiv"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index ac8b527..05c1f62 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Обновить ежедневные обои на главном экране"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Обновить ежедневные обои"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Предварительный просмотр обоев"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Завершить редактирование обоев"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Обновление ежедневных обоев…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Не удалось обновить обои. Проверьте подключение к Интернету и повторите попытку."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Сохраненные на устройстве"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 4ced87c..81e57c5 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -67,6 +67,9 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"දිනපතා මුල් පිටු තිර වෝල්පේපරය නැවුම් කරන්න"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"දිනපතා වෝල්පේපරය නැවුම් කරන්න"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"වෝල්පේපර පෙරදසුන් තිරය"</string>
+ <string name="folded_device_state_description" msgid="4972608448265616264">"නැවූ"</string>
+ <string name="unfolded_device_state_description" msgid="3071975681472460627">"නොනැවූ"</string>
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"වෝල්පේපරය සංස්කරණය කර නිමයි"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"දෛනික වෝල්පේපරය නැවුම් කරමින්…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"දෛනික වෝල්පේපරය යළි නැවුම් කිරීම අසාර්ථක විය. කරුණාකර ඔබගේ ජාල සම්බන්ධතාව පරික්ෂා කර නැවත උත්සාහ කරන්න."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"උපාංගය-මත වෝල්පේපර"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index b3ee9ee..8bc8b88 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Obnoviť dennú tapetu na ploche"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Obnoviť dennú tapetu"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Obrazovka ukážky tapety"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Úprava tapety bola dokončená"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Obnovuje sa denná tapeta…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Dennú tapetu sa nepodarilo obnoviť. Skontrolujte pripojenie k sieti a skúste to znova."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Tapety v zariadení"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 7bd153f..5470c40 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Osvežitev dnevnega ozadja za začetni zaslon"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Osvežitev dnevnega ozadja"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Zaslon s predogledom zaslonskega ozadja"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Urejanje zaslonska ozadja je končano"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Osvežitev dnevnega ozadja …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Dnevnega ozadja ni bilo mogoče osvežiti. Preverite omrežno povezavo in poskusite znova."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Ozadja v napravi"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 2b9ddee..83fa62a 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Rifresko imazhin e përditshëm të sfondit të ekranit kryesor"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Rifresko imazhin e përditshëm të sfondit"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Ekrani i pamjes paraprake të imazhit të sfondit"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Modifikimi i imazhit të sfondit u krye"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Po rifreskon imazhin e përditshëm të sfondit..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Rifreskimi i imazhit të përditshëm të sfondit dështoi. Kontrollo lidhjen e rrjetit dhe provo përsëri."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Imazhet e sfondit në pajisje"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index a00ff99..28a4290 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Освежи дневну позадину за почетни екран"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Освежи дневну позадину"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Екран приказа позадине"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Измене позадине су завршене"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Дневна позадина се освежава…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Освежавање дневне позадине није успело. Проверите мрежну везу и пробајте поново."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Позадине на уређају"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index a2e867d..b49a1fe 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Uppdatera dagens bakgrund för startskärmen"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Uppdatera dagens bakgrund"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Förhandsgranskning av skärmens bakgrund"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Bakgrunden har redigerats klart"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Dagens bakgrund uppdateras …"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Det gick inte att uppdatera dagens bakgrund. Kontrollera nätverksanslutningen och försök igen."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Bakgrunder på enheten"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 3354aaa..61aba03 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Onyesha upya mandhari ya skrini ya kwanza ya kila siku"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Onyesha upya mandhari ya kila siku"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Skrini ya kukagua mandhari"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Nimemaliza kubadilisha mandhari"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Inaonyesha upya mandhari ya kila siku..."</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Imeshindwa kuonyesha upya mandhari ya kila siku. Tafadhali kagua muunganisho wako kisha ujaribu tena."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Mandhari yaliyo kwenye kifaa"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 8cb3083..aecb231 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"முகப்புத் திரையில் தினசரி வால்பேப்பரைப் புதுப்பிக்கும் பட்டன்"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"தினசரி வால்பேப்பரைப் புதுப்பிக்கும் பட்டன்"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"வால்பேப்பர் மாதிரிக்காட்சித் திரை"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"வால்பேப்பரை எடிட் செய்வதை முடிக்கும்"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"தினசரி வால்பேப்பரைப் புதுப்பிக்கிறது…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"தினசரி வால்பேப்பரைப் புதுப்பிக்க முடியவில்லை. நெட்வொர்க் இணைப்பைச் சரிபார்த்து, மீண்டும் முயலவும்."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"சாதனத்திலுள்ள வால்பேப்பர்கள்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index b1b15f1..7b45e62 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"రోజువారీ హోమ్ స్క్రీన్ వాల్పేపర్ను రిఫ్రెష్ చేస్తుంది"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"రోజువారీ వాల్పేపర్ను రిఫ్రెష్ చేస్తుంది"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"వాల్పేపర్ ప్రివ్యూ స్క్రీన్"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"వాల్పేపర్ను ఎడిట్ చేయడం పూర్తయింది"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"రోజువారీ వాల్పేపర్ను రిఫ్రెష్ చేస్తోంది…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"రోజువారీ వాల్పేపర్ను రిఫ్రెష్ చేయడంలో విఫలమైంది. దయచేసి మీ నెట్వర్క్ కనెక్షన్ను చెక్ చేసుకొని, ఆపై మళ్లీ ట్రై చేయండి."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"పరికరంలో వాల్పేపర్లు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 1e6e472..c871e10 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"รีเฟรชวอลเปเปอร์หน้าจอหลักรายวัน"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"รีเฟรชวอลเปเปอร์รายวัน"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"หน้าจอตัวอย่างวอลเปเปอร์"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"แก้ไขวอลเปเปอร์เสร็จแล้ว"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"กำลังรีเฟรชวอลเปเปอร์รายวัน…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"รีเฟรชวอลเปเปอร์รายวันไม่ได้ โปรดตรวจสอบการเชื่อมต่อเครือข่าย แล้วลองใหม่อีกครั้ง"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"วอลเปเปอร์บนอุปกรณ์"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index cc6abb8..a8ecb04 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"I-refresh ang pang-araw-araw na wallpaper ng home screen"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"I-refresh ang pang-araw-araw na wallpaper"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Screen ng preview ng wallpaper"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Tapos nang mag-edit ng wallpaper"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Nire-refresh ang pang-araw-araw na wallpaper…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Hindi na-refresh ang pang-araw-araw na wallpaper. Pakitingnan ang iyong koneksyon sa network at subukan ulit."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Mga nasa device na wallpaper"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 5711719..d84eec7 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Günlük ana ekran duvar kağıdını yenile"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Günlük duvar kağıdını yenile"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Duvar kağıdı önizleme ekranı"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Duvar kağıdı düzenleme işlemi tamamlandı"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Günlük duvar kağıdı yenileniyor…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Günlük duvar kağıdı yenilenemedi. Lütfen ağ bağlantınızı kontrol edip tekrar deneyin."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Cihazdaki duvar kağıtları"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 921409c..874406e 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Оновити щоденний фоновий малюнок на головному екрані"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Оновити щоденний фоновий малюнок"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Екран попереднього перегляду фонового малюнка"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Завершити редагування фонового малюнка"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Оновлення щоденного фонового малюнка…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Не вдалось оновити щоденний фоновий малюнок. Перевірте з’єднання з мережею й повторіть спробу."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Фонові малюнки на пристрої"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 30e80e2..51a0e26 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"روزانہ ہوم اسکرین کا وال پیپر ریفریش کریں"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"روزانہ وال پیپر ریفریش کریں"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"وال پیپر پیش منظر اسکرین"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"وال پیپر میں ترمیم ہو گئی"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"روزانہ وال پیپر ریفریش ہو رہا ہے…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"روزانہ وال پیپر ریفریش کرنے میں ناکام۔ براہ کرم اپنا نیٹ ورک کنکشن چیک کر کے دوبارہ کوشش کریں۔"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"آلہ میں اسٹور کردہ وال پیپرز"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index e37e90c..c7b4f50 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Kunlik bosh ekran fon rasmini yangilash"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Kunlik fon rasmini yangilash"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Fon rasmiga razm solish ekrani"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Fon rasmi tahririni yakunlash"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Kunlik fon rasmi yangilanmoqda…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Kunlik fon rasmi yangilanmadi. Internet aloqasini tekshiring va qaytadan urining."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Qurilmadagi fon rasmlari"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 645ea85..bd13014 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Làm mới hình nền màn hình chính hàng ngày"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Làm mới hình nền hàng ngày"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Màn hình xem trước hình nền"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Hoàn tất chỉnh sửa hình nền"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Đang làm mới hình nền hàng ngày…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Không thể làm mới hình nền hàng ngày. Vui lòng kiểm tra kết nối mạng của bạn và thử lại."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Hình nền trên thiết bị"</string>
diff --git a/res/values-w600dp-port/dimens.xml b/res/values-w600dp-port/dimens.xml
index 07d8b0f..381565c 100644
--- a/res/values-w600dp-port/dimens.xml
+++ b/res/values-w600dp-port/dimens.xml
@@ -51,4 +51,9 @@
<!-- Clipping of the home screen overlay -->
<dimen name="home_screen_overlay_top_clipping">0dp</dimen>
<dimen name="home_screen_overlay_bottom_clipping">100dp</dimen>
+
+ <!-- Dimensions for set wallpaper dialog with previews -->
+ <dimen name="set_wallpaper_dialog_foldable_width">360dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">320dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">250dp</dimen>
</resources>
\ No newline at end of file
diff --git a/res/values-w600dp/dimens.xml b/res/values-w600dp/dimens.xml
index c976b0c..7a79d82 100644
--- a/res/values-w600dp/dimens.xml
+++ b/res/values-w600dp/dimens.xml
@@ -26,5 +26,12 @@
<!-- Dimensions for small "dual" previews screen. -->
<dimen name="small_dual_preview_edge_space">94dp</dimen>
- <dimen name="set_wallpaper_dialog_foldable_preview_width">280dp</dimen>
+ <!-- Dimensions for set wallpaper dialog with previews -->
+ <dimen name="set_wallpaper_dialog_handheld_width">520dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_content_width">450dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_width">220dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_height">352dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_width">410dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">370dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">300dp</dimen>
</resources>
\ No newline at end of file
diff --git a/res/values-w700dp-port/dimens.xml b/res/values-w700dp-port/dimens.xml
new file mode 100644
index 0000000..b7dd74a
--- /dev/null
+++ b/res/values-w700dp-port/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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
+ -->
+<resources>
+ <!-- Dimensions for set wallpaper dialog with previews -->
+ <dimen name="set_wallpaper_dialog_foldable_width">410dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">370dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">300dp</dimen>
+</resources>
diff --git a/res/values-w700dp/dimens.xml b/res/values-w700dp/dimens.xml
new file mode 100644
index 0000000..36018a5
--- /dev/null
+++ b/res/values-w700dp/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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
+ -->
+<resources>
+ <!-- Dimensions for set wallpaper dialog with previews -->
+ <dimen name="set_wallpaper_dialog_foldable_width">330dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">290dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">220dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values-w800dp-port/dimens.xml b/res/values-w800dp-port/dimens.xml
new file mode 100644
index 0000000..bee39f9
--- /dev/null
+++ b/res/values-w800dp-port/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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
+ -->
+<resources>
+ <!-- Dimensions for wallpaper effects dialog -->
+ <dimen name="set_wallpaper_dialog_handheld_width">540dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_content_width">450dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_width">220dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_height">352dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values-w800dp/dimens.xml b/res/values-w800dp/dimens.xml
index 54c607c..67b3706 100644
--- a/res/values-w800dp/dimens.xml
+++ b/res/values-w800dp/dimens.xml
@@ -69,4 +69,13 @@
display.
-->
<dimen name="screen_preview_width">600dp</dimen>
+
+ <!-- Dimensions for wallpaper effects dialog -->
+ <dimen name="set_wallpaper_dialog_handheld_width">900dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_content_width">840dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_width">416dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_preview_height">260dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_width">410dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">370dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">300dp</dimen>
</resources>
\ No newline at end of file
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index e1d2f84..31c5884 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"刷新每日主屏幕壁纸"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"刷新每日壁纸"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"壁纸预览画面"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"壁纸编辑完毕"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"正在刷新每日壁纸…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"无法刷新每日壁纸。请检查您的网络连接状况,然后重试。"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"设备上的壁纸"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 1b11ad9..b58a094 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"重新整理主畫面的每日桌布"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"重新整理每日桌布"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"桌布預覽畫面"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"完成編輯桌布"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"正在重新整理每日桌布…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"無法重新整理每日桌布。請檢查你的網絡連線,然後再試一次。"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"裝置上的桌布"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index e086c29..bfca996 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"重新整理主畫面每日桌布"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"重新整理每日桌布"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"桌布預覽畫面"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"桌布編輯完畢"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"正在重新整理每日桌布…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"無法重新整理每日桌布。請檢查你的網路連線,然後再試一次。"</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"裝置桌布"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index b2f207d..2079961 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -67,6 +67,11 @@
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"Vuselela isithombe sangemuva sasekhaya sansuku zonke"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"Vuselela isithombe sangemuva sansuku zonke"</string>
<string name="preview_screen_description" msgid="3386387053327775919">"Isikrini sokubuka kuqala sangemuva"</string>
+ <!-- no translation found for folded_device_state_description (4972608448265616264) -->
+ <skip />
+ <!-- no translation found for unfolded_device_state_description (3071975681472460627) -->
+ <skip />
+ <string name="full_preview_check_button_description" msgid="700484353763952975">"Iqedile ukuhlela isithombe sangemuva"</string>
<string name="refreshing_daily_wallpaper_dialog_message" msgid="1975910873362855761">"Ivuselela isithombe sangemuva sansuku zonke…"</string>
<string name="refresh_daily_wallpaper_failed_message" msgid="4749879993812557166">"Yehlulekile ukuvuselela isithombe sangemuva sansuku zonke. Sicela uhlole ukuxhumeka kwakho kwenethiwekhi uphinde uzame futhi."</string>
<string name="on_device_wallpapers_category_title" msgid="805819102071369004">"Izithombe zangemuva ezikudivayisi"</string>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index 1c2e03b..ba9d2a6 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -16,4 +16,5 @@
-->
<resources>
<bool name="is_large_screen">false</bool>
+ <bool name="isFragmentStatusBarLightText">false</bool>
</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0da23c5..276de54 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -185,6 +185,9 @@
<dimen name="wallpaper_info_pane_interaction_top_margin">39dp</dimen>
<dimen name="wallpaper_info_pane_explore_button_top_margin">50dp</dimen>
+ <!-- Minimum height for the wallpaper info explore button. -->
+ <dimen name="wallpaper_touch_target_min_height">48dp</dimen>
+
<dimen name="option_border_width">2dp</dimen>
<dimen name="option_selected_border_width">3dp</dimen>
<dimen name="option_title_font_text_size">14sp</dimen>
@@ -264,6 +267,10 @@
<dimen name="set_wallpaper_button_margin_end">16dp</dimen>
<dimen name="set_wallpaper_button_min_height">48dp</dimen>
+ <!-- Set wallpaper dialog -->
+ <dimen name="set_wallpaper_progress_dialog_padding">16dp</dimen>
+ <dimen name="set_wallpaper_progress_dialog_progress_bar_margin_end">10dp</dimen>
+
<!-- Wallpaper control button group -->
<dimen name="wallpaper_control_button_group_divider_space">16dp</dimen>
<dimen name="wallpaper_control_button_group_margin_top">24dp</dimen>
@@ -281,6 +288,8 @@
<!-- Floating Sheet -->
<dimen name="floating_sheet_corner_radius">12dp</dimen>
<dimen name="floating_sheet_margin">24dp</dimen>
+ <dimen name="floating_sheet_bottom_margin">120dp</dimen>
+ <dimen name="floating_sheet_customize_content_min_height">120dp</dimen>
<!-- Dimensions for "Wallpaper category headers" -->
<dimen name="wallpaper_header_text_size">16sp</dimen>
@@ -357,11 +366,14 @@
<dimen name="small_preview_button_radius">15dp</dimen>
<!-- Dimensions for set wallpaper dialog with previews -->
- <dimen name="set_wallpaper_dialog_foldable_preview_width">270dp</dimen>
- <dimen name="set_wallpaper_dialog_handheld_width">270dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_width">370dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_content_width">320dp</dimen>
+ <dimen name="set_wallpaper_dialog_foldable_preview_width">290dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_width">340dp</dimen>
+ <dimen name="set_wallpaper_dialog_handheld_content_width">270dp</dimen>
<dimen name="set_wallpaper_dialog_handheld_preview_width">130dp</dimen>
<dimen name="set_wallpaper_dialog_handheld_preview_height">260dp</dimen>
- <dimen name="set_wallpaper_dialog_button_margin_vertical">16dp</dimen>
+ <dimen name="set_wallpaper_dialog_button_margin_vertical">8dp</dimen>
<dimen name="set_wallpaper_dialog_bottom_padding">16dp</dimen>
<dimen name="set_wallpaper_dialog_preview_corner_radius">14dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3600e55..11a1064 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -237,6 +237,16 @@
<!-- Content description for the wallpaper preview screen. [CHAR LIMIT=none] -->
<string name="preview_screen_description">Wallpaper preview screen</string>
+ <!-- Content description when the device is in a folded state. [CHAR LIMIT=none] -->
+ <string name="folded_device_state_description">Folded</string>
+
+ <!-- Content description when device is in an unfolded state. [CHAR LIMIT=none] -->
+ <string name="unfolded_device_state_description">Unfolded</string>
+
+ <!-- Content description for a button on full preview screen to confirm user's wallpaper
+ edit. [CHAR LIMIT=none] -->
+ <string name="full_preview_check_button_description">Done editing wallpaper</string>
+
<!-- Message shown to user in a progress dialog when the app is in the process of refreshing the
daily wallpaper. [CHAR LIMIT=none] -->
<string name="refreshing_daily_wallpaper_dialog_message">
diff --git a/src/com/android/wallpaper/config/BaseFlags.kt b/src/com/android/wallpaper/config/BaseFlags.kt
index 6c713c6..35b4f16 100644
--- a/src/com/android/wallpaper/config/BaseFlags.kt
+++ b/src/com/android/wallpaper/config/BaseFlags.kt
@@ -17,10 +17,10 @@
import android.app.WallpaperManager
import android.content.Context
+import com.android.settings.accessibility.Flags.enableColorContrastControl
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
-import com.android.wallpaper.Flags.multiCropPreviewUiFlag
import com.android.wallpaper.Flags.refactorWallpaperCategoryFlag
import com.android.wallpaper.Flags.wallpaperRestorerFlag
import com.android.wallpaper.module.InjectorProvider
@@ -36,9 +36,7 @@
open fun isInterruptModelDownloadEnabled() = false
open fun isWallpaperRestorerEnabled() = wallpaperRestorerFlag()
open fun isWallpaperCategoryRefactoringEnabled() = refactorWallpaperCategoryFlag()
-
- /** Enables new preview UI if both [isMultiCropEnabled] and this flag are true. */
- open fun isMultiCropPreviewUiEnabled() = multiCropPreviewUiFlag()
+ open fun isColorContrastControlEnabled() = enableColorContrastControl()
open fun isMultiCropEnabled() = WallpaperManager.isMultiCropEnabled()
diff --git a/src/com/android/wallpaper/effects/EffectsController.java b/src/com/android/wallpaper/effects/EffectsController.java
index b7f4f04..965fd69 100644
--- a/src/com/android/wallpaper/effects/EffectsController.java
+++ b/src/com/android/wallpaper/effects/EffectsController.java
@@ -15,10 +15,13 @@
*/
package com.android.wallpaper.effects;
+import android.app.WallpaperInfo;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
+import androidx.annotation.NonNull;
+
/**
* Utility class to provide methods to generate effects for the wallpaper.
*/
@@ -44,13 +47,16 @@
public static final int RESULT_FOREGROUND_DOWNLOAD_SUCCEEDED = 512;
public static final int RESULT_FOREGROUND_DOWNLOAD_FAILED = 1024;
public static final int RESULT_PROBE_FOREGROUND_DOWNLOADING = 2048;
+
/**
* Interface of the Effect enum.
*/
public interface EffectEnumInterface {
}
+
public enum Effect implements EffectEnumInterface {
NONE,
+ UNKNOWN,
}
protected boolean mBound = false;
@@ -71,6 +77,21 @@
}
/**
+ * Returns true if an effects component is available on the current device
+ */
+ public boolean areEffectsAvailable() {
+ return false;
+ }
+
+ /**
+ * Returns true if the given {@link WallpaperInfo} corresponds to a wallpaper matching the
+ * "Effects" wallpaper.
+ */
+ public boolean isEffectsWallpaper(@NonNull WallpaperInfo info) {
+ return false;
+ }
+
+ /**
* Destroys the controller
*/
public void destroy() {
@@ -94,10 +115,12 @@
}
/** Sets the {@link EffectsServiceListener} to receive updates. */
- public void setListener(EffectsServiceListener listener) {}
+ public void setListener(EffectsServiceListener listener) {
+ }
/** Removes the listener set via {@link #setListener(EffectsServiceListener)}. */
- public void removeListener() {}
+ public void removeListener() {
+ }
/** Returns true if the effect is expected by this controller. */
public boolean isTargetEffect(EffectEnumInterface effect) {
@@ -113,7 +136,8 @@
*
* @param effect The effect that was generated.
* @param bundle The data that the Service might have sent to the picker.
- * @param error The error code. if there's an error, value is greater than zero.
+ * @param error The error code. if there's an error, value is greater than
+ * zero.
* @param originalStatusCode The original status code used for metrics logging.
* @param errorMessage The error message.
*/
@@ -157,4 +181,14 @@
public Uri getContentUri() {
return Uri.EMPTY;
}
+
+ /** */
+ public void interruptGenerate(com.android.wallpaper.effects.Effect effect) {}
+
+ /**
+ * This initiates the downloading of the ML models for a given effect
+ *
+ * @param effect The Effect for which we want to download the ML model
+ */
+ public void startForegroundDownload(com.android.wallpaper.effects.Effect effect){}
}
diff --git a/src/com/android/wallpaper/model/CurrentWallpaperInfo.java b/src/com/android/wallpaper/model/CurrentWallpaperInfo.java
index a1f1a81..2093053 100755
--- a/src/com/android/wallpaper/model/CurrentWallpaperInfo.java
+++ b/src/com/android/wallpaper/model/CurrentWallpaperInfo.java
@@ -127,8 +127,7 @@
BaseFlags flags = InjectorProvider.getInjector().getFlags();
// Only get the full wallpaper asset when previewing a multi-crop wallpaper, otherwise get
// the cropped asset.
- boolean getFullAsset = flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled()
- && !mCropHints.isEmpty();
+ boolean getFullAsset = flags.isMultiCropEnabled() && !mCropHints.isEmpty();
return (isSystemBuiltIn)
? new BuiltInWallpaperAsset(context)
diff --git a/src/com/android/wallpaper/model/WallpaperInfo.java b/src/com/android/wallpaper/model/WallpaperInfo.java
index 82b0e40..eefcadb 100755
--- a/src/com/android/wallpaper/model/WallpaperInfo.java
+++ b/src/com/android/wallpaper/model/WallpaperInfo.java
@@ -321,9 +321,7 @@
/** Returns the crop {@link Rect} of each displaySize for this wallpaper. */
public @Nullable Map<Point, Rect> getWallpaperCropHints() {
BaseFlags flags = InjectorProvider.getInjector().getFlags();
- boolean isMultiCropEnabled =
- flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled();
- if (!isMultiCropEnabled) {
+ if (!flags.isMultiCropEnabled()) {
return null;
}
diff --git a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt b/src/com/android/wallpaper/model/wallpaper/DeviceDisplayType.kt
similarity index 71%
rename from src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
rename to src/com/android/wallpaper/model/wallpaper/DeviceDisplayType.kt
index 4001f83..f3a05d9 100644
--- a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
+++ b/src/com/android/wallpaper/model/wallpaper/DeviceDisplayType.kt
@@ -15,7 +15,12 @@
*/
package com.android.wallpaper.model.wallpaper
-enum class FoldableDisplay {
- FOLDED,
- UNFOLDED,
+enum class DeviceDisplayType {
+ SINGLE, // The screen of a single-screen device
+ FOLDED, // The outer screen of a foldable
+ UNFOLDED; // The inner screen of a foldable
+
+ companion object {
+ val FOLDABLE_DISPLAY_TYPES = setOf(FOLDED, UNFOLDED)
+ }
}
diff --git a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
index 9e8cb95..46e0f27 100755
--- a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
+++ b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
@@ -60,8 +60,7 @@
WallpaperInfoCallback callback) {
BaseFlags flags = InjectorProvider.getInjector().getFlags();
- final boolean isMultiCropEnabled =
- flags.isMultiCropEnabled() && flags.isMultiCropPreviewUiEnabled();
+ final boolean isMultiCropEnabled = flags.isMultiCropEnabled();
boolean isHomeWallpaperSynced = homeWallpaperSynced(context);
boolean isLockWallpaperSynced = lockWallpaperSynced(context);
@@ -74,7 +73,8 @@
DisplayUtils displayUtils = InjectorProvider.getInjector().getDisplayUtils(context);
WallpaperClient wallpaperClient = InjectorProvider.getInjector().getWallpaperClient(
context);
- List<Point> displaySizes = displayUtils.getInternalDisplaySizes();
+ List<Point> displaySizes = displayUtils
+ .getInternalDisplaySizes(/* allDimensions= */ true);
if (mHomeWallpaper != null) {
boolean isHomeWallpaperStatic = mHomeWallpaper.getWallpaperComponent() == null
|| mHomeWallpaper.getWallpaperComponent().getComponent() == null;
diff --git a/src/com/android/wallpaper/module/DefaultNetworkStatusNotifier.java b/src/com/android/wallpaper/module/DefaultNetworkStatusNotifier.java
index 8bd3a8f..5b8aabf 100755
--- a/src/com/android/wallpaper/module/DefaultNetworkStatusNotifier.java
+++ b/src/com/android/wallpaper/module/DefaultNetworkStatusNotifier.java
@@ -22,22 +22,29 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import dagger.hilt.android.qualifiers.ApplicationContext;
+
import java.util.ArrayList;
import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Implementation of {@link NetworkStatusNotifier} which uses
* {@link android.net.ConnectivityManager} to provide network status.
*/
-public class DefaultNetworkStatusNotifier implements NetworkStatusNotifier {
+@Singleton
+public class DefaultNetworkStatusNotifier implements NetworkStatusNotifier {
private Context mAppContext;
private ConnectivityManager mConnectivityManager;
private BroadcastReceiver mReceiver;
private List<Listener> mListeners;
- public DefaultNetworkStatusNotifier(Context context) {
- mAppContext = context.getApplicationContext();
+ @Inject
+ public DefaultNetworkStatusNotifier(@ApplicationContext Context context) {
+ mAppContext = context;
mConnectivityManager =
(ConnectivityManager) mAppContext.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/src/com/android/wallpaper/module/DefaultWallpaperPreferences.kt b/src/com/android/wallpaper/module/DefaultWallpaperPreferences.kt
index a59b0a3..5f10d59 100755
--- a/src/com/android/wallpaper/module/DefaultWallpaperPreferences.kt
+++ b/src/com/android/wallpaper/module/DefaultWallpaperPreferences.kt
@@ -905,19 +905,36 @@
wallpaperModel: LiveWallpaperModel
) {}
- override fun setHasPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
+ override fun setHasSmallPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
sharedPrefs
.edit()
.putBoolean(
- WallpaperPreferenceKeys.KEY_HAS_PREVIEW_TOOLTIP_BEEN_SHOWN,
+ WallpaperPreferenceKeys.KEY_HAS_SMALL_PREVIEW_TOOLTIP_BEEN_SHOWN,
hasTooltipBeenShown
)
.apply()
}
- override fun getHasPreviewTooltipBeenShown(): Boolean {
+ override fun getHasSmallPreviewTooltipBeenShown(): Boolean {
return sharedPrefs.getBoolean(
- WallpaperPreferenceKeys.KEY_HAS_PREVIEW_TOOLTIP_BEEN_SHOWN,
+ WallpaperPreferenceKeys.KEY_HAS_SMALL_PREVIEW_TOOLTIP_BEEN_SHOWN,
+ false
+ )
+ }
+
+ override fun setHasFullPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
+ sharedPrefs
+ .edit()
+ .putBoolean(
+ WallpaperPreferenceKeys.KEY_HAS_FULL_PREVIEW_TOOLTIP_BEEN_SHOWN,
+ hasTooltipBeenShown
+ )
+ .apply()
+ }
+
+ override fun getHasFullPreviewTooltipBeenShown(): Boolean {
+ return sharedPrefs.getBoolean(
+ WallpaperPreferenceKeys.KEY_HAS_FULL_PREVIEW_TOOLTIP_BEEN_SHOWN,
false
)
}
diff --git a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
index fd13598..ed071fb 100755
--- a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
+++ b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java
@@ -44,6 +44,8 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
/**
* Default implementation of {@link WallpaperRefresher} which refreshes wallpaper metadata
@@ -63,6 +65,8 @@
private final WallpaperClient mWallpaperClient;
+ private final Executor mExecutor = Executors.newCachedThreadPool();
+
/**
* @param context The application's context.
@@ -84,7 +88,7 @@
@Override
public void refresh(RefreshListener listener) {
GetWallpaperMetadataAsyncTask task = new GetWallpaperMetadataAsyncTask(listener);
- task.execute();
+ task.executeOnExecutor(mExecutor);
}
/**
@@ -370,7 +374,8 @@
private Map<Point, Rect> getCurrentWallpaperCropHints(
@WallpaperManager.SetWallpaperFlags int which) {
- List<Point> displaySizes = mDisplayUtils.getInternalDisplaySizes();
+ List<Point> displaySizes = mDisplayUtils
+ .getInternalDisplaySizes(/* allDimensions= */ true);
return mWallpaperClient.getCurrentCropHints(displaySizes, which);
}
}
diff --git a/src/com/android/wallpaper/module/WallpaperPicker2Injector.kt b/src/com/android/wallpaper/module/WallpaperPicker2Injector.kt
index c71b5ae..3f37594 100755
--- a/src/com/android/wallpaper/module/WallpaperPicker2Injector.kt
+++ b/src/com/android/wallpaper/module/WallpaperPicker2Injector.kt
@@ -56,6 +56,7 @@
import com.android.wallpaper.picker.individual.IndividualPickerFragment
import com.android.wallpaper.picker.undo.data.repository.UndoRepository
import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
+import com.android.wallpaper.system.UiModeManagerWrapper
import com.android.wallpaper.util.DisplayUtils
import dagger.Lazy
import javax.inject.Inject
@@ -102,6 +103,8 @@
private var viewOnlyPreviewActivityIntentFactory: InlinePreviewIntentFactory? = null
@Inject lateinit var userEventLogger: Lazy<UserEventLogger>
+ @Inject lateinit var uiModeManager: UiModeManagerWrapper
+
override fun getApplicationCoroutineScope(): CoroutineScope {
return mainScope
}
@@ -305,7 +308,7 @@
}
override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
- if (getFlags().isMultiCropEnabled() && getFlags().isMultiCropPreviewUiEnabled()) {
+ if (getFlags().isMultiCropEnabled()) {
return injectedWallpaperInteractor.get()
}
@@ -324,7 +327,7 @@
}
override fun getWallpaperClient(context: Context): WallpaperClient {
- if (getFlags().isMultiCropEnabled() && getFlags().isMultiCropPreviewUiEnabled()) {
+ if (getFlags().isMultiCropEnabled()) {
return injectedWallpaperClient.get()
}
diff --git a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java
index 20e8dee..0e7a88e 100755
--- a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java
+++ b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java
@@ -34,8 +34,10 @@
public static final String KEY_LOCK_WALLPAPER_ACTION_URL = "lock_wallpaper_action_url";
public static final String KEY_LOCK_WALLPAPER_HASH_CODE = "lock_wallpaper_hash_code";
public static final String KEY_LOCK_WALLPAPER_COLLECTION_ID = "lock_wallpaper_collection_id";
- public static final String KEY_HAS_PREVIEW_TOOLTIP_BEEN_SHOWN =
- "has_preview_tooltip_been_shown";
+ public static final String KEY_HAS_SMALL_PREVIEW_TOOLTIP_BEEN_SHOWN =
+ "has_small_preview_tooltip_been_shown";
+ public static final String KEY_HAS_FULL_PREVIEW_TOOLTIP_BEEN_SHOWN =
+ "has_full_preview_tooltip_been_shown";
/**
* Preferences with these keys should not be backed up
diff --git a/src/com/android/wallpaper/module/WallpaperPreferences.kt b/src/com/android/wallpaper/module/WallpaperPreferences.kt
index 6fbb34a..5563a06 100755
--- a/src/com/android/wallpaper/module/WallpaperPreferences.kt
+++ b/src/com/android/wallpaper/module/WallpaperPreferences.kt
@@ -407,10 +407,16 @@
)
/** Sets whether the preview tooltip should be shown. */
- fun setHasPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean)
+ fun setHasSmallPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean)
/** Gets whether the preview tooltip should be shown. */
- fun getHasPreviewTooltipBeenShown(): Boolean
+ fun getHasSmallPreviewTooltipBeenShown(): Boolean
+
+ /** Sets whether the preview tooltip should be shown. */
+ fun setHasFullPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean)
+
+ /** Gets whether the preview tooltip should be shown. */
+ fun getHasFullPreviewTooltipBeenShown(): Boolean
/** The possible wallpaper presentation modes, i.e., either "static" or "rotating". */
@IntDef(PRESENTATION_MODE_STATIC, PRESENTATION_MODE_ROTATING) annotation class PresentationMode
diff --git a/src/com/android/wallpaper/picker/AppbarFragment.java b/src/com/android/wallpaper/picker/AppbarFragment.java
index 339b8c6..f668d67 100644
--- a/src/com/android/wallpaper/picker/AppbarFragment.java
+++ b/src/com/android/wallpaper/picker/AppbarFragment.java
@@ -19,17 +19,21 @@
import static android.view.View.VISIBLE;
import android.annotation.MenuRes;
+import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
+import android.view.Window;
import android.widget.TextView;
import android.widget.Toolbar;
import android.widget.Toolbar.OnMenuItemClickListener;
import androidx.annotation.Nullable;
+import androidx.core.view.WindowCompat;
+import androidx.core.view.WindowInsetsControllerCompat;
import com.android.wallpaper.R;
import com.android.wallpaper.config.BaseFlags;
@@ -129,6 +133,7 @@
// Update toolbar and status bar color.
setToolbarColor(getToolbarColorId());
+ setUpStatusBar(isStatusBarLightText());
CharSequence title;
if (getArguments() != null) {
@@ -168,6 +173,21 @@
return R.color.toolbar_color;
}
+ protected void setUpStatusBar(boolean shouldUseLightText) {
+ Activity activity = getActivity();
+ if (activity == null) {
+ return;
+ }
+ Window window = activity.getWindow();
+ WindowInsetsControllerCompat windowInsetsController =
+ WindowCompat.getInsetsController(window, window.getDecorView());
+ windowInsetsController.setAppearanceLightStatusBars(!shouldUseLightText);
+ }
+
+ protected boolean isStatusBarLightText() {
+ return getResources().getBoolean(R.bool.isFragmentStatusBarLightText);
+ }
+
protected int getToolbarTextColor() {
return ResourceUtils.getColorAttr(getActivity(), android.R.attr.textColorPrimary);
}
diff --git a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
index 9bdc85b..bcb6f9e 100644
--- a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
+++ b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
@@ -27,6 +27,7 @@
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
+import android.view.Window;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -36,6 +37,7 @@
import androidx.fragment.app.FragmentManager;
import com.android.wallpaper.R;
+import com.android.wallpaper.config.BaseFlags;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController;
import com.android.wallpaper.model.PermissionRequester;
@@ -94,6 +96,11 @@
enforcePortraitForHandheldAndFoldedDisplay();
+ BaseFlags flags = injector.getFlags();
+ if (flags.isMultiCropEnabled()) {
+ getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
+ }
+
// Restore this Activity's state before restoring contained Fragments state.
super.onCreate(savedInstanceState);
// Trampoline for the two panes
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index aacb04b..3f2ec34 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -484,7 +484,7 @@
mProgressBar.setVisibility(View.VISIBLE);
View wallpaperPreviewContainer = LayoutInflater.from(context).inflate(
- R.layout.fullscreen_wallpaper_preview, null);
+ R.layout.fullscreen_wallpaper_preview_old, null);
mFullResImageView = wallpaperPreviewContainer.findViewById(R.id.full_res_image);
mLowResImageView = wallpaperPreviewContainer.findViewById(R.id.low_res_image);
mLowResImageView.setRenderEffect(
diff --git a/src/com/android/wallpaper/picker/PreviewActivity.java b/src/com/android/wallpaper/picker/PreviewActivity.java
index da0d3e3..c1fc1f7 100644
--- a/src/com/android/wallpaper/picker/PreviewActivity.java
+++ b/src/com/android/wallpaper/picker/PreviewActivity.java
@@ -130,7 +130,7 @@
LargeScreenMultiPanesChecker multiPanesChecker = new LargeScreenMultiPanesChecker();
final boolean isMultiPanel = multiPanesChecker.isMultiPanesEnabled(appContext);
- if (flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled()) {
+ if (flags.isMultiCropEnabled()) {
return WallpaperPreviewActivity.Companion.newIntent(appContext,
wallpaper, isAssetIdPresent, mIsViewAsHome, /* isNewTask= */ isMultiPanel);
}
diff --git a/src/com/android/wallpaper/picker/StandalonePreviewActivity.java b/src/com/android/wallpaper/picker/StandalonePreviewActivity.java
index 2a9ea51..096aa7b 100644
--- a/src/com/android/wallpaper/picker/StandalonePreviewActivity.java
+++ b/src/com/android/wallpaper/picker/StandalonePreviewActivity.java
@@ -32,7 +32,6 @@
import com.android.wallpaper.R;
import com.android.wallpaper.config.BaseFlags;
import com.android.wallpaper.model.ImageWallpaperInfo;
-import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.picker.AppbarFragment.AppbarFragmentHost;
import com.android.wallpaper.picker.preview.ui.WallpaperPreviewActivity;
@@ -143,17 +142,17 @@
private void loadPreviewFragment() {
BaseFlags flags = InjectorProvider.getInjector().getFlags();
Intent intent = getIntent();
- WallpaperInfo wallpaper = new ImageWallpaperInfo(intent.getData());
- if (flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled()) {
- startActivity(WallpaperPreviewActivity.Companion.newIntent(
- this.getApplicationContext(), wallpaper, /* isAssetIdPresent= */ false,
- /* isViewAsHome= */ true, /* isNewTask= */ false));
+ if (flags.isMultiCropEnabled()) {
+ Intent wallpaperIntent = WallpaperPreviewActivity.Companion.newIntent(
+ this.getApplicationContext(), intent, /* isAssetIdPresent= */ false,
+ /* isViewAsHome= */ true, /* isNewTask= */ false);
+ startActivity(wallpaperIntent);
finish();
return;
}
Fragment fragment = InjectorProvider.getInjector().getPreviewFragment(
/* context */ this,
- wallpaper,
+ new ImageWallpaperInfo(intent.getData()),
/* viewAsHome= */ true,
/* isAssetIdPresent= */ false,
/* isNewTask= */ false);
diff --git a/src/com/android/wallpaper/picker/ViewOnlyPreviewActivity.java b/src/com/android/wallpaper/picker/ViewOnlyPreviewActivity.java
index 48734a7..4d1b398 100644
--- a/src/com/android/wallpaper/picker/ViewOnlyPreviewActivity.java
+++ b/src/com/android/wallpaper/picker/ViewOnlyPreviewActivity.java
@@ -110,7 +110,7 @@
LargeScreenMultiPanesChecker multiPanesChecker = new LargeScreenMultiPanesChecker();
final boolean isMultiPanel = multiPanesChecker.isMultiPanesEnabled(appContext);
final BaseFlags flags = InjectorProvider.getInjector().getFlags();
- if (flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled()) {
+ if (flags.isMultiCropEnabled()) {
return WallpaperPreviewActivity.Companion.newIntent(appContext, wallpaper,
isAssetIdPresent, mIsViewAsHome, /* isNewTask= */ isMultiPanel);
}
diff --git a/src/com/android/wallpaper/picker/category/client /DefaultWallpaperCategoryClient.kt b/src/com/android/wallpaper/picker/category/client /DefaultWallpaperCategoryClient.kt
new file mode 100644
index 0000000..d2d3a39
--- /dev/null
+++ b/src/com/android/wallpaper/picker/category/client /DefaultWallpaperCategoryClient.kt
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.picker.category.client
+
+import android.content.Context
+import android.util.Log
+import com.android.wallpaper.R
+import com.android.wallpaper.model.Category
+import com.android.wallpaper.model.DefaultWallpaperInfo
+import com.android.wallpaper.model.ImageCategory
+import com.android.wallpaper.model.LegacyPartnerWallpaperInfo
+import com.android.wallpaper.model.PartnerWallpaperInfo
+import com.android.wallpaper.model.WallpaperCategory
+import com.android.wallpaper.model.WallpaperInfo
+import com.android.wallpaper.module.DefaultCategoryProvider
+import com.android.wallpaper.module.PartnerProvider
+import com.android.wallpaper.picker.data.category.CategoryModel
+import com.android.wallpaper.util.WallpaperXMLParser
+import com.android.wallpaper.util.converter.category.CategoryFactory
+import dagger.hilt.android.qualifiers.ApplicationContext
+import java.io.IOException
+import java.util.Locale
+import javax.inject.Inject
+import org.xmlpull.v1.XmlPullParser
+import org.xmlpull.v1.XmlPullParserException
+
+/**
+ * This class is responsible for fetching wallpaper categories, listed as follows:
+ * 1. MyPhotos category that allows users to select custom photos
+ * 2. OnDevice category that are pre-loaded wallpapers on device (legacy way of pre-loading
+ * wallpapers, modern way is described below)
+ * 3. System categories on device (modern way of pre-loading wallpapers on device)
+ */
+class DefaultWallpaperCategoryClient
+@Inject
+constructor(
+ @ApplicationContext val context: Context,
+ private val partnerProvider: PartnerProvider,
+ private val categoryFactory: CategoryFactory,
+ private val wallpaperXMLParser: WallpaperXMLParser
+) {
+
+ /** This method is used for fetching and creating the MyPhotos category tile. */
+ fun getMyPhotosCategory(): CategoryModel {
+ val imageCategory =
+ ImageCategory(
+ context.getString(R.string.my_photos_category_title),
+ context.getString(R.string.image_wallpaper_collection_id),
+ DefaultCategoryProvider.getPriorityMyPhotos(context),
+ R.drawable.wallpaperpicker_emptystate /* overlayIconResId */
+ )
+ return categoryFactory.getCategoryModel(context, imageCategory)
+ }
+
+ /**
+ * This method is used for fetching the on-device categories. This returns a category which
+ * incorporates both GEL and bundled wallpapers.
+ */
+ suspend fun getOnDeviceCategory(): CategoryModel? {
+ val onDeviceWallpapers = mutableListOf<WallpaperInfo?>()
+
+ if (!partnerProvider.shouldHideDefaultWallpaper()) {
+ val defaultWallpaperInfo = DefaultWallpaperInfo()
+ onDeviceWallpapers.add(defaultWallpaperInfo)
+ }
+
+ val partnerWallpaperInfos = PartnerWallpaperInfo.getAll(context)
+ onDeviceWallpapers.addAll(partnerWallpaperInfos)
+
+ val legacyPartnerWallpaperInfos = LegacyPartnerWallpaperInfo.getAll(context)
+ onDeviceWallpapers.addAll(legacyPartnerWallpaperInfos)
+
+ val privateWallpapers = getPrivateDeviceWallpapers()
+ privateWallpapers?.let { onDeviceWallpapers.addAll(it) }
+
+ return onDeviceWallpapers
+ .takeIf { it.isNotEmpty() }
+ ?.let {
+ val wallpaperCategory =
+ WallpaperCategory(
+ context.getString(R.string.on_device_wallpapers_category_title),
+ context.getString(R.string.on_device_wallpaper_collection_id),
+ it,
+ PRIORITY_ON_DEVICE
+ )
+ categoryFactory.getCategoryModel(context, wallpaperCategory)
+ }
+ }
+
+ /** This method is used for fetching the system categories. */
+ suspend fun getSystemCategories(): List<CategoryModel> {
+ val partnerRes = partnerProvider.resources
+ val packageName = partnerProvider.packageName
+ val categories = mutableListOf<Category>()
+ val categoryModels = mutableListOf<CategoryModel>()
+ if (partnerRes == null || packageName == null) {
+ return categoryModels
+ }
+
+ val wallpapersResId =
+ partnerRes.getIdentifier(PartnerProvider.WALLPAPER_RES_ID, "xml", packageName)
+ // Certain partner configurations don't have wallpapers provided, so need to check;
+ // return early if they are missing.
+ if (wallpapersResId == 0) {
+ return categoryModels
+ }
+
+ try {
+ val parser = partnerRes.getXml(wallpapersResId)
+ val depth = parser.depth
+ var type: Int
+ while (
+ parser.next().also { type = it } != XmlPullParser.END_TAG ||
+ parser.depth > depth && type != XmlPullParser.END_DOCUMENT
+ ) {
+ if (type == XmlPullParser.START_TAG && WallpaperCategory.TAG_NAME == parser.name) {
+ val category = wallpaperXMLParser.parseCategory(parser)
+ category?.let { categories.add(it) }
+ }
+ }
+ } catch (e: Exception) {
+ when (e) {
+ is IOException,
+ is XmlPullParserException -> {
+ Log.w(TAG, "Couldn't read system wallpapers definition", e)
+ return emptyList()
+ }
+ else -> throw e
+ }
+ }
+ return categories.map { category -> categoryFactory.getCategoryModel(context, category) }
+ }
+
+ private fun getLocale(): Locale {
+ return context.resources.configuration.locales.get(0)
+ }
+
+ private fun getPrivateDeviceWallpapers(): Collection<WallpaperInfo?>? {
+ return null
+ }
+
+ companion object {
+ private const val TAG = "DefaultWallpaperCategoryClient"
+
+ /**
+ * Relative category priorities. Lower numbers correspond to higher priorities (i.e., should
+ * appear higher in the categories list).
+ */
+ const val PRIORITY_MY_PHOTOS_WHEN_CREATIVE_WALLPAPERS_DISABLED = 1
+ private const val PRIORITY_MY_PHOTOS_WHEN_CREATIVE_WALLPAPERS_ENABLED = 51
+ private const val PRIORITY_SYSTEM = 100
+ private const val PRIORITY_ON_DEVICE = 200
+ private const val PRIORITY_LIVE = 300
+ private const val PRIORITY_THIRD_PARTY = 400
+ const val CREATIVE_CATEGORY_PRIORITY = 1
+ }
+}
diff --git a/src/com/android/wallpaper/picker/customization/animation/view/LoadingAnimation.kt b/src/com/android/wallpaper/picker/customization/animation/view/LoadingAnimation.kt
index 175516f..95a3be6 100644
--- a/src/com/android/wallpaper/picker/customization/animation/view/LoadingAnimation.kt
+++ b/src/com/android/wallpaper/picker/customization/animation/view/LoadingAnimation.kt
@@ -111,8 +111,12 @@
elapsedTime = seed ?: (0L..10000L).random()
+ fadeInAnimator?.removeAllListeners()
+ fadeInAnimator?.removeAllUpdateListeners()
fadeInAnimator?.cancel()
timeAnimator?.cancel()
+ revealAnimator?.removeAllListeners()
+ revealAnimator?.removeAllUpdateListeners()
revealAnimator?.cancel()
fadeInAnimator =
@@ -159,7 +163,11 @@
)
return
- if (animationState == AnimationState.FADE_IN_PLAYING) fadeInAnimator?.cancel()
+ if (animationState == AnimationState.FADE_IN_PLAYING) {
+ fadeInAnimator?.removeAllListeners()
+ fadeInAnimator?.removeAllUpdateListeners()
+ fadeInAnimator?.cancel()
+ }
animationState = AnimationState.REVEAL_PLAYING
@@ -221,7 +229,11 @@
)
return
- if (animationState == AnimationState.FADE_IN_PLAYING) fadeInAnimator?.cancel()
+ if (animationState == AnimationState.FADE_IN_PLAYING) {
+ fadeInAnimator?.removeAllListeners()
+ fadeInAnimator?.removeAllUpdateListeners()
+ fadeInAnimator?.cancel()
+ }
animationState = AnimationState.FADE_OUT_PLAYING
@@ -329,6 +341,8 @@
/** Cancels the animation. Unlike end() , cancel() causes the animation to stop in its tracks */
fun cancel() {
+ fadeInAnimator?.removeAllListeners()
+ fadeInAnimator?.removeAllUpdateListeners()
fadeInAnimator?.cancel()
timeAnimator?.cancel()
revealAnimator?.removeAllListeners()
@@ -338,6 +352,8 @@
/** Ends the animation, and causes the animation to skip to the end state */
fun end() {
+ fadeInAnimator?.removeAllListeners()
+ fadeInAnimator?.removeAllUpdateListeners()
fadeInAnimator?.end()
timeAnimator?.end()
revealAnimator?.removeAllListeners()
diff --git a/src/com/android/wallpaper/picker/customization/data/content/WallpaperClient.kt b/src/com/android/wallpaper/picker/customization/data/content/WallpaperClient.kt
index 649a140..bead9ae 100644
--- a/src/com/android/wallpaper/picker/customization/data/content/WallpaperClient.kt
+++ b/src/com/android/wallpaper/picker/customization/data/content/WallpaperClient.kt
@@ -22,13 +22,13 @@
import android.graphics.Bitmap
import android.graphics.Point
import android.graphics.Rect
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint
import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination
import com.android.wallpaper.picker.customization.shared.model.WallpaperModel
import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
-import java.io.InputStream
import kotlinx.coroutines.flow.Flow
/** Defines interface for classes that can interact with the Wallpaper API. */
@@ -48,16 +48,17 @@
* @param wallpaperModel The wallpaper model of the wallpaper.
* @param bitmap The bitmap of the static wallpaper. Note that the bitmap should be the
* original, full-size bitmap.
- * @param wallpaperSize raw wallpaper size
- * @param fullPreviewCropModels full preview crop info for each dimension that user has cropped
+ * @param wallpaperSize raw wallpaper size.
+ * @param asset wallpaper asset.
+ * @param fullPreviewCropModels full preview crop info for each dimension that user has cropped.
*/
suspend fun setStaticWallpaper(
@SetWallpaperEntryPoint setWallpaperEntryPoint: Int,
destination: WallpaperDestination,
wallpaperModel: StaticWallpaperModel,
- inputStream: InputStream?,
bitmap: Bitmap,
wallpaperSize: Point,
+ asset: Asset,
fullPreviewCropModels: Map<Point, FullPreviewCropModel>?,
)
diff --git a/src/com/android/wallpaper/picker/customization/data/content/WallpaperClientImpl.kt b/src/com/android/wallpaper/picker/customization/data/content/WallpaperClientImpl.kt
index 7edc234..5e6ddfd 100644
--- a/src/com/android/wallpaper/picker/customization/data/content/WallpaperClientImpl.kt
+++ b/src/com/android/wallpaper/picker/customization/data/content/WallpaperClientImpl.kt
@@ -35,9 +35,13 @@
import android.net.Uri
import android.os.Looper
import android.util.Log
-import androidx.collection.ArrayMap
+import com.android.app.tracing.TraceUtils.traceAsync
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.asset.BitmapUtils
+import com.android.wallpaper.asset.CurrentWallpaperAsset
+import com.android.wallpaper.asset.StreamableAsset
import com.android.wallpaper.model.CreativeCategory
+import com.android.wallpaper.model.CreativeWallpaperInfo
import com.android.wallpaper.model.LiveWallpaperPrefMetadata
import com.android.wallpaper.model.StaticWallpaperPrefMetadata
import com.android.wallpaper.model.WallpaperInfo
@@ -54,9 +58,12 @@
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
import com.android.wallpaper.util.WallpaperCropUtils
+import com.android.wallpaper.util.converter.WallpaperModelFactory.Companion.getCommonWallpaperData
+import com.android.wallpaper.util.converter.WallpaperModelFactory.Companion.getCreativeWallpaperData
import java.io.IOException
import java.io.InputStream
import java.util.EnumMap
+import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
@@ -131,44 +138,48 @@
@SetWallpaperEntryPoint setWallpaperEntryPoint: Int,
destination: WallpaperDestination,
wallpaperModel: StaticWallpaperModel,
- inputStream: InputStream?,
bitmap: Bitmap,
wallpaperSize: Point,
+ asset: Asset,
fullPreviewCropModels: Map<Point, FullPreviewCropModel>?,
) {
if (destination == HOME || destination == BOTH) {
- // Disable rotation wallpaper when setting to home screen. Daily rotation rotates both
- // home and lock screen wallpaper when lock screen is not set; otherwise daily rotation
- // only rotates home screen while lock screen wallpaper stays as what it's set to.
+ // Disable rotation wallpaper when setting to home screen. Daily rotation rotates
+ // both home and lock screen wallpaper when lock screen is not set; otherwise daily
+ // rotation only rotates home screen while lock screen wallpaper stays as what it's
+ // set to.
stopWallpaperRotation()
}
- val cropHintsWithParallax =
- fullPreviewCropModels?.let { cropModels ->
- cropModels.mapValues { it.value.adjustCropForParallax(wallpaperSize) }
- }
- ?: emptyMap()
- val managerId =
- wallpaperManager.setStaticWallpaperToSystem(
- inputStream,
- bitmap,
- cropHintsWithParallax,
- destination,
+ traceAsync(TAG, "setStaticWallpaper") {
+ val cropHintsWithParallax =
+ fullPreviewCropModels?.let { cropModels ->
+ cropModels.mapValues { it.value.adjustCropForParallax(wallpaperSize) }
+ }
+ ?: emptyMap()
+ val managerId =
+ wallpaperManager.setStaticWallpaperToSystem(
+ asset.getStream(),
+ bitmap,
+ cropHintsWithParallax,
+ destination,
+ asset,
+ )
+
+ wallpaperPreferences.setStaticWallpaperMetadata(
+ metadata = wallpaperModel.getMetadata(bitmap, managerId),
+ destination = destination,
)
- wallpaperPreferences.setStaticWallpaperMetadata(
- metadata = wallpaperModel.getMetadata(bitmap, managerId),
- destination = destination,
- )
-
- // Save the static wallpaper to recent wallpapers
- // TODO(b/309138446): check if we can update recent with all cropHints from WM later
- wallpaperPreferences.addStaticWallpaperToRecentWallpapers(
- destination,
- wallpaperModel,
- bitmap,
- cropHintsWithParallax,
- )
+ // Save the static wallpaper to recent wallpapers
+ // TODO(b/309138446): check if we can update recent with all cropHints from WM later
+ wallpaperPreferences.addStaticWallpaperToRecentWallpapers(
+ destination,
+ wallpaperModel,
+ bitmap,
+ cropHintsWithParallax,
+ )
+ }
}
private fun stopWallpaperRotation() {
@@ -188,8 +199,11 @@
bitmap: Bitmap,
cropHints: Map<Point, Rect>,
destination: WallpaperDestination,
+ asset: Asset,
): Int {
- return if (inputStream != null) {
+ // The InputStream of current wallpaper points to system wallpaper file which will be
+ // overwritten during set wallpaper and reads 0 bytes, use Bitmap instead.
+ return if (inputStream != null && asset !is CurrentWallpaperAsset) {
setStreamWithCrops(
inputStream,
cropHints,
@@ -254,46 +268,73 @@
wallpaperModel: LiveWallpaperModel,
) {
if (destination == HOME || destination == BOTH) {
- // Disable rotation wallpaper when setting to home screen. Daily rotation rotates both
- // home and lock screen wallpaper when lock screen is not set; otherwise daily rotation
- // only rotates home screen while lock screen wallpaper stays as what it's set to.
+ // Disable rotation wallpaper when setting to home screen. Daily rotation rotates
+ // both home and lock screen wallpaper when lock screen is not set; otherwise daily
+ // rotation only rotates home screen while lock screen wallpaper stays as what it's
+ // set to.
stopWallpaperRotation()
}
- if (wallpaperModel.creativeWallpaperData != null) {
- saveCreativeWallpaperAtExternal(wallpaperModel, destination)
+ traceAsync(TAG, "setLiveWallpaper") {
+ val updatedWallpaperModel =
+ wallpaperModel.creativeWallpaperData?.let {
+ saveCreativeWallpaperAtExternal(wallpaperModel, destination)
+ }
+ ?: wallpaperModel
+
+ val managerId =
+ wallpaperManager.setLiveWallpaperToSystem(updatedWallpaperModel, destination)
+
+ wallpaperPreferences.setLiveWallpaperMetadata(
+ metadata = updatedWallpaperModel.getMetadata(managerId),
+ destination = destination,
+ )
+
+ wallpaperPreferences.addLiveWallpaperToRecentWallpapers(
+ destination,
+ updatedWallpaperModel
+ )
}
-
- val managerId = wallpaperManager.setLiveWallpaperToSystem(wallpaperModel, destination)
-
- wallpaperPreferences.setLiveWallpaperMetadata(
- metadata = wallpaperModel.getMetadata(managerId),
- destination = destination,
- )
-
- wallpaperPreferences.addLiveWallpaperToRecentWallpapers(destination, wallpaperModel)
}
- /** Call the external app to save the creative wallpaper. */
+ /**
+ * Call the external app to save the creative wallpaper, and return an updated model based on
+ * the response.
+ */
private fun saveCreativeWallpaperAtExternal(
wallpaperModel: LiveWallpaperModel,
destination: WallpaperDestination,
- ) {
+ ): LiveWallpaperModel? {
wallpaperModel.getSaveWallpaperUriAndAuthority(destination)?.let { (uri, authority) ->
try {
context.contentResolver.acquireContentProviderClient(authority).use { client ->
- client?.query(
- /* url= */ uri,
- /* projection= */ null,
- /* selection= */ null,
- /* selectionArgs= */ null,
- /* sortOrder= */ null,
+ val cursor =
+ client?.query(
+ /* url= */ uri,
+ /* projection= */ null,
+ /* selection= */ null,
+ /* selectionArgs= */ null,
+ /* sortOrder= */ null,
+ )
+ if (cursor == null || !cursor.moveToFirst()) return null
+ val info =
+ CreativeWallpaperInfo.buildFromCursor(
+ wallpaperModel.liveWallpaperData.systemWallpaperInfo,
+ cursor
+ )
+ // NB: need to regenerate common data to update the thumbnail asset
+ return LiveWallpaperModel(
+ info.getCommonWallpaperData(context),
+ wallpaperModel.liveWallpaperData,
+ info.getCreativeWallpaperData(),
+ wallpaperModel.internalLiveWallpaperData
)
}
} catch (e: Exception) {
Log.e(TAG, "Failed updating creative live wallpaper at external.")
}
}
+ return null
}
/**
@@ -392,11 +433,14 @@
updateValues.put(KEY_ID, wallpaperId)
updateValues.put(KEY_SCREEN, destination.asString())
updateValues.put(KEY_SET_WALLPAPER_ENTRY_POINT, setWallpaperEntryPoint)
- val updatedRowCount = context.contentResolver.update(SET_WALLPAPER_URI, updateValues, null)
- if (updatedRowCount == 0) {
- Log.e(TAG, "Error setting wallpaper: $wallpaperId")
+ traceAsync(TAG, "setRecentWallpaper") {
+ val updatedRowCount =
+ context.contentResolver.update(SET_WALLPAPER_URI, updateValues, null)
+ if (updatedRowCount == 0) {
+ Log.e(TAG, "Error setting wallpaper: $wallpaperId")
+ }
+ onDone.invoke()
}
- onDone.invoke()
}
private suspend fun queryRecentWallpapers(
@@ -556,19 +600,13 @@
@SetWallpaperFlags which: Int
): Map<Point, Rect>? {
val flags = InjectorProvider.getInjector().getFlags()
- val isMultiCropEnabled = flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled()
- if (!isMultiCropEnabled) {
+ if (!flags.isMultiCropEnabled()) {
return null
}
val cropHints: List<Rect>? =
wallpaperManager.getBitmapCrops(displaySizes, which, /* originalBitmap= */ true)
- val cropHintsMap: MutableMap<Point, Rect> = ArrayMap()
- if (cropHints != null) {
- for (i in cropHints.indices) {
- cropHintsMap[displaySizes[i]] = cropHints[i]
- }
- }
- return cropHintsMap
+
+ return cropHints?.indices?.associate { displaySizes[it] to cropHints[it] }
}
override suspend fun getWallpaperColors(
@@ -612,7 +650,7 @@
WallpaperCropUtils.calculateCropRect(
context,
it.hostViewSize,
- it.cropSurfaceSize,
+ it.cropViewSize,
wallpaperSize,
cropHint,
it.wallpaperZoom,
@@ -623,6 +661,15 @@
?: cropHint
}
+ private suspend fun Asset.getStream(): InputStream? =
+ suspendCancellableCoroutine { k: CancellableContinuation<InputStream?> ->
+ if (this is StreamableAsset) {
+ fetchInputStream { k.resumeWith(Result.success(it)) }
+ } else {
+ k.resumeWith(Result.success(null))
+ }
+ }
+
companion object {
private const val TAG = "WallpaperClientImpl"
private const val AUTHORITY = "com.google.android.apps.wallpaper.recents"
diff --git a/src/com/android/wallpaper/picker/customization/data/repository/WallpaperRepository.kt b/src/com/android/wallpaper/picker/customization/data/repository/WallpaperRepository.kt
index ec3e58c..ac69bdd 100644
--- a/src/com/android/wallpaper/picker/customization/data/repository/WallpaperRepository.kt
+++ b/src/com/android/wallpaper/picker/customization/data/repository/WallpaperRepository.kt
@@ -22,6 +22,7 @@
import android.graphics.Point
import android.graphics.Rect
import android.util.LruCache
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.module.WallpaperPreferences
import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint
import com.android.wallpaper.picker.customization.data.content.WallpaperClient
@@ -30,7 +31,6 @@
import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
-import java.io.InputStream
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -124,9 +124,9 @@
@SetWallpaperEntryPoint setWallpaperEntryPoint: Int,
destination: WallpaperDestination,
wallpaperModel: StaticWallpaperModel,
- inputStream: InputStream?,
bitmap: Bitmap,
wallpaperSize: Point,
+ asset: Asset,
fullPreviewCropModels: Map<Point, FullPreviewCropModel>? = null,
) {
// TODO(b/303317694): provide set wallpaper status as flow
@@ -135,9 +135,9 @@
setWallpaperEntryPoint,
destination,
wallpaperModel,
- inputStream,
bitmap,
wallpaperSize,
+ asset,
fullPreviewCropModels,
)
}
diff --git a/src/com/android/wallpaper/picker/customization/ui/binder/ScreenPreviewBinder.kt b/src/com/android/wallpaper/picker/customization/ui/binder/ScreenPreviewBinder.kt
index 891177b..62ac400 100644
--- a/src/com/android/wallpaper/picker/customization/ui/binder/ScreenPreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/customization/ui/binder/ScreenPreviewBinder.kt
@@ -134,7 +134,7 @@
val flags = BaseFlags.get()
val isPageTransitionsFeatureEnabled = flags.isPageTransitionsFeatureEnabled(activity)
- val isMultiCropEnabled = flags.isMultiCropEnabled() && flags.isMultiCropPreviewUiEnabled()
+ val isMultiCropEnabled = flags.isMultiCropEnabled()
val showLoadingAnimation =
flags.isPreviewLoadingAnimationEnabled(activity.applicationContext)
diff --git a/src/com/android/wallpaper/picker/data/CreativeWallpaperData.kt b/src/com/android/wallpaper/picker/data/CreativeWallpaperData.kt
index 2b50acb..8c5362a 100644
--- a/src/com/android/wallpaper/picker/data/CreativeWallpaperData.kt
+++ b/src/com/android/wallpaper/picker/data/CreativeWallpaperData.kt
@@ -29,4 +29,5 @@
val description: String,
val contentDescription: String?,
val isCurrent: Boolean,
+ val creativeWallpaperEffectsData: CreativeWallpaperEffectsData?,
)
diff --git a/src/com/android/wallpaper/picker/data/CreativeWallpaperEffectsData.kt b/src/com/android/wallpaper/picker/data/CreativeWallpaperEffectsData.kt
new file mode 100644
index 0000000..b7d6897
--- /dev/null
+++ b/src/com/android/wallpaper/picker/data/CreativeWallpaperEffectsData.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 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.wallpaper.picker.data
+
+import android.net.Uri
+
+/** Represents data that is specific to only effects for CreativeWallpapers. */
+data class CreativeWallpaperEffectsData(
+ val effectsBottomSheetTitle: String,
+ val effectsBottomSheetSubtitle: String,
+ val currentEffectId: String,
+ val clearActionUri: Uri,
+ val effectsUri: Uri,
+)
diff --git a/src/com/android/wallpaper/picker/data/DownloadableWallpaperData.kt b/src/com/android/wallpaper/picker/data/DownloadableWallpaperData.kt
index a739ab8..a6a95b2 100644
--- a/src/com/android/wallpaper/picker/data/DownloadableWallpaperData.kt
+++ b/src/com/android/wallpaper/picker/data/DownloadableWallpaperData.kt
@@ -24,5 +24,4 @@
val systemWallpaperInfo: WallpaperInfo,
val isTitleVisible: Boolean,
val isApplied: Boolean,
- val effectNames: String?,
)
diff --git a/src/com/android/wallpaper/picker/data/LiveWallpaperData.kt b/src/com/android/wallpaper/picker/data/LiveWallpaperData.kt
index 73180f3..7efa2ea 100644
--- a/src/com/android/wallpaper/picker/data/LiveWallpaperData.kt
+++ b/src/com/android/wallpaper/picker/data/LiveWallpaperData.kt
@@ -24,5 +24,6 @@
val systemWallpaperInfo: WallpaperInfo,
val isTitleVisible: Boolean,
val isApplied: Boolean,
+ val isEffectWallpaper: Boolean,
val effectNames: String?
)
diff --git a/src/com/android/wallpaper/picker/data/category /CollectionCategoryData.kt b/src/com/android/wallpaper/picker/data/category /CollectionCategoryData.kt
index 80d9cb3..a02cbab 100644
--- a/src/com/android/wallpaper/picker/data/category /CollectionCategoryData.kt
+++ b/src/com/android/wallpaper/picker/data/category /CollectionCategoryData.kt
@@ -21,7 +21,7 @@
/** Represents set of attributes that depict a collection of wallpapers. */
data class CollectionCategoryData(
- val wallpaperModels: List<WallpaperModel>,
+ val wallpaperModels: MutableList<WallpaperModel>,
val thumbAsset: Asset,
val featuredThumbnailIndex: Int,
val isSingleWallpaperCategory: Boolean
diff --git a/src/com/android/wallpaper/picker/preview/data/repository/CreativeEffectsRepository.kt b/src/com/android/wallpaper/picker/preview/data/repository/CreativeEffectsRepository.kt
new file mode 100644
index 0000000..1b520c6
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/data/repository/CreativeEffectsRepository.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.picker.preview.data.repository
+
+import android.content.ContentValues
+import android.content.Context
+import android.net.Uri
+import android.util.Log
+import com.android.wallpaper.model.WallpaperAction
+import com.android.wallpaper.model.WallpaperInfoContract
+import com.android.wallpaper.picker.data.CreativeWallpaperEffectsData
+import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
+import com.android.wallpaper.picker.preview.shared.model.CreativeEffectsModel
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.android.scopes.ActivityRetainedScoped
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.withContext
+
+@ActivityRetainedScoped
+class CreativeEffectsRepository
+@Inject
+constructor(
+ @ApplicationContext private val context: Context,
+ @BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
+) {
+
+ private val _creativeEffectsModel = MutableStateFlow<CreativeEffectsModel?>(null)
+ val creativeEffectsModel = _creativeEffectsModel.asStateFlow()
+
+ private var clearActionUri: Uri? = null
+
+ suspend fun initializeEffect(data: CreativeWallpaperEffectsData) {
+ withContext(bgDispatcher) {
+ clearActionUri = data.clearActionUri
+ try {
+ data.effectsUri.authority
+ ?.let { context.contentResolver.acquireContentProviderClient(it) }
+ ?.use { it.query(data.effectsUri, null, null, null, null) }
+ ?.use { effectsCursor ->
+ while (effectsCursor.moveToNext()) {
+ val effectsToggleUri =
+ Uri.parse(
+ effectsCursor.getString(
+ effectsCursor.getColumnIndex(
+ WallpaperInfoContract.WALLPAPER_EFFECTS_TOGGLE_URI
+ )
+ )
+ )
+ val effectsButtonLabel: String =
+ effectsCursor.getString(
+ effectsCursor.getColumnIndex(
+ WallpaperInfoContract.WALLPAPER_EFFECTS_BUTTON_LABEL
+ )
+ )
+ val effectsId: String =
+ effectsCursor.getString(
+ effectsCursor.getColumnIndex(
+ WallpaperInfoContract.WALLPAPER_EFFECTS_TOGGLE_ID
+ )
+ )
+ _creativeEffectsModel.value =
+ CreativeEffectsModel(
+ title = data.effectsBottomSheetTitle,
+ subtitle = data.effectsBottomSheetSubtitle,
+ actions =
+ listOf(
+ WallpaperAction(
+ label = effectsButtonLabel,
+ applyActionUri = effectsToggleUri,
+ effectId = effectsId,
+ toggled = effectsId == data.currentEffectId,
+ )
+ ),
+ )
+ }
+ }
+ } catch (e: Exception) {
+ Log.e(TAG, "Read wallpaper effects with exception.", e)
+ }
+ }
+ }
+
+ suspend fun turnOnCreativeEffect(actionPosition: Int) {
+ withContext(bgDispatcher) {
+ val clearActionUri =
+ clearActionUri
+ ?: throw NullPointerException(
+ "clearActionUri should be initialized already if creative wallpaper" +
+ " effects are available."
+ )
+ val model = _creativeEffectsModel.value ?: return@withContext
+ val updatedActions =
+ model.actions.mapIndexed { index, action ->
+ val applyActionUri = action.applyActionUri
+ if (actionPosition == index && applyActionUri != null) {
+ context.contentResolver.update(applyActionUri, ContentValues(), null)
+ }
+ action.copy(toggled = actionPosition == index && applyActionUri != null)
+ }
+ if (actionPosition < 0) {
+ context.contentResolver.update(clearActionUri, ContentValues(), null)
+ }
+ _creativeEffectsModel.value = model.copy(actions = updatedActions)
+ }
+ }
+
+ fun destroy() {
+ _creativeEffectsModel.value = null
+ clearActionUri = null
+ }
+
+ companion object {
+ private const val TAG = "CreativeEffectsRepository"
+ }
+}
diff --git a/src/com/android/wallpaper/picker/preview/data/repository/EffectsRepository.kt b/src/com/android/wallpaper/picker/preview/data/repository/ImageEffectsRepository.kt
similarity index 68%
rename from src/com/android/wallpaper/picker/preview/data/repository/EffectsRepository.kt
rename to src/com/android/wallpaper/picker/preview/data/repository/ImageEffectsRepository.kt
index 0fd887e..699de62 100644
--- a/src/com/android/wallpaper/picker/preview/data/repository/EffectsRepository.kt
+++ b/src/com/android/wallpaper/picker/preview/data/repository/ImageEffectsRepository.kt
@@ -24,12 +24,17 @@
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
import android.service.wallpaper.WallpaperService
+import android.stats.style.StyleEnums
import android.util.Log
import com.android.wallpaper.config.BaseFlags
import com.android.wallpaper.effects.Effect
import com.android.wallpaper.effects.EffectContract
import com.android.wallpaper.effects.EffectsController
+import com.android.wallpaper.effects.EffectsController.EffectEnumInterface
+import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.data.LiveWallpaperData
import com.android.wallpaper.picker.data.WallpaperId
import com.android.wallpaper.picker.data.WallpaperModel
@@ -38,21 +43,22 @@
import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.EffectTextRes
import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.android.scopes.ActivityRetainedScoped
import java.io.IOException
import javax.inject.Inject
-import javax.inject.Singleton
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext
import org.xmlpull.v1.XmlPullParserException
-@Singleton
-class EffectsRepository
+@ActivityRetainedScoped
+class ImageEffectsRepository
@Inject
constructor(
@ApplicationContext private val context: Context,
private val effectsController: EffectsController,
+ private val logger: UserEventLogger,
@BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
) {
enum class EffectStatus {
@@ -62,31 +68,43 @@
EFFECT_DOWNLOAD_IN_PROGRESS,
EFFECT_APPLY_IN_PROGRESS,
EFFECT_APPLIED,
+ EFFECT_DOWNLOAD_FAILED,
}
private val _effectStatus = MutableStateFlow(EffectStatus.EFFECT_DISABLE)
val effectStatus = _effectStatus.asStateFlow()
- val wallpaperEffect = MutableStateFlow<Effect?>(null)
+ private val _wallpaperEffect = MutableStateFlow<Effect?>(null)
+ val wallpaperEffect = _wallpaperEffect.asStateFlow()
// This StaticWallpaperModel is set when initializing the repository and used for
// 1. Providing essential data to construct LiveWallpaperData when effect is enabled
// 2. Reverting back to the original static image wallpaper when effect is disabled
private lateinit var staticWallpaperModel: StaticWallpaperModel
private lateinit var onWallpaperUpdated: (wallpaper: WallpaperModel) -> Unit
+ private val timeOutHandler: Handler = Handler(Looper.getMainLooper())
+ private var startGeneratingTime = 0L
+ private var startDownloadTime = 0L
+
+ /** Returns whether effects are available at all on the device */
+ fun areEffectsAvailable(): Boolean {
+ return effectsController.areEffectsAvailable()
+ }
+
suspend fun initializeEffect(
staticWallpaperModel: StaticWallpaperModel,
onWallpaperModelUpdated: (wallpaper: WallpaperModel) -> Unit
) {
this.staticWallpaperModel = staticWallpaperModel
onWallpaperUpdated = onWallpaperModelUpdated
+
withContext(bgDispatcher) {
val listener =
EffectsController.EffectsServiceListener {
- _,
+ effect,
bundle,
resultCode,
originalStatusCode,
- errorMessage ->
+ _ ->
when (resultCode) {
EffectsController.RESULT_PROBE_SUCCESS -> {
_effectStatus.value = EffectStatus.EFFECT_READY
@@ -103,36 +121,52 @@
_effectStatus.value = EffectStatus.EFFECT_DOWNLOAD_IN_PROGRESS
}
EffectsController.RESULT_FOREGROUND_DOWNLOAD_SUCCEEDED -> {
- // TODO logger.logEffectForegroundDownload
+ logger.logEffectForegroundDownload(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_ON_SUCCESS,
+ System.currentTimeMillis() - startDownloadTime,
+ )
_effectStatus.value = EffectStatus.EFFECT_READY
}
- EffectsController.RESULT_FOREGROUND_DOWNLOAD_FAILED -> {
- // TODO logger.logEffectForegroundDownload
- _effectStatus.value = EffectStatus.EFFECT_DOWNLOAD_READY
+ EffectsController.RESULT_FOREGROUND_DOWNLOAD_FAILED,
+ EffectsController.RESULT_ERROR_TRY_AGAIN_LATER -> {
+ logger.logEffectForegroundDownload(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_ON_FAILED,
+ System.currentTimeMillis() - startDownloadTime,
+ )
+ _effectStatus.value = EffectStatus.EFFECT_DOWNLOAD_FAILED
}
- EffectsController.RESULT_SUCCESS -> {
- _effectStatus.value = EffectStatus.EFFECT_APPLIED
- // TODO logger.logEffectApply
- bundle.getCinematicWallpaperModel()?.let {
- onWallpaperUpdated.invoke(it)
- }
- }
+ EffectsController.RESULT_SUCCESS,
EffectsController.RESULT_SUCCESS_WITH_GENERATION_ERROR -> {
_effectStatus.value = EffectStatus.EFFECT_APPLIED
- // TODO logger.logEffectApply
- bundle.getCinematicWallpaperModel()?.let {
+ logger.logEffectApply(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_ON_SUCCESS,
+ /* timeElapsedMillis= */ System.currentTimeMillis() -
+ startGeneratingTime,
+ /* resultCode= */ originalStatusCode
+ )
+ bundle.getCinematicWallpaperModel(effect)?.let {
onWallpaperUpdated.invoke(it)
}
}
EffectsController.RESULT_SUCCESS_REUSED -> {
_effectStatus.value = EffectStatus.EFFECT_APPLIED
- bundle.getCinematicWallpaperModel()?.let {
+ bundle.getCinematicWallpaperModel(effect)?.let {
onWallpaperUpdated.invoke(it)
}
}
else -> {
// TODO onImageEffectFailed
- _effectStatus.value = EffectStatus.EFFECT_READY
+ _effectStatus.value = EffectStatus.EFFECT_DOWNLOAD_FAILED
+ logger.logEffectApply(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_ON_FAILED,
+ /* timeElapsedMillis= */ System.currentTimeMillis() -
+ startGeneratingTime,
+ /* resultCode= */ originalStatusCode
+ )
}
}
}
@@ -157,7 +191,7 @@
while (it.moveToNext()) {
val titleRow: Int = it.getColumnIndex(EffectContract.KEY_EFFECT_TITLE)
val idRow: Int = it.getColumnIndex(EffectContract.KEY_EFFECT_ID)
- wallpaperEffect.value =
+ _wallpaperEffect.value =
Effect(
it.getInt(idRow),
it.getString(titleRow),
@@ -175,7 +209,9 @@
}
}
- private fun Bundle.getCinematicWallpaperModel(): LiveWallpaperModel? {
+ private fun Bundle.getCinematicWallpaperModel(
+ effect: EffectEnumInterface
+ ): LiveWallpaperModel? {
val componentName =
if (containsKey(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT)) {
getParcelable<ComponentName>(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT)
@@ -219,7 +255,8 @@
systemWallpaperInfo = wallpaperInfo,
isTitleVisible = false,
isApplied = false,
- effectNames = null,
+ isEffectWallpaper = effectsController.isEffectsWallpaper(wallpaperInfo),
+ effectNames = effect.toString(),
)
return LiveWallpaperModel(
commonWallpaperData = commonWallpaperData,
@@ -236,7 +273,8 @@
}
}
- fun enableImageEffect(effect: EffectsController.EffectEnumInterface) {
+ fun enableImageEffect(effect: EffectEnumInterface) {
+ startGeneratingTime = System.currentTimeMillis()
_effectStatus.value = EffectStatus.EFFECT_APPLY_IN_PROGRESS
// TODO: Maybe we should call reconnect wallpaper if we have created a LiveWallpaperModel
// if (mLiveWallpaperInfo != null) {
@@ -245,20 +283,39 @@
// }
val uri = staticWallpaperModel.imageWallpaperData?.uri ?: return
effectsController.generateEffect(effect, uri)
- // TODO: Implement time out
+ timeOutHandler.postDelayed(
+ {
+ wallpaperEffect.value?.let { effectsController.interruptGenerate(it) }
+ _effectStatus.value = EffectStatus.EFFECT_READY
+ logger.logEffectApply(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_ON_FAILED,
+ System.currentTimeMillis() - startGeneratingTime,
+ EffectsController.ERROR_ORIGINAL_TIME_OUT,
+ )
+ },
+ TIME_OUT_TIME_IN_MS
+ )
}
fun disableImageEffect() {
// TODO implement disabling effect
_effectStatus.value = EffectStatus.EFFECT_READY
+ logger.logEffectApply(
+ wallpaperEffect.value?.type.toString(),
+ StyleEnums.EFFECT_APPLIED_OFF,
+ 0L,
+ 0,
+ )
onWallpaperUpdated.invoke(staticWallpaperModel)
}
fun destroy() {
effectsController.removeListener()
+ _wallpaperEffect.value = null
}
- fun isTargetEffect(effect: EffectsController.EffectEnumInterface): Boolean {
+ fun isTargetEffect(effect: EffectEnumInterface): Boolean {
return effectsController.isTargetEffect(effect)
}
@@ -272,7 +329,28 @@
)
}
+ /**
+ * This function triggers the downloading of the machine learning models. The downloading occurs
+ * in the foreground off the main thread so it's safe to trigger it from the main thread.
+ */
+ fun startEffectsModelDownload(effect: Effect) {
+ effectsController.startForegroundDownload(effect)
+ _effectStatus.value = EffectStatus.EFFECT_DOWNLOAD_IN_PROGRESS
+ startDownloadTime = System.currentTimeMillis()
+ logger.logEffectForegroundDownload(
+ getEffectNameForLogging(),
+ StyleEnums.EFFECT_APPLIED_STARTED,
+ 0,
+ )
+ }
+
+ private fun getEffectNameForLogging(): String {
+ val effect = wallpaperEffect.value
+ return effect?.type?.toString() ?: EffectsController.Effect.UNKNOWN.toString()
+ }
+
companion object {
private const val TAG = "EffectsRepository"
+ private const val TIME_OUT_TIME_IN_MS = 90000L
}
}
diff --git a/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepository.kt b/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepository.kt
index 020593c..deaaca7 100644
--- a/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepository.kt
+++ b/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepository.kt
@@ -47,13 +47,24 @@
_wallpaperModel.value = wallpaperModel
}
- private val _hasTooltipBeenShown: MutableStateFlow<Boolean> =
- MutableStateFlow(preferences.getHasPreviewTooltipBeenShown())
- val hasTooltipBeenShown: StateFlow<Boolean> = _hasTooltipBeenShown.asStateFlow()
+ private val _hasSmallPreviewTooltipBeenShown: MutableStateFlow<Boolean> =
+ MutableStateFlow(preferences.getHasFullPreviewTooltipBeenShown())
+ val hasSmallPreviewTooltipBeenShown: StateFlow<Boolean> =
+ _hasSmallPreviewTooltipBeenShown.asStateFlow()
- fun dismissTooltip() {
- _hasTooltipBeenShown.value = true
- preferences.setHasPreviewTooltipBeenShown(true)
+ fun hideSmallPreviewTooltip() {
+ _hasSmallPreviewTooltipBeenShown.value = true
+ preferences.setHasSmallPreviewTooltipBeenShown(true)
+ }
+
+ private val _hasFullPreviewTooltipBeenShown: MutableStateFlow<Boolean> =
+ MutableStateFlow(preferences.getHasFullPreviewTooltipBeenShown())
+ val hasFullPreviewTooltipBeenShown: StateFlow<Boolean> =
+ _hasFullPreviewTooltipBeenShown.asStateFlow()
+
+ fun hideFullPreviewTooltip() {
+ _hasFullPreviewTooltipBeenShown.value = true
+ preferences.setHasFullPreviewTooltipBeenShown(true)
}
suspend fun downloadWallpaper(): LiveWallpaperDownloadResultModel? =
diff --git a/src/com/android/wallpaper/picker/preview/domain/interactor/PreviewActionsInteractor.kt b/src/com/android/wallpaper/picker/preview/domain/interactor/PreviewActionsInteractor.kt
index 1b471cd..870497e 100644
--- a/src/com/android/wallpaper/picker/preview/domain/interactor/PreviewActionsInteractor.kt
+++ b/src/com/android/wallpaper/picker/preview/domain/interactor/PreviewActionsInteractor.kt
@@ -16,9 +16,11 @@
package com.android.wallpaper.picker.preview.domain.interactor
+import com.android.wallpaper.effects.Effect
import com.android.wallpaper.effects.EffectsController.EffectEnumInterface
import com.android.wallpaper.picker.data.WallpaperModel
-import com.android.wallpaper.picker.preview.data.repository.EffectsRepository
+import com.android.wallpaper.picker.preview.data.repository.CreativeEffectsRepository
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository
import com.android.wallpaper.picker.preview.data.repository.WallpaperPreviewRepository
import com.android.wallpaper.picker.preview.shared.model.LiveWallpaperDownloadResultModel
import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2
@@ -35,30 +37,36 @@
@Inject
constructor(
private val wallpaperPreviewRepository: WallpaperPreviewRepository,
- private val effectsRepository: EffectsRepository,
+ private val imageEffectsRepository: ImageEffectsRepository,
+ private val creativeEffectsRepository: CreativeEffectsRepository,
) {
val wallpaperModel: StateFlow<WallpaperModel?> = wallpaperPreviewRepository.wallpaperModel
private val _isDownloadingWallpaper = MutableStateFlow<Boolean>(false)
val isDownloadingWallpaper: Flow<Boolean> = _isDownloadingWallpaper.asStateFlow()
- val effectsStatus = effectsRepository.effectStatus
- val effect = effectsRepository.wallpaperEffect
+ val imageEffectsStatus = imageEffectsRepository.effectStatus
+ val imageEffect = imageEffectsRepository.wallpaperEffect
+ val creativeEffectsModel = creativeEffectsRepository.creativeEffectsModel
+
+ suspend fun turnOnCreativeEffect(actionPosition: Int) {
+ creativeEffectsRepository.turnOnCreativeEffect(actionPosition)
+ }
fun enableImageEffect(effect: EffectEnumInterface) {
- effectsRepository.enableImageEffect(effect)
+ imageEffectsRepository.enableImageEffect(effect)
}
fun disableImageEffect() {
- effectsRepository.disableImageEffect()
+ imageEffectsRepository.disableImageEffect()
}
fun isTargetEffect(effect: EffectEnumInterface): Boolean {
- return effectsRepository.isTargetEffect(effect)
+ return imageEffectsRepository.isTargetEffect(effect)
}
fun getEffectTextRes(): WallpaperEffectsView2.EffectTextRes {
- return effectsRepository.getEffectTextRes()
+ return imageEffectsRepository.getEffectTextRes()
}
suspend fun downloadWallpaper(): LiveWallpaperDownloadResultModel? {
@@ -67,4 +75,8 @@
_isDownloadingWallpaper.value = false
return wallpaperModel
}
+
+ fun startEffectsMLDownload(effect: Effect) {
+ imageEffectsRepository.startEffectsModelDownload(effect)
+ }
}
diff --git a/src/com/android/wallpaper/picker/preview/domain/interactor/WallpaperPreviewInteractor.kt b/src/com/android/wallpaper/picker/preview/domain/interactor/WallpaperPreviewInteractor.kt
index 20da4f4..da6b835 100644
--- a/src/com/android/wallpaper/picker/preview/domain/interactor/WallpaperPreviewInteractor.kt
+++ b/src/com/android/wallpaper/picker/preview/domain/interactor/WallpaperPreviewInteractor.kt
@@ -20,6 +20,7 @@
import android.graphics.Bitmap
import android.graphics.Point
import android.graphics.Rect
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository
import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination
@@ -28,7 +29,6 @@
import com.android.wallpaper.picker.preview.data.repository.WallpaperPreviewRepository
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
import dagger.hilt.android.scopes.ActivityRetainedScoped
-import java.io.InputStream
import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow
@@ -41,25 +41,30 @@
) {
val wallpaperModel: StateFlow<WallpaperModel?> = wallpaperPreviewRepository.wallpaperModel
- val hasTooltipBeenShown: StateFlow<Boolean> = wallpaperPreviewRepository.hasTooltipBeenShown
- fun dismissTooltip() = wallpaperPreviewRepository.dismissTooltip()
+ val hasSmallPreviewTooltipBeenShown: StateFlow<Boolean> =
+ wallpaperPreviewRepository.hasSmallPreviewTooltipBeenShown
+ fun hideSmallPreviewTooltip() = wallpaperPreviewRepository.hideSmallPreviewTooltip()
+
+ val hasFullPreviewTooltipBeenShown: StateFlow<Boolean> =
+ wallpaperPreviewRepository.hasFullPreviewTooltipBeenShown
+ fun hideFullPreviewTooltip() = wallpaperPreviewRepository.hideFullPreviewTooltip()
suspend fun setStaticWallpaper(
@UserEventLogger.SetWallpaperEntryPoint setWallpaperEntryPoint: Int,
destination: WallpaperDestination,
wallpaperModel: StaticWallpaperModel,
- inputStream: InputStream?,
bitmap: Bitmap,
wallpaperSize: Point,
+ asset: Asset,
fullPreviewCropModels: Map<Point, FullPreviewCropModel>? = null,
) {
wallpaperRepository.setStaticWallpaper(
setWallpaperEntryPoint,
destination,
wallpaperModel,
- inputStream,
bitmap,
wallpaperSize,
+ asset,
fullPreviewCropModels,
)
}
diff --git a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt b/src/com/android/wallpaper/picker/preview/shared/model/CreativeEffectsModel.kt
similarity index 65%
copy from src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
copy to src/com/android/wallpaper/picker/preview/shared/model/CreativeEffectsModel.kt
index 4001f83..11cb86d 100644
--- a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
+++ b/src/com/android/wallpaper/picker/preview/shared/model/CreativeEffectsModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -13,9 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.wallpaper.model.wallpaper
-enum class FoldableDisplay {
- FOLDED,
- UNFOLDED,
-}
+package com.android.wallpaper.picker.preview.shared.model
+
+import com.android.wallpaper.model.WallpaperAction
+
+data class CreativeEffectsModel(
+ val title: String,
+ val subtitle: String,
+ val actions: List<WallpaperAction>,
+)
diff --git a/src/com/android/wallpaper/picker/preview/shared/model/FullPreviewCropModel.kt b/src/com/android/wallpaper/picker/preview/shared/model/FullPreviewCropModel.kt
index 6e83b21..3d13184 100644
--- a/src/com/android/wallpaper/picker/preview/shared/model/FullPreviewCropModel.kt
+++ b/src/com/android/wallpaper/picker/preview/shared/model/FullPreviewCropModel.kt
@@ -44,5 +44,5 @@
/** The size of the view hosting the wallpaper, e.g. SurfaceView. */
val hostViewSize: Point,
/** A larger version of hostViewSize that can safely contain parallax. */
- val cropSurfaceSize: Point,
+ val cropViewSize: Point,
)
diff --git a/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivity.kt b/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivity.kt
index 74e8eff..e0fc0d1 100644
--- a/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivity.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivity.kt
@@ -18,9 +18,9 @@
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
-import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
+import android.view.Window
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
@@ -28,11 +28,14 @@
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.NavHostFragment
import com.android.wallpaper.R
+import com.android.wallpaper.model.ImageWallpaperInfo
import com.android.wallpaper.model.WallpaperInfo
import com.android.wallpaper.picker.AppbarFragment
import com.android.wallpaper.picker.BasePreviewActivity
import com.android.wallpaper.picker.data.WallpaperModel
-import com.android.wallpaper.picker.preview.data.repository.EffectsRepository
+import com.android.wallpaper.picker.di.modules.MainDispatcher
+import com.android.wallpaper.picker.preview.data.repository.CreativeEffectsRepository
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository
import com.android.wallpaper.picker.preview.data.repository.WallpaperPreviewRepository
import com.android.wallpaper.picker.preview.data.util.LiveWallpaperDownloader
import com.android.wallpaper.picker.preview.ui.fragment.SmallPreviewFragment
@@ -47,8 +50,8 @@
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
/** This activity holds the flow for the preview screen. */
@AndroidEntryPoint(BasePreviewActivity::class)
@@ -58,25 +61,46 @@
@Inject lateinit var displayUtils: DisplayUtils
@Inject lateinit var wallpaperModelFactory: WallpaperModelFactory
@Inject lateinit var wallpaperPreviewRepository: WallpaperPreviewRepository
- @Inject lateinit var effectsRepository: EffectsRepository
+
+ @Inject lateinit var imageEffectsRepository: ImageEffectsRepository
+ @Inject lateinit var creativeEffectsRepository: CreativeEffectsRepository
@Inject lateinit var liveWallpaperDownloader: LiveWallpaperDownloader
+ @MainDispatcher @Inject lateinit var mainScope: CoroutineScope
private val wallpaperPreviewViewModel: WallpaperPreviewViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
+ window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
super.onCreate(savedInstanceState)
enforcePortraitForHandheldAndFoldedDisplay()
+ wallpaperPreviewViewModel.updateDisplayConfiguration()
window.navigationBarColor = Color.TRANSPARENT
window.statusBarColor = Color.TRANSPARENT
setContentView(R.layout.activity_wallpaper_preview)
+ val wallpaper =
+ checkNotNull(intent.getParcelableExtra(EXTRA_WALLPAPER_INFO, WallpaperInfo::class.java))
+ .convertToWallpaperModel()
+ val navController =
+ (supportFragmentManager.findFragmentById(R.id.wallpaper_preview_nav_host)
+ as NavHostFragment)
+ .navController
+ val graph = navController.navInflater.inflate(R.navigation.wallpaper_preview_nav_graph)
+ val startDestinationArgs: Bundle? =
+ (wallpaper as? WallpaperModel.LiveWallpaperModel)
+ ?.let {
+ if (it.isNewCreativeWallpaper()) it.getNewCreativeWallpaperArgs() else null
+ }
+ ?.also {
+ // For creating a new creative wallpaper, replace the default start destination
+ // with CreativeEditPreviewFragment.
+ graph.setStartDestination(R.id.creativeEditPreviewFragment)
+ }
+ navController.setGraph(graph, startDestinationArgs)
// Fits screen to navbar and statusbar
WindowCompat.setDecorFitsSystemWindows(window, ActivityUtils.isSUWMode(this))
val isAssetIdPresent = intent.getBooleanExtra(IS_ASSET_ID_PRESENT, false)
wallpaperPreviewViewModel.isNewTask = intent.getBooleanExtra(IS_NEW_TASK, false)
wallpaperPreviewViewModel.isViewAsHome = intent.getBooleanExtra(EXTRA_VIEW_AS_HOME, false)
- val wallpaper =
- checkNotNull(intent.getParcelableExtra(EXTRA_WALLPAPER_INFO, WallpaperInfo::class.java))
- .convertToWallpaperModel()
wallpaperPreviewRepository.setWallpaperModel(wallpaper)
val whichPreview =
if (isAssetIdPresent) WallpaperConnection.WhichPreview.EDIT_NON_CURRENT
@@ -97,9 +121,20 @@
)
}
- if ((wallpaper as? WallpaperModel.StaticWallpaperModel)?.imageWallpaperData != null) {
+ val creativeWallpaperEffectData =
+ (wallpaper as? WallpaperModel.LiveWallpaperModel)
+ ?.creativeWallpaperData
+ ?.creativeWallpaperEffectsData
+ if (creativeWallpaperEffectData != null) {
lifecycleScope.launch {
- effectsRepository.initializeEffect(
+ creativeEffectsRepository.initializeEffect(creativeWallpaperEffectData)
+ }
+ } else if (
+ (wallpaper as? WallpaperModel.StaticWallpaperModel)?.imageWallpaperData != null &&
+ imageEffectsRepository.areEffectsAvailable()
+ ) {
+ lifecycleScope.launch {
+ imageEffectsRepository.initializeEffect(
staticWallpaperModel = wallpaper,
onWallpaperModelUpdated = { wallpaper ->
wallpaperPreviewRepository.setWallpaperModel(wallpaper)
@@ -107,28 +142,6 @@
)
}
}
-
- val liveWallpaperModel = (wallpaper as? WallpaperModel.LiveWallpaperModel)
- if (liveWallpaperModel != null && liveWallpaperModel.isNewCreativeWallpaper()) {
- // If it's a new creative wallpaper, override the start destination to the fullscreen
- // fragment for the create-new flow of creative wallpapers
- val navController =
- (supportFragmentManager.findFragmentById(R.id.wallpaper_preview_nav_host)
- as NavHostFragment)
- .navController
- val navGraph =
- navController.navInflater.inflate(R.navigation.wallpaper_preview_nav_graph)
- navGraph.setStartDestination(R.id.creativeNewPreviewFragment)
- navController.setGraph(
- navGraph,
- Bundle().apply {
- putParcelable(
- SmallPreviewFragment.ARG_EDIT_INTENT,
- liveWallpaperModel.liveWallpaperData.getEditActivityIntent()
- )
- }
- )
- }
}
override fun onUpArrowPressed() {
@@ -148,17 +161,31 @@
}
override fun onDestroy() {
- liveWallpaperDownloader.cleanup()
- (wallpaperPreviewViewModel.wallpaper.value as? WallpaperModel.LiveWallpaperModel)?.let {
- runBlocking { WallpaperConnectionUtils.disconnect(applicationContext, it) }
+ imageEffectsRepository.destroy()
+ creativeEffectsRepository.destroy()
+ // TODO(b/333879532): Only disconnect when leaving the Activity without introducing black
+ // preview. If onDestroy is caused by an orientation change, we should keep the connection
+ // to avoid initiating the engines again.
+ // TODO(b/328302105): MainScope ensures the job gets done non-blocking even if the
+ // activity has been destroyed already. Consider making this part of
+ // WallpaperConnectionUtils.
+ mainScope.launch {
+ liveWallpaperDownloader.cleanup()
+ (wallpaperPreviewViewModel.wallpaper.value as? WallpaperModel.LiveWallpaperModel)?.let {
+ WallpaperConnectionUtils.disconnect(
+ appContext,
+ it,
+ wallpaperPreviewViewModel.smallerDisplaySize
+ )
+ WallpaperConnectionUtils.disconnect(
+ appContext,
+ it,
+ wallpaperPreviewViewModel.wallpaperDisplaySize.value
+ )
+ }
}
- effectsRepository.destroy()
- super.onDestroy()
- }
- override fun onConfigurationChanged(newConfig: Configuration) {
- super.onConfigurationChanged(newConfig)
- enforcePortraitForHandheldAndFoldedDisplay()
+ super.onDestroy()
}
private fun WallpaperInfo.convertToWallpaperModel(): WallpaperModel {
@@ -192,6 +219,46 @@
intent.putExtra(IS_NEW_TASK, isNewTask)
return intent
}
+
+ /**
+ * Returns a new [Intent] that can be used to start [WallpaperPreviewActivity], explicitly
+ * propagating any permissions on the wallpaper data to the new [Intent].
+ *
+ * @param context application context.
+ * @param wallpaperInfo selected by user for editing preview.
+ * @param isNewTask true to launch at a new task.
+ *
+ * TODO(b/291761856): Use wallpaper model to replace wallpaper info.
+ */
+ fun newIntent(
+ context: Context,
+ originalIntent: Intent,
+ isAssetIdPresent: Boolean,
+ isViewAsHome: Boolean = false,
+ isNewTask: Boolean = false,
+ ): Intent {
+ val data = originalIntent.data
+ val intent =
+ newIntent(
+ context,
+ ImageWallpaperInfo(data),
+ isAssetIdPresent,
+ isViewAsHome,
+ isNewTask
+ )
+ // Both these lines are required for permission propagation
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ intent.setData(data)
+ return intent
+ }
+
+ private fun WallpaperModel.LiveWallpaperModel.getNewCreativeWallpaperArgs() =
+ Bundle().apply {
+ putParcelable(
+ SmallPreviewFragment.ARG_EDIT_INTENT,
+ liveWallpaperData.getEditActivityIntent(true),
+ )
+ }
}
/**
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewPagerBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewPagerBinder.kt
index 50f3062..042d6b7 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewPagerBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewPagerBinder.kt
@@ -17,16 +17,16 @@
import android.content.Context
import android.view.View
+import android.view.View.OVER_SCROLL_NEVER
import androidx.lifecycle.LifecycleOwner
import com.android.wallpaper.R
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.model.wallpaper.PreviewPagerPage
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.DualPreviewViewPager
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.adapters.DualPreviewPagerAdapter
import com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout
import com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout.Companion.getViewId
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import kotlinx.coroutines.CoroutineScope
/** Binds dual preview home screen and lock screen view pager. */
object DualPreviewPagerBinder {
@@ -36,16 +36,14 @@
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
applicationContext: Context,
viewLifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
currentNavDestId: Int,
navigate: (View) -> Unit,
) {
// implement adapter for the dual preview pager
dualPreviewView.adapter = DualPreviewPagerAdapter { view, position ->
- PreviewTooltipBinder.bind(
+ PreviewTooltipBinder.bindSmallPreviewTooltip(
tooltipStub = view.requireViewById(R.id.tooltip_stub),
- enableClickToDismiss = false,
- viewModel = wallpaperPreviewViewModel,
+ viewModel = wallpaperPreviewViewModel.smallTooltipViewModel,
lifecycleOwner = viewLifecycleOwner,
)
@@ -54,29 +52,31 @@
val displaySizes =
mapOf(
- FoldableDisplay.FOLDED to wallpaperPreviewViewModel.smallerDisplaySize,
- FoldableDisplay.UNFOLDED to wallpaperPreviewViewModel.wallpaperDisplaySize,
+ DeviceDisplayType.FOLDED to wallpaperPreviewViewModel.smallerDisplaySize,
+ DeviceDisplayType.UNFOLDED to
+ wallpaperPreviewViewModel.wallpaperDisplaySize.value,
)
dualDisplayAspectRatioLayout.setDisplaySizes(displaySizes)
dualPreviewView.setDisplaySizes(displaySizes)
- FoldableDisplay.entries.forEach { display ->
+ DeviceDisplayType.FOLDABLE_DISPLAY_TYPES.forEach { display ->
val previewDisplaySize = dualDisplayAspectRatioLayout.getPreviewDisplaySize(display)
previewDisplaySize?.let {
SmallPreviewBinder.bind(
applicationContext = applicationContext,
view = dualDisplayAspectRatioLayout.requireViewById(display.getViewId()),
viewModel = wallpaperPreviewViewModel,
- mainScope = mainScope,
viewLifecycleOwner = viewLifecycleOwner,
screen = PreviewPagerPage.entries[position].screen,
displaySize = it,
- foldableDisplay = display,
+ deviceDisplayType = display,
currentNavDestId = currentNavDestId,
navigate = navigate,
)
}
}
+
+ dualPreviewView.overScrollMode = OVER_SCROLL_NEVER
}
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewSelectorBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewSelectorBinder.kt
index a69f29d..1721376 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewSelectorBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/DualPreviewSelectorBinder.kt
@@ -20,8 +20,8 @@
import androidx.lifecycle.LifecycleOwner
import androidx.viewpager.widget.ViewPager
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.DualPreviewViewPager
+import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.adapters.TabTextPagerAdapter
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import kotlinx.coroutines.CoroutineScope
/**
* This binder binds the data and view models for the dual preview collection on the small preview
@@ -35,7 +35,6 @@
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
applicationContext: Context,
viewLifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
currentNavDestId: Int,
navigate: (View) -> Unit,
) {
@@ -50,10 +49,13 @@
wallpaperPreviewViewModel,
applicationContext,
viewLifecycleOwner,
- mainScope,
currentNavDestId,
navigate,
)
+ tabsViewPager.currentItem =
+ (tabsViewPager.adapter as TabTextPagerAdapter).getPageNumber(
+ wallpaperPreviewViewModel.isViewAsHome
+ )
}
private fun synchronizePreviewAndTabsPager(
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/FullWallpaperPreviewBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/FullWallpaperPreviewBinder.kt
index f9179cd..b047feb 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/FullWallpaperPreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/FullWallpaperPreviewBinder.kt
@@ -15,21 +15,30 @@
*/
package com.android.wallpaper.picker.preview.ui.binder
+import android.annotation.SuppressLint
import android.content.Context
-import android.graphics.Rect
+import android.graphics.Point
+import android.os.Bundle
+import android.view.Gravity
import android.view.LayoutInflater
import android.view.SurfaceHolder
import android.view.SurfaceView
import android.view.View
+import android.widget.FrameLayout
import android.widget.ImageView
+import androidx.cardview.widget.CardView
+import androidx.core.view.doOnLayout
+import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import androidx.transition.Transition
+import androidx.transition.doOnEnd
import com.android.wallpaper.R
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.picker.TouchForwardingLayout
import com.android.wallpaper.picker.data.WallpaperModel
-import com.android.wallpaper.picker.di.modules.MainDispatcher
import com.android.wallpaper.picker.preview.shared.model.CropSizeModel
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
import com.android.wallpaper.picker.preview.ui.util.SubsamplingScaleImageViewUtil.setOnNewCropListener
@@ -38,12 +47,14 @@
import com.android.wallpaper.picker.preview.ui.view.FullPreviewFrameLayout
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
import com.android.wallpaper.util.DisplayUtils
+import com.android.wallpaper.util.RtlUtils.isRtl
import com.android.wallpaper.util.WallpaperCropUtils
import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils
+import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils.shouldEnforceSingleEngine
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import java.lang.Integer.min
import kotlin.math.max
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@@ -54,121 +65,277 @@
applicationContext: Context,
view: View,
viewModel: WallpaperPreviewViewModel,
+ transition: Transition?,
displayUtils: DisplayUtils,
lifecycleOwner: LifecycleOwner,
- @MainDispatcher mainScope: CoroutineScope,
+ savedInstanceState: Bundle?,
+ onWallpaperLoaded: ((Boolean) -> Unit)? = null,
) {
val wallpaperPreviewCrop: FullPreviewFrameLayout =
view.requireViewById(R.id.wallpaper_preview_crop)
+ val previewCard: CardView = view.requireViewById(R.id.preview_card)
+ val scrimView: View = view.requireViewById(R.id.preview_scrim)
+ var transitionDisposableHandle: DisposableHandle? = null
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
- viewModel.fullWallpaper.collect { (_, config, _) ->
+ viewModel.fullWallpaper.collect { (_, _, displaySize, _) ->
+ val currentSize = displayUtils.getRealSize(checkNotNull(view.context.display))
wallpaperPreviewCrop.setCurrentAndTargetDisplaySize(
- displayUtils.getRealSize(checkNotNull(view.context.display)),
- config.displaySize,
+ currentSize,
+ displaySize,
)
+
+ val setFinalPreviewCardRadiusAndEndLoading = { isWallpaperFullScreen: Boolean ->
+ if (isWallpaperFullScreen) {
+ previewCard.radius = 0f
+ }
+ scrimView.isVisible = isWallpaperFullScreen
+ onWallpaperLoaded?.invoke(isWallpaperFullScreen)
+ }
+ val isPreviewingFullScreen = displaySize == currentSize
+ if (transition == null || savedInstanceState != null) {
+ setFinalPreviewCardRadiusAndEndLoading(isPreviewingFullScreen)
+ } else {
+ transitionDisposableHandle?.dispose()
+ val listener =
+ transition.doOnEnd {
+ setFinalPreviewCardRadiusAndEndLoading(isPreviewingFullScreen)
+ }
+ transitionDisposableHandle = DisposableHandle {
+ listener.let { transition.removeListener(it) }
+ }
+ }
}
}
+ transitionDisposableHandle?.dispose()
}
val surfaceView: SurfaceView = view.requireViewById(R.id.wallpaper_surface)
val surfaceTouchForwardingLayout: TouchForwardingLayout =
view.requireViewById(R.id.touch_forwarding_layout)
- var job: Job? = null
- surfaceView.setZOrderMediaOverlay(true)
- surfaceView.holder.addCallback(
- object : SurfaceViewUtil.SurfaceCallback {
- override fun surfaceCreated(holder: SurfaceHolder) {
- val surfaceSize = holder.surface.defaultSize
- val cropSurfaceSize =
- WallpaperCropUtils.calculateCropSurfaceSize(
- view.resources,
- max(surfaceSize.x, surfaceSize.y),
- min(surfaceSize.x, surfaceSize.y),
- surfaceSize.x,
- surfaceSize.y
- )
- job =
- lifecycleOwner.lifecycleScope.launch {
- viewModel.fullWallpaper.collect {
- (wallpaper, config, allowUserCropping, whichPreview) ->
- if (wallpaper is WallpaperModel.LiveWallpaperModel) {
- WallpaperConnectionUtils.connect(
- applicationContext,
- mainScope,
- wallpaper,
- whichPreview,
- config.screen.toFlag(),
- surfaceView,
- )
- } else if (wallpaper is WallpaperModel.StaticWallpaperModel) {
- val (lowResImageView, fullResImageView) =
- initStaticPreviewSurface(
- applicationContext,
- surfaceView,
- ) { crop, zoom ->
- viewModel.staticWallpaperPreviewViewModel
- .fullPreviewCropModels[config.displaySize] =
- FullPreviewCropModel(
- cropHint = crop,
- cropSizeModel =
- CropSizeModel(
- wallpaperZoom = zoom,
- hostViewSize = surfaceSize,
- cropSurfaceSize = cropSurfaceSize,
- ),
- )
- }
- // We do not allow users to pinch to crop if it is a
- // downloadable wallpaper.
- if (allowUserCropping) {
- surfaceTouchForwardingLayout.initTouchForwarding(
- fullResImageView
- )
- }
-
- // Bind static wallpaper
- StaticWallpaperPreviewBinder.bind(
- lowResImageView,
- fullResImageView,
- viewModel.staticWallpaperPreviewViewModel,
- config.displaySize,
- lifecycleOwner,
- )
- }
- }
- }
+ val displayId = view.context.display.displayId
+ if (displayUtils.hasMultiInternalDisplays()) {
+ val currentDescription = surfaceTouchForwardingLayout.contentDescription?.toString()
+ val descriptionResourceId =
+ if (viewModel.getDisplayId(DeviceDisplayType.FOLDED) == displayId) {
+ R.string.folded_device_state_description
+ } else {
+ R.string.unfolded_device_state_description
}
+ val descriptionString =
+ surfaceTouchForwardingLayout.context.getString(descriptionResourceId)
+ surfaceTouchForwardingLayout.contentDescription = currentDescription + descriptionString
+ }
- override fun surfaceDestroyed(holder: SurfaceHolder) {
- job?.cancel()
- // Note that we disconnect wallpaper connection for live wallpapers in
- // WallpaperPreviewActivity's onDestroy().
- // This is to reduce multiple times of connecting and disconnecting live
- // wallpaper services, when going back and forth small and full preview.
- }
+ var surfaceCallback: SurfaceViewUtil.SurfaceCallback? = null
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ surfaceCallback =
+ bindSurface(
+ applicationContext = applicationContext,
+ surfaceView = surfaceView,
+ surfaceTouchForwardingLayout = surfaceTouchForwardingLayout,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ )
+ surfaceView.setZOrderMediaOverlay(true)
+ surfaceView.holder.addCallback(surfaceCallback)
}
- )
- // TODO (b/300979155): Clean up surface when no longer needed, e.g. onDestroyed
+ // When OnDestroy, release the surface
+ surfaceCallback?.let {
+ surfaceView.holder.removeCallback(it)
+ surfaceCallback = null
+ }
+ }
}
- private fun initStaticPreviewSurface(
+ /**
+ * Create a surface callback that binds the surface when surface created. Note that we return
+ * the surface callback reference so that we can remove the callback from the surface when the
+ * screen is destroyed.
+ */
+ private fun bindSurface(
applicationContext: Context,
surfaceView: SurfaceView,
- onNewCrop: (crop: Rect, zoom: Float) -> Unit
- ): Pair<ImageView, SubsamplingScaleImageView> {
- val preview =
- LayoutInflater.from(applicationContext)
- .inflate(R.layout.fullscreen_wallpaper_preview, null)
- surfaceView.attachView(preview)
- val fullResImageView =
- preview.requireViewById<SubsamplingScaleImageView>(R.id.full_res_image)
- fullResImageView.setOnNewCropListener { crop, zoom -> onNewCrop.invoke(crop, zoom) }
- return Pair(preview.requireViewById(R.id.low_res_image), fullResImageView)
+ surfaceTouchForwardingLayout: TouchForwardingLayout,
+ viewModel: WallpaperPreviewViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ): SurfaceViewUtil.SurfaceCallback {
+ return object : SurfaceViewUtil.SurfaceCallback {
+
+ var job: Job? = null
+ var surfaceOrigWidth: Int? = null
+ var surfaceOrigHeight: Int? = null
+
+ // Suppress lint warning for setting on touch listener to a live wallpaper surface view.
+ // This is because the touch effect on a live wallpaper is purely visual, instead of
+ // functional. The effect can be different for different live wallpapers.
+ @SuppressLint("ClickableViewAccessibility")
+ override fun surfaceCreated(holder: SurfaceHolder) {
+ job =
+ lifecycleOwner.lifecycleScope.launch {
+ viewModel.fullWallpaper.collect {
+ (wallpaper, config, displaySize, allowUserCropping, whichPreview) ->
+ if (wallpaper is WallpaperModel.LiveWallpaperModel) {
+ val engineRenderingConfig =
+ WallpaperConnectionUtils.EngineRenderingConfig(
+ wallpaper.shouldEnforceSingleEngine(),
+ config.deviceDisplayType,
+ viewModel.smallerDisplaySize,
+ displaySize,
+ )
+ WallpaperConnectionUtils.connect(
+ applicationContext,
+ wallpaper,
+ whichPreview,
+ config.screen.toFlag(),
+ surfaceView,
+ engineRenderingConfig,
+ )
+ surfaceTouchForwardingLayout.initTouchForwarding(surfaceView)
+ surfaceView.setOnTouchListener { _, event ->
+ lifecycleOwner.lifecycleScope.launch {
+ WallpaperConnectionUtils.dispatchTouchEvent(
+ wallpaper,
+ engineRenderingConfig,
+ event,
+ )
+ }
+ false
+ }
+ } else if (wallpaper is WallpaperModel.StaticWallpaperModel) {
+ val preview =
+ LayoutInflater.from(applicationContext)
+ .inflate(R.layout.fullscreen_wallpaper_preview, null)
+ adjustSizeAndAttachPreview(
+ applicationContext,
+ surfaceOrigWidth
+ ?: surfaceView.width.also { surfaceOrigWidth = it },
+ surfaceOrigHeight
+ ?: surfaceView.height.also { surfaceOrigHeight = it },
+ surfaceView,
+ preview,
+ )
+
+ val fullResImageView =
+ preview.requireViewById<SubsamplingScaleImageView>(
+ R.id.full_res_image
+ )
+ fullResImageView.doOnLayout {
+ val imageSize =
+ Point(fullResImageView.width, fullResImageView.height)
+ val cropImageSize =
+ WallpaperCropUtils.calculateCropSurfaceSize(
+ applicationContext.resources,
+ max(imageSize.x, imageSize.y),
+ min(imageSize.x, imageSize.y),
+ imageSize.x,
+ imageSize.y
+ )
+ fullResImageView.setOnNewCropListener { crop, zoom ->
+ viewModel.staticWallpaperPreviewViewModel
+ .fullPreviewCropModels[displaySize] =
+ FullPreviewCropModel(
+ cropHint = crop,
+ cropSizeModel =
+ CropSizeModel(
+ wallpaperZoom = zoom,
+ hostViewSize = imageSize,
+ cropViewSize = cropImageSize,
+ ),
+ )
+ }
+ }
+ val lowResImageView =
+ preview.requireViewById<ImageView>(R.id.low_res_image)
+
+ // We do not allow users to pinch to crop if it is a
+ // downloadable wallpaper.
+ if (allowUserCropping) {
+ surfaceTouchForwardingLayout.initTouchForwarding(
+ fullResImageView
+ )
+ }
+
+ // Bind static wallpaper
+ StaticWallpaperPreviewBinder.bind(
+ lowResImageView = lowResImageView,
+ fullResImageView = fullResImageView,
+ viewModel = viewModel.staticWallpaperPreviewViewModel,
+ displaySize = displaySize,
+ viewLifecycleOwner = lifecycleOwner,
+ isFullScreen = true,
+ )
+ }
+ }
+ }
+ }
+
+ override fun surfaceDestroyed(holder: SurfaceHolder) {
+ job?.cancel()
+ job = null
+ // Clean up surface view's on touche listener
+ surfaceTouchForwardingLayout.removeTouchForwarding()
+ surfaceView.setOnTouchListener(null)
+ // Note that we disconnect wallpaper connection for live wallpapers in
+ // WallpaperPreviewActivity's onDestroy().
+ // This is to reduce multiple times of connecting and disconnecting live
+ // wallpaper services, when going back and forth small and full preview.
+ }
+ }
+ }
+
+ // When showing full screen, we set the parent SurfaceView to be bigger than the image by N
+ // percent (usually 10%) as given by getSystemWallpaperMaximumScale. This ensures that no matter
+ // what scale and pan is set by the user, at least N% of the source image in the preview will be
+ // preserved around the visible crop. This is needed for system zoom out animations.
+ private fun adjustSizeAndAttachPreview(
+ applicationContext: Context,
+ origWidth: Int,
+ origHeight: Int,
+ surfaceView: SurfaceView,
+ preview: View,
+ ) {
+ val scale = WallpaperCropUtils.getSystemWallpaperMaximumScale(applicationContext)
+
+ val width = (origWidth * scale).toInt()
+ val height = (origHeight * scale).toInt()
+ val left =
+ ((origWidth - width) / 2).let {
+ if (isRtl(applicationContext)) {
+ -it
+ } else {
+ it
+ }
+ }
+ val top = (origHeight - height) / 2
+
+ val params = surfaceView.layoutParams
+ params.width = width
+ params.height = height
+ surfaceView.x = left.toFloat()
+ surfaceView.y = top.toFloat()
+ surfaceView.layoutParams = params
+ surfaceView.requestLayout()
+
+ preview.measure(
+ View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
+ )
+ preview.layout(0, 0, width, height)
+
+ surfaceView.attachView(preview, width, height)
}
private fun TouchForwardingLayout.initTouchForwarding(targetView: View) {
+ // Make sure the touch forwarding layout same size of the target view
+ layoutParams = FrameLayout.LayoutParams(targetView.width, targetView.height, Gravity.CENTER)
setForwardingEnabled(true)
setTargetView(targetView)
}
+
+ private fun TouchForwardingLayout.removeTouchForwarding() {
+ setForwardingEnabled(false)
+ setTargetView(null)
+ }
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewActionsBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewActionsBinder.kt
index d392c66..df0c9d5 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewActionsBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewActionsBinder.kt
@@ -16,13 +16,13 @@
package com.android.wallpaper.picker.preview.ui.binder
import android.content.Intent
-import android.graphics.Point
import android.net.Uri
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.preview.ui.view.PreviewActionFloatingSheet
import com.android.wallpaper.picker.preview.ui.view.PreviewActionGroup
@@ -36,6 +36,7 @@
import com.android.wallpaper.picker.preview.ui.viewmodel.DeleteConfirmationDialogViewModel
import com.android.wallpaper.picker.preview.ui.viewmodel.PreviewActionsViewModel
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperActionsToggleAdapter
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
import kotlinx.coroutines.launch
@@ -47,7 +48,7 @@
floatingSheet: PreviewActionFloatingSheet,
previewViewModel: WallpaperPreviewViewModel,
actionsViewModel: PreviewActionsViewModel,
- displaySize: Point,
+ deviceDisplayType: DeviceDisplayType,
lifecycleOwner: LifecycleOwner,
logger: UserEventLogger,
onStartEditActivity: (intent: Intent) -> Unit,
@@ -93,30 +94,6 @@
}
}
- launch {
- actionsViewModel.informationFloatingSheetViewModel.collect { viewModel ->
- if (viewModel == null) {
- floatingSheet.collapse()
- } else {
- val onExploreButtonClicked =
- viewModel.exploreActionUrl?.let { url ->
- {
- logger.logWallpaperExploreButtonClicked()
- val appContext = floatingSheet.context.applicationContext
- appContext.startActivity(
- Intent(Intent.ACTION_VIEW, Uri.parse(url))
- )
- }
- }
- floatingSheet.setInformationContent(
- viewModel.attributions,
- onExploreButtonClicked
- )
- floatingSheet.expand()
- }
- }
- }
-
/** [DOWNLOAD] */
launch {
actionsViewModel.isDownloadVisible.collect {
@@ -187,8 +164,8 @@
{
// We need to set default wallpaper preview config view model
// before entering full screen with edit activity overlay.
- previewViewModel.setDefaultWallpaperPreviewConfigViewModel(
- displaySize
+ previewViewModel.setDefaultFullPreviewConfigViewModel(
+ deviceDisplayType
)
onStartEditActivity.invoke(it)
}
@@ -235,28 +212,6 @@
}
}
- launch {
- actionsViewModel.effectFloatingSheetViewModel.collect { viewModel ->
- if (viewModel == null) {
- floatingSheet.collapse()
- } else {
- floatingSheet.setEffectContent(
- viewModel.effectType,
- viewModel.myPhotosClickListener,
- viewModel.collapseFloatingSheetListener,
- viewModel.effectSwitchListener,
- viewModel.effectDownloadClickListener,
- viewModel.status,
- viewModel.resultCode,
- viewModel.errorMessage,
- viewModel.title,
- viewModel.effectTextRes,
- )
- floatingSheet.expand()
- }
- }
- }
-
/** [SHARE] */
launch {
actionsViewModel.isShareVisible.collect { actionGroup.setIsVisible(SHARE, it) }
@@ -272,6 +227,71 @@
)
}
}
+
+ /** Floating sheet behavior */
+ launch {
+ actionsViewModel.previewFloatingSheetViewModel.collect { floatingSheetViewModel
+ ->
+ if (floatingSheetViewModel != null) {
+ val (
+ informationViewModel,
+ imageEffectViewModel,
+ creativeEffectViewModel,
+ customizeViewModel,
+ ) = floatingSheetViewModel
+ when {
+ informationViewModel != null -> {
+ floatingSheet.setInformationContent(
+ informationViewModel.attributions,
+ informationViewModel.exploreActionUrl?.let { url ->
+ {
+ logger.logWallpaperExploreButtonClicked()
+ floatingSheet.context.startActivity(
+ Intent(Intent.ACTION_VIEW, Uri.parse(url))
+ )
+ }
+ },
+ )
+ }
+ imageEffectViewModel != null ->
+ floatingSheet.setImageEffectContent(
+ imageEffectViewModel.effectType,
+ imageEffectViewModel.myPhotosClickListener,
+ imageEffectViewModel.collapseFloatingSheetListener,
+ imageEffectViewModel.effectSwitchListener,
+ imageEffectViewModel.effectDownloadClickListener,
+ imageEffectViewModel.status,
+ imageEffectViewModel.resultCode,
+ imageEffectViewModel.errorMessage,
+ imageEffectViewModel.title,
+ imageEffectViewModel.effectTextRes,
+ )
+ creativeEffectViewModel != null ->
+ floatingSheet.setCreativeEffectContent(
+ creativeEffectViewModel.title,
+ creativeEffectViewModel.subtitle,
+ creativeEffectViewModel.wallpaperActions,
+ object :
+ WallpaperActionsToggleAdapter.WallpaperEffectSwitchListener {
+ override fun onEffectSwitchChanged(checkedItem: Int) {
+ launch {
+ creativeEffectViewModel
+ .wallpaperEffectSwitchListener(checkedItem)
+ }
+ }
+ },
+ )
+ customizeViewModel != null ->
+ floatingSheet.setCustomizeContent(
+ customizeViewModel.customizeSliceUri
+ )
+ }
+ floatingSheet.expand()
+ } else {
+ floatingSheet.collapse()
+ }
+ }
+ }
}
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewEffectsLoadingBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewEffectsLoadingBinder.kt
new file mode 100644
index 0000000..fc952ef
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewEffectsLoadingBinder.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wallpaper.picker.preview.ui.binder
+
+import android.content.Context
+import android.content.res.Configuration
+import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.monet.ColorScheme
+import com.android.wallpaper.picker.customization.animation.view.LoadingAnimation
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLIED
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLY_IN_PROGRESS
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_DOWNLOAD_FAILED
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_READY
+import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
+import com.android.wallpaper.util.ResourceUtils
+import kotlinx.coroutines.launch
+
+object PreviewEffectsLoadingBinder {
+ interface Binding {
+ fun destroy()
+ }
+
+ fun bind(
+ view: View,
+ viewModel: WallpaperPreviewViewModel,
+ viewLifecycleOwner: LifecycleOwner,
+ ): Binding {
+ var loadingAnimation: LoadingAnimation? = null
+ val job =
+ viewLifecycleOwner.lifecycleScope.launch {
+ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ loadingAnimation = getLoadingAnimation(view)
+ viewModel.effectStatus.collect { status ->
+ if (status == EFFECT_APPLY_IN_PROGRESS) {
+ loadingAnimation?.playLoadingAnimation(seed = null)
+ } else if (
+ status == EFFECT_APPLIED ||
+ status == EFFECT_READY ||
+ status == EFFECT_DOWNLOAD_FAILED
+ ) {
+ // Play reveal animation whether applying the effect succeeded or
+ // failed.
+ loadingAnimation?.playRevealAnimation()
+ }
+ }
+ }
+ loadingAnimation?.cancel()
+ loadingAnimation = null
+ }
+ return object : Binding {
+ override fun destroy() {
+ job.cancel()
+ loadingAnimation?.cancel()
+ loadingAnimation = null
+ }
+ }
+ }
+
+ private fun getLoadingAnimation(view: View): LoadingAnimation {
+ val context: Context = view.context
+ val loadingAnimation =
+ LoadingAnimation(
+ revealOverlay = view,
+ revealType = LoadingAnimation.RevealType.FADE,
+ timeOutDuration = null
+ )
+ val colorAccent = ResourceUtils.getColorAttr(context, android.R.attr.colorAccent)
+ val isDarkTheme =
+ (context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) ==
+ Configuration.UI_MODE_NIGHT_YES
+ loadingAnimation.updateColor(ColorScheme(colorAccent, isDarkTheme))
+ return loadingAnimation
+ }
+}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewPagerBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewPagerBinder.kt
index 2e0bf54..8ced558 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewPagerBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewPagerBinder.kt
@@ -23,11 +23,11 @@
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.android.wallpaper.R
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.model.wallpaper.PreviewPagerPage
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.adapters.SinglePreviewPagerAdapter
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.pagetransformers.PreviewCardPageTransformer
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import kotlinx.coroutines.CoroutineScope
/** Binds single preview home screen and lock screen tabs view pager. */
object PreviewPagerBinder {
@@ -36,7 +36,6 @@
fun bind(
applicationContext: Context,
viewLifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
previewsViewPager: ViewPager2,
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
previewDisplaySize: Point,
@@ -45,10 +44,9 @@
) {
previewsViewPager.apply {
adapter = SinglePreviewPagerAdapter { viewHolder, position ->
- PreviewTooltipBinder.bind(
+ PreviewTooltipBinder.bindSmallPreviewTooltip(
tooltipStub = viewHolder.itemView.requireViewById(R.id.tooltip_stub),
- enableClickToDismiss = false,
- viewModel = wallpaperPreviewViewModel,
+ viewModel = wallpaperPreviewViewModel.smallTooltipViewModel,
lifecycleOwner = viewLifecycleOwner,
)
@@ -58,8 +56,7 @@
viewModel = wallpaperPreviewViewModel,
screen = PreviewPagerPage.entries[position].screen,
displaySize = previewDisplaySize,
- foldableDisplay = null,
- mainScope = mainScope,
+ deviceDisplayType = DeviceDisplayType.SINGLE,
viewLifecycleOwner = viewLifecycleOwner,
currentNavDestId = currentNavDestId,
navigate = navigate,
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewSelectorBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewSelectorBinder.kt
index 4747e0b..1245efc 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewSelectorBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewSelectorBinder.kt
@@ -21,8 +21,8 @@
import androidx.lifecycle.LifecycleOwner
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
+import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.adapters.TabTextPagerAdapter
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import kotlinx.coroutines.CoroutineScope
/** Binds and synchronizes the tab and preview view pagers. */
object PreviewSelectorBinder {
@@ -34,7 +34,6 @@
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
applicationContext: Context,
viewLifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
currentNavDestId: Int,
navigate: (View) -> Unit,
) {
@@ -45,7 +44,6 @@
PreviewPagerBinder.bind(
applicationContext,
viewLifecycleOwner,
- mainScope,
previewsViewPager,
wallpaperPreviewViewModel,
previewDisplaySize,
@@ -55,6 +53,10 @@
// synchronize the two pagers
synchronizePreviewAndTabsPager(tabsViewPager, previewsViewPager)
+ tabsViewPager.currentItem =
+ (tabsViewPager.adapter as TabTextPagerAdapter).getPageNumber(
+ wallpaperPreviewViewModel.isViewAsHome
+ )
}
private fun synchronizePreviewAndTabsPager(
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewTooltipBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewTooltipBinder.kt
index d116fd5..82c4550 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/PreviewTooltipBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/PreviewTooltipBinder.kt
@@ -17,35 +17,104 @@
import android.view.View
import android.view.ViewStub
+import android.view.animation.AccelerateDecelerateInterpolator
+import androidx.core.view.doOnLayout
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
+import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
object PreviewTooltipBinder {
- fun bind(
+ interface TooltipViewModel {
+ val shouldShowTooltip: Flow<Boolean>
+ fun dismissTooltip()
+ }
+
+ fun bindSmallPreviewTooltip(
tooltipStub: ViewStub,
- enableClickToDismiss: Boolean,
- viewModel: WallpaperPreviewViewModel,
+ viewModel: TooltipViewModel,
lifecycleOwner: LifecycleOwner,
) {
var tooltip: View? = null
lifecycleOwner.lifecycleScope.launch {
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
- viewModel.shouldShowTooltip().collect { shouldShowTooltip ->
+ viewModel.shouldShowTooltip.collect { shouldShowTooltip ->
if (shouldShowTooltip && tooltip == null) {
tooltip = tooltipStub.inflate()
- if (enableClickToDismiss) {
- tooltip?.setOnClickListener { viewModel.dismissTooltip() }
+ }
+ tooltip?.doOnLayout {
+ it.isVisible = true
+ it.alpha = if (shouldShowTooltip) 0f else 1f
+ it.pivotX = it.measuredWidth / 2f
+ it.pivotY = it.measuredHeight.toFloat()
+ it.scaleX = if (shouldShowTooltip) 0.2f else 1f
+ it.scaleY = if (shouldShowTooltip) 0.2f else 1f
+
+ if (shouldShowTooltip) {
+ it.animate()
+ .scaleX(1f)
+ .scaleY(1f)
+ .alpha(1f)
+ .setStartDelay(1000L)
+ .setDuration(200L)
+ .setInterpolator(AccelerateDecelerateInterpolator())
+ .start()
+ } else {
+ it.animate()
+ .alpha(0f)
+ .setDuration(75L)
+ .setInterpolator(AccelerateDecelerateInterpolator())
+ .withEndAction { tooltip?.isVisible = false }
+ .start()
}
}
- // TODO (b/303318205): animate tooltip
- // Only show tooltip if it has not been shown before.
- tooltip?.isVisible = shouldShowTooltip
+ }
+ }
+ }
+ }
+ }
+
+ fun bindFullPreviewTooltip(
+ tooltipStub: ViewStub,
+ viewModel: TooltipViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ var tooltip: View? = null
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.shouldShowTooltip.collect { shouldShowTooltip ->
+ if (shouldShowTooltip && tooltip == null) {
+ tooltip = tooltipStub.inflate()
+ tooltip?.setOnClickListener { viewModel.dismissTooltip() }
+ }
+ tooltip?.doOnLayout {
+ it.isVisible = true
+ it.alpha = if (shouldShowTooltip) 0f else 1f
+ it.translationY = if (shouldShowTooltip) -20f else 0f
+
+ if (shouldShowTooltip) {
+ it.animate()
+ .alpha(1f)
+ .translationY(0f)
+ .setStartDelay(500L)
+ .setDuration(200L)
+ .setInterpolator(AccelerateDecelerateInterpolator())
+ .start()
+ } else {
+ it.animate()
+ .alpha(0f)
+ .translationY(-20f)
+ .setDuration(75L)
+ .setInterpolator(AccelerateDecelerateInterpolator())
+ .withEndAction { tooltip?.isVisible = false }
+ .start()
+ }
+ }
}
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperDialogBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperDialogBinder.kt
index 6e35021..afbae67 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperDialogBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperDialogBinder.kt
@@ -26,7 +26,7 @@
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.wallpaper.R
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.CustomizationSections.Screen
import com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout
import com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout.Companion.getViewId
@@ -62,7 +62,6 @@
previewLayout,
wallpaperPreviewViewModel,
lifecycleOwner,
- mainScope,
currentNavDestId,
navigate,
)
@@ -72,7 +71,6 @@
wallpaperPreviewViewModel,
handheldDisplaySize,
lifecycleOwner,
- mainScope,
currentNavDestId,
navigate,
)
@@ -125,7 +123,6 @@
previewLayout: View,
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
lifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
currentNavDestId: Int,
navigate: ((View) -> Unit)?,
) {
@@ -138,22 +135,22 @@
dualDisplayAspectRatioLayout.setDisplaySizes(
mapOf(
- FoldableDisplay.FOLDED to wallpaperPreviewViewModel.smallerDisplaySize,
- FoldableDisplay.UNFOLDED to wallpaperPreviewViewModel.wallpaperDisplaySize,
+ DeviceDisplayType.FOLDED to wallpaperPreviewViewModel.smallerDisplaySize,
+ DeviceDisplayType.UNFOLDED to
+ wallpaperPreviewViewModel.wallpaperDisplaySize.value,
)
)
- FoldableDisplay.entries.forEach { display ->
+ DeviceDisplayType.FOLDABLE_DISPLAY_TYPES.forEach { display ->
val previewDisplaySize = dualDisplayAspectRatioLayout.getPreviewDisplaySize(display)
previewDisplaySize?.let {
SmallPreviewBinder.bind(
applicationContext = previewLayout.context.applicationContext,
view = dualDisplayAspectRatioLayout.requireViewById(display.getViewId()),
viewModel = wallpaperPreviewViewModel,
- mainScope = mainScope,
viewLifecycleOwner = lifecycleOwner,
screen = screenId.key,
displaySize = it,
- foldableDisplay = display,
+ deviceDisplayType = display,
currentNavDestId = currentNavDestId,
navigate = navigate,
)
@@ -167,7 +164,6 @@
wallpaperPreviewViewModel: WallpaperPreviewViewModel,
displaySize: Point,
lifecycleOwner: LifecycleOwner,
- mainScope: CoroutineScope,
currentNavDestId: Int,
navigate: ((View) -> Unit)?,
) {
@@ -182,8 +178,7 @@
viewModel = wallpaperPreviewViewModel,
screen = screenId.key,
displaySize = displaySize,
- foldableDisplay = null,
- mainScope = mainScope,
+ deviceDisplayType = DeviceDisplayType.SINGLE,
viewLifecycleOwner = lifecycleOwner,
currentNavDestId = currentNavDestId,
navigate = navigate,
@@ -198,6 +193,7 @@
dialogViewModel: WallpaperPreviewViewModel,
) {
selector.isActivated = selectedScreens.contains(screen)
+ selector.isSelected = selector.isActivated
selector.setOnClickListener { dialogViewModel.onSetWallpaperDialogScreenSelected(screen) }
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperProgressDialogBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperProgressDialogBinder.kt
index 4d97fb2..c61f670 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperProgressDialogBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/SetWallpaperProgressDialogBinder.kt
@@ -16,7 +16,7 @@
package com.android.wallpaper.picker.preview.ui.binder
-import android.app.ProgressDialog
+import android.app.AlertDialog
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
@@ -28,7 +28,7 @@
object SetWallpaperProgressDialogBinder {
fun bind(
- dialog: ProgressDialog,
+ dialog: AlertDialog,
viewModel: WallpaperPreviewViewModel,
lifecycleOwner: LifecycleOwner,
) {
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/SmallPreviewBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/SmallPreviewBinder.kt
index 36f4d57..c6ac7d0 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/SmallPreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/SmallPreviewBinder.kt
@@ -20,24 +20,25 @@
import android.view.SurfaceView
import android.view.View
import androidx.cardview.widget.CardView
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.android.wallpaper.R
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.CustomizationSections.Screen
-import com.android.wallpaper.picker.di.modules.MainDispatcher
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
object SmallPreviewBinder {
- /** @param foldableDisplay Only used for foldable devices; otherwise, set to null. */
+
fun bind(
applicationContext: Context,
view: View,
viewModel: WallpaperPreviewViewModel,
screen: Screen,
displaySize: Point,
- foldableDisplay: FoldableDisplay?,
- @MainDispatcher mainScope: CoroutineScope,
+ deviceDisplayType: DeviceDisplayType,
viewLifecycleOwner: LifecycleOwner,
currentNavDestId: Int,
navigate: ((View) -> Unit)? = null,
@@ -46,19 +47,27 @@
val wallpaperSurface: SurfaceView = view.requireViewById(R.id.wallpaper_surface)
val workspaceSurface: SurfaceView = view.requireViewById(R.id.workspace_surface)
- if (R.id.smallPreviewFragment == currentNavDestId) {
- view.setOnClickListener {
- viewModel.onSmallPreviewClicked(screen, foldableDisplay)
- navigate?.invoke(previewCard)
+ viewLifecycleOwner.lifecycleScope.launch {
+ launch {
+ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ if (R.id.smallPreviewFragment == currentNavDestId) {
+ view.setOnClickListener {
+ viewModel.onSmallPreviewClicked(screen, deviceDisplayType)
+ navigate?.invoke(previewCard)
+ }
+ } else if (R.id.setWallpaperDialog == currentNavDestId) {
+ previewCard.radius =
+ previewCard.resources.getDimension(
+ R.dimen.set_wallpaper_dialog_preview_corner_radius
+ )
+ }
+ }
+ // Remove on click listener when on destroyed
+ view.setOnClickListener(null)
}
- } else if (R.id.setWallpaperDialog == currentNavDestId) {
- previewCard.radius =
- previewCard.resources.getDimension(
- R.dimen.set_wallpaper_dialog_preview_corner_radius
- )
}
- val config = viewModel.getWorkspacePreviewConfig(screen, foldableDisplay)
+ val config = viewModel.getWorkspacePreviewConfig(screen, deviceDisplayType)
WorkspacePreviewBinder.bind(
workspaceSurface,
config,
@@ -72,8 +81,8 @@
screen = screen,
displaySize = displaySize,
applicationContext = applicationContext,
- mainScope = mainScope,
viewLifecycleOwner = viewLifecycleOwner,
+ deviceDisplayType = deviceDisplayType,
)
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/SmallWallpaperPreviewBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/SmallWallpaperPreviewBinder.kt
index 0453495..ddfa0b6 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/SmallWallpaperPreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/SmallWallpaperPreviewBinder.kt
@@ -21,19 +21,21 @@
import android.view.LayoutInflater
import android.view.SurfaceHolder
import android.view.SurfaceView
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.android.wallpaper.R
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.CustomizationSections.Screen
import com.android.wallpaper.picker.customization.shared.model.WallpaperColorsModel
import com.android.wallpaper.picker.data.WallpaperModel
-import com.android.wallpaper.picker.di.modules.MainDispatcher
import com.android.wallpaper.picker.preview.ui.util.SurfaceViewUtil
import com.android.wallpaper.picker.preview.ui.util.SurfaceViewUtil.attachView
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils
+import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils.shouldEnforceSingleEngine
import com.android.wallpaper.util.wallpaperconnection.WallpaperEngineConnection.WallpaperEngineConnectionListener
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
@@ -53,71 +55,122 @@
screen: Screen,
displaySize: Point,
applicationContext: Context,
- @MainDispatcher mainScope: CoroutineScope,
viewLifecycleOwner: LifecycleOwner,
+ deviceDisplayType: DeviceDisplayType,
) {
- var job: Job? = null
- surface.setZOrderMediaOverlay(true)
- surface.holder.addCallback(
- object : SurfaceViewUtil.SurfaceCallback {
- override fun surfaceCreated(holder: SurfaceHolder) {
- job =
- viewLifecycleOwner.lifecycleScope.launch {
- viewModel.smallWallpaper.collect { (wallpaper, whichPreview) ->
- if (wallpaper is WallpaperModel.LiveWallpaperModel) {
- WallpaperConnectionUtils.connect(
- applicationContext,
- mainScope,
- wallpaper,
- whichPreview,
- screen.toFlag(),
- surface,
- object : WallpaperEngineConnectionListener {
- override fun onWallpaperColorsChanged(
- colors: WallpaperColors?,
- displayId: Int
- ) {
- viewModel.setWallpaperConnectionColors(
- WallpaperColorsModel.Loaded(colors)
- )
- }
+ var surfaceCallback: SurfaceViewUtil.SurfaceCallback? = null
+ viewLifecycleOwner.lifecycleScope.launch {
+ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ surfaceCallback =
+ bindSurface(
+ applicationContext = applicationContext,
+ surface = surface,
+ viewModel = viewModel,
+ screen = screen,
+ deviceDisplayType = deviceDisplayType,
+ displaySize = displaySize,
+ lifecycleOwner = viewLifecycleOwner,
+ )
+ surface.setZOrderMediaOverlay(true)
+ surfaceCallback?.let { surface.holder.addCallback(it) }
+ }
+ // When OnDestroy, release the surface
+ surfaceCallback?.let {
+ surface.holder.removeCallback(it)
+ surfaceCallback = null
+ }
+ }
+ }
+
+ /**
+ * Create a surface callback that binds the surface when surface created. Note that we return
+ * the surface callback reference so that we can remove the callback from the surface when the
+ * screen is destroyed.
+ */
+ private fun bindSurface(
+ applicationContext: Context,
+ surface: SurfaceView,
+ viewModel: WallpaperPreviewViewModel,
+ screen: Screen,
+ deviceDisplayType: DeviceDisplayType,
+ displaySize: Point,
+ lifecycleOwner: LifecycleOwner,
+ ): SurfaceViewUtil.SurfaceCallback {
+
+ return object : SurfaceViewUtil.SurfaceCallback {
+
+ var job: Job? = null
+ var loadingAnimationBinding: PreviewEffectsLoadingBinder.Binding? = null
+
+ override fun surfaceCreated(holder: SurfaceHolder) {
+ job =
+ lifecycleOwner.lifecycleScope.launch {
+ viewModel.smallWallpaper.collect { (wallpaper, whichPreview) ->
+ if (wallpaper is WallpaperModel.LiveWallpaperModel) {
+ WallpaperConnectionUtils.connect(
+ applicationContext,
+ wallpaper,
+ whichPreview,
+ screen.toFlag(),
+ surface,
+ WallpaperConnectionUtils.EngineRenderingConfig(
+ wallpaper.shouldEnforceSingleEngine(),
+ deviceDisplayType = deviceDisplayType,
+ viewModel.smallerDisplaySize,
+ viewModel.wallpaperDisplaySize.value,
+ ),
+ object : WallpaperEngineConnectionListener {
+ override fun onWallpaperColorsChanged(
+ colors: WallpaperColors?,
+ displayId: Int
+ ) {
+ viewModel.setWallpaperConnectionColors(
+ WallpaperColorsModel.Loaded(colors)
+ )
}
- )
- } else if (wallpaper is WallpaperModel.StaticWallpaperModel) {
- val staticPreviewView =
- LayoutInflater.from(applicationContext)
- .inflate(R.layout.fullscreen_wallpaper_preview, null)
- surface.attachView(staticPreviewView)
- // Bind static wallpaper
- StaticWallpaperPreviewBinder.bind(
- lowResImageView =
- staticPreviewView.requireViewById(R.id.low_res_image),
- fullResImageView =
+ },
+ )
+ } else if (wallpaper is WallpaperModel.StaticWallpaperModel) {
+ val staticPreviewView =
+ LayoutInflater.from(applicationContext)
+ .inflate(R.layout.fullscreen_wallpaper_preview, null)
+ surface.attachView(staticPreviewView)
+ // Bind static wallpaper
+ StaticWallpaperPreviewBinder.bind(
+ lowResImageView =
+ staticPreviewView.requireViewById(R.id.low_res_image),
+ fullResImageView =
+ staticPreviewView.requireViewById(R.id.full_res_image),
+ viewModel = viewModel.staticWallpaperPreviewViewModel,
+ displaySize = displaySize,
+ viewLifecycleOwner = lifecycleOwner,
+ )
+ // This is to possibly shut down all live wallpaper services
+ // if they exist; otherwise static wallpaper can not show up.
+ WallpaperConnectionUtils.disconnectAllServices(applicationContext)
+
+ loadingAnimationBinding =
+ PreviewEffectsLoadingBinder.bind(
+ view =
staticPreviewView.requireViewById(R.id.full_res_image),
- viewModel = viewModel.staticWallpaperPreviewViewModel,
- displaySize = displaySize,
- viewLifecycleOwner = viewLifecycleOwner,
- shouldCalibrateWithSystemScale = true,
+ viewModel = viewModel,
+ viewLifecycleOwner = lifecycleOwner,
)
- // This is to possibly shut down all live wallpaper services
- // if they exist; otherwise static wallpaper can not show up.
- WallpaperConnectionUtils.disconnectAllServices(
- applicationContext
- )
- }
}
}
- }
-
- override fun surfaceDestroyed(holder: SurfaceHolder) {
- job?.cancel()
- // Note that we disconnect wallpaper connection for live wallpapers in
- // WallpaperPreviewActivity's onDestroy().
- // This is to reduce multiple times of connecting and disconnecting live
- // wallpaper services, when going back and forth small and full preview.
- }
+ }
}
- )
- // TODO (b/300979155): Clean up surface when no longer needed, e.g. onDestroyed
+
+ override fun surfaceDestroyed(holder: SurfaceHolder) {
+ job?.cancel()
+ job = null
+ loadingAnimationBinding?.destroy()
+ loadingAnimationBinding = null
+ // Note that we disconnect wallpaper connection for live wallpapers in
+ // WallpaperPreviewActivity's onDestroy().
+ // This is to reduce multiple times of connecting and disconnecting live
+ // wallpaper services, when going back and forth small and full preview.
+ }
+ }
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/StaticWallpaperPreviewBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/StaticWallpaperPreviewBinder.kt
index c481ea7..10abd08 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/StaticWallpaperPreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/StaticWallpaperPreviewBinder.kt
@@ -25,13 +25,13 @@
import android.view.animation.Interpolator
import android.view.animation.PathInterpolator
import android.widget.ImageView
+import androidx.core.view.doOnLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.TraceUtils.trace
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
import com.android.wallpaper.picker.preview.ui.util.FullResImageViewUtil
-import com.android.wallpaper.picker.preview.ui.view.SystemScaledWallpaperPreviewSurfaceView
import com.android.wallpaper.picker.preview.ui.viewmodel.StaticWallpaperPreviewViewModel
import com.android.wallpaper.util.RtlUtils
import com.android.wallpaper.util.WallpaperCropUtils
@@ -45,23 +45,23 @@
private val ALPHA_OUT: Interpolator = PathInterpolator(0f, 0f, 0.8f, 1f)
private const val CROSS_FADE_DURATION: Long = 200
- fun bind(
+ suspend fun bind(
lowResImageView: ImageView,
fullResImageView: SubsamplingScaleImageView,
viewModel: StaticWallpaperPreviewViewModel,
displaySize: Point,
viewLifecycleOwner: LifecycleOwner,
- shouldCalibrateWithSystemScale: Boolean = false,
+ isFullScreen: Boolean = false,
) {
lowResImageView.initLowResImageView()
fullResImageView.initFullResImageView()
- viewLifecycleOwner.lifecycleScope.launch {
- viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
- launch { viewModel.lowResBitmap.collect { lowResImageView.setImageBitmap(it) } }
+ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch { viewModel.lowResBitmap.collect { lowResImageView.setImageBitmap(it) } }
- launch {
- viewModel.subsamplingScaleImageViewModel.collect { imageModel ->
+ launch {
+ viewModel.subsamplingScaleImageViewModel.collect { imageModel ->
+ trace(TAG) {
val cropHint = imageModel.fullPreviewCropModels?.get(displaySize)?.cropHint
fullResImageView.setFullResImage(
ImageSource.cachedBitmap(imageModel.rawWallpaperBitmap),
@@ -69,11 +69,11 @@
displaySize,
cropHint,
RtlUtils.isRtl(lowResImageView.context),
- shouldCalibrateWithSystemScale,
+ isFullScreen,
)
- // Fill in the default crop region if the displaySize for this preview is
- // missing.
+ // Fill in the default crop region if the displaySize for this preview
+ // is missing.
viewModel.fullPreviewCropModels.putIfAbsent(
displaySize,
FullPreviewCropModel(
@@ -111,42 +111,42 @@
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
}
- /**
- * @param shouldCalibrateWithSystemScale This flag should be true for rendering small previews.
- * Unlikely full wallpaper preview for static wallpapers, small wallpaper preview does not
- * scale up the surface view larger than the display view to conform with the system's actual
- * wallpaper scale (see [SystemScaledWallpaperPreviewSurfaceView]). Instead we need to apply
- * this system scale to [SubsamplingScaleImageView].
- */
private fun SubsamplingScaleImageView.setFullResImage(
imageSource: ImageSource,
rawWallpaperSize: Point,
displaySize: Point,
cropHint: Rect?,
isRtl: Boolean,
- shouldCalibrateWithSystemScale: Boolean = false,
+ isFullScreen: Boolean,
) {
// Set the full res image
setImage(imageSource)
// Calculate the scale and the center point for the full res image
- FullResImageViewUtil.getScaleAndCenter(
- Point(measuredWidth, measuredHeight),
- rawWallpaperSize,
- displaySize,
- cropHint,
- isRtl,
- )
- .let { scaleAndCenter ->
- minScale = scaleAndCenter.minScale
- maxScale = scaleAndCenter.maxScale
- val scale =
- if (shouldCalibrateWithSystemScale)
- WallpaperCropUtils.getSystemWallpaperMaximumScale(
- context.applicationContext
- )
- else 1F
- setScaleAndCenter(scaleAndCenter.defaultScale * scale, scaleAndCenter.center)
- }
+ doOnLayout {
+ FullResImageViewUtil.getScaleAndCenter(
+ Point(measuredWidth, measuredHeight),
+ rawWallpaperSize,
+ displaySize,
+ cropHint,
+ isRtl,
+ )
+ .let { scaleAndCenter ->
+ // For full screen, the preview image container size has already been adjusted
+ // to preserve a boundary beyond the visible crop per comment at
+ // FullWallpaperPreviewBinder#adjustSizesForCropping.
+ // For small screen preview, we need to apply additional scaling since the
+ // container is the same size as the preview.
+ val scale =
+ if (isFullScreen) 1f
+ else
+ WallpaperCropUtils.getSystemWallpaperMaximumScale(
+ context.applicationContext
+ )
+ minScale = scaleAndCenter.minScale * scale
+ maxScale = scaleAndCenter.maxScale
+ setScaleAndCenter(scaleAndCenter.defaultScale * scale, scaleAndCenter.center)
+ }
+ }
}
private fun crossFadeInFullResImageView(lowResImageView: ImageView, fullResImageView: View) {
@@ -164,4 +164,6 @@
}
)
}
+
+ private const val TAG = "StaticWallpaperPreviewBinder"
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/binder/WorkspacePreviewBinder.kt b/src/com/android/wallpaper/picker/preview/ui/binder/WorkspacePreviewBinder.kt
index b629d5b..d1af583 100644
--- a/src/com/android/wallpaper/picker/preview/ui/binder/WorkspacePreviewBinder.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/binder/WorkspacePreviewBinder.kt
@@ -17,20 +17,27 @@
import android.app.WallpaperColors
import android.os.Bundle
+import android.os.Message
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.core.os.bundleOf
+import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import com.android.wallpaper.picker.customization.shared.model.WallpaperColorsModel
import com.android.wallpaper.picker.preview.ui.util.SurfaceViewUtil
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
import com.android.wallpaper.picker.preview.ui.viewmodel.WorkspacePreviewConfigViewModel
import com.android.wallpaper.util.PreviewUtils
import com.android.wallpaper.util.SurfaceViewUtils
+import kotlin.coroutines.resume
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
object WorkspacePreviewBinder {
fun bind(
@@ -39,25 +46,73 @@
viewModel: WallpaperPreviewViewModel,
lifecycleOwner: LifecycleOwner,
) {
- surface.setZOrderMediaOverlay(true)
- surface.holder.addCallback(
- object : SurfaceViewUtil.SurfaceCallback {
- override fun surfaceCreated(holder: SurfaceHolder) {
+ var surfaceCallback: SurfaceViewUtil.SurfaceCallback? = null
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ surfaceCallback =
+ bindSurface(
+ surface = surface,
+ viewModel = viewModel,
+ config = config,
+ lifecycleOwner = lifecycleOwner,
+ )
+ surface.setZOrderMediaOverlay(true)
+ surface.holder.addCallback(surfaceCallback)
+ }
+ // When OnDestroy, release the surface
+ surfaceCallback?.let {
+ surface.holder.removeCallback(it)
+ surfaceCallback = null
+ }
+ }
+ }
+
+ /**
+ * Create a surface callback that binds the surface when surface created. Note that we return
+ * the surface callback reference so that we can remove the callback from the surface when the
+ * screen is destroyed.
+ */
+ private fun bindSurface(
+ surface: SurfaceView,
+ viewModel: WallpaperPreviewViewModel,
+ config: WorkspacePreviewConfigViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ): SurfaceViewUtil.SurfaceCallback {
+ return object : SurfaceViewUtil.SurfaceCallback {
+
+ var job: Job? = null
+ var previewDisposableHandle: DisposableHandle? = null
+
+ override fun surfaceCreated(holder: SurfaceHolder) {
+ job =
lifecycleOwner.lifecycleScope.launch {
viewModel.wallpaperColorsModel.collect {
if (it is WallpaperColorsModel.Loaded) {
- renderWorkspacePreview(
- surface = surface,
- previewUtils = config.previewUtils,
- displayId = config.displayId,
- wallpaperColors = it.colors
- )
+ val workspaceCallback =
+ renderWorkspacePreview(
+ surface = surface,
+ previewUtils = config.previewUtils,
+ displayId =
+ viewModel.getDisplayId(config.deviceDisplayType),
+ wallpaperColors = it.colors
+ )
+ // Dispose the previous preview on the renderer side.
+ previewDisposableHandle?.dispose()
+ previewDisposableHandle = DisposableHandle {
+ config.previewUtils.cleanUp(workspaceCallback)
+ }
}
}
}
- }
}
- )
+
+ override fun surfaceDestroyed(holder: SurfaceHolder) {
+ job?.cancel()
+ job = null
+ previewDisposableHandle?.dispose()
+ previewDisposableHandle = null
+ }
+ }
}
/**
@@ -69,10 +124,43 @@
viewModel: WallpaperPreviewViewModel,
lifecycleOwner: LifecycleOwner,
) {
- surface.setZOrderMediaOverlay(true)
- surface.holder.addCallback(
- object : SurfaceViewUtil.SurfaceCallback {
- override fun surfaceCreated(holder: SurfaceHolder) {
+ var surfaceCallback: SurfaceViewUtil.SurfaceCallback? = null
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.CREATED) {
+ surfaceCallback =
+ bindFullSurface(
+ surface = surface,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ )
+ surface.setZOrderMediaOverlay(true)
+ surface.holder.addCallback(surfaceCallback)
+ }
+ // When OnDestroy, release the surface
+ surfaceCallback?.let {
+ surface.holder.removeCallback(it)
+ surfaceCallback = null
+ }
+ }
+ }
+
+ /**
+ * Create a surface callback that binds the surface when surface created. Note that we return
+ * the surface callback reference so that we can remove the callback from the surface when the
+ * screen is destroyed.
+ */
+ private fun bindFullSurface(
+ surface: SurfaceView,
+ viewModel: WallpaperPreviewViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ): SurfaceViewUtil.SurfaceCallback {
+ return object : SurfaceViewUtil.SurfaceCallback {
+
+ var job: Job? = null
+ var previewDisposableHandle: DisposableHandle? = null
+
+ override fun surfaceCreated(holder: SurfaceHolder) {
+ job =
lifecycleOwner.lifecycleScope.launch {
combine(
viewModel.fullWorkspacePreviewConfigViewModel,
@@ -82,26 +170,40 @@
}
.collect { (config, colorsModel) ->
if (colorsModel is WallpaperColorsModel.Loaded) {
- renderWorkspacePreview(
- surface = surface,
- previewUtils = config.previewUtils,
- displayId = config.displayId,
- wallpaperColors = colorsModel.colors
- )
+ val workspaceCallback =
+ renderWorkspacePreview(
+ surface = surface,
+ previewUtils = config.previewUtils,
+ displayId =
+ viewModel.getDisplayId(config.deviceDisplayType),
+ wallpaperColors = colorsModel.colors
+ )
+ // Dispose the previous preview on the renderer side.
+ previewDisposableHandle?.dispose()
+ previewDisposableHandle = DisposableHandle {
+ config.previewUtils.cleanUp(workspaceCallback)
+ }
}
}
}
- }
}
- )
+
+ override fun surfaceDestroyed(holder: SurfaceHolder) {
+ job?.cancel()
+ job = null
+ previewDisposableHandle?.dispose()
+ previewDisposableHandle = null
+ }
+ }
}
- private fun renderWorkspacePreview(
+ private suspend fun renderWorkspacePreview(
surface: SurfaceView,
previewUtils: PreviewUtils,
displayId: Int,
wallpaperColors: WallpaperColors? = null,
- ) {
+ ): Message? {
+ var workspaceCallback: Message? = null
if (previewUtils.supportsPreview()) {
val extras = bundleOf(Pair(SurfaceViewUtils.KEY_DISPLAY_ID, displayId))
wallpaperColors?.let {
@@ -112,29 +214,34 @@
surface,
extras,
)
- previewUtils.renderPreview(
- request,
- object : PreviewUtils.WorkspacePreviewCallback {
- override fun onPreviewRendered(resultBundle: Bundle?) {
- if (resultBundle != null) {
- SurfaceViewUtils.getSurfacePackage(resultBundle).apply {
- if (this != null) {
- surface.setChildSurfacePackage(this)
- } else {
- Log.w(
- TAG,
- "Result bundle from rendering preview does not contain " +
- "a child surface package."
- )
+ workspaceCallback = suspendCancellableCoroutine { continuation ->
+ previewUtils.renderPreview(
+ request,
+ object : PreviewUtils.WorkspacePreviewCallback {
+ override fun onPreviewRendered(resultBundle: Bundle?) {
+ if (resultBundle != null) {
+ SurfaceViewUtils.getSurfacePackage(resultBundle).apply {
+ if (this != null) {
+ surface.setChildSurfacePackage(this)
+ } else {
+ Log.w(
+ TAG,
+ "Result bundle from rendering preview does not contain " +
+ "a child surface package."
+ )
+ }
}
+ continuation.resume(SurfaceViewUtils.getCallback(resultBundle))
+ } else {
+ Log.w(TAG, "Result bundle from rendering preview is null.")
+ continuation.resume(null)
}
- } else {
- Log.w(TAG, "Result bundle from rendering preview is null.")
}
}
- }
- )
+ )
+ }
}
+ return workspaceCallback
}
const val TAG = "WorkspacePreviewBinder"
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeEditPreviewFragment.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeEditPreviewFragment.kt
new file mode 100644
index 0000000..9d3d308
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeEditPreviewFragment.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wallpaper.picker.preview.ui.fragment
+
+import android.app.Activity.RESULT_OK
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.SurfaceView
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.Toolbar
+import androidx.activity.result.contract.ActivityResultContract
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.core.view.isVisible
+import androidx.fragment.app.activityViewModels
+import androidx.navigation.fragment.findNavController
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.AppbarFragment
+import com.android.wallpaper.picker.preview.ui.binder.FullWallpaperPreviewBinder
+import com.android.wallpaper.picker.preview.ui.fragment.SmallPreviewFragment.Companion.ARG_EDIT_INTENT
+import com.android.wallpaper.picker.preview.ui.viewmodel.PreviewActionsViewModel
+import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
+import com.android.wallpaper.util.DisplayUtils
+import dagger.hilt.android.AndroidEntryPoint
+import dagger.hilt.android.qualifiers.ApplicationContext
+import javax.inject.Inject
+
+/** Shows full preview with an edit activity overlay. */
+@AndroidEntryPoint(AppbarFragment::class)
+class CreativeEditPreviewFragment : Hilt_CreativeEditPreviewFragment() {
+
+ @Inject @ApplicationContext lateinit var appContext: Context
+ @Inject lateinit var displayUtils: DisplayUtils
+
+ private val wallpaperPreviewViewModel by activityViewModels<WallpaperPreviewViewModel>()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val view = inflater.inflate(R.layout.fragment_full_preview, container, false)
+ setUpToolbar(view)
+
+ wallpaperPreviewViewModel.setDefaultFullPreviewConfigViewModel(
+ deviceDisplayType = displayUtils.getCurrentDisplayType(requireActivity()),
+ )
+
+ FullWallpaperPreviewBinder.bind(
+ applicationContext = appContext,
+ view = view,
+ viewModel = wallpaperPreviewViewModel,
+ transition = null,
+ displayUtils = displayUtils,
+ lifecycleOwner = viewLifecycleOwner,
+ savedInstanceState = savedInstanceState,
+ )
+
+ view.requireViewById<Toolbar>(R.id.toolbar).isVisible = false
+ view.requireViewById<SurfaceView>(R.id.workspace_surface).isVisible = false
+ view.requireViewById<Button>(R.id.crop_wallpaper_button).isVisible = false
+
+ val intent =
+ arguments?.getParcelable(ARG_EDIT_INTENT, Intent::class.java)
+ ?: throw IllegalArgumentException(
+ "To render the first screen in the create new creative wallpaper flow, the intent for rendering the edit activity overlay can not be null."
+ )
+ val isCreateNew =
+ intent.getBooleanExtra(PreviewActionsViewModel.EXTRA_KEY_IS_CREATE_NEW, false)
+ val creativeWallpaperEditActivityResult =
+ if (isCreateNew) {
+ requireActivity().activityResultRegistry.register(
+ CREATIVE_RESULT_REGISTRY,
+ ActivityResultContracts.StartActivityForResult()
+ ) {
+ wallpaperPreviewViewModel.isCurrentlyEditingCreativeWallpaper = false
+ // Callback when the overlaying edit activity is finished. Result code of
+ // RESULT_OK means the user clicked on the check button; RESULT_CANCELED
+ // otherwise.
+ if (it.resultCode == RESULT_OK) {
+ // When clicking on the check button, navigate to the small preview
+ // fragment.
+ findNavController()
+ .navigate(
+ R.id.action_creativeEditPreviewFragment_to_smallPreviewFragment
+ )
+ } else {
+ activity?.finish()
+ }
+ }
+ } else {
+ requireActivity().activityResultRegistry.register(
+ CREATIVE_RESULT_REGISTRY,
+ object : ActivityResultContract<Intent, Int>() {
+ override fun createIntent(context: Context, input: Intent): Intent {
+ return input
+ }
+
+ override fun parseResult(resultCode: Int, intent: Intent?): Int {
+ wallpaperPreviewViewModel.isCurrentlyEditingCreativeWallpaper = false
+ return resultCode
+ }
+ },
+ ) {
+ findNavController().popBackStack()
+ }
+ }
+
+ if (!wallpaperPreviewViewModel.isCurrentlyEditingCreativeWallpaper) {
+ wallpaperPreviewViewModel.isCurrentlyEditingCreativeWallpaper = true
+ creativeWallpaperEditActivityResult.launch(intent)
+ }
+
+ return view
+ }
+
+ override fun getToolbarColorId(): Int {
+ return android.R.color.transparent
+ }
+
+ companion object {
+ private const val CREATIVE_RESULT_REGISTRY = "creative_result_registry"
+ }
+}
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeNewPreviewFragment.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeNewPreviewFragment.kt
deleted file mode 100644
index e4f7491..0000000
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/CreativeNewPreviewFragment.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.wallpaper.picker.preview.ui.fragment
-
-import android.app.Activity.RESULT_OK
-import android.content.Context
-import android.content.Intent
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.SurfaceView
-import android.view.View
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.Toolbar
-import androidx.activity.result.contract.ActivityResultContract
-import androidx.core.view.isVisible
-import androidx.fragment.app.activityViewModels
-import androidx.navigation.fragment.findNavController
-import com.android.wallpaper.R
-import com.android.wallpaper.picker.AppbarFragment
-import com.android.wallpaper.picker.di.modules.MainDispatcher
-import com.android.wallpaper.picker.preview.ui.binder.FullWallpaperPreviewBinder
-import com.android.wallpaper.picker.preview.ui.fragment.SmallPreviewFragment.Companion.ARG_EDIT_INTENT
-import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
-import com.android.wallpaper.util.DisplayUtils
-import dagger.hilt.android.AndroidEntryPoint
-import dagger.hilt.android.qualifiers.ApplicationContext
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-
-/** Shows full preview with an edit activity overlay. */
-@AndroidEntryPoint(AppbarFragment::class)
-class CreativeNewPreviewFragment : Hilt_CreativeNewPreviewFragment() {
-
- @Inject @ApplicationContext lateinit var appContext: Context
- @Inject lateinit var displayUtils: DisplayUtils
- @Inject @MainDispatcher lateinit var mainScope: CoroutineScope
-
- private val wallpaperPreviewViewModel by activityViewModels<WallpaperPreviewViewModel>()
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val view = inflater.inflate(R.layout.fragment_full_preview, container, false)
- setUpToolbar(view)
-
- FullWallpaperPreviewBinder.bind(
- applicationContext = appContext,
- view = view,
- viewModel = wallpaperPreviewViewModel,
- displayUtils = displayUtils,
- lifecycleOwner = viewLifecycleOwner,
- mainScope = mainScope,
- )
-
- wallpaperPreviewViewModel.setDefaultWallpaperPreviewConfigViewModel(
- displayUtils.getRealSize(requireActivity().display)
- )
- view.requireViewById<Toolbar>(R.id.toolbar).isVisible = false
- view.requireViewById<SurfaceView>(R.id.workspace_surface).isVisible = false
- view.requireViewById<Button>(R.id.crop_wallpaper_button).isVisible = false
-
- val intent =
- arguments?.getParcelable(ARG_EDIT_INTENT, Intent::class.java)
- ?: throw IllegalArgumentException(
- "To render the first screen in the create new creative wallpaper flow, the intent for rendering the edit activity overlay can not be null."
- )
- val creativeWallpaperEditActivityResult =
- registerForActivityResult(
- object : ActivityResultContract<Intent, Int>() {
- override fun createIntent(context: Context, input: Intent): Intent {
- return input
- }
-
- override fun parseResult(resultCode: Int, intent: Intent?): Int {
- return resultCode
- }
- },
- ) {
- // Callback when the overlaying edit activity is finished. Result code of RESULT_OK
- // means the user clicked on the check button; RESULT_CANCELED otherwise.
- if (it == RESULT_OK) {
- // When clicking on the check button, navigate to the small preview fragment.
- findNavController()
- .navigate(R.id.action_creativeNewPreviewFragment_to_smallPreviewFragment)
- } else {
- activity?.finish()
- }
- }
- creativeWallpaperEditActivityResult.launch(intent)
-
- return view
- }
-
- override fun getToolbarColorId(): Int {
- return android.R.color.transparent
- }
-}
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/FullPreviewFragment.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/FullPreviewFragment.kt
index 1a34086..eb0bc8f 100644
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/FullPreviewFragment.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/FullPreviewFragment.kt
@@ -16,36 +16,28 @@
package com.android.wallpaper.picker.preview.ui.fragment
import android.content.Context
-import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
-import android.view.SurfaceView
import android.view.View
import android.view.ViewGroup
-import android.widget.Button
-import android.widget.Toolbar
-import androidx.activity.result.contract.ActivityResultContract
import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
-import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
-import androidx.transition.TransitionInflater
+import androidx.transition.Transition
import com.android.wallpaper.R
import com.android.wallpaper.picker.AppbarFragment
-import com.android.wallpaper.picker.di.modules.MainDispatcher
import com.android.wallpaper.picker.preview.ui.binder.CropWallpaperButtonBinder
import com.android.wallpaper.picker.preview.ui.binder.FullWallpaperPreviewBinder
import com.android.wallpaper.picker.preview.ui.binder.PreviewTooltipBinder
import com.android.wallpaper.picker.preview.ui.binder.WorkspacePreviewBinder
-import com.android.wallpaper.picker.preview.ui.fragment.SmallPreviewFragment.Companion.ARG_EDIT_INTENT
+import com.android.wallpaper.picker.preview.ui.transition.ChangeScaleAndPosition
import com.android.wallpaper.picker.preview.ui.viewmodel.WallpaperPreviewViewModel
import com.android.wallpaper.util.DisplayUtils
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
/** Shows full preview of user selected wallpaper for cropping, zooming and positioning. */
@AndroidEntryPoint(AppbarFragment::class)
@@ -53,16 +45,13 @@
@Inject @ApplicationContext lateinit var appContext: Context
@Inject lateinit var displayUtils: DisplayUtils
- @Inject @MainDispatcher lateinit var mainScope: CoroutineScope
private val wallpaperPreviewViewModel by activityViewModels<WallpaperPreviewViewModel>()
+ private var useLightToolbar = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- if (ENABLE_ANIMATION) {
- sharedElementEnterTransition =
- TransitionInflater.from(appContext).inflateTransition(R.transition.shared_view)
- }
+ sharedElementEnterTransition = ChangeScaleAndPosition()
}
override fun onCreateView(
@@ -79,40 +68,18 @@
SmallPreviewFragment.FULL_PREVIEW_SHARED_ELEMENT_ID
)
- val creativeWallpaperEditActivityResult =
- registerForActivityResult(
- object : ActivityResultContract<Intent, Int>() {
- override fun createIntent(context: Context, input: Intent): Intent {
- return input
- }
-
- override fun parseResult(resultCode: Int, intent: Intent?): Int {
- return resultCode
- }
- },
- ) {
- // Callback when the overlaying edit activity is finished. Result code of RESULT_OK
- // means the user clicked on the check button; RESULT_CANCELED otherwise.
- findNavController().popBackStack()
- }
- // If edit intent is nonnull, we launch the edit overlay activity, with the wallpaper
- // preview from the Wallpaper Picker app's fragment.
- arguments?.getParcelable(ARG_EDIT_INTENT, Intent::class.java)?.let {
- view.requireViewById<Toolbar>(R.id.toolbar).isVisible = false
- view.requireViewById<SurfaceView>(R.id.workspace_surface).isVisible = false
- view.requireViewById<Button>(R.id.crop_wallpaper_button).isVisible = false
- creativeWallpaperEditActivityResult.launch(it)
- return view
- }
-
FullWallpaperPreviewBinder.bind(
applicationContext = appContext,
view = view,
viewModel = wallpaperPreviewViewModel,
+ transition = sharedElementEnterTransition as? Transition,
displayUtils = displayUtils,
lifecycleOwner = viewLifecycleOwner,
- mainScope = mainScope,
- )
+ savedInstanceState = savedInstanceState,
+ ) { isFullScreen ->
+ useLightToolbar = isFullScreen
+ setUpToolbar(view)
+ }
CropWallpaperButtonBinder.bind(
button = view.requireViewById(R.id.crop_wallpaper_button),
@@ -128,10 +95,9 @@
lifecycleOwner = viewLifecycleOwner,
)
- PreviewTooltipBinder.bind(
+ PreviewTooltipBinder.bindFullPreviewTooltip(
tooltipStub = view.requireViewById(R.id.tooltip_stub),
- enableClickToDismiss = true,
- viewModel = wallpaperPreviewViewModel,
+ viewModel = wallpaperPreviewViewModel.fullTooltipViewModel,
lifecycleOwner = viewLifecycleOwner,
)
@@ -148,10 +114,15 @@
}
override fun getToolbarTextColor(): Int {
- return ContextCompat.getColor(requireContext(), R.color.system_on_surface)
+ return if (useLightToolbar) {
+ ContextCompat.getColor(requireContext(), android.R.color.system_on_primary_light)
+ } else {
+ ContextCompat.getColor(requireContext(), R.color.system_on_surface)
+ }
}
- companion object {
- const val ENABLE_ANIMATION = false
+ override fun isStatusBarLightText(): Boolean {
+ return requireContext().resources.getBoolean(R.bool.isFragmentStatusBarLightText) or
+ useLightToolbar
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/SetWallpaperDialogFragment.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/SetWallpaperDialogFragment.kt
index 24ceaf4..be1d58c 100644
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/SetWallpaperDialogFragment.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/SetWallpaperDialogFragment.kt
@@ -17,12 +17,16 @@
package com.android.wallpaper.picker.preview.ui.fragment
import android.app.Activity
+import android.app.ActivityOptions
import android.app.AlertDialog
import android.app.Dialog
import android.content.DialogInterface
import android.content.Intent
import android.os.Bundle
+import android.transition.Slide
+import android.view.Gravity
import android.view.LayoutInflater
+import android.widget.FrameLayout.LayoutParams
import android.widget.Toast
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
@@ -50,6 +54,17 @@
private val wallpaperPreviewViewModel by activityViewModels<WallpaperPreviewViewModel>()
+ override fun onStart() {
+ super.onStart()
+ // Set dialog size
+ val widthDimenId =
+ if (displayUtils.hasMultiInternalDisplays()) R.dimen.set_wallpaper_dialog_foldable_width
+ else R.dimen.set_wallpaper_dialog_handheld_width
+ requireDialog()
+ .window
+ ?.setLayout(resources.getDimension(widthDimenId).toInt(), LayoutParams.WRAP_CONTENT)
+ }
+
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
super.onCreateDialog(savedInstanceState)
@@ -83,6 +98,7 @@
.show()
if (activityReference != null) {
if (wallpaperPreviewViewModel.isNewTask) {
+ activityReference.window?.exitTransition = Slide(Gravity.END)
val intent = Intent(activityReference, TrampolinePickerActivity::class.java)
intent.setFlags(
Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
@@ -92,11 +108,15 @@
if (wallpaperPreviewViewModel.isViewAsHome) LAUNCH_SOURCE_LAUNCHER
else LAUNCH_SOURCE_SETTINGS_HOMEPAGE
)
- activityReference.startActivity(intent)
+ activityReference.startActivity(
+ intent,
+ ActivityOptions.makeSceneTransitionAnimation(activityReference)
+ .toBundle()
+ )
} else {
activityReference.setResult(Activity.RESULT_OK)
- activityReference.finish()
}
+ activityReference.finish()
}
},
onDismissDialog = { findNavController().popBackStack() },
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/SmallPreviewFragment.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/SmallPreviewFragment.kt
index d0ec9e5..a269252 100644
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/SmallPreviewFragment.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/SmallPreviewFragment.kt
@@ -16,7 +16,6 @@
package com.android.wallpaper.picker.preview.ui.fragment
import android.app.AlertDialog
-import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
@@ -27,18 +26,21 @@
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.fragment.app.activityViewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import com.android.wallpaper.R
import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.AppbarFragment
-import com.android.wallpaper.picker.di.modules.MainDispatcher
import com.android.wallpaper.picker.preview.ui.binder.DualPreviewSelectorBinder
import com.android.wallpaper.picker.preview.ui.binder.PreviewActionsBinder
import com.android.wallpaper.picker.preview.ui.binder.PreviewSelectorBinder
import com.android.wallpaper.picker.preview.ui.binder.SetWallpaperButtonBinder
import com.android.wallpaper.picker.preview.ui.binder.SetWallpaperProgressDialogBinder
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.DualPreviewViewPager
+import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.adapters.TabTextPagerAdapter
import com.android.wallpaper.picker.preview.ui.fragment.smallpreview.views.TabsPagerContainer
import com.android.wallpaper.picker.preview.ui.view.PreviewActionGroup
import com.android.wallpaper.picker.preview.ui.viewmodel.Action
@@ -47,7 +49,7 @@
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
/**
* This fragment displays the preview of the selected wallpaper on all available workspaces and
@@ -58,11 +60,10 @@
@Inject @ApplicationContext lateinit var appContext: Context
@Inject lateinit var displayUtils: DisplayUtils
- @Inject @MainDispatcher lateinit var mainScope: CoroutineScope
@Inject lateinit var logger: UserEventLogger
private val wallpaperPreviewViewModel by activityViewModels<WallpaperPreviewViewModel>()
- private lateinit var setWallpaperProgressDialog: ProgressDialog
+ private lateinit var setWallpaperProgressDialog: AlertDialog
override fun onCreateView(
inflater: LayoutInflater,
@@ -86,14 +87,10 @@
viewModel = wallpaperPreviewViewModel,
lifecycleOwner = viewLifecycleOwner,
) {
- findNavController().navigate(R.id.action_smallPreviewFragment_to_setWallpaperDialog)
+ findNavController().navigate(R.id.setWallpaperDialog)
}
- setWallpaperProgressDialog =
- ProgressDialog(context, R.style.LightDialogTheme).apply {
- setTitle(null)
- setMessage(context.getString(R.string.set_wallpaper_progress_message))
- isIndeterminate = true
- }
+
+ setWallpaperProgressDialog = getSetWallpaperProgressDialog(inflater)
SetWallpaperProgressDialogBinder.bind(
dialog = setWallpaperProgressDialog,
viewModel = wallpaperPreviewViewModel,
@@ -120,20 +117,24 @@
if (displayUtils.hasMultiInternalDisplays()) {
val dualPreviewView: DualPreviewViewPager =
view.requireViewById(R.id.dual_preview_pager)
- val tabPager: TabsPagerContainer = view.requireViewById(R.id.pager_container)
+ val viewPager =
+ view.requireViewById<TabsPagerContainer>(R.id.pager_container).getViewPager()
DualPreviewSelectorBinder.bind(
- tabPager.getViewPager(),
+ viewPager,
dualPreviewView,
wallpaperPreviewViewModel,
appContext,
viewLifecycleOwner,
- mainScope,
currentNavDestId,
) { sharedElement ->
+ wallpaperPreviewViewModel.isViewAsHome =
+ (viewPager.adapter as TabTextPagerAdapter).getIsHome(viewPager.currentItem)
ViewCompat.setTransitionName(sharedElement, SMALL_PREVIEW_SHARED_ELEMENT_ID)
val extras =
FragmentNavigatorExtras(sharedElement to FULL_PREVIEW_SHARED_ELEMENT_ID)
+ // Set to false on small-to-full preview transition to remove surfaceView jank.
+ (view as ViewGroup).isTransitionGroup = false
findNavController()
.navigate(
resId = R.id.action_smallPreviewFragment_to_fullPreviewFragment,
@@ -143,22 +144,26 @@
)
}
} else {
- val tabPager: TabsPagerContainer = view.requireViewById(R.id.pager_container)
+ val viewPager =
+ view.requireViewById<TabsPagerContainer>(R.id.pager_container).getViewPager()
PreviewSelectorBinder.bind(
- tabPager.getViewPager(),
+ viewPager,
view.requireViewById(R.id.pager_previews),
displayUtils.getRealSize(displayUtils.getWallpaperDisplay()),
// TODO: pass correct view models for the view pager
wallpaperPreviewViewModel,
appContext,
viewLifecycleOwner,
- mainScope,
currentNavDestId,
) { sharedElement ->
+ wallpaperPreviewViewModel.isViewAsHome =
+ (viewPager.adapter as TabTextPagerAdapter).getIsHome(viewPager.currentItem)
ViewCompat.setTransitionName(sharedElement, SMALL_PREVIEW_SHARED_ELEMENT_ID)
val extras =
FragmentNavigatorExtras(sharedElement to FULL_PREVIEW_SHARED_ELEMENT_ID)
+ // Set to false on small-to-full preview transition to remove surfaceView jank.
+ (view as ViewGroup).isTransitionGroup = false
findNavController()
.navigate(
resId = R.id.action_smallPreviewFragment_to_fullPreviewFragment,
@@ -168,6 +173,14 @@
)
}
}
+
+ viewLifecycleOwner.lifecycleScope.launch {
+ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ // Always reset isTransitionGroup value on start for the edge case that the
+ // navigation is cancelled and the fragment resumes.
+ (view as ViewGroup).isTransitionGroup = true
+ }
+ }
}
private fun bindPreviewActions(view: View) {
@@ -192,13 +205,13 @@
floatingSheet = view.requireViewById(R.id.floating_sheet),
previewViewModel = wallpaperPreviewViewModel,
actionsViewModel = wallpaperPreviewViewModel.previewActionsViewModel,
- displaySize = displayUtils.getRealSize(requireActivity().display),
+ deviceDisplayType = displayUtils.getCurrentDisplayType(requireActivity()),
lifecycleOwner = viewLifecycleOwner,
logger = logger,
onStartEditActivity = {
findNavController()
.navigate(
- resId = R.id.action_smallPreviewFragment_to_fullPreviewFragment,
+ resId = R.id.action_smallPreviewFragment_to_creativeEditPreviewFragment,
args = Bundle().apply { putParcelable(ARG_EDIT_INTENT, it) },
navOptions = null,
navigatorExtras = null,
@@ -228,6 +241,13 @@
)
}
+ private fun getSetWallpaperProgressDialog(
+ inflater: LayoutInflater,
+ ): AlertDialog {
+ val dialogView = inflater.inflate(R.layout.set_wallpaper_progress_dialog_view, null)
+ return AlertDialog.Builder(activity).setView(dialogView).create()
+ }
+
companion object {
const val SMALL_PREVIEW_SHARED_ELEMENT_ID = "small_preview_shared_element"
const val FULL_PREVIEW_SHARED_ELEMENT_ID = "full_preview_shared_element"
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/DualPreviewViewPager.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/DualPreviewViewPager.kt
index 9ed8e06..1f4cc93 100644
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/DualPreviewViewPager.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/DualPreviewViewPager.kt
@@ -20,7 +20,7 @@
import android.util.AttributeSet
import androidx.viewpager.widget.ViewPager
import com.android.wallpaper.R
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.picker.preview.ui.view.DualDisplayAspectRatioLayout
/**
@@ -32,7 +32,7 @@
class DualPreviewViewPager
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null /* attrs */) : ViewPager(context, attrs) {
- private var previewDisplaySizes: Map<FoldableDisplay, Point>? = null
+ private var previewDisplaySizes: Map<DeviceDisplayType, Point>? = null
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (previewDisplaySizes == null) {
@@ -47,13 +47,13 @@
it.getDimension(R.dimen.small_preview_inter_preview_margin) * 3
}
- val smallDisplayAR =
- getPreviewDisplaySize(FoldableDisplay.FOLDED).let { it.x.toFloat() / it.y }
+ val smallDisplayAspectRatio =
+ getPreviewDisplaySize(DeviceDisplayType.FOLDED).let { it.x.toFloat() / it.y }
- val largeDisplayAR =
- getPreviewDisplaySize(FoldableDisplay.UNFOLDED).let { it.x.toFloat() / it.y }
+ val largeDisplayAspectRatio =
+ getPreviewDisplaySize(DeviceDisplayType.UNFOLDED).let { it.x.toFloat() / it.y }
- val viewPagerHeight = parentWidth / (largeDisplayAR + smallDisplayAR)
+ val viewPagerHeight = parentWidth / (largeDisplayAspectRatio + smallDisplayAspectRatio)
super.onMeasure(
widthMeasureSpec,
@@ -64,7 +64,7 @@
)
}
- fun setDisplaySizes(displaySizes: Map<FoldableDisplay, Point>) {
+ fun setDisplaySizes(displaySizes: Map<DeviceDisplayType, Point>) {
previewDisplaySizes = displaySizes
}
@@ -74,7 +74,7 @@
* Outside this class we should get display size via
* [DualDisplayAspectRatioLayout.getPreviewDisplaySize].
*/
- private fun getPreviewDisplaySize(display: FoldableDisplay): Point {
+ private fun getPreviewDisplaySize(display: DeviceDisplayType): Point {
return checkNotNull(previewDisplaySizes?.get(display))
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/adapters/TabTextPagerAdapter.kt b/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/adapters/TabTextPagerAdapter.kt
index 6f4e98c..dfba8c4 100644
--- a/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/adapters/TabTextPagerAdapter.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/fragment/smallpreview/adapters/TabTextPagerAdapter.kt
@@ -37,6 +37,22 @@
return view == `object`
}
+ /**
+ * Obtains the page number for the home or lock tab
+ *
+ * @param isHome if true, this function will return the page number for the home tab, if false
+ * if false, the one for the lock tab
+ */
+ fun getPageNumber(isHome: Boolean): Int {
+ return textPages.indexOf(
+ if (isHome) R.string.home_screen_message else R.string.lock_screen_message
+ )
+ }
+
+ fun getIsHome(currentItem: Int): Boolean {
+ return textPages[currentItem] == R.string.home_screen_message
+ }
+
override fun instantiateItem(container: ViewGroup, position: Int): Any {
val itemView =
LayoutInflater.from(container.context).inflate(R.layout.item_text, container, false)
diff --git a/src/com/android/wallpaper/picker/preview/ui/transition/ChangeScaleAndPosition.kt b/src/com/android/wallpaper/picker/preview/ui/transition/ChangeScaleAndPosition.kt
new file mode 100644
index 0000000..3a93a47
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/ui/transition/ChangeScaleAndPosition.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.picker.preview.ui.transition
+
+import android.animation.Animator
+import android.animation.ObjectAnimator
+import android.animation.PropertyValuesHolder
+import android.view.ViewGroup
+import androidx.core.animation.doOnStart
+import androidx.transition.Transition
+import androidx.transition.TransitionValues
+
+class ChangeScaleAndPosition : Transition() {
+
+ override fun captureStartValues(transitionValues: TransitionValues) {
+ captureValues(transitionValues)
+ }
+
+ override fun captureEndValues(transitionValues: TransitionValues) {
+ captureValues(transitionValues)
+ }
+
+ override fun getTransitionProperties() = properties
+
+ private fun captureValues(transitionValues: TransitionValues) {
+ val view = transitionValues.view
+ val values = transitionValues.values
+
+ val screenLocation = IntArray(2)
+ view.getLocationOnScreen(screenLocation)
+ values[PROPNAME_POSX] = screenLocation[0]
+ values[PROPNAME_POSY] = screenLocation[1]
+
+ values[PROPNAME_WIDTH] = view.width
+ values[PROPNAME_HEIGHT] = view.height
+ }
+
+ override fun createAnimator(
+ sceneRoot: ViewGroup,
+ startValues: TransitionValues?,
+ endValues: TransitionValues?
+ ): Animator? {
+ if (startValues == null || endValues == null) return null
+
+ val leftDelta =
+ ((startValues.values[PROPNAME_POSX] as Int) - (endValues.values[PROPNAME_POSX] as Int))
+ .toFloat()
+ val topDelta =
+ ((startValues.values[PROPNAME_POSY] as Int) - (endValues.values[PROPNAME_POSY] as Int))
+ .toFloat()
+
+ val scaleWidth =
+ (startValues.values[PROPNAME_WIDTH] as Int).toFloat() /
+ (endValues.values[PROPNAME_WIDTH] as Int).toFloat()
+ val scaleHeight =
+ (startValues.values[PROPNAME_HEIGHT] as Int).toFloat() /
+ (endValues.values[PROPNAME_HEIGHT] as Int).toFloat()
+
+ val view = endValues.view
+ val anim =
+ ObjectAnimator.ofPropertyValuesHolder(
+ view,
+ PropertyValuesHolder.ofFloat("scaleX", scaleWidth, 1f),
+ PropertyValuesHolder.ofFloat("scaleY", scaleHeight, 1f),
+ PropertyValuesHolder.ofFloat("translationX", leftDelta, 0f),
+ PropertyValuesHolder.ofFloat("translationY", topDelta, 0f)
+ )
+ anim.doOnStart {
+ view.pivotX = 0f
+ view.pivotY = 0f
+ }
+ return anim
+ }
+
+ companion object {
+ private const val PROPNAME_POSX = "changeScaleAndPosition:posX"
+ private const val PROPNAME_POSY = "changeScaleAndPosition:posY"
+ private const val PROPNAME_WIDTH = "changeScaleAndPosition:width"
+ private const val PROPNAME_HEIGHT = "changeScaleAndPosition:height"
+ val properties = arrayOf(PROPNAME_POSX, PROPNAME_POSY, PROPNAME_WIDTH, PROPNAME_HEIGHT)
+ }
+}
diff --git a/src/com/android/wallpaper/picker/preview/ui/util/SurfaceViewUtil.kt b/src/com/android/wallpaper/picker/preview/ui/util/SurfaceViewUtil.kt
index 635e9b8..4fd5593 100644
--- a/src/com/android/wallpaper/picker/preview/ui/util/SurfaceViewUtil.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/util/SurfaceViewUtil.kt
@@ -24,11 +24,11 @@
object SurfaceViewUtil {
- fun SurfaceView.attachView(view: View) {
+ fun SurfaceView.attachView(view: View, newWidth: Int = width, newHeight: Int = height) {
// Detach view from its parent, if the view has one
(view.parent as ViewGroup?)?.removeView(view)
val host = SurfaceControlViewHost(context, display, hostToken)
- host.setView(view, width, height)
+ host.setView(view, newWidth, newHeight)
setChildSurfacePackage(checkNotNull(host.surfacePackage))
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/view/DualDisplayAspectRatioLayout.kt b/src/com/android/wallpaper/picker/preview/ui/view/DualDisplayAspectRatioLayout.kt
index 376a88b..5c806ef 100644
--- a/src/com/android/wallpaper/picker/preview/ui/view/DualDisplayAspectRatioLayout.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/view/DualDisplayAspectRatioLayout.kt
@@ -20,7 +20,7 @@
import android.util.AttributeSet
import android.widget.LinearLayout
import com.android.wallpaper.R
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import kotlin.math.max
/**
@@ -32,7 +32,7 @@
attrs: AttributeSet?,
) : LinearLayout(context, attrs) {
- private var previewDisplaySizes: Map<FoldableDisplay, Point>? = null
+ private var previewDisplaySizes: Map<DeviceDisplayType, Point>? = null
/**
* This measures the desired size of the preview views for both of foldable device's displays.
@@ -56,8 +56,8 @@
// TODO: This only works for portrait mode currently, need to incorporate landscape
val parentWidth = this.measuredWidth - totalMarginPixels
- val smallDisplaySize = checkNotNull(getPreviewDisplaySize(FoldableDisplay.FOLDED))
- val largeDisplaySize = checkNotNull(getPreviewDisplaySize(FoldableDisplay.UNFOLDED))
+ val smallDisplaySize = checkNotNull(getPreviewDisplaySize(DeviceDisplayType.FOLDED))
+ val largeDisplaySize = checkNotNull(getPreviewDisplaySize(DeviceDisplayType.UNFOLDED))
// calculate the aspect ratio (ar) of the folded display
val smallDisplayAR = smallDisplaySize.x.toFloat() / smallDisplaySize.y
@@ -134,20 +134,24 @@
)
}
- fun setDisplaySizes(displaySizes: Map<FoldableDisplay, Point>) {
+ fun setDisplaySizes(displaySizes: Map<DeviceDisplayType, Point>) {
previewDisplaySizes = displaySizes
}
- fun getPreviewDisplaySize(display: FoldableDisplay): Point? {
+ fun getPreviewDisplaySize(display: DeviceDisplayType): Point? {
return previewDisplaySizes?.get(display)
}
companion object {
/** Defines children view ids for [DualDisplayAspectRatioLayout]. */
- fun FoldableDisplay.getViewId(): Int {
+ fun DeviceDisplayType.getViewId(): Int {
return when (this) {
- FoldableDisplay.FOLDED -> R.id.small_preview_folded_preview
- FoldableDisplay.UNFOLDED -> R.id.small_preview_unfolded_preview
+ DeviceDisplayType.SINGLE ->
+ throw IllegalStateException(
+ "DualDisplayAspectRatioLayout does not supper handheld DeviceDisplayType"
+ )
+ DeviceDisplayType.FOLDED -> R.id.small_preview_folded_preview
+ DeviceDisplayType.UNFOLDED -> R.id.small_preview_unfolded_preview
}
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/view/FullPreviewFrameLayout.kt b/src/com/android/wallpaper/picker/preview/ui/view/FullPreviewFrameLayout.kt
index 810bcc8..5aa5c9d 100644
--- a/src/com/android/wallpaper/picker/preview/ui/view/FullPreviewFrameLayout.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/view/FullPreviewFrameLayout.kt
@@ -52,7 +52,6 @@
val maxRect = targetSize.findMaxRectWithRatioIn(currentSize)
val width = maxRect.x.toInt()
val height = maxRect.y.toInt()
- setMeasuredDimension(width, height)
measureChildren(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
diff --git a/src/com/android/wallpaper/picker/preview/ui/view/PreviewActionFloatingSheet.kt b/src/com/android/wallpaper/picker/preview/ui/view/PreviewActionFloatingSheet.kt
index b5081fe..e23703e 100644
--- a/src/com/android/wallpaper/picker/preview/ui/view/PreviewActionFloatingSheet.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/view/PreviewActionFloatingSheet.kt
@@ -16,6 +16,7 @@
package com.android.wallpaper.picker.preview.ui.view
import android.content.Context
+import android.net.Uri
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewGroup
@@ -23,9 +24,17 @@
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.view.isVisible
+import androidx.lifecycle.LiveData
+import androidx.slice.Slice
+import androidx.slice.widget.SliceLiveData
+import androidx.slice.widget.SliceView
import com.android.wallpaper.R
import com.android.wallpaper.effects.EffectsController.EffectEnumInterface
+import com.android.wallpaper.model.WallpaperAction
import com.android.wallpaper.util.SizeCalculator
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperActionSelectionBottomSheet
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperActionsToggleAdapter
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperActionsToggleAdapter.WallpaperEffectSwitchListener
import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
@@ -41,6 +50,8 @@
private val floatingSheetContainer: ViewGroup
private val floatingSheetBehavior: BottomSheetBehavior<ViewGroup>
+ private var customizeLiveDataAndView: Pair<LiveData<Slice>, SliceView>? = null
+
init {
LayoutInflater.from(context).inflate(R.layout.floating_sheet2, this, true)
floatingSheetView = requireViewById(R.id.floating_sheet_content)
@@ -50,7 +61,7 @@
floatingSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
}
- fun setEffectContent(
+ fun setImageEffectContent(
effect: EffectEnumInterface,
myPhotosClickListener: OnClickListener,
collapseFloatingSheetListener: OnClickListener,
@@ -81,9 +92,34 @@
floatingSheetView.addView(view)
}
+ fun setCreativeEffectContent(
+ title: String,
+ subtitle: String,
+ wallpaperActions: List<WallpaperAction>,
+ wallpaperEffectSwitchListener: WallpaperEffectSwitchListener,
+ ) {
+ val view =
+ LayoutInflater.from(context)
+ .inflate(R.layout.wallpaper_action_selection_bottom_sheet, this, false)
+ as WallpaperActionSelectionBottomSheet
+ view.setBottomSheetTitle(title)
+ view.setBottomSheetSubtitle(subtitle)
+ view.setUpActionToggleOptions(
+ WallpaperActionsToggleAdapter(
+ // TODO(b/270729418): enable multiple effect options once final design is
+ // agreed upon.
+ // Forcing only one effect item for now
+ if (wallpaperActions.isNotEmpty()) wallpaperActions.subList(0, 1) else listOf(),
+ wallpaperEffectSwitchListener,
+ )
+ )
+ floatingSheetView.removeAllViews()
+ floatingSheetView.addView(view)
+ }
+
fun setInformationContent(
attributions: List<String?>?,
- onExploreButtonClicked: (() -> Unit)?,
+ onExploreButtonClickListener: OnClickListener?,
) {
val view = LayoutInflater.from(context).inflate(R.layout.wallpaper_info_view2, this, false)
val title: TextView = view.requireViewById(R.id.wallpaper_info_title)
@@ -111,21 +147,36 @@
}
}
}
- if (onExploreButtonClicked != null) {
- exploreButton.isVisible = true
- exploreButton.setOnClickListener { onExploreButtonClicked.invoke() }
- }
+
+ exploreButton.isVisible = onExploreButtonClickListener != null
+ exploreButton.setOnClickListener(onExploreButtonClickListener)
}
floatingSheetView.removeAllViews()
floatingSheetView.addView(view)
}
+ fun setCustomizeContent(uri: Uri) {
+ removeCustomizeLiveDataObserver()
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.preview_customize_settings2, this, false)
+ val settingsSliceView: SliceView =
+ view.requireViewById<SliceView>(R.id.settings_slice).apply {
+ mode = SliceView.MODE_LARGE
+ isScrollable = false
+ }
+ customizeLiveDataAndView = SliceLiveData.fromUri(view.context, uri) to settingsSliceView
+ customizeLiveDataAndView?.let { (liveData, observer) -> liveData.observeForever(observer) }
+ floatingSheetView.removeAllViews()
+ floatingSheetView.addView(view)
+ }
+
fun expand() {
floatingSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
}
fun collapse() {
floatingSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
+ removeCustomizeLiveDataObserver()
}
/**
@@ -142,4 +193,9 @@
fun removeFloatingSheetCallback(callback: BottomSheetCallback) {
floatingSheetBehavior.removeBottomSheetCallback(callback)
}
+
+ private fun removeCustomizeLiveDataObserver() {
+ customizeLiveDataAndView?.let { (liveData, observer) -> liveData.removeObserver(observer) }
+ customizeLiveDataAndView = null
+ }
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/view/SystemScaledWallpaperPreviewSurfaceView.kt b/src/com/android/wallpaper/picker/preview/ui/view/SystemScaledSubsamplingScaleImageView.kt
similarity index 82%
rename from src/com/android/wallpaper/picker/preview/ui/view/SystemScaledWallpaperPreviewSurfaceView.kt
rename to src/com/android/wallpaper/picker/preview/ui/view/SystemScaledSubsamplingScaleImageView.kt
index 78127da..d6874cc 100644
--- a/src/com/android/wallpaper/picker/preview/ui/view/SystemScaledWallpaperPreviewSurfaceView.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/view/SystemScaledSubsamplingScaleImageView.kt
@@ -17,15 +17,15 @@
import android.content.Context
import android.util.AttributeSet
-import android.view.SurfaceView
import com.android.wallpaper.util.WallpaperCropUtils
+import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
/**
- * A [SurfaceView] for wallpaper preview that scales and centers the surface to simulate the actual
- * wallpaper surface's default system zoom.
+ * A [SubsamplingScaleImageView] for wallpaper preview that scales and centers the surface to
+ * simulate the actual wallpaper surface's default system zoom.
*/
-class SystemScaledWallpaperPreviewSurfaceView(context: Context, attrs: AttributeSet? = null) :
- SurfaceView(context, attrs) {
+class SystemScaledSubsamplingScaleImageView(context: Context, attrs: AttributeSet? = null) :
+ SubsamplingScaleImageView(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewConfigViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullPreviewConfigViewModel.kt
similarity index 73%
rename from src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewConfigViewModel.kt
rename to src/com/android/wallpaper/picker/preview/ui/viewmodel/FullPreviewConfigViewModel.kt
index 4e4707b..34a1656 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewConfigViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullPreviewConfigViewModel.kt
@@ -15,15 +15,15 @@
*/
package com.android.wallpaper.picker.preview.ui.viewmodel
-import android.graphics.Point
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.CustomizationSections.Screen
-/** Configuration for a wallpaper preview. */
-data class WallpaperPreviewConfigViewModel(
+/** Configuration for a full preview, used by both wallpaper and workspace. */
+data class FullPreviewConfigViewModel(
/** The [Screen] the preview is rendering. */
val screen: Screen,
- /** The display size the preview is based on. */
- val displaySize: Point,
+ /** Is it a folded or unfolded display. Null for handheld. */
+ val deviceDisplayType: DeviceDisplayType,
)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullResWallpaperViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullResWallpaperViewModel.kt
index 57aba6a..90facf3 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullResWallpaperViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullResWallpaperViewModel.kt
@@ -17,12 +17,12 @@
import android.graphics.Bitmap
import android.graphics.Point
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
-import java.io.InputStream
data class FullResWallpaperViewModel(
val rawWallpaperBitmap: Bitmap,
val rawWallpaperSize: Point,
- val stream: InputStream?,
+ val asset: Asset,
val fullPreviewCropModels: Map<Point, FullPreviewCropModel>?,
)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullWallpaperPreviewViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullWallpaperPreviewViewModel.kt
index 7ab1f36..7bd2991 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullWallpaperPreviewViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/FullWallpaperPreviewViewModel.kt
@@ -15,12 +15,20 @@
*/
package com.android.wallpaper.picker.preview.ui.viewmodel
+import android.graphics.Point
import com.android.wallpaper.picker.data.WallpaperModel
import com.android.wallpaper.util.WallpaperConnection.WhichPreview
+/** Information needed to bind a wallpaper in the full preview. */
data class FullWallpaperPreviewViewModel(
+ /** The wallpaper model to preview. */
val wallpaper: WallpaperModel,
- val config: WallpaperPreviewConfigViewModel,
+ /** Configuration for a full preview. */
+ val config: FullPreviewConfigViewModel,
+ /** The display size the preview is based on. */
+ val displaySize: Point,
+ /** Whether to enable user cropping on the given wallpaper. */
val allowUserCropping: Boolean,
+ /** Different possible scenarios for the preview. */
val whichPreview: WhichPreview,
)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/PreviewActionsViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/PreviewActionsViewModel.kt
index 463182f..bba0e0d 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/PreviewActionsViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/PreviewActionsViewModel.kt
@@ -18,16 +18,22 @@
import android.content.ClipData
import android.content.ComponentName
+import android.content.Context
import android.content.Intent
import android.net.Uri
import android.service.wallpaper.WallpaperSettingsActivity
+import com.android.wallpaper.effects.Effect
import com.android.wallpaper.effects.EffectsController.EffectEnumInterface
import com.android.wallpaper.picker.data.CreativeWallpaperData
import com.android.wallpaper.picker.data.DownloadableWallpaperData
import com.android.wallpaper.picker.data.LiveWallpaperData
import com.android.wallpaper.picker.data.WallpaperModel
import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
-import com.android.wallpaper.picker.preview.data.repository.EffectsRepository
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLIED
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_APPLY_IN_PROGRESS
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_DOWNLOAD_IN_PROGRESS
+import com.android.wallpaper.picker.preview.data.repository.ImageEffectsRepository.EffectStatus.EFFECT_DOWNLOAD_READY
import com.android.wallpaper.picker.preview.domain.interactor.PreviewActionsInteractor
import com.android.wallpaper.picker.preview.ui.util.LiveWallpaperDeleteUtil
import com.android.wallpaper.picker.preview.ui.viewmodel.Action.CUSTOMIZE
@@ -36,16 +42,26 @@
import com.android.wallpaper.picker.preview.ui.viewmodel.Action.EFFECTS
import com.android.wallpaper.picker.preview.ui.viewmodel.Action.INFORMATION
import com.android.wallpaper.picker.preview.ui.viewmodel.Action.SHARE
-import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.EffectFloatingSheetViewModel
+import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.CreativeEffectFloatingSheetViewModel
+import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.CustomizeFloatingSheetViewModel
+import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.ImageEffectFloatingSheetViewModel
import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.InformationFloatingSheetViewModel
+import com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet.PreviewFloatingSheetViewModel
import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.EffectDownloadClickListener
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.EffectSwitchListener
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.Status.DOWNLOADING
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.Status.IDLE
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.Status.PROCESSING
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.Status.SHOW_DOWNLOAD_BUTTON
+import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2.Status.SUCCESS
+import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
/** View model for the preview action buttons */
@@ -55,37 +71,30 @@
constructor(
private val interactor: PreviewActionsInteractor,
liveWallpaperDeleteUtil: LiveWallpaperDeleteUtil,
+ @ApplicationContext private val context: Context,
) {
/** [INFORMATION] */
- private val _informationFloatingSheetViewModel: Flow<InformationFloatingSheetViewModel?> =
+ private val informationFloatingSheetViewModel: Flow<InformationFloatingSheetViewModel?> =
interactor.wallpaperModel.map { wallpaperModel ->
if (wallpaperModel == null || !wallpaperModel.shouldShowInformationFloatingSheet()) {
null
} else {
InformationFloatingSheetViewModel(
wallpaperModel.commonWallpaperData.attributions,
- wallpaperModel.commonWallpaperData.exploreActionUrl,
+ if (wallpaperModel.commonWallpaperData.exploreActionUrl.isNullOrEmpty()) {
+ null
+ } else {
+ wallpaperModel.commonWallpaperData.exploreActionUrl
+ }
)
}
}
- val isInformationVisible: Flow<Boolean> = _informationFloatingSheetViewModel.map { it != null }
+ val isInformationVisible: Flow<Boolean> = informationFloatingSheetViewModel.map { it != null }
private val _isInformationChecked: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isInformationChecked: Flow<Boolean> = _isInformationChecked.asStateFlow()
- // Floating sheet contents for the bottom sheet dialog. If content is null, the bottom sheet
- // should collapse, otherwise, expended.
- val informationFloatingSheetViewModel: Flow<InformationFloatingSheetViewModel?> =
- combine(isInformationChecked, _informationFloatingSheetViewModel) { checked, viewModel ->
- if (checked && viewModel != null) {
- viewModel
- } else {
- null
- }
- }
- .distinctUntilChanged()
-
val onInformationClicked: Flow<(() -> Unit)?> =
combine(isInformationVisible, isInformationChecked) { show, isChecked ->
if (show) {
@@ -180,8 +189,11 @@
/** [EDIT] */
val editIntent: Flow<Intent?> =
- interactor.wallpaperModel.map {
- (it as? WallpaperModel.LiveWallpaperModel)?.liveWallpaperData?.getEditActivityIntent()
+ interactor.wallpaperModel.map { model ->
+ (model as? LiveWallpaperModel)?.liveWallpaperData?.getEditActivityIntent(false)?.let {
+ intent ->
+ if (intent.resolveActivityInfo(context.packageManager, 0) != null) intent else null
+ }
}
val isEditVisible: Flow<Boolean> = editIntent.map { it != null }
@@ -189,8 +201,15 @@
val isEditChecked: Flow<Boolean> = _isEditChecked.asStateFlow()
/** [CUSTOMIZE] */
- private val _isCustomizeVisible: MutableStateFlow<Boolean> = MutableStateFlow(false)
- val isCustomizeVisible: Flow<Boolean> = _isCustomizeVisible.asStateFlow()
+ private val customizeFloatingSheetViewModel: Flow<CustomizeFloatingSheetViewModel?> =
+ interactor.wallpaperModel.map {
+ (it as? LiveWallpaperModel)
+ ?.liveWallpaperData
+ ?.systemWallpaperInfo
+ ?.settingsSliceUri
+ ?.let { CustomizeFloatingSheetViewModel(it) }
+ }
+ val isCustomizeVisible: Flow<Boolean> = customizeFloatingSheetViewModel.map { it != null }
private val _isCustomizeChecked: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isCustomizeChecked: Flow<Boolean> = _isCustomizeChecked.asStateFlow()
@@ -210,41 +229,66 @@
}
/** [EFFECTS] */
- private val _effectFloatingSheetViewModel: Flow<EffectFloatingSheetViewModel?> =
- combine(interactor.wallpaperModel, interactor.effectsStatus, interactor.effect) {
- wallpaper,
- status,
- effect ->
- (wallpaper as? WallpaperModel.StaticWallpaperModel)?.imageWallpaperData?.uri
- ?: return@combine null
- effect ?: return@combine null
- when (status) {
- EffectsRepository.EffectStatus.EFFECT_DISABLE -> {
- null
- }
- else -> {
- getEffectFloatingSheetViewModel(status, effect.title, effect.type)
+ private val imageEffectFloatingSheetViewModel: Flow<ImageEffectFloatingSheetViewModel?> =
+ combine(interactor.imageEffectsStatus, interactor.imageEffect) {
+ imageEffectStatus,
+ imageEffect ->
+ imageEffect?.let {
+ when (imageEffectStatus) {
+ ImageEffectsRepository.EffectStatus.EFFECT_DISABLE -> {
+ null
+ }
+ else -> {
+ getImageEffectFloatingSheetViewModel(
+ imageEffectStatus,
+ imageEffect,
+ )
+ }
}
}
}
- private fun getEffectFloatingSheetViewModel(
- status: EffectsRepository.EffectStatus,
- title: String,
- effectType: EffectEnumInterface,
- ): EffectFloatingSheetViewModel {
+ private val creativeEffectFloatingSheetViewModel: Flow<CreativeEffectFloatingSheetViewModel?> =
+ interactor.creativeEffectsModel.map { creativeEffectsModel ->
+ creativeEffectsModel?.let {
+ CreativeEffectFloatingSheetViewModel(
+ title = it.title,
+ subtitle = it.subtitle,
+ wallpaperActions = it.actions,
+ wallpaperEffectSwitchListener = { interactor.turnOnCreativeEffect(it) },
+ )
+ }
+ }
+
+ private fun getImageEffectFloatingSheetViewModel(
+ status: ImageEffectsRepository.EffectStatus,
+ effect: Effect,
+ ): ImageEffectFloatingSheetViewModel {
val floatingSheetViewStatus =
when (status) {
- EffectsRepository.EffectStatus.EFFECT_APPLY_IN_PROGRESS ->
- WallpaperEffectsView2.Status.PROCESSING
- EffectsRepository.EffectStatus.EFFECT_APPLIED ->
- WallpaperEffectsView2.Status.SUCCESS
- else -> WallpaperEffectsView2.Status.IDLE
+ EFFECT_APPLY_IN_PROGRESS -> {
+ PROCESSING
+ }
+ EFFECT_APPLIED -> {
+ SUCCESS
+ }
+ EFFECT_DOWNLOAD_READY -> {
+ SHOW_DOWNLOAD_BUTTON
+ }
+ EFFECT_DOWNLOAD_IN_PROGRESS -> {
+ DOWNLOADING
+ }
+ ImageEffectsRepository.EffectStatus.EFFECT_DOWNLOAD_FAILED -> {
+ WallpaperEffectsView2.Status.FAILED
+ }
+ else -> {
+ IDLE
+ }
}
- return EffectFloatingSheetViewModel(
+ return ImageEffectFloatingSheetViewModel(
myPhotosClickListener = {},
collapseFloatingSheetListener = {},
- object : WallpaperEffectsView2.EffectSwitchListener {
+ object : EffectSwitchListener {
override fun onEffectSwitchChanged(
effect: EffectEnumInterface,
isChecked: Boolean
@@ -258,37 +302,30 @@
}
}
},
- object : WallpaperEffectsView2.EffectDownloadClickListener {
+ object : EffectDownloadClickListener {
override fun onEffectDownloadClick() {
- TODO("Not yet implemented")
+ interactor.startEffectsMLDownload(effect)
}
},
floatingSheetViewStatus,
resultCode = null,
errorMessage = null,
- title,
- effectType,
+ effect.title,
+ effect.type,
interactor.getEffectTextRes(),
)
}
- val isEffectsVisible: Flow<Boolean> = _effectFloatingSheetViewModel.map { it != null }
+ val isEffectsVisible: Flow<Boolean> =
+ combine(imageEffectFloatingSheetViewModel, creativeEffectFloatingSheetViewModel) {
+ imageEffect,
+ creativeEffect ->
+ imageEffect != null || creativeEffect != null
+ }
private val _isEffectsChecked: MutableStateFlow<Boolean> = MutableStateFlow(false)
val isEffectsChecked: Flow<Boolean> = _isEffectsChecked.asStateFlow()
- // Floating sheet contents for the bottom sheet dialog. If content is null, the bottom sheet
- // should collapse, otherwise, expended.
- val effectFloatingSheetViewModel: Flow<EffectFloatingSheetViewModel?> =
- combine(isEffectsChecked, _effectFloatingSheetViewModel) { checked, viewModel ->
- if (checked && viewModel != null) {
- viewModel
- } else {
- null
- }
- }
- .distinctUntilChanged()
-
val onEffectsClicked: Flow<(() -> Unit)?> =
combine(isEffectsVisible, isEffectsChecked) { show, isChecked ->
if (show) {
@@ -310,6 +347,46 @@
}
val isShareVisible: Flow<Boolean> = shareIntent.map { it != null }
+ // Floating sheet contents for the bottom sheet dialog. If content is null, the bottom sheet
+ // should collapse, otherwise, expended.
+ val previewFloatingSheetViewModel: Flow<PreviewFloatingSheetViewModel?> =
+ combine7(
+ isInformationChecked,
+ isEffectsChecked,
+ isCustomizeChecked,
+ informationFloatingSheetViewModel,
+ imageEffectFloatingSheetViewModel,
+ creativeEffectFloatingSheetViewModel,
+ customizeFloatingSheetViewModel,
+ ) {
+ isInformationChecked,
+ isEffectsChecked,
+ isCustomizeChecked,
+ informationFloatingSheetViewModel,
+ imageEffectFloatingSheetViewModel,
+ creativeEffectFloatingSheetViewModel,
+ customizeFloatingSheetViewModel ->
+ if (isInformationChecked && informationFloatingSheetViewModel != null) {
+ PreviewFloatingSheetViewModel(
+ informationFloatingSheetViewModel = informationFloatingSheetViewModel
+ )
+ } else if (isEffectsChecked && imageEffectFloatingSheetViewModel != null) {
+ PreviewFloatingSheetViewModel(
+ imageEffectFloatingSheetViewModel = imageEffectFloatingSheetViewModel
+ )
+ } else if (isEffectsChecked && creativeEffectFloatingSheetViewModel != null) {
+ PreviewFloatingSheetViewModel(
+ creativeEffectFloatingSheetViewModel = creativeEffectFloatingSheetViewModel
+ )
+ } else if (isCustomizeChecked && customizeFloatingSheetViewModel != null) {
+ PreviewFloatingSheetViewModel(
+ customizeFloatingSheetViewModel = customizeFloatingSheetViewModel
+ )
+ } else {
+ null
+ }
+ }
+
fun onFloatingSheetCollapsed() {
// When floating collapsed, we should look for those actions that expand the floating sheet
// and see which is checked, and uncheck it.
@@ -320,6 +397,10 @@
if (_isEffectsChecked.value) {
_isEffectsChecked.value = false
}
+
+ if (_isCustomizeChecked.value) {
+ _isCustomizeChecked.value = false
+ }
}
private fun uncheckAllOthersExcept(action: Action) {
@@ -341,6 +422,8 @@
}
companion object {
+ const val EXTRA_KEY_IS_CREATE_NEW = "is_create_new"
+
private fun WallpaperModel.shouldShowInformationFloatingSheet(): Boolean {
if (
this is LiveWallpaperModel &&
@@ -377,7 +460,11 @@
}
}
- fun LiveWallpaperData.getEditActivityIntent(): Intent? {
+ /**
+ * @param isCreateNew: True means creating a new creative wallpaper. False means editing an
+ * existing wallpaper.
+ */
+ fun LiveWallpaperData.getEditActivityIntent(isCreateNew: Boolean): Intent? {
val settingsActivity = systemWallpaperInfo.settingsActivity
if (settingsActivity.isNullOrEmpty()) {
return null
@@ -386,6 +473,7 @@
Intent().apply {
component = ComponentName(systemWallpaperInfo.packageName, settingsActivity)
putExtra(WallpaperSettingsActivity.EXTRA_PREVIEW_MODE, true)
+ putExtra(EXTRA_KEY_IS_CREATE_NEW, isCreateNew)
}
return intent
}
@@ -393,6 +481,31 @@
fun LiveWallpaperModel.isNewCreativeWallpaper(): Boolean {
return creativeWallpaperData?.deleteUri?.toString()?.isEmpty() == true
}
+
+ /** The original combine function can only take up to 5 flows. */
+ inline fun <T1, T2, T3, T4, T5, T6, T7, R> combine7(
+ flow: Flow<T1>,
+ flow2: Flow<T2>,
+ flow3: Flow<T3>,
+ flow4: Flow<T4>,
+ flow5: Flow<T5>,
+ flow6: Flow<T6>,
+ flow7: Flow<T7>,
+ crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7) -> R
+ ): Flow<R> {
+ return combine(flow, flow2, flow3, flow4, flow5, flow6, flow7) { args: Array<*> ->
+ @Suppress("UNCHECKED_CAST")
+ transform(
+ args[0] as T1,
+ args[1] as T2,
+ args[2] as T3,
+ args[3] as T4,
+ args[4] as T5,
+ args[5] as T6,
+ args[6] as T7,
+ )
+ }
+ }
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/StaticWallpaperPreviewViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/StaticWallpaperPreviewViewModel.kt
index 15f33b2..e0d84e6 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/StaticWallpaperPreviewViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/StaticWallpaperPreviewViewModel.kt
@@ -23,7 +23,6 @@
import android.graphics.Point
import android.graphics.Rect
import com.android.wallpaper.asset.Asset
-import com.android.wallpaper.asset.StreamableAsset
import com.android.wallpaper.module.WallpaperPreferences
import com.android.wallpaper.picker.customization.shared.model.WallpaperColorsModel
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
@@ -34,7 +33,6 @@
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ViewModelScoped
import java.io.ByteArrayOutputStream
-import java.io.InputStream
import javax.inject.Inject
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.CoroutineDispatcher
@@ -91,8 +89,8 @@
.map { it.staticWallpaperData.asset.getLowResBitmap(context) }
.filterNotNull()
.flowOn(bgDispatcher)
- // Asset detail includes the dimensions, bitmap and input stream decoded from the asset.
- private val assetDetail: Flow<Triple<Point, Bitmap?, InputStream?>?> =
+ // Asset detail includes the dimensions, bitmap and the asset.
+ private val assetDetail: Flow<Triple<Point, Bitmap?, Asset>?> =
interactor.wallpaperModel
.map { (it as? StaticWallpaperModel)?.staticWallpaperData?.asset }
.map {
@@ -101,8 +99,7 @@
} else {
val dimensions = it.decodeRawDimensions()
val bitmap = it.decodeBitmap(dimensions)
- val stream = it.getStream()
- Triple(dimensions, bitmap, stream)
+ Triple(dimensions, bitmap, it)
}
}
.flowOn(bgDispatcher)
@@ -115,9 +112,14 @@
if (assetDetail == null) {
null
} else {
- val (dimensions, bitmap, stream) = assetDetail
+ val (dimensions, bitmap, asset) = assetDetail
bitmap?.let {
- FullResWallpaperViewModel(bitmap, dimensions, stream, cropHintsInfo)
+ FullResWallpaperViewModel(
+ bitmap,
+ dimensions,
+ asset,
+ cropHintsInfo,
+ )
}
}
}
@@ -174,15 +176,6 @@
decodeBitmap(dimensions.x, dimensions.y, /* hardwareBitmapAllowed= */ false, callback)
}
- private suspend fun Asset.getStream(): InputStream? =
- suspendCancellableCoroutine { k: CancellableContinuation<InputStream?> ->
- if (this is StreamableAsset) {
- fetchInputStream { k.resumeWith(Result.success(it)) }
- } else {
- k.resumeWith(Result.success(null))
- }
- }
-
// TODO b/296288298 Create a util class functions for Bitmap and Asset
private fun Bitmap.extractColors(): WallpaperColors? {
val tmpOut = ByteArrayOutputStream()
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewViewModel.kt
index 3cd5286..f4a4133 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/WallpaperPreviewViewModel.kt
@@ -20,7 +20,7 @@
import android.stats.style.StyleEnums
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.android.wallpaper.model.wallpaper.FoldableDisplay
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.module.CustomizationSections
import com.android.wallpaper.module.CustomizationSections.Screen
import com.android.wallpaper.picker.customization.shared.model.WallpaperColorsModel
@@ -30,9 +30,11 @@
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
import com.android.wallpaper.picker.di.modules.PreviewUtilsModule.HomeScreenPreviewUtils
import com.android.wallpaper.picker.di.modules.PreviewUtilsModule.LockScreenPreviewUtils
+import com.android.wallpaper.picker.preview.domain.interactor.PreviewActionsInteractor
import com.android.wallpaper.picker.preview.domain.interactor.WallpaperPreviewInteractor
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
import com.android.wallpaper.picker.preview.ui.WallpaperPreviewActivity
+import com.android.wallpaper.picker.preview.ui.binder.PreviewTooltipBinder
import com.android.wallpaper.util.DisplayUtils
import com.android.wallpaper.util.PreviewUtils
import com.android.wallpaper.util.WallpaperConnection.WhichPreview
@@ -45,6 +47,7 @@
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map
@@ -57,6 +60,7 @@
@Inject
constructor(
private val interactor: WallpaperPreviewInteractor,
+ actionsInteractor: PreviewActionsInteractor,
staticWallpaperPreviewViewModelFactory: StaticWallpaperPreviewViewModel.Factory,
val previewActionsViewModel: PreviewActionsViewModel,
private val displayUtils: DisplayUtils,
@@ -64,30 +68,63 @@
@LockScreenPreviewUtils private val lockPreviewUtils: PreviewUtils,
) : ViewModel() {
+ // Don't update smaller display since we always use portrait, always use wallpaper display on
+ // single display device.
+ val smallerDisplaySize = displayUtils.getRealSize(displayUtils.getSmallerDisplay())
+ private val _wallpaperDisplaySize =
+ MutableStateFlow(displayUtils.getRealSize(displayUtils.getWallpaperDisplay()))
+ val wallpaperDisplaySize = _wallpaperDisplaySize.asStateFlow()
+
val staticWallpaperPreviewViewModel =
staticWallpaperPreviewViewModelFactory.create(viewModelScope)
- val smallerDisplaySize = displayUtils.getRealSize(displayUtils.getSmallerDisplay())
- val wallpaperDisplaySize = displayUtils.getRealSize(displayUtils.getWallpaperDisplay())
var isViewAsHome = false
var isNewTask = false
val wallpaper: StateFlow<WallpaperModel?> = interactor.wallpaperModel
- fun shouldShowTooltip(): Flow<Boolean> =
- combine(interactor.wallpaperModel.filterNotNull(), interactor.hasTooltipBeenShown) {
- wallpaper,
- hasTooltipBeenShown ->
- // Only show tooltip for non-downloadable static wallpapers. Hide tooltip for live
- // wallpaper and downloadable wallpaper as their crop is not adjustable.
- if (wallpaper is StaticWallpaperModel && !wallpaper.isDownloadableWallpaper()) {
- // Only show tooltip if it has not been shown before.
- !hasTooltipBeenShown
- } else {
- false
- }
+ // Used to display loading indication on the preview.
+ val effectStatus = actionsInteractor.imageEffectsStatus
+
+ // This flag prevents launching the creative edit activity again when orientation change.
+ // On orientation change, the fragment's onCreateView will be called again.
+ var isCurrentlyEditingCreativeWallpaper = false
+
+ fun updateDisplayConfiguration() {
+ _wallpaperDisplaySize.value = displayUtils.getRealSize(displayUtils.getWallpaperDisplay())
+ }
+
+ private val isWallpaperCroppable: Flow<Boolean> =
+ wallpaper.map { wallpaper ->
+ wallpaper is StaticWallpaperModel && !wallpaper.isDownloadableWallpaper()
}
- fun dismissTooltip() = interactor.dismissTooltip()
+ val smallTooltipViewModel =
+ object : PreviewTooltipBinder.TooltipViewModel {
+ override val shouldShowTooltip: Flow<Boolean> =
+ combine(isWallpaperCroppable, interactor.hasSmallPreviewTooltipBeenShown) {
+ isCroppable,
+ hasTooltipBeenShown ->
+ // Only show tooltip if it has not been shown before.
+ isCroppable && !hasTooltipBeenShown
+ }
+ .distinctUntilChanged()
+
+ override fun dismissTooltip() = interactor.hideSmallPreviewTooltip()
+ }
+
+ val fullTooltipViewModel =
+ object : PreviewTooltipBinder.TooltipViewModel {
+ override val shouldShowTooltip: Flow<Boolean> =
+ combine(isWallpaperCroppable, interactor.hasFullPreviewTooltipBeenShown) {
+ isCroppable,
+ hasTooltipBeenShown ->
+ // Only show tooltip if it has not been shown before.
+ isCroppable && !hasTooltipBeenShown
+ }
+ .distinctUntilChanged()
+
+ override fun dismissTooltip() = interactor.hideFullPreviewTooltip()
+ }
private val _whichPreview = MutableStateFlow<WhichPreview?>(null)
private val whichPreview: Flow<WhichPreview> = _whichPreview.asStateFlow().filterNotNull()
@@ -129,10 +166,10 @@
val wallpaperColorsModel: Flow<WallpaperColorsModel> =
merge(liveWallpaperColors, staticWallpaperPreviewViewModel.wallpaperColors)
- // This is only used for the full screen wallpaper preview.
- private val fullWallpaperPreviewConfigViewModel:
- MutableStateFlow<WallpaperPreviewConfigViewModel?> =
+ // This is only used for the full screen preview.
+ private val _fullPreviewConfigViewModel: MutableStateFlow<FullPreviewConfigViewModel?> =
MutableStateFlow(null)
+ val fullPreviewConfigViewModel = _fullPreviewConfigViewModel.asStateFlow()
// This is only used for the small screen wallpaper preview.
val smallWallpaper: Flow<Pair<WallpaperModel, WhichPreview>> =
@@ -144,29 +181,38 @@
val fullWallpaper: Flow<FullWallpaperPreviewViewModel> =
combine(
wallpaper.filterNotNull(),
- fullWallpaperPreviewConfigViewModel.filterNotNull(),
+ fullPreviewConfigViewModel.filterNotNull(),
whichPreview,
- ) { wallpaper, config, whichPreview ->
+ wallpaperDisplaySize,
+ ) { wallpaper, config, whichPreview, wallpaperDisplaySize ->
+ val displaySize =
+ when (config.deviceDisplayType) {
+ DeviceDisplayType.SINGLE -> wallpaperDisplaySize
+ DeviceDisplayType.FOLDED -> smallerDisplaySize
+ DeviceDisplayType.UNFOLDED -> wallpaperDisplaySize
+ }
FullWallpaperPreviewViewModel(
wallpaper = wallpaper,
- config = config,
+ config =
+ FullPreviewConfigViewModel(
+ config.screen,
+ config.deviceDisplayType,
+ ),
+ displaySize = displaySize,
allowUserCropping =
wallpaper is StaticWallpaperModel && !wallpaper.isDownloadableWallpaper(),
whichPreview = whichPreview,
)
}
- // This is only used for the full screen wallpaper preview.
- private val _fullWorkspacePreviewConfigViewModel:
- MutableStateFlow<WorkspacePreviewConfigViewModel?> =
- MutableStateFlow(null)
-
- // This is only used for the full screen wallpaper preview.
+ // This is only used for the full screen workspace preview.
val fullWorkspacePreviewConfigViewModel: Flow<WorkspacePreviewConfigViewModel> =
- _fullWorkspacePreviewConfigViewModel.filterNotNull()
+ fullPreviewConfigViewModel.filterNotNull().map {
+ getWorkspacePreviewConfig(it.screen, it.deviceDisplayType)
+ }
val onCropButtonClick: Flow<(() -> Unit)?> =
- combine(wallpaper, fullWallpaperPreviewConfigViewModel.filterNotNull()) { wallpaper, _ ->
+ combine(wallpaper, fullPreviewConfigViewModel.filterNotNull()) { wallpaper, _ ->
if (wallpaper is StaticWallpaperModel && !wallpaper.isDownloadableWallpaper()) {
{
staticWallpaperPreviewViewModel.run {
@@ -235,10 +281,15 @@
StyleEnums.SET_WALLPAPER_ENTRY_POINT_WALLPAPER_PREVIEW,
destination = destination,
wallpaperModel = wallpaper,
- inputStream = it.stream,
bitmap = it.rawWallpaperBitmap,
wallpaperSize = it.rawWallpaperSize,
- fullPreviewCropModels = it.fullPreviewCropModels,
+ asset = it.asset,
+ fullPreviewCropModels =
+ if (it.fullPreviewCropModels.isNullOrEmpty()) {
+ staticWallpaperPreviewViewModel.fullPreviewCropModels
+ } else {
+ it.fullPreviewCropModels
+ },
)
}
is LiveWallpaperModel -> {
@@ -275,7 +326,7 @@
fun getWorkspacePreviewConfig(
screen: Screen,
- foldableDisplay: FoldableDisplay?,
+ deviceDisplayType: DeviceDisplayType,
): WorkspacePreviewConfigViewModel {
val previewUtils =
when (screen) {
@@ -286,67 +337,50 @@
lockPreviewUtils
}
}
- val displayId =
- when (foldableDisplay) {
- FoldableDisplay.FOLDED -> {
- displayUtils.getSmallerDisplay().displayId
- }
- FoldableDisplay.UNFOLDED -> {
- displayUtils.getWallpaperDisplay().displayId
- }
- null -> {
- displayUtils.getWallpaperDisplay().displayId
- }
- }
+ // Do not directly store display Id in the view model because display Id can change on fold
+ // and unfold whereas view models persist. Store FoldableDisplay instead and convert in the
+ // binder.
return WorkspacePreviewConfigViewModel(
previewUtils = previewUtils,
- displayId = displayId,
+ deviceDisplayType = deviceDisplayType,
)
}
+ fun getDisplayId(deviceDisplayType: DeviceDisplayType): Int {
+ return when (deviceDisplayType) {
+ DeviceDisplayType.SINGLE -> {
+ displayUtils.getWallpaperDisplay().displayId
+ }
+ DeviceDisplayType.FOLDED -> {
+ displayUtils.getSmallerDisplay().displayId
+ }
+ DeviceDisplayType.UNFOLDED -> {
+ displayUtils.getWallpaperDisplay().displayId
+ }
+ }
+ }
+
fun onSmallPreviewClicked(
screen: Screen,
- foldableDisplay: FoldableDisplay?,
+ deviceDisplayType: DeviceDisplayType,
) {
- fullWallpaperPreviewConfigViewModel.value =
- getWallpaperPreviewConfig(screen, foldableDisplay)
- _fullWorkspacePreviewConfigViewModel.value =
- getWorkspacePreviewConfig(screen, foldableDisplay)
+ smallTooltipViewModel.dismissTooltip()
+ _fullPreviewConfigViewModel.value = FullPreviewConfigViewModel(screen, deviceDisplayType)
}
- fun setDefaultWallpaperPreviewConfigViewModel(displaySize: Point) {
- fullWallpaperPreviewConfigViewModel.value =
- WallpaperPreviewConfigViewModel(
+ fun setDefaultFullPreviewConfigViewModel(
+ deviceDisplayType: DeviceDisplayType,
+ ) {
+ _fullPreviewConfigViewModel.value =
+ FullPreviewConfigViewModel(
Screen.HOME_SCREEN,
- displaySize,
+ deviceDisplayType,
)
}
- private fun getWallpaperPreviewConfig(
- screen: Screen,
- foldableDisplay: FoldableDisplay?,
- ): WallpaperPreviewConfigViewModel {
- val displaySize =
- when (foldableDisplay) {
- FoldableDisplay.FOLDED -> {
- smallerDisplaySize
- }
- FoldableDisplay.UNFOLDED -> {
- wallpaperDisplaySize
- }
- null -> {
- wallpaperDisplaySize
- }
- }
- return WallpaperPreviewConfigViewModel(
- screen = screen,
- displaySize = displaySize,
- )
- }
-
companion object {
private fun WallpaperModel.isDownloadableWallpaper(): Boolean {
- return this is StaticWallpaperModel && this.downloadableWallpaperData != null
+ return this is StaticWallpaperModel && downloadableWallpaperData != null
}
}
}
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WorkspacePreviewConfigViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/WorkspacePreviewConfigViewModel.kt
index 35f5111..01abe30 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/WorkspacePreviewConfigViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/WorkspacePreviewConfigViewModel.kt
@@ -15,6 +15,7 @@
*/
package com.android.wallpaper.picker.preview.ui.viewmodel
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.util.PreviewUtils
/** Defines configuration associated with a single workspace preview. */
@@ -23,6 +24,6 @@
/** The preview utils for rendering the workspace preview, different for Home & Lock screens. */
val previewUtils: PreviewUtils,
- /** The ID of the display to be rendered. */
- val displayId: Int,
+ /** The foldable display to be rendered, or null if the device is not a foldable. */
+ val deviceDisplayType: DeviceDisplayType,
)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CreativeEffectFloatingSheetViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CreativeEffectFloatingSheetViewModel.kt
new file mode 100644
index 0000000..0e7f551
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CreativeEffectFloatingSheetViewModel.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.picker.preview.ui.viewmodel.floatingSheet
+
+import com.android.wallpaper.model.WallpaperAction
+
+/** This data class represents the view data for the creative wallpaper effect floating sheet */
+data class CreativeEffectFloatingSheetViewModel(
+ val title: String,
+ val subtitle: String,
+ val wallpaperActions: List<WallpaperAction>,
+ val wallpaperEffectSwitchListener: suspend (checkedItem: Int) -> Unit,
+)
diff --git a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CustomizeFloatingSheetViewModel.kt
similarity index 70%
copy from src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
copy to src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CustomizeFloatingSheetViewModel.kt
index 4001f83..1a07603 100644
--- a/src/com/android/wallpaper/model/wallpaper/FoldableDisplay.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/CustomizeFloatingSheetViewModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.wallpaper.model.wallpaper
-enum class FoldableDisplay {
- FOLDED,
- UNFOLDED,
-}
+package com.android.wallpaper.picker.preview.ui.viewmodel.floatingSheet
+
+import android.net.Uri
+
+data class CustomizeFloatingSheetViewModel(
+ val customizeSliceUri: Uri,
+)
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/EffectFloatingSheetViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/ImageEffectFloatingSheetViewModel.kt
similarity index 90%
rename from src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/EffectFloatingSheetViewModel.kt
rename to src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/ImageEffectFloatingSheetViewModel.kt
index 3ff26d2..b4ad10b 100644
--- a/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/EffectFloatingSheetViewModel.kt
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/ImageEffectFloatingSheetViewModel.kt
@@ -20,8 +20,8 @@
import com.android.wallpaper.effects.EffectsController.EffectEnumInterface
import com.android.wallpaper.widget.floatingsheetcontent.WallpaperEffectsView2
-/** This data class represents the view data for the effect floating sheet */
-data class EffectFloatingSheetViewModel(
+/** This data class represents the view data for the image wallpaper effect floating sheet */
+data class ImageEffectFloatingSheetViewModel(
val myPhotosClickListener: View.OnClickListener,
val collapseFloatingSheetListener: View.OnClickListener,
val effectSwitchListener: WallpaperEffectsView2.EffectSwitchListener,
diff --git a/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/PreviewFloatingSheetViewModel.kt b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/PreviewFloatingSheetViewModel.kt
new file mode 100644
index 0000000..a2a6bc7
--- /dev/null
+++ b/src/com/android/wallpaper/picker/preview/ui/viewmodel/floatingSheet/PreviewFloatingSheetViewModel.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.picker.preview.ui.viewmodel.floatingSheet
+
+/**
+ * Represents the floating sheet view model. Note that we expect that when
+ * PreviewFloatingSheetViewModel is present, only one of the field is nonnull, while others should
+ * be null.
+ */
+data class PreviewFloatingSheetViewModel(
+ val informationFloatingSheetViewModel: InformationFloatingSheetViewModel? = null,
+ val imageEffectFloatingSheetViewModel: ImageEffectFloatingSheetViewModel? = null,
+ val creativeEffectFloatingSheetViewModel: CreativeEffectFloatingSheetViewModel? = null,
+ val customizeFloatingSheetViewModel: CustomizeFloatingSheetViewModel? = null,
+)
diff --git a/src/com/android/wallpaper/system/UiModeManagerImpl.kt b/src/com/android/wallpaper/system/UiModeManagerImpl.kt
new file mode 100644
index 0000000..4fe55f0
--- /dev/null
+++ b/src/com/android/wallpaper/system/UiModeManagerImpl.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.system
+
+import android.app.UiModeManager
+import android.content.Context
+import dagger.hilt.android.qualifiers.ApplicationContext
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class UiModeManagerImpl @Inject constructor(@ApplicationContext context: Context) :
+ UiModeManagerWrapper {
+ val uiModeManager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager?
+ override fun addContrastChangeListener(
+ executor: Executor,
+ listener: UiModeManager.ContrastChangeListener,
+ ) {
+ uiModeManager?.addContrastChangeListener(executor, listener)
+ }
+
+ override fun removeContrastChangeListener(listener: UiModeManager.ContrastChangeListener) {
+ uiModeManager?.removeContrastChangeListener(listener)
+ }
+
+ override fun getContrast(): Float? {
+ return uiModeManager?.contrast
+ }
+
+ override fun setNightModeActivated(isActive: Boolean) {
+ uiModeManager?.setNightModeActivated(isActive)
+ }
+}
diff --git a/src/com/android/wallpaper/system/UiModeManagerWrapper.kt b/src/com/android/wallpaper/system/UiModeManagerWrapper.kt
new file mode 100644
index 0000000..8dd419c
--- /dev/null
+++ b/src/com/android/wallpaper/system/UiModeManagerWrapper.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.system
+
+import android.app.UiModeManager.ContrastChangeListener
+import java.util.concurrent.Executor
+
+interface UiModeManagerWrapper {
+
+ fun addContrastChangeListener(executor: Executor, listener: ContrastChangeListener)
+
+ fun removeContrastChangeListener(listener: ContrastChangeListener)
+
+ fun getContrast(): Float?
+
+ fun setNightModeActivated(isActive: Boolean)
+}
diff --git a/src/com/android/wallpaper/util/DisplayUtils.kt b/src/com/android/wallpaper/util/DisplayUtils.kt
index fa1d879..35979a4 100644
--- a/src/com/android/wallpaper/util/DisplayUtils.kt
+++ b/src/com/android/wallpaper/util/DisplayUtils.kt
@@ -25,6 +25,7 @@
import android.view.Surface.ROTATION_270
import android.view.Surface.ROTATION_90
import com.android.systemui.shared.recents.utilities.Utilities
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import kotlin.math.min
/**
@@ -153,6 +154,17 @@
return smallestDisplay ?: largestDisplay
}
+ fun getCurrentDisplayType(activity: Activity): DeviceDisplayType {
+ if (!hasMultiInternalDisplays()) {
+ return DeviceDisplayType.SINGLE
+ }
+ return if (isOnWallpaperDisplay(activity)) {
+ DeviceDisplayType.UNFOLDED
+ } else {
+ DeviceDisplayType.FOLDED
+ }
+ }
+
private fun getRealArea(display: Display): Int {
val displayInfo = DisplayInfo()
display.getDisplayInfo(displayInfo)
@@ -169,7 +181,17 @@
return allDisplays.filter { it.type == Display.TYPE_INTERNAL }
}
- fun getInternalDisplaySizes(): List<Point> {
- return getInternalDisplays().map { getRealSize(it) }
+ fun getInternalDisplaySizes(
+ allDimensions: Boolean = false,
+ ): List<Point> {
+ return getInternalDisplays()
+ .map { getRealSize(it) }
+ .let {
+ if (allDimensions) {
+ it + it.map { size -> Point(size.y, size.x) }
+ } else {
+ it
+ }
+ }
}
}
diff --git a/src/com/android/wallpaper/util/PreviewUtils.kt b/src/com/android/wallpaper/util/PreviewUtils.kt
index cf1a1e5..8754c2c 100644
--- a/src/com/android/wallpaper/util/PreviewUtils.kt
+++ b/src/com/android/wallpaper/util/PreviewUtils.kt
@@ -24,6 +24,7 @@
import android.os.Bundle
import android.os.Handler
import android.os.Looper
+import android.os.Message
import android.text.TextUtils
import java.util.concurrent.Executors
@@ -95,6 +96,12 @@
}
}
+ /** Cleans up the preview on the renderer side */
+ fun cleanUp(workspaceCallback: Message?) {
+ // Send any message to clean up the corresponding preview on the renderer side.
+ workspaceCallback?.replyTo?.send(workspaceCallback)
+ }
+
/** Easy way to generate a Uri with the provider info from this class. */
fun getUri(path: String?): Uri {
return Uri.Builder()
diff --git a/src/com/android/wallpaper/util/WallpaperCropUtils.java b/src/com/android/wallpaper/util/WallpaperCropUtils.java
index 2fcc2fd..4e770b4 100755
--- a/src/com/android/wallpaper/util/WallpaperCropUtils.java
+++ b/src/com/android/wallpaper/util/WallpaperCropUtils.java
@@ -195,8 +195,7 @@
Point defaultCropSurfaceSize, Point targetHostSize, int scrollX, int scrollY,
boolean cropExtraWidth) {
BaseFlags flags = InjectorProvider.getInjector().getFlags();
- boolean isMultiCropEnabled =
- flags.isMultiCropPreviewUiEnabled() && flags.isMultiCropEnabled();
+ boolean isMultiCropEnabled = flags.isMultiCropEnabled();
// Calculate Rect of wallpaper in physical pixel terms (i.e., scaled to current zoom).
int scaledWallpaperWidth = Math.round(wallpaperSize.x * wallpaperZoom);
int scaledWallpaperHeight = Math.round(wallpaperSize.y * wallpaperZoom);
diff --git a/src/com/android/wallpaper/util/WallpaperXMLParser.kt b/src/com/android/wallpaper/util/WallpaperXMLParser.kt
new file mode 100644
index 0000000..271992a
--- /dev/null
+++ b/src/com/android/wallpaper/util/WallpaperXMLParser.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.util
+
+import android.content.Context
+import android.content.res.XmlResourceParser
+import android.util.Xml
+import com.android.wallpaper.model.LiveWallpaperInfo
+import com.android.wallpaper.model.SystemStaticWallpaperInfo
+import com.android.wallpaper.model.WallpaperCategory
+import com.android.wallpaper.model.WallpaperInfo
+import com.android.wallpaper.module.PartnerProvider
+import javax.inject.Inject
+import javax.inject.Singleton
+import org.xmlpull.v1.XmlPullParser
+
+/**
+ * Utility class for parsing an XML file containing information about a list of wallpapers. The
+ * logic in this class has been extracted into a separate class which uses dependency injection and
+ * was earlier present in a single method.
+ */
+@Singleton
+class WallpaperXMLParser
+@Inject
+constructor(private val context: Context, private val partnerProvider: PartnerProvider) {
+
+ fun parseCategory(parser: XmlResourceParser): WallpaperCategory? {
+ val categoryBuilder =
+ WallpaperCategory.Builder(partnerProvider.resources, Xml.asAttributeSet(parser))
+ categoryBuilder.setPriorityIfEmpty(PRIORITY_SYSTEM)
+ var publishedPlaceholder = false
+ val pair = parseXML(parser, parser.depth, categoryBuilder, false)
+ publishedPlaceholder = pair.first
+ val category = categoryBuilder.build()
+ return if (category.unmodifiableWallpapers.isNotEmpty()) category else null
+ }
+
+ private fun parseXML(
+ parser: XmlResourceParser,
+ categoryDepth: Int,
+ categoryBuilder: WallpaperCategory.Builder,
+ publishedPlaceholder: Boolean
+ ): Pair<Boolean, Int> {
+ var type1 = parser.eventType
+ var publishedPlaceholder1 = publishedPlaceholder
+ while (
+ parser.next().also { type1 = it } != XmlPullParser.END_TAG ||
+ parser.depth > categoryDepth
+ ) {
+ if (type1 == XmlPullParser.START_TAG) {
+ var wallpaper: WallpaperInfo? = null
+ if (SystemStaticWallpaperInfo.TAG_NAME == parser.name) {
+ wallpaper =
+ SystemStaticWallpaperInfo.fromAttributeSet(
+ partnerProvider.packageName,
+ categoryBuilder.id,
+ Xml.asAttributeSet(parser)
+ )
+ } else if (LiveWallpaperInfo.TAG_NAME == parser.name) {
+ wallpaper =
+ LiveWallpaperInfo.fromAttributeSet(
+ context,
+ categoryBuilder.id,
+ Xml.asAttributeSet(parser)
+ )
+ }
+ if (wallpaper != null) {
+ categoryBuilder.addWallpaper(wallpaper)
+ if (!publishedPlaceholder1) {
+ publishedPlaceholder1 = true
+ }
+ }
+ }
+ }
+ return Pair(publishedPlaceholder1, type1)
+ }
+
+ companion object {
+ private const val PRIORITY_SYSTEM = 100
+ }
+}
diff --git a/src/com/android/wallpaper/util/converter/WallpaperModelFactory.kt b/src/com/android/wallpaper/util/converter/WallpaperModelFactory.kt
index 7bd24e2..63a0113 100644
--- a/src/com/android/wallpaper/util/converter/WallpaperModelFactory.kt
+++ b/src/com/android/wallpaper/util/converter/WallpaperModelFactory.kt
@@ -20,6 +20,7 @@
import android.content.ComponentName
import android.content.Context
import android.util.Log
+import com.android.wallpaper.effects.EffectsController
import com.android.wallpaper.model.CreativeWallpaperInfo
import com.android.wallpaper.model.CurrentWallpaperInfo
import com.android.wallpaper.model.ImageWallpaperInfo
@@ -28,6 +29,7 @@
import com.android.wallpaper.picker.data.ColorInfo
import com.android.wallpaper.picker.data.CommonWallpaperData
import com.android.wallpaper.picker.data.CreativeWallpaperData
+import com.android.wallpaper.picker.data.CreativeWallpaperEffectsData
import com.android.wallpaper.picker.data.Destination
import com.android.wallpaper.picker.data.ImageWallpaperData
import com.android.wallpaper.picker.data.LiveWallpaperData
@@ -100,7 +102,10 @@
)
}
- fun LiveWallpaperInfo.getLiveWallpaperData(context: Context): LiveWallpaperData {
+ fun LiveWallpaperInfo.getLiveWallpaperData(
+ context: Context,
+ effectsController: EffectsController? = null
+ ): LiveWallpaperData {
val groupNameOfWallpaper = (this as? CreativeWallpaperInfo)?.groupName ?: ""
val wallpaperManager = WallpaperManager.getInstance(context)
val currentHomeWallpaper =
@@ -111,6 +116,10 @@
systemWallpaperInfo = info,
isTitleVisible = isVisibleTitle,
isApplied = isApplied(currentHomeWallpaper, currentLockWallpaper),
+ // TODO (331227828): don't relay on effectNames to determine if this is an effect
+ // live wallpaper
+ isEffectWallpaper = effectsController?.isEffectsWallpaper(info)
+ ?: (effectNames != null),
effectNames = effectNames,
)
}
@@ -126,6 +135,25 @@
description = description ?: "",
contentDescription = contentDescription,
isCurrent = isCurrent,
+ creativeWallpaperEffectsData = getCreativeWallpaperEffectData(),
+ )
+ }
+
+ private fun CreativeWallpaperInfo.getCreativeWallpaperEffectData():
+ CreativeWallpaperEffectsData? {
+ val effectsBottomSheetTitle =
+ effectsBottomSheetTitle.takeUnless { it.isNullOrEmpty() } ?: return null
+ val effectsBottomSheetSubtitle =
+ effectsBottomSheetSubtitle.takeUnless { it.isNullOrEmpty() } ?: return null
+ val clearActionsUri =
+ clearActionsUri.takeUnless { it?.scheme.isNullOrEmpty() } ?: return null
+ val effectsUri = effectsUri.takeUnless { it?.scheme.isNullOrEmpty() } ?: return null
+ return CreativeWallpaperEffectsData(
+ effectsBottomSheetTitle = effectsBottomSheetTitle,
+ effectsBottomSheetSubtitle = effectsBottomSheetSubtitle,
+ currentEffectId = currentlyAppliedEffectId ?: "",
+ clearActionUri = clearActionsUri,
+ effectsUri = effectsUri,
)
}
diff --git a/src/com/android/wallpaper/util/converter/category/CategoryFactory.kt b/src/com/android/wallpaper/util/converter/category/CategoryFactory.kt
index 9c55656..72edccb 100644
--- a/src/com/android/wallpaper/util/converter/category/CategoryFactory.kt
+++ b/src/com/android/wallpaper/util/converter/category/CategoryFactory.kt
@@ -57,11 +57,13 @@
private fun WallpaperCategory.getCollectionsCategoryData(
context: Context
- ): CollectionCategoryData? {
+ ): CollectionCategoryData {
val wallpaperModelList =
- wallpapers.map { wallpaperInfo ->
- wallpaperModelFactory.getWallpaperModel(context, wallpaperInfo)
- }
+ wallpapers
+ .map { wallpaperInfo ->
+ wallpaperModelFactory.getWallpaperModel(context, wallpaperInfo)
+ }
+ .toMutableList()
return CollectionCategoryData(
wallpaperModels = wallpaperModelList,
thumbAsset = thumbAsset,
diff --git a/src/com/android/wallpaper/util/wallpaperconnection/WallpaperConnectionUtils.kt b/src/com/android/wallpaper/util/wallpaperconnection/WallpaperConnectionUtils.kt
index fc344cb..0ac6014 100644
--- a/src/com/android/wallpaper/util/wallpaperconnection/WallpaperConnectionUtils.kt
+++ b/src/com/android/wallpaper/util/wallpaperconnection/WallpaperConnectionUtils.kt
@@ -1,31 +1,32 @@
package com.android.wallpaper.util.wallpaperconnection
import android.app.WallpaperInfo
+import android.app.WallpaperManager
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Matrix
import android.graphics.Point
+import android.net.Uri
import android.os.RemoteException
import android.service.wallpaper.IWallpaperEngine
import android.service.wallpaper.IWallpaperService
import android.service.wallpaper.WallpaperService
import android.util.Log
-import android.view.Display
+import android.view.MotionEvent
import android.view.SurfaceControl
import android.view.SurfaceView
-import android.view.View
+import com.android.app.tracing.TraceUtils.traceAsync
+import com.android.wallpaper.model.wallpaper.DeviceDisplayType
import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
-import com.android.wallpaper.picker.di.modules.MainDispatcher
-import com.android.wallpaper.util.ScreenSizeCalculator
import com.android.wallpaper.util.WallpaperConnection
import com.android.wallpaper.util.WallpaperConnection.WhichPreview
import com.android.wallpaper.util.wallpaperconnection.WallpaperConnectionUtils.getKey
import kotlinx.coroutines.CancellableContinuation
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@@ -40,80 +41,108 @@
// Note that when one wallpaper engine's render is mirrored to a new surface view, we call
// engine.mirrorSurfaceControl() and will have a new surface control instance.
private val surfaceControlMap = mutableMapOf<String, MutableList<SurfaceControl>>()
+ // Track the currently used creative wallpaper config preview URI to avoid unnecessary multiple
+ // update queries for the same preview.
+ private val creativeWallpaperConfigPreviewUriMap = mutableMapOf<String, Uri>()
private val mutex = Mutex()
/** Only call this function when the surface view is attached. */
suspend fun connect(
context: Context,
- @MainDispatcher mainScope: CoroutineScope,
wallpaperModel: LiveWallpaperModel,
whichPreview: WhichPreview,
destinationFlag: Int,
surfaceView: SurfaceView,
+ engineRenderingConfig: EngineRenderingConfig,
listener: WallpaperEngineConnection.WallpaperEngineConnectionListener? = null,
) {
val wallpaperInfo = wallpaperModel.liveWallpaperData.systemWallpaperInfo
- val engineKey = wallpaperInfo.getKey()
- val displayMetrics = getDisplayMetrics(surfaceView)
+ val engineDisplaySize = engineRenderingConfig.getEngineDisplaySize()
+ val engineKey = wallpaperInfo.getKey(engineDisplaySize)
- // Update the creative wallpaper uri before starting the service.
- wallpaperModel.creativeWallpaperData?.configPreviewUri?.let {
- context.contentResolver.update(it, ContentValues(), null)
- }
-
- if (!engineMap.containsKey(engineKey)) {
- mutex.withLock {
- if (!engineMap.containsKey(engineKey)) {
- engineMap[engineKey] =
- mainScope.async {
- initEngine(
- context,
- wallpaperModel.getWallpaperServiceIntent(),
- displayMetrics,
- destinationFlag,
- whichPreview,
- surfaceView,
- listener,
- )
+ traceAsync(TAG, "connect") {
+ // Update the creative wallpaper uri before starting the service.
+ wallpaperModel.creativeWallpaperData?.configPreviewUri?.let {
+ val uriKey = wallpaperInfo.getKey()
+ if (!creativeWallpaperConfigPreviewUriMap.containsKey(uriKey)) {
+ mutex.withLock {
+ if (!creativeWallpaperConfigPreviewUriMap.containsKey(uriKey)) {
+ context.contentResolver.update(it, ContentValues(), null)
+ creativeWallpaperConfigPreviewUriMap[uriKey] = it
}
+ }
}
}
- }
- engineMap[engineKey]?.await()?.let { (_, engineConnection) ->
- engineConnection.engine?.let {
- mirrorAndReparent(engineKey, it, surfaceView, displayMetrics)
+ if (!engineMap.containsKey(engineKey)) {
+ mutex.withLock {
+ if (!engineMap.containsKey(engineKey)) {
+ engineMap[engineKey] = coroutineScope {
+ async {
+ initEngine(
+ context,
+ wallpaperModel.getWallpaperServiceIntent(),
+ engineDisplaySize,
+ destinationFlag,
+ whichPreview,
+ surfaceView,
+ listener,
+ )
+ }
+ }
+ }
+ }
}
- }
- }
- private fun LiveWallpaperModel.getWallpaperServiceIntent(): Intent {
- return liveWallpaperData.systemWallpaperInfo.let {
- Intent(WallpaperService.SERVICE_INTERFACE).setClassName(it.packageName, it.serviceName)
+ engineMap[engineKey]?.await()?.let { (_, engineConnection) ->
+ engineConnection.engine?.let {
+ mirrorAndReparent(
+ engineKey,
+ it,
+ surfaceView,
+ engineRenderingConfig.getEngineDisplaySize(),
+ engineRenderingConfig.enforceSingleEngine,
+ )
+ }
+ }
}
}
suspend fun disconnect(
context: Context,
wallpaperModel: LiveWallpaperModel,
+ displaySize: Point,
) {
- val engineKey = wallpaperModel.liveWallpaperData.systemWallpaperInfo.getKey()
- if (engineMap.containsKey(engineKey)) {
- mutex.withLock {
- engineMap.remove(engineKey)?.await()?.let { (serviceConnection, engineConnection) ->
- engineConnection.engine?.destroy()
- engineConnection.removeListener()
- context.unbindService(serviceConnection)
+ val engineKey = wallpaperModel.liveWallpaperData.systemWallpaperInfo.getKey(displaySize)
+
+ traceAsync(TAG, "disconnect") {
+ if (engineMap.containsKey(engineKey)) {
+ mutex.withLock {
+ engineMap.remove(engineKey)?.await()?.let {
+ (serviceConnection, engineConnection) ->
+ engineConnection.engine?.destroy()
+ engineConnection.removeListener()
+ context.unbindService(serviceConnection)
+ }
}
}
- }
- if (surfaceControlMap.containsKey(engineKey)) {
- mutex.withLock {
- surfaceControlMap.remove(engineKey)?.let { surfaceControls ->
- surfaceControls.forEach { it.release() }
- surfaceControls.clear()
+ if (surfaceControlMap.containsKey(engineKey)) {
+ mutex.withLock {
+ surfaceControlMap.remove(engineKey)?.let { surfaceControls ->
+ surfaceControls.forEach { it.release() }
+ surfaceControls.clear()
+ }
+ }
+ }
+
+ val uriKey = wallpaperModel.liveWallpaperData.systemWallpaperInfo.getKey()
+ if (creativeWallpaperConfigPreviewUriMap.containsKey(uriKey)) {
+ mutex.withLock {
+ if (creativeWallpaperConfigPreviewUriMap.containsKey(uriKey)) {
+ creativeWallpaperConfigPreviewUriMap.remove(uriKey)
+ }
}
}
}
@@ -137,6 +166,53 @@
}
}
}
+
+ creativeWallpaperConfigPreviewUriMap.clear()
+ }
+
+ suspend fun dispatchTouchEvent(
+ wallpaperModel: LiveWallpaperModel,
+ engineRenderingConfig: EngineRenderingConfig,
+ event: MotionEvent,
+ ) {
+ val engine =
+ wallpaperModel.liveWallpaperData.systemWallpaperInfo
+ .getKey(engineRenderingConfig.getEngineDisplaySize())
+ .let { engineKey -> engineMap[engineKey]?.await()?.second?.engine }
+
+ if (engine != null) {
+ val action: Int = event.actionMasked
+ val dup = MotionEvent.obtainNoHistory(event).also { it.setLocation(event.x, event.y) }
+ val pointerIndex = event.actionIndex
+ try {
+ engine.dispatchPointer(dup)
+ if (action == MotionEvent.ACTION_UP) {
+ engine.dispatchWallpaperCommand(
+ WallpaperManager.COMMAND_TAP,
+ event.x.toInt(),
+ event.y.toInt(),
+ 0,
+ null
+ )
+ } else if (action == MotionEvent.ACTION_POINTER_UP) {
+ engine.dispatchWallpaperCommand(
+ WallpaperManager.COMMAND_SECONDARY_TAP,
+ event.getX(pointerIndex).toInt(),
+ event.getY(pointerIndex).toInt(),
+ 0,
+ null
+ )
+ }
+ } catch (e: RemoteException) {
+ Log.e(TAG, "Remote exception of wallpaper connection", e)
+ }
+ }
+ }
+
+ private fun LiveWallpaperModel.getWallpaperServiceIntent(): Intent {
+ return liveWallpaperData.systemWallpaperInfo.let {
+ Intent(WallpaperService.SERVICE_INTERFACE).setClassName(it.packageName, it.serviceName)
+ }
}
private suspend fun initEngine(
@@ -157,8 +233,13 @@
return Pair(serviceConnection, engineConnection)
}
- private fun WallpaperInfo.getKey(): String {
- return this.packageName.plus(":").plus(this.serviceName)
+ private fun WallpaperInfo.getKey(displaySize: Point? = null): String {
+ val keyWithoutSizeInformation = this.packageName.plus(":").plus(this.serviceName)
+ return if (displaySize != null) {
+ keyWithoutSizeInformation.plus(":").plus("${displaySize.x}x${displaySize.y}")
+ } else {
+ keyWithoutSizeInformation
+ }
}
private suspend fun bindWallpaperService(
@@ -195,7 +276,8 @@
engineKey: String,
engine: IWallpaperEngine,
parentSurface: SurfaceView,
- displayMetrics: Point
+ displayMetrics: Point,
+ enforceSingleEngine: Boolean,
) {
fun logError(e: Exception) {
Log.e(WallpaperConnection::class.simpleName, "Fail to reparent wallpaper surface", e)
@@ -211,10 +293,10 @@
SurfaceControl.Transaction().use { t ->
t.setMatrix(
wallpaperSurfaceControl,
- values[Matrix.MSCALE_X],
- values[Matrix.MSKEW_Y],
+ if (enforceSingleEngine) values[Matrix.MSCALE_Y] else values[Matrix.MSCALE_X],
values[Matrix.MSKEW_X],
- values[Matrix.MSCALE_Y]
+ values[Matrix.MSKEW_Y],
+ values[Matrix.MSCALE_Y],
)
t.reparent(wallpaperSurfaceControl, parentSurfaceControl)
t.show(wallpaperSurfaceControl)
@@ -256,9 +338,35 @@
return values
}
- private fun getDisplayMetrics(view: View): Point {
- val screenSizeCalculator = ScreenSizeCalculator.getInstance()
- val display: Display = view.display
- return screenSizeCalculator.getScreenSize(display)
+ data class EngineRenderingConfig(
+ val enforceSingleEngine: Boolean,
+ val deviceDisplayType: DeviceDisplayType,
+ val smallDisplaySize: Point,
+ val wallpaperDisplaySize: Point,
+ ) {
+ fun getEngineDisplaySize(): Point {
+ // If we need to enforce single engine, always return the larger screen's preview
+ return if (enforceSingleEngine) {
+ return wallpaperDisplaySize
+ } else {
+ getPreviewDisplaySize()
+ }
+ }
+
+ private fun getPreviewDisplaySize(): Point {
+ return when (deviceDisplayType) {
+ DeviceDisplayType.SINGLE -> wallpaperDisplaySize
+ DeviceDisplayType.FOLDED -> smallDisplaySize
+ DeviceDisplayType.UNFOLDED -> wallpaperDisplaySize
+ }
+ }
+ }
+
+ fun LiveWallpaperModel.shouldEnforceSingleEngine(): Boolean {
+ return when {
+ creativeWallpaperData != null -> false
+ liveWallpaperData.isEffectWallpaper -> false
+ else -> true // Only fallback to single engine rendering for legacy live wallpapers
+ }
}
}
diff --git a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionSelectionBottomSheetContent.kt b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionSelectionBottomSheetContent.kt
index 29377d5..57d9fce 100644
--- a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionSelectionBottomSheetContent.kt
+++ b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionSelectionBottomSheetContent.kt
@@ -60,7 +60,6 @@
// agreed upon.
// Forcing only one effect item for now
Arrays.asList(wallpaperActions.get(0)),
- clearActionsUri,
wallpaperEffectSwitchListener
)
)
diff --git a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionsToggleAdapter.kt b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionsToggleAdapter.kt
index b145a92..b131cf1 100644
--- a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionsToggleAdapter.kt
+++ b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperActionsToggleAdapter.kt
@@ -15,7 +15,6 @@
*/
package com.android.wallpaper.widget.floatingsheetcontent
-import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -31,7 +30,6 @@
*/
class WallpaperActionsToggleAdapter(
private val actionToggles: List<WallpaperAction>,
- private val clearToggle: Uri,
private val wallpaperEffectSwitchListener: WallpaperEffectSwitchListener
) : RecyclerView.Adapter<WallpaperActionsToggleAdapter.ViewHolder>() {
diff --git a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperEffectsView2.kt b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperEffectsView2.kt
index 3dadf54..ef52194 100644
--- a/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperEffectsView2.kt
+++ b/src/com/android/wallpaper/widget/floatingsheetcontent/WallpaperEffectsView2.kt
@@ -73,7 +73,7 @@
SUCCESS,
PROCESSING,
SHOW_DOWNLOAD_BUTTON,
- DOWNLOADING,
+ DOWNLOADING, // downloading of ml models in progress
}
/**
@@ -210,7 +210,6 @@
container?.visibility = INVISIBLE
downloadProgression?.visibility = INVISIBLE
downloadButtonLayout?.visibility = INVISIBLE
- downloadProgression?.visibility = INVISIBLE
}
private fun showFailedLayout(errorMessage: String?) {
@@ -220,7 +219,6 @@
container?.visibility = VISIBLE
downloadProgression?.visibility = INVISIBLE
downloadButtonLayout?.visibility = INVISIBLE
- downloadProgression?.visibility = INVISIBLE
}
private fun controlButtonByCode(view: View?, resultCode: Int?, mask: Int) {
diff --git a/src_override/com/android/wallpaper/module/AppModule.kt b/src_override/com/android/wallpaper/module/AppModule.kt
index 6cd5e4d..9d1a6ea 100644
--- a/src_override/com/android/wallpaper/module/AppModule.kt
+++ b/src_override/com/android/wallpaper/module/AppModule.kt
@@ -20,6 +20,8 @@
import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.preview.data.util.DefaultLiveWallpaperDownloader
import com.android.wallpaper.picker.preview.data.util.LiveWallpaperDownloader
+import com.android.wallpaper.system.UiModeManagerImpl
+import com.android.wallpaper.system.UiModeManagerWrapper
import com.android.wallpaper.util.converter.DefaultWallpaperModelFactory
import com.android.wallpaper.util.converter.WallpaperModelFactory
import dagger.Binds
@@ -47,6 +49,8 @@
impl: DefaultLiveWallpaperDownloader
): LiveWallpaperDownloader
+ @Binds @Singleton abstract fun bindUiModeManager(impl: UiModeManagerImpl): UiModeManagerWrapper
+
companion object {
@Provides
@Singleton
diff --git a/tests/common/src/com/android/wallpaper/testing/FakeUiModeManager.kt b/tests/common/src/com/android/wallpaper/testing/FakeUiModeManager.kt
new file mode 100644
index 0000000..649133d
--- /dev/null
+++ b/tests/common/src/com/android/wallpaper/testing/FakeUiModeManager.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 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.wallpaper.testing
+
+import android.app.UiModeManager.ContrastChangeListener
+import com.android.wallpaper.system.UiModeManagerWrapper
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class FakeUiModeManager @Inject constructor() : UiModeManagerWrapper {
+ val listeners = mutableListOf<ContrastChangeListener>()
+ private var _contrast: Float? = 0.0f
+
+ override fun addContrastChangeListener(
+ executor: Executor,
+ listener: ContrastChangeListener,
+ ) {
+ listeners.add(listener)
+ }
+
+ override fun removeContrastChangeListener(listener: ContrastChangeListener) {
+ listeners.remove(listener)
+ }
+
+ override fun getContrast(): Float? {
+ return _contrast
+ }
+
+ fun setContrast(contrast: Float?) {
+ _contrast = contrast
+ contrast?.let { v -> listeners.forEach { it.onContrastChanged(v) } }
+ }
+
+ override fun setNightModeActivated(isActive: Boolean) {
+ // no-op
+ }
+}
diff --git a/tests/common/src/com/android/wallpaper/testing/FakeWallpaperClient.kt b/tests/common/src/com/android/wallpaper/testing/FakeWallpaperClient.kt
index 58d83c6..bed547e 100644
--- a/tests/common/src/com/android/wallpaper/testing/FakeWallpaperClient.kt
+++ b/tests/common/src/com/android/wallpaper/testing/FakeWallpaperClient.kt
@@ -21,6 +21,7 @@
import android.graphics.Bitmap
import android.graphics.Point
import android.graphics.Rect
+import com.android.wallpaper.asset.Asset
import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint
import com.android.wallpaper.picker.customization.data.content.WallpaperClient
import com.android.wallpaper.picker.customization.shared.model.WallpaperDestination
@@ -28,7 +29,6 @@
import com.android.wallpaper.picker.data.WallpaperModel.LiveWallpaperModel
import com.android.wallpaper.picker.data.WallpaperModel.StaticWallpaperModel
import com.android.wallpaper.picker.preview.shared.model.FullPreviewCropModel
-import java.io.InputStream
import kotlin.math.min
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -89,9 +89,9 @@
setWallpaperEntryPoint: Int,
destination: WallpaperDestination,
wallpaperModel: StaticWallpaperModel,
- inputStream: InputStream?,
bitmap: Bitmap,
wallpaperSize: Point,
+ asset: Asset,
fullPreviewCropModels: Map<Point, FullPreviewCropModel>?,
) {
TODO("Not yet implemented")
diff --git a/tests/common/src/com/android/wallpaper/testing/TestInjector.kt b/tests/common/src/com/android/wallpaper/testing/TestInjector.kt
index 6e1321d..0d75080 100644
--- a/tests/common/src/com/android/wallpaper/testing/TestInjector.kt
+++ b/tests/common/src/com/android/wallpaper/testing/TestInjector.kt
@@ -266,7 +266,7 @@
}
override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
- if (getFlags().isMultiCropEnabled() && getFlags().isMultiCropPreviewUiEnabled()) {
+ if (getFlags().isMultiCropEnabled()) {
return injectedWallpaperInteractor
}
diff --git a/tests/common/src/com/android/wallpaper/testing/TestWallpaperPreferences.kt b/tests/common/src/com/android/wallpaper/testing/TestWallpaperPreferences.kt
index e7480cf..0ddfb26 100644
--- a/tests/common/src/com/android/wallpaper/testing/TestWallpaperPreferences.kt
+++ b/tests/common/src/com/android/wallpaper/testing/TestWallpaperPreferences.kt
@@ -84,7 +84,8 @@
private var mLockLiveWallpaperPrefMetadata: LiveWallpaperPrefMetadata? = null
private val mWallStoredColor: HashMap<String, String> = HashMap()
- private var hasPreviewTooltipBeenShown = true
+ private var hasSmallPreviewTooltipBeenShown = false
+ private var hasFullPreviewTooltipBeenShown = false
init {
wallpaperPresentationMode = WallpaperPreferences.PRESENTATION_MODE_STATIC
@@ -485,12 +486,20 @@
wallpaperModel: WallpaperModel.LiveWallpaperModel
) {}
- override fun setHasPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
- this.hasPreviewTooltipBeenShown = hasTooltipBeenShown
+ override fun setHasSmallPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
+ this.hasSmallPreviewTooltipBeenShown = hasTooltipBeenShown
}
- override fun getHasPreviewTooltipBeenShown(): Boolean {
- return hasPreviewTooltipBeenShown
+ override fun getHasSmallPreviewTooltipBeenShown(): Boolean {
+ return hasSmallPreviewTooltipBeenShown
+ }
+
+ override fun setHasFullPreviewTooltipBeenShown(hasTooltipBeenShown: Boolean) {
+ this.hasFullPreviewTooltipBeenShown = hasTooltipBeenShown
+ }
+
+ override fun getHasFullPreviewTooltipBeenShown(): Boolean {
+ return hasFullPreviewTooltipBeenShown
}
private fun setAppLaunchCount(count: Int) {
diff --git a/tests/common/src/com/android/wallpaper/testing/WallpaperModelUtils.kt b/tests/common/src/com/android/wallpaper/testing/WallpaperModelUtils.kt
index 4ec057f..22aee65 100644
--- a/tests/common/src/com/android/wallpaper/testing/WallpaperModelUtils.kt
+++ b/tests/common/src/com/android/wallpaper/testing/WallpaperModelUtils.kt
@@ -128,6 +128,7 @@
systemWallpaperInfo,
isTitleVisible,
isApplied,
+ effectNames != null,
effectNames
),
creativeWallpaperData = null,
diff --git a/tests/module/src/com/android/wallpaper/TestModule.kt b/tests/module/src/com/android/wallpaper/TestModule.kt
index 18b3a9f..d86f75b 100644
--- a/tests/module/src/com/android/wallpaper/TestModule.kt
+++ b/tests/module/src/com/android/wallpaper/TestModule.kt
@@ -22,6 +22,8 @@
import com.android.wallpaper.module.logging.UserEventLogger
import com.android.wallpaper.picker.preview.data.util.DefaultLiveWallpaperDownloader
import com.android.wallpaper.picker.preview.data.util.LiveWallpaperDownloader
+import com.android.wallpaper.system.UiModeManagerWrapper
+import com.android.wallpaper.testing.FakeUiModeManager
import com.android.wallpaper.testing.TestInjector
import com.android.wallpaper.testing.TestWallpaperPreferences
import com.android.wallpaper.util.converter.DefaultWallpaperModelFactory
@@ -54,4 +56,6 @@
abstract fun bindLiveWallpaperDownloader(
impl: DefaultLiveWallpaperDownloader
): LiveWallpaperDownloader
+
+ @Binds @Singleton abstract fun bindUiModeManager(impl: FakeUiModeManager): UiModeManagerWrapper
}
diff --git a/tests/robotests/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepositoryTest.kt b/tests/robotests/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepositoryTest.kt
index 26e8820..c63cfa9 100644
--- a/tests/robotests/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepositoryTest.kt
+++ b/tests/robotests/src/com/android/wallpaper/picker/preview/data/repository/WallpaperPreviewRepositoryTest.kt
@@ -98,18 +98,22 @@
@Test
fun dismissTooltip() {
- prefs.setHasPreviewTooltipBeenShown(false)
+ prefs.setHasSmallPreviewTooltipBeenShown(false)
+ prefs.setHasFullPreviewTooltipBeenShown(false)
underTest =
WallpaperPreviewRepository(
liveWallpaperDownloader = TestLiveWallpaperDownloader(null),
preferences = prefs,
bgDispatcher = testDispatcher,
)
- assertThat(underTest.hasTooltipBeenShown.value).isFalse()
+ assertThat(underTest.hasSmallPreviewTooltipBeenShown.value).isFalse()
+ assertThat(underTest.hasFullPreviewTooltipBeenShown.value).isFalse()
- underTest.dismissTooltip()
- assertThat(prefs.getHasPreviewTooltipBeenShown()).isTrue()
- assertThat(underTest.hasTooltipBeenShown.value).isTrue()
+ underTest.hideSmallPreviewTooltip()
+ assertThat(prefs.getHasSmallPreviewTooltipBeenShown()).isTrue()
+ assertThat(underTest.hasSmallPreviewTooltipBeenShown.value).isTrue()
+ assertThat(prefs.getHasFullPreviewTooltipBeenShown()).isFalse()
+ assertThat(underTest.hasFullPreviewTooltipBeenShown.value).isFalse()
}
@Test
@@ -195,6 +199,7 @@
systemWallpaperInfo = wallpaperInfo,
isTitleVisible = false,
isApplied = false,
+ isEffectWallpaper = false,
effectNames = null,
),
creativeWallpaperData = null,
diff --git a/tests/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivityTest.kt b/tests/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivityTest.kt
index 7778b91..fce9ed8 100644
--- a/tests/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivityTest.kt
+++ b/tests/src/com/android/wallpaper/picker/preview/ui/WallpaperPreviewActivityTest.kt
@@ -22,7 +22,6 @@
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
-import com.android.wallpaper.Flags.FLAG_MULTI_CROP_PREVIEW_UI_FLAG
import com.android.wallpaper.model.WallpaperInfo
import com.android.wallpaper.module.InjectorProvider
import com.android.wallpaper.testing.TestInjector
@@ -67,7 +66,7 @@
@Test
@Ignore("b/327241549")
- @EnableFlags(FLAG_MULTI_CROP_PREVIEW_UI_FLAG, FLAG_MULTI_CROP)
+ @EnableFlags(FLAG_MULTI_CROP)
fun showsNavHostFragment() {
val scenario: ActivityScenario<WallpaperPreviewActivity> =
ActivityScenario.launch(activityStartIntent)