Merge SP1A.210709.002
Change-Id: Iaa036c379d2b1c0e196fdecc1e4d3c4ddf6cabc6
diff --git a/Android.bp b/Android.bp
index 871e193..7e55969 100644
--- a/Android.bp
+++ b/Android.bp
@@ -27,11 +27,12 @@
static_libs: [
"androidx.appcompat_appcompat",
"androidx.cardview_cardview",
+ "androidx-constraintlayout_constraintlayout",
"androidx.exifinterface_exifinterface",
"androidx.lifecycle_lifecycle-runtime-ktx",
"androidx.recyclerview_recyclerview",
"androidx.slice_slice-view",
- "androidx-constraintlayout_constraintlayout",
+ "androidx.viewpager2_viewpager2",
"com.google.android.material_material",
"glide-prebuilt",
"kotlinx-coroutines-android",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5c020af..72d721d 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -91,7 +91,7 @@
<activity-alias
android:name="com.android.wallpaper.picker.CategoryPickerActivity"
- android:targetActivity="com.android.wallpaper.picker.TopLevelPickerActivity"
+ android:targetActivity="com.android.wallpaper.picker.CustomizationPickerActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
diff --git a/res/color-night/separated_tabs_indicator_color.xml b/res/color-night/separated_tabs_indicator_color.xml
new file mode 100644
index 0000000..7313a16
--- /dev/null
+++ b/res/color-night/separated_tabs_indicator_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <item android:color="?androidprv:attr/colorAccentSecondary" />
+</selector>
diff --git a/res/color-night/separated_tabs_text_color.xml b/res/color-night/separated_tabs_text_color.xml
new file mode 100644
index 0000000..8fb9488
--- /dev/null
+++ b/res/color-night/separated_tabs_text_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:color="?android:textColorPrimaryInverse"/>
+ <item android:state_enabled="false" android:color="?android:textColorTertiary"/>
+ <item android:color="?android:textColorSecondary"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/separated_tabs_indicator_color.xml b/res/color/separated_tabs_indicator_color.xml
new file mode 100644
index 0000000..cbce7d0
--- /dev/null
+++ b/res/color/separated_tabs_indicator_color.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+ <item android:color="?androidprv:attr/colorAccentPrimary" />
+</selector>
\ No newline at end of file
diff --git a/res/color/separated_tabs_text_color.xml b/res/color/separated_tabs_text_color.xml
new file mode 100644
index 0000000..96f3193
--- /dev/null
+++ b/res/color/separated_tabs_text_color.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:color="?android:textColorPrimary"/>
+ <item android:state_enabled="false" android:color="?android:textColorTertiary"/>
+ <item android:color="?android:textColorSecondary"/>
+</selector>
\ No newline at end of file
diff --git a/res/color/tab_text_color.xml b/res/color/tab_text_color.xml
deleted file mode 100644
index 70b364a..0000000
--- a/res/color/tab_text_color.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="false" android:color="?android:textColorTertiary"/>
- <item android:color="?android:textColorSecondary"/>
-</selector>
\ No newline at end of file
diff --git a/res/drawable/separated_tabs_indicator_background.xml b/res/drawable/separated_tabs_indicator_background.xml
index 942810a..05e52e5 100644
--- a/res/drawable/separated_tabs_indicator_background.xml
+++ b/res/drawable/separated_tabs_indicator_background.xml
@@ -15,11 +15,10 @@
limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:insetLeft="@dimen/separated_tabs_inset_horizontal"
android:insetRight="@dimen/separated_tabs_inset_horizontal">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorAccentPrimary" />
+ <solid android:color="@color/separated_tabs_indicator_color" />
<corners android:radius="@dimen/separated_tabs_corner_radius" />
</shape>
</inset>
diff --git a/res/drawable/separated_tabs_ripple_mask.xml b/res/drawable/separated_tabs_ripple_mask.xml
new file mode 100644
index 0000000..ad39a50
--- /dev/null
+++ b/res/drawable/separated_tabs_ripple_mask.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <inset
+ android:insetLeft="@dimen/separated_tabs_inset_horizontal"
+ android:insetRight="@dimen/separated_tabs_inset_horizontal">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/separated_tabs_corner_radius" />
+ <solid android:color="?android:colorControlHighlight" />
+ </shape>
+ </inset>
+ </item>
+</ripple>
diff --git a/res/layout/dialog_set_wallpaper.xml b/res/layout/dialog_set_wallpaper.xml
index 81d6253..f1102bd 100755
--- a/res/layout/dialog_set_wallpaper.xml
+++ b/res/layout/dialog_set_wallpaper.xml
@@ -19,6 +19,7 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="?androidprv:attr/colorSurface"
android:padding="@dimen/set_wallpaper_dialog_padding">
<LinearLayout
diff --git a/res/layout/dialog_set_wallpaper_title.xml b/res/layout/dialog_set_wallpaper_title.xml
index 9332021..3267939 100755
--- a/res/layout/dialog_set_wallpaper_title.xml
+++ b/res/layout/dialog_set_wallpaper_title.xml
@@ -14,8 +14,10 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:background="?androidprv:attr/colorSurface"
android:orientation="vertical">
<Space
@@ -36,9 +38,15 @@
<TextView
android:id="@+id/dialog_set_wallpaper_title"
android:layout_width="match_parent"
- android:layout_height="64dp"
+ android:layout_height="wrap_content"
+ android:fontFamily="@*android:string/config_headlineFontFamily"
+ android:minHeight="32dp"
android:textColor="?android:attr/textColorPrimary"
android:textSize="24sp"
android:gravity="center" />
+ <Space
+ android:layout_height="8dp"
+ android:layout_width="wrap_content" />
+
</LinearLayout>
diff --git a/res/layout/separated_tabs.xml b/res/layout/separated_tabs.xml
index 1445101..12603e0 100644
--- a/res/layout/separated_tabs.xml
+++ b/res/layout/separated_tabs.xml
@@ -14,21 +14,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.google.android.material.tabs.TabLayout
+<com.android.wallpaper.widget.SeparatedTabLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/separated_tabs"
android:layout_width="match_parent"
android:layout_height="@dimen/separated_tabs_height"
app:tabBackground="@drawable/separated_tabs_background"
- app:tabRippleColor="?android:colorControlHighlight"
app:tabIndicatorAnimationDuration="0"
app:tabIndicator="@drawable/separated_tabs_indicator_background"
- app:tabIndicatorColor="?androidprv:attr/colorAccentPrimary"
+ app:tabIndicatorColor="@color/separated_tabs_indicator_color"
app:tabIndicatorFullWidth="true"
app:tabIndicatorGravity="stretch"
app:tabGravity="fill"
- app:tabTextColor="@color/tab_text_color"
- app:tabSelectedTextColor="?android:textColorPrimary"
+ app:tabTextColor="@color/separated_tabs_text_color"
app:tabTextAppearance="@style/SeparatedTabsTextAppearance" />
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index e18c790..29ab0df 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -21,7 +21,7 @@
<!-- no translation found for app_name (8773648973927541493) -->
<skip />
<string name="select_wallpaper_label" msgid="6989581259339646085">"Wallpaper categories"</string>
- <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set Wallpaper"</string>
+ <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set wallpaper"</string>
<string name="set_wallpaper_progress_message" msgid="7986528287618716715">"Setting wallpaper…"</string>
<string name="try_again" msgid="8278874823700921234">"Try again"</string>
<string name="set_wallpaper_error_message" msgid="6819986999041085130">"Unable to set wallpaper."</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index e18c790..29ab0df 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -21,7 +21,7 @@
<!-- no translation found for app_name (8773648973927541493) -->
<skip />
<string name="select_wallpaper_label" msgid="6989581259339646085">"Wallpaper categories"</string>
- <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set Wallpaper"</string>
+ <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set wallpaper"</string>
<string name="set_wallpaper_progress_message" msgid="7986528287618716715">"Setting wallpaper…"</string>
<string name="try_again" msgid="8278874823700921234">"Try again"</string>
<string name="set_wallpaper_error_message" msgid="6819986999041085130">"Unable to set wallpaper."</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index e18c790..29ab0df 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -21,7 +21,7 @@
<!-- no translation found for app_name (8773648973927541493) -->
<skip />
<string name="select_wallpaper_label" msgid="6989581259339646085">"Wallpaper categories"</string>
- <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set Wallpaper"</string>
+ <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set wallpaper"</string>
<string name="set_wallpaper_progress_message" msgid="7986528287618716715">"Setting wallpaper…"</string>
<string name="try_again" msgid="8278874823700921234">"Try again"</string>
<string name="set_wallpaper_error_message" msgid="6819986999041085130">"Unable to set wallpaper."</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index e18c790..29ab0df 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -21,7 +21,7 @@
<!-- no translation found for app_name (8773648973927541493) -->
<skip />
<string name="select_wallpaper_label" msgid="6989581259339646085">"Wallpaper categories"</string>
- <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set Wallpaper"</string>
+ <string name="set_wallpaper_button_text" msgid="4426286890442731310">"Set wallpaper"</string>
<string name="set_wallpaper_progress_message" msgid="7986528287618716715">"Setting wallpaper…"</string>
<string name="try_again" msgid="8278874823700921234">"Try again"</string>
<string name="set_wallpaper_error_message" msgid="6819986999041085130">"Unable to set wallpaper."</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index a46d775..abca829 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -60,7 +60,7 @@
<string name="currently_set_lock_wallpaper_thumbnail" msgid="2094209303934569997">"हाल लक स्क्रिनमा सेट गरिएको वालपेपरको थम्बनेल"</string>
<string name="currently_set_wallpaper_thumbnail" msgid="8651887838745545107">"हाल सेट गरिएको वालपेपरको थम्बनेल"</string>
<string name="wallpaper_thumbnail" msgid="569931475923605974">"वालपेपरको थम्बनेल"</string>
- <string name="explore_home_screen" msgid="8756346794535765482">"गृह स्क्रिनको वालपेपरको अन्वेषण गर्नुहोस्"</string>
+ <string name="explore_home_screen" msgid="8756346794535765482">"होम स्क्रिनको वालपेपरको अन्वेषण गर्नुहोस्"</string>
<string name="explore_lock_screen" msgid="268938342103703665">"लक स्क्रिनको वालपेपरको अन्वेषण गर्नुहोस्"</string>
<string name="refresh_daily_wallpaper_home_content_description" msgid="2770445044556164259">"गृहपृष्ठको दैनिक वालपेपर पुनः ताजा गर्नुहोस्"</string>
<string name="refresh_daily_wallpaper_content_description" msgid="4362142658237147583">"दैनिक वालपेपर पुनः ताजा गर्नुहोस्"</string>
diff --git a/res/values-notnight-v27/styles.xml b/res/values-notnight-v27/styles.xml
index 72098f6..95c5ee5 100755
--- a/res/values-notnight-v27/styles.xml
+++ b/res/values-notnight-v27/styles.xml
@@ -44,5 +44,8 @@
<style name="LightDialogTheme" parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar">
<item name="android:layout">@layout/abc_alert_dialog_material</item>
<item name="windowActionBar">false</item>
+ <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
+ <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+ <item name="android:dialogCornerRadius">24dp</item>
</style>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1b773ba..8e13fb0 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -89,7 +89,7 @@
<dimen name="set_wallpaper_dialog_item_min_width">300dp</dimen>
<dimen name="set_wallpaper_dialog_item_outer_corner_radius">12dp</dimen>
<dimen name="set_wallpaper_dialog_item_inner_corner_radius">4dp</dimen>
- <dimen name="set_wallpaper_dialog_icon_size">24dp</dimen>
+ <dimen name="set_wallpaper_dialog_icon_size">32dp</dimen>
<!-- Dimensions for the "wallpaper disabled by administrator" UI. -->
<dimen name="wallpaper_disabled_asset_margin_bottom">26dp</dimen>
@@ -126,7 +126,7 @@
<!-- Dimensions for the "disabled by admin" UI in desktop mode. -->
<dimen name="disabled_by_admin_desktop_message_text_size">13sp</dimen>
- <dimen name="preview_bottom_sheet_corner_radius">?android:attr/dialogCornerRadius</dimen>
+ <dimen name="preview_bottom_sheet_corner_radius">12dp</dimen>
<!-- Dimensions for PreviewPager and PageIndicator. -->
<dimen name="preview_indicator_width">16dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 051ca4b..071792b 100755
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -88,6 +88,9 @@
<style name="LightDialogTheme" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
<item name="android:layout">@layout/abc_alert_dialog_material</item>
<item name="windowActionBar">false</item>
+ <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
+ <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
+ <item name="android:dialogCornerRadius">24dp</item>
</style>
<style name="ProgressDialogThemePreL" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
@@ -140,7 +143,7 @@
<!-- Studio can't directly reference ?androidprv:attr/textColorOnAccent here,
so we set the text color on the dialog items instead. -->
<style name="set_wallpaper_destination_item">
- <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
+ <item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
<item name="android:minHeight">@dimen/set_wallpaper_dialog_item_min_height</item>
<item name="android:minWidth">@dimen/set_wallpaper_dialog_item_min_width</item>
<item name="android:textAlignment">center</item>
diff --git a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
index 16bfffe..d97f598 100644
--- a/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
+++ b/src/com/android/wallpaper/picker/CustomizationPickerActivity.java
@@ -15,9 +15,11 @@
*/
package com.android.wallpaper.picker;
+import static com.android.wallpaper.util.ActivityUtils.isSUWMode;
+import static com.android.wallpaper.util.ActivityUtils.isWallpaperOnlyMode;
+
import android.app.Activity;
import android.content.Intent;
-import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
@@ -61,12 +63,7 @@
FragmentTransactionChecker, PermissionRequester, CategorySelectorFragmentHost,
IndividualPickerFragmentHost, WallpaperPreviewNavigator {
- public static final String WALLPAPER_FLAVOR_EXTRA =
- "com.android.launcher3.WALLPAPER_FLAVOR";
- public static final String WALLPAPER_FOCUS = "focus_wallpaper";
-
private static final String TAG = "CustomizationPickerActivity";
- private static final String WALLPAPER_ONLY = "wallpaper_only";
private WallpaperPickerDelegate mDelegate;
private UserEventLogger mUserEventLogger;
@@ -87,17 +84,11 @@
// Restore this Activity's state before restoring contained Fragments state.
super.onCreate(savedInstanceState);
- if (WALLPAPER_ONLY.equals(getIntent().getStringExtra(WALLPAPER_FLAVOR_EXTRA))
- || !supportCustomizationSections()) {
- skipToWallpaperPicker();
- return;
- }
-
setContentView(R.layout.activity_customization_picker);
mBottomActionBar = findViewById(R.id.bottom_actionbar);
// See go/pdr-edge-to-edge-guide.
- WindowCompat.setDecorFitsSystemWindows(getWindow(), /* decorFitsSystemWindows= */ false);
+ WindowCompat.setDecorFitsSystemWindows(getWindow(), isSUWMode(this));
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment == null) {
@@ -108,8 +99,10 @@
injector.getPreferences(this).incrementAppLaunched();
DailyLoggingAlarmScheduler.setAlarm(getApplicationContext());
- // Switch to the customization picker fragment.
- switchFragment(CustomizationPickerFragment.newInstance(getString(R.string.app_name)));
+ // Switch to the target fragment.
+ switchFragment(isWallpaperOnlyMode(getIntent())
+ ? WallpaperOnlyFragment.newInstance(getString(R.string.wallpaper_app_name))
+ : CustomizationPickerFragment.newInstance(getString(R.string.app_name)));
}
// Deep link case
@@ -146,8 +139,7 @@
protected void onResume() {
super.onResume();
mIsSafeToCommitFragmentTransaction = true;
- boolean wallpaperOnly =
- WALLPAPER_ONLY.equals(getIntent().getStringExtra(WALLPAPER_FLAVOR_EXTRA));
+ boolean wallpaperOnly = isWallpaperOnlyMode(getIntent());
boolean provisioned = Settings.Global.getInt(getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
@@ -171,38 +163,6 @@
}
@Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- if (WALLPAPER_ONLY.equals(intent.getStringExtra(WALLPAPER_FLAVOR_EXTRA))) {
- Log.d(TAG, "WALLPAPER_ONLY intent, reverting to Wallpaper Picker");
- skipToWallpaperPicker();
- }
- }
-
- private void skipToWallpaperPicker() {
- Intent intent = new Intent(this, TopLevelPickerActivity.class);
-
- if (getIntent() != null && getIntent().getExtras() != null) {
- intent.putExtras(getIntent().getExtras());
- }
-
- if (DeepLinkUtils.isDeepLink(getIntent())) {
- intent.setData(getIntent().getData());
- }
- startActivity(intent);
- finish();
- }
-
- private boolean supportCustomizationSections() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
- || "S".equals(Build.VERSION.CODENAME)) {
- return true;
- }
- Log.d(TAG, "Build version < S, customization sections feature is not supported");
- return false;
- }
-
- @Override
public void onBackPressed() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof BottomActionBarFragment
@@ -348,7 +308,11 @@
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (mDelegate.handleActivityResult(requestCode, resultCode, data)) {
- finishActivityWithResultOk();
+ if (isSUWMode(this)) {
+ finishActivityForSUW();
+ } else {
+ finishActivityWithResultOk();
+ }
}
}
@@ -361,6 +325,13 @@
LaunchUtils.launchHome(this);
}
+ private void finishActivityForSUW() {
+ overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
+ // Return RESULT_CANCELED to make the "Change wallpaper" tile in SUW not be disabled.
+ setResult(Activity.RESULT_CANCELED);
+ finish();
+ }
+
@Override
public BottomActionBar getBottomActionBar() {
return mBottomActionBar;
@@ -379,6 +350,6 @@
@Override
public boolean isUpArrowSupported() {
- return true;
+ return !isSUWMode(this);
}
}
diff --git a/src/com/android/wallpaper/picker/CustomizationPickerFragment.java b/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
index 9710f0f..8884c0e 100644
--- a/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
+++ b/src/com/android/wallpaper/picker/CustomizationPickerFragment.java
@@ -15,6 +15,7 @@
*/
package com.android.wallpaper.picker;
+import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
@@ -87,8 +88,21 @@
initSections(savedInstanceState);
mSectionControllers.forEach(controller ->
- sectionContainer.addView(controller.createView(getContext())));
- restoreViewState(savedInstanceState);
+ mNestedScrollView.post(() -> {
+ final Context context = getContext();
+ if (context == null) {
+ Log.w(TAG, "Adding section views with null context");
+ return;
+ }
+ sectionContainer.addView(controller.createView(context));
+ }
+ )
+ );
+ final Bundle savedInstanceStateRef = savedInstanceState;
+ // Post it to the end of adding views to ensure restoring view state the last task.
+ mNestedScrollView.post(() ->
+ restoreViewState(savedInstanceStateRef)
+ );
return view;
}
@@ -179,7 +193,7 @@
mSectionControllers.addAll(getAvailableSections(allSectionControllers));
}
- private List<CustomizationSectionController<?>> getAvailableSections (
+ protected List<CustomizationSectionController<?>> getAvailableSections(
List<CustomizationSectionController<?>> controllers) {
return controllers.stream()
.filter(controller -> {
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index 0ceaa3d..c41d394 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -38,6 +38,7 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
+import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
@@ -72,7 +73,6 @@
import com.android.wallpaper.widget.BottomActionBar;
import com.android.wallpaper.widget.BottomActionBar.AccessibilityCallback;
import com.android.wallpaper.widget.LockScreenPreviewer;
-import com.android.wallpaper.widget.WallpaperInfoView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
@@ -82,6 +82,8 @@
import java.io.ByteArrayOutputStream;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
@@ -93,10 +95,14 @@
private static final String TAG = "ImagePreviewFragment";
private static final float DEFAULT_WALLPAPER_MAX_ZOOM = 8f;
+ private static final Executor sExecutor = Executors.newCachedThreadPool();
private final WallpaperSurfaceCallback mWallpaperSurfaceCallback =
new WallpaperSurfaceCallback();
+ private final AtomicInteger mImageScaleChangeCounter = new AtomicInteger(0);
+ private final AtomicInteger mRecalculateColorCounter = new AtomicInteger(0);
+
private SubsamplingScaleImageView mFullResImageView;
private Asset mWallpaperAsset;
private Point mScreenSize;
@@ -105,8 +111,6 @@
private TouchForwardingLayout mTouchForwardingLayout;
private ConstraintLayout mContainer;
private SurfaceView mWallpaperSurface;
- private WallpaperInfoView mWallpaperInfoView;
- private AtomicInteger mImageScaleChangeCounter = new AtomicInteger(0);
protected SurfaceView mWorkspaceSurface;
protected WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
@@ -225,10 +229,8 @@
@Override
protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
super.onBottomActionBarReady(bottomActionBar);
- mWallpaperInfoView = (WallpaperInfoView)
- LayoutInflater.from(getContext()).inflate(
- R.layout.wallpaper_info_view, /* root= */null);
- mBottomActionBar.attachViewToBottomSheetAndBindAction(mWallpaperInfoView, INFORMATION);
+ mBottomActionBar.bindBottomSheetContentWithAction(
+ new WallpaperInfoContent(getContext()), INFORMATION);
mBottomActionBar.showActionsOnly(INFORMATION, EDIT, APPLY);
mBottomActionBar.setActionClickListener(APPLY, this::onSetWallpaperClicked);
@@ -255,8 +257,6 @@
});
mBottomActionBar.show();
- // Loads wallpaper info and populate into view.
- setUpExploreIntentAndLabel(this::populateWallpaperInfo);
// To avoid applying the wallpaper when the wallpaper's not parsed.
mBottomActionBar.disableActions();
// If the wallpaper is parsed, enable the bottom action bar.
@@ -350,25 +350,31 @@
new BitmapCropper.Callback() {
@Override
public void onBitmapCropped(Bitmap croppedBitmap) {
- boolean shouldRecycle = false;
- ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
- if (croppedBitmap.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) {
- byte[] outByteArray = tmpOut.toByteArray();
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
- Bitmap decodedPng = BitmapFactory.decodeByteArray(outByteArray, 0,
- outByteArray.length);
- croppedBitmap = decodedPng;
- }
- if (croppedBitmap.getConfig() == Bitmap.Config.HARDWARE) {
- croppedBitmap = croppedBitmap.copy(Bitmap.Config.ARGB_8888, false);
- shouldRecycle = true;
- }
- WallpaperColors colors = WallpaperColors.fromBitmap(croppedBitmap);
- if (shouldRecycle) {
- croppedBitmap.recycle();
- }
- onWallpaperColorsChanged(colors);
+ mRecalculateColorCounter.incrementAndGet();
+ sExecutor.execute(() -> {
+ boolean shouldRecycle = false;
+ ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
+ Bitmap cropped = croppedBitmap;
+ if (cropped.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) {
+ byte[] outByteArray = tmpOut.toByteArray();
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredColorSpace =
+ ColorSpace.get(ColorSpace.Named.SRGB);
+ cropped = BitmapFactory.decodeByteArray(outByteArray, 0,
+ outByteArray.length);
+ }
+ if (cropped.getConfig() == Bitmap.Config.HARDWARE) {
+ cropped = cropped.copy(Bitmap.Config.ARGB_8888, false);
+ shouldRecycle = true;
+ }
+ WallpaperColors colors = WallpaperColors.fromBitmap(cropped);
+ if (shouldRecycle) {
+ cropped.recycle();
+ }
+ if (mRecalculateColorCounter.decrementAndGet() == 0) {
+ Handler.getMain().post(() -> onWallpaperColorsChanged(colors));
+ }
+ });
}
@Override
@@ -378,17 +384,6 @@
});
}
- private void populateWallpaperInfo() {
- if (mWallpaperInfoView != null && mWallpaper != null) {
- mWallpaperInfoView.populateWallpaperInfo(
- mWallpaper,
- mActionLabel,
- WallpaperInfoHelper.shouldShowExploreButton(
- getContext(), mExploreIntent),
- this::onExploreClicked);
- }
- }
-
/**
* Makes the MosaicView visible with an alpha fade-in animation while fading out the loading
* indicator.
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index 8b8ed44..ec17767 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -31,6 +31,7 @@
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -73,9 +74,9 @@
import com.android.wallpaper.util.WallpaperSurfaceCallback;
import com.android.wallpaper.widget.BottomActionBar;
import com.android.wallpaper.widget.BottomActionBar.AccessibilityCallback;
+import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent;
import com.android.wallpaper.widget.LockScreenPreviewer;
import com.android.wallpaper.widget.WallpaperColorsLoader;
-import com.android.wallpaper.widget.WallpaperInfoView;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
@@ -101,7 +102,6 @@
* @see IWallpaperConnection
*/
protected WallpaperConnection mWallpaperConnection;
- protected WallpaperInfoView mWallpaperInfoView;
protected CardView mHomePreviewCard;
protected SurfaceView mWorkspaceSurface;
protected WallpaperSurfaceCallback mWallpaperSurfaceCallback;
@@ -164,17 +164,6 @@
Activity activity = requireActivity();
mScreenSize = ScreenSizeCalculator.getInstance().getScreenSize(
activity.getWindowManager().getDefaultDisplay());
-
- mWallpaperInfoView = (WallpaperInfoView) LayoutInflater.from(getContext())
- .inflate(R.layout.wallpaper_info_view, /* root= */ null);
- setUpExploreIntentAndLabel(
- () -> mWallpaperInfoView.populateWallpaperInfo(
- mWallpaper,
- mActionLabel,
- WallpaperInfoHelper.shouldShowExploreButton(getContext(), mExploreIntent),
- this::onExploreClicked)
- );
-
mPreviewContainer = view.findViewById(R.id.live_wallpaper_preview);
mTouchForwardingLayout = view.findViewById(R.id.touch_forwarding_layout);
// Set aspect ratio on the preview card.
@@ -271,7 +260,8 @@
@Override
public void onDestroyView() {
super.onDestroyView();
- if (mSettingsLiveData != null && mSettingsLiveData.hasObservers()) {
+ if (mSettingsLiveData != null && mSettingsLiveData.hasObservers()
+ && mSettingsSliceView != null) {
mSettingsLiveData.removeObserver(mSettingsSliceView);
mSettingsLiveData = null;
}
@@ -353,7 +343,8 @@
super.onBottomActionBarReady(bottomActionBar);
mBottomActionBar.showActionsOnly(INFORMATION, DELETE, EDIT, CUSTOMIZE, APPLY);
mBottomActionBar.setActionClickListener(APPLY, unused -> onSetWallpaperClicked(null));
- mBottomActionBar.attachViewToBottomSheetAndBindAction(mWallpaperInfoView, INFORMATION);
+ mBottomActionBar.bindBottomSheetContentWithAction(
+ new WallpaperInfoContent(getContext()), INFORMATION);
View separatedTabsContainer = getView().findViewById(R.id.separated_tabs_container);
// Update target view's accessibility param since it will be blocked by the bottom sheet
@@ -376,14 +367,9 @@
});
final Uri uriSettingsSlice = getSettingsSliceUri(mWallpaper.getWallpaperComponent());
if (uriSettingsSlice != null) {
- View previewPage = LayoutInflater.from(getContext())
- .inflate(R.layout.preview_customize_settings, null);
- mSettingsSliceView = previewPage.findViewById(R.id.settings_slice);
- mSettingsSliceView.setMode(SliceView.MODE_LARGE);
- mSettingsSliceView.setScrollable(false);
mSettingsLiveData = SliceLiveData.fromUri(requireContext(), uriSettingsSlice);
- mSettingsLiveData.observeForever(mSettingsSliceView);
- mBottomActionBar.attachViewToBottomSheetAndBindAction(previewPage, CUSTOMIZE);
+ mBottomActionBar.bindBottomSheetContentWithAction(
+ new PreviewCustomizeSettingsContent(getContext()), CUSTOMIZE);
} else {
if (mSettingsIntent != null) {
mBottomActionBar.setActionClickListener(CUSTOMIZE, listener ->
@@ -546,4 +532,35 @@
private boolean isPackagePreInstalled(ApplicationInfo info) {
return info != null && (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
+
+ private final class PreviewCustomizeSettingsContent extends BottomSheetContent<View> {
+
+ private PreviewCustomizeSettingsContent(Context context) {
+ super(context);
+ }
+
+ @Override
+ public int getViewId() {
+ return R.layout.preview_customize_settings;
+ }
+
+ @Override
+ public void onViewCreated(View previewPage) {
+ mSettingsSliceView = previewPage.findViewById(R.id.settings_slice);
+ mSettingsSliceView.setMode(SliceView.MODE_LARGE);
+ mSettingsSliceView.setScrollable(false);
+ if (mSettingsLiveData != null) {
+ mSettingsLiveData.observeForever(mSettingsSliceView);
+ }
+ }
+
+ @Override
+ public void onRecreateView(View oldPreviewPage) {
+ super.onRecreateView(oldPreviewPage);
+ if (mSettingsLiveData != null && mSettingsLiveData.hasObservers()
+ && mSettingsSliceView != null) {
+ mSettingsLiveData.removeObserver(mSettingsSliceView);
+ }
+ }
+ }
}
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index a94e1f6..74bdd6f 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -51,6 +51,8 @@
import com.android.wallpaper.module.WallpaperSetter;
import com.android.wallpaper.util.FullScreenAnimation;
import com.android.wallpaper.widget.BottomActionBar;
+import com.android.wallpaper.widget.BottomActionBar.BottomSheetContent;
+import com.android.wallpaper.widget.WallpaperInfoView;
import com.google.android.material.tabs.TabLayout;
@@ -119,11 +121,6 @@
private static final int UNUSED_REQUEST_CODE = 1;
private static final String TAG = "PreviewFragment";
- @PreviewMode
- protected int mPreviewMode;
-
- protected boolean mViewAsHome;
-
/**
* When true, enables a test mode of operation -- in which certain UI features are disabled to
* allow for UI tests to run correctly. Works around issue in ProgressDialog currently where the
@@ -136,13 +133,13 @@
protected WallpaperSetter mWallpaperSetter;
protected UserEventLogger mUserEventLogger;
protected BottomActionBar mBottomActionBar;
-
- protected Intent mExploreIntent;
- protected CharSequence mActionLabel;
-
// For full screen animations.
protected View mRootView;
protected FullScreenAnimation mFullScreenAnimation;
+ @PreviewMode protected int mPreviewMode;
+ protected boolean mViewAsHome;
+
+ private OnBackPressedCallback mOnBackPressedCallback;
/**
* Staged error dialog fragments that were unable to be shown when the hosting activity didn't
@@ -207,17 +204,34 @@
protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
super.onBottomActionBarReady(bottomActionBar);
mBottomActionBar = bottomActionBar;
- setBottomActionBarAndFullScreenActions();
- }
-
- private void setBottomActionBarAndFullScreenActions() {
mBottomActionBar.setActionClickListener(EDIT, (view) -> {
mFullScreenAnimation.startAnimation(/* toFullScreen= */ true);
mBottomActionBar.deselectAction(EDIT);
});
+ setFullScreenActions(mRootView.findViewById(R.id.fullscreen_buttons_container));
+ if (mOnBackPressedCallback == null) {
+ mOnBackPressedCallback = new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ if (mFullScreenAnimation.isFullScreen()) {
+ mFullScreenAnimation.startAnimation(/* toFullScreen= */ false);
+ return;
+ }
+ if (mBottomActionBar != null && !mBottomActionBar.isBottomSheetCollapsed()) {
+ mBottomActionBar.collapseBottomSheetIfExpanded();
+ return;
+ }
+ getActivity().finish();
+ }
+ };
+ getActivity().getOnBackPressedDispatcher().addCallback(this, mOnBackPressedCallback);
+ }
+ }
+
+ protected void setFullScreenActions(View container) {
// Update the button text for the current workspace visibility.
- Button hideUiPreviewButton = mRootView.findViewById(R.id.hide_ui_preview_button);
+ Button hideUiPreviewButton = container.findViewById(R.id.hide_ui_preview_button);
hideUiPreviewButton.setText(mFullScreenAnimation.getWorkspaceVisibility()
? R.string.hide_ui_preview_text
: R.string.show_ui_preview_text);
@@ -231,28 +245,10 @@
mFullScreenAnimation.setWorkspaceVisibility(!visible);
}
);
- mRootView.findViewById(R.id.set_as_wallpaper_button).setOnClickListener(
- this::onSetWallpaperClicked
- );
+ container.findViewById(R.id.set_as_wallpaper_button).setOnClickListener(
+ this::onSetWallpaperClicked);
mFullScreenAnimation.ensureBottomActionBarIsCorrectlyLocated();
-
- OnBackPressedCallback callback = new OnBackPressedCallback(true) {
- @Override
- public void handleOnBackPressed() {
- if (mFullScreenAnimation.isFullScreen()) {
- mFullScreenAnimation.startAnimation(/* toFullScreen= */ false);
- return;
- }
- if (mBottomActionBar != null && !mBottomActionBar.isBottomSheetCollapsed()) {
- mBottomActionBar.collapseBottomSheetIfExpanded();
- return;
- }
- getActivity().finish();
- }
- };
-
- getActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
protected List<String> getAttributions(Context context) {
@@ -290,23 +286,6 @@
}
}
- protected void setUpExploreIntentAndLabel(@Nullable Runnable callback) {
- Context context = getContext();
- if (context == null) {
- return;
- }
-
- WallpaperInfoHelper.loadExploreIntent(context, mWallpaper,
- (actionLabel, exploreIntent) -> {
- mActionLabel = actionLabel;
- mExploreIntent = exploreIntent;
- if (callback != null) {
- callback.run();
- }
- }
- );
- }
-
protected abstract boolean isLoaded();
@Override
@@ -348,20 +327,9 @@
mWallpaper instanceof LiveWallpaperInfo);
}
- protected void onExploreClicked(View button) {
- if (getContext() == null) {
- return;
- }
- Context context = getContext();
- mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context),
- mWallpaper.getActionLabelRes(context));
-
- startActivity(mExploreIntent);
- }
-
protected void setUpTabs(TabLayout tabs) {
- tabs.addTab(tabs.newTab().setText(getContext().getString(R.string.home_screen_message)));
- tabs.addTab(tabs.newTab().setText(getContext().getString(R.string.lock_screen_message)));
+ tabs.addTab(tabs.newTab().setText(R.string.home_screen_message));
+ tabs.addTab(tabs.newTab().setText(R.string.lock_screen_message));
tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
@@ -454,4 +422,70 @@
return getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL;
}
+
+ protected final class WallpaperInfoContent extends BottomSheetContent<WallpaperInfoView> {
+
+ @Nullable private Intent mExploreIntent;
+ private CharSequence mActionLabel;
+
+ protected WallpaperInfoContent(Context context) {
+ super(context);
+ }
+
+ @Override
+ public int getViewId() {
+ return R.layout.wallpaper_info_view;
+ }
+
+ @Override
+ public void onViewCreated(WallpaperInfoView view) {
+ if (mWallpaper == null) {
+ return;
+ }
+
+ if (mActionLabel == null) {
+ setUpExploreIntentAndLabel(() -> populateWallpaperInfo(view));
+ } else {
+ populateWallpaperInfo(view);
+ }
+ }
+
+ private void setUpExploreIntentAndLabel(@Nullable Runnable callback) {
+ Context context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ WallpaperInfoHelper.loadExploreIntent(context, mWallpaper,
+ (actionLabel, exploreIntent) -> {
+ mActionLabel = actionLabel;
+ mExploreIntent = exploreIntent;
+ if (callback != null) {
+ callback.run();
+ }
+ }
+ );
+ }
+
+ private void onExploreClicked(View button) {
+ Context context = getContext();
+ if (context == null) {
+ return;
+ }
+
+ mUserEventLogger.logActionClicked(mWallpaper.getCollectionId(context),
+ mWallpaper.getActionLabelRes(context));
+
+ startActivity(mExploreIntent);
+ }
+
+ private void populateWallpaperInfo(WallpaperInfoView view) {
+ view.populateWallpaperInfo(
+ mWallpaper,
+ mActionLabel,
+ WallpaperInfoHelper.shouldShowExploreButton(
+ getContext(), mExploreIntent),
+ this::onExploreClicked);
+ }
+ }
}
diff --git a/src/com/android/wallpaper/picker/WallpaperOnlyFragment.java b/src/com/android/wallpaper/picker/WallpaperOnlyFragment.java
new file mode 100644
index 0000000..b59b853
--- /dev/null
+++ b/src/com/android/wallpaper/picker/WallpaperOnlyFragment.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wallpaper.picker;
+
+import com.android.wallpaper.model.CustomizationSectionController;
+import com.android.wallpaper.model.WallpaperSectionController;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** The Fragment UI for wallpaper only section. */
+public class WallpaperOnlyFragment extends CustomizationPickerFragment {
+
+ /** Initiates WallpaperOnlyFragment instance. */
+ public static WallpaperOnlyFragment newInstance(CharSequence title) {
+ WallpaperOnlyFragment fragment = new WallpaperOnlyFragment();
+ fragment.setArguments(AppbarFragment.createArguments(title));
+ return fragment;
+ }
+
+ @Override
+ protected List<CustomizationSectionController<?>> getAvailableSections(
+ List<CustomizationSectionController<?>> controllers) {
+ List<CustomizationSectionController<?>> wallpaperOnlySections = controllers.stream()
+ .filter(controller -> controller instanceof WallpaperSectionController)
+ .collect(Collectors.toList());
+ return super.getAvailableSections(wallpaperOnlySections);
+ }
+}
diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
index 97c2eaa..a7d1f5c 100755
--- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
+++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
@@ -582,6 +582,9 @@
if (mCategory == null) {
return;
}
+ if (getContext() == null) {
+ return;
+ }
// Wallpaper count could change, so we may need to change the layout(2 or 3 columns layout)
GridLayoutManager gridLayoutManager = (GridLayoutManager) mImageGrid.getLayoutManager();
diff --git a/src/com/android/wallpaper/util/ActivityUtils.java b/src/com/android/wallpaper/util/ActivityUtils.java
index eb2adb2..1fccd2f 100755
--- a/src/com/android/wallpaper/util/ActivityUtils.java
+++ b/src/com/android/wallpaper/util/ActivityUtils.java
@@ -97,4 +97,14 @@
context.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, SUW_COMPLETE)
== SUW_NOT_YET);
}
+
+ /**
+ * Returns true if it's wallpaper only mode.
+ *
+ * @param intent activity intent.
+ */
+ public static boolean isWallpaperOnlyMode(Intent intent) {
+ return "wallpaper_only".equals(
+ intent.getStringExtra("com.android.launcher3.WALLPAPER_FLAVOR"));
+ }
}
\ No newline at end of file
diff --git a/src/com/android/wallpaper/widget/BottomActionBar.java b/src/com/android/wallpaper/widget/BottomActionBar.java
index 8c0169b..c20d578 100644
--- a/src/com/android/wallpaper/widget/BottomActionBar.java
+++ b/src/com/android/wallpaper/widget/BottomActionBar.java
@@ -28,6 +28,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.ImageViewCompat;
@@ -96,6 +97,52 @@
void onBottomSheetExpanded();
}
+ /**
+ * Object to host content view for bottom sheet to display.
+ *
+ * <p> The view would be created in the constructor.
+ */
+ public static abstract class BottomSheetContent<T extends View> {
+
+ private T mContentView;
+ private boolean mIsVisible;
+
+ public BottomSheetContent(Context context) {
+ mContentView = createView(context);
+ setVisibility(false);
+ }
+
+ /** Gets the view id to inflate. */
+ @LayoutRes
+ public abstract int getViewId();
+
+ /** Gets called when the content view is created. */
+ public abstract void onViewCreated(T view);
+
+ /** Gets called when the current content view is going to recreate. */
+ public void onRecreateView(T oldView) {}
+
+ private void recreateView(Context context) {
+ // Inform that the view is going to recreate.
+ onRecreateView(mContentView);
+ // Create a new view with the given context.
+ mContentView = createView(context);
+ setVisibility(mIsVisible);
+ }
+
+ private T createView(Context context) {
+ T contentView = (T) LayoutInflater.from(context).inflate(getViewId(), null);
+ onViewCreated(contentView);
+ contentView.setFocusable(true);
+ return contentView;
+ }
+
+ private void setVisibility(boolean isVisible) {
+ mIsVisible = isVisible;
+ mContentView.setVisibility(mIsVisible ? VISIBLE : GONE);
+ }
+ }
+
// TODO(b/154299462): Separate downloadable related actions from WallpaperPicker.
/** The action items in the bottom action bar. */
public enum BottomAction {
@@ -103,7 +150,8 @@
}
private final Map<BottomAction, View> mActionMap = new EnumMap<>(BottomAction.class);
- private final Map<BottomAction, View> mContentViewMap = new EnumMap<>(BottomAction.class);
+ private final Map<BottomAction, BottomSheetContent<?>> mContentViewMap =
+ new EnumMap<>(BottomAction.class);
private final Map<BottomAction, OnActionSelectedListener> mActionSelectedListeners =
new EnumMap<>(BottomAction.class);
@@ -185,17 +233,16 @@
}
/**
- * Adds content view to the bottom sheet and binds with a {@code BottomAction} to
- * expand / collapse the bottom sheet.
+ * Binds the {@code bottomSheetContent} with the {@code action}, the {@code action} button
+ * would be able to expand/collapse the bottom sheet to show the content.
*
- * @param contentView the view with content to be added on the bottom sheet
+ * @param bottomSheetContent the content object with view being added to the bottom sheet
* @param action the action to be bound to expand / collapse the bottom sheet
*/
- public void attachViewToBottomSheetAndBindAction(View contentView, BottomAction action) {
- contentView.setVisibility(GONE);
- contentView.setFocusable(true);
- mContentViewMap.put(action, contentView);
- mBottomSheetView.addView(contentView);
+ public void bindBottomSheetContentWithAction(BottomSheetContent<?> bottomSheetContent,
+ BottomAction action) {
+ mContentViewMap.put(action, bottomSheetContent);
+ mBottomSheetView.addView(bottomSheetContent.mContentView);
setActionClickListener(action, actionView -> {
if (mBottomSheetBehavior.getState() == STATE_COLLAPSED) {
updateContentViewFor(action);
@@ -467,8 +514,18 @@
/** Dynamic update color with {@code Context}. */
public void setColor(Context context) {
+ // Set bottom sheet background.
mBottomSheetView.setBackground(context.getDrawable(R.drawable.bottom_sheet_background));
+ if (mBottomSheetView.getChildCount() > 0) {
+ // Update the bottom sheet content view if any.
+ mBottomSheetView.removeAllViews();
+ mContentViewMap.values().forEach(bottomSheetContent -> {
+ bottomSheetContent.recreateView(context);
+ mBottomSheetView.addView(bottomSheetContent.mContentView);
+ });
+ }
+ // Set the bar background and action buttons.
ViewGroup actionTabs = findViewById(R.id.action_tabs);
actionTabs.setBackgroundColor(
ResourceUtils.getColorAttr(context, android.R.attr.colorBackground));
@@ -507,7 +564,7 @@
}
private void updateContentViewFor(BottomAction action) {
- mContentViewMap.forEach((a, v) -> v.setVisibility(a.equals(action) ? VISIBLE : GONE));
+ mContentViewMap.forEach((a, content) -> content.setVisibility(a.equals(action)));
}
private boolean isExpandable(BottomAction action) {
diff --git a/src/com/android/wallpaper/widget/SeparatedTabLayout.java b/src/com/android/wallpaper/widget/SeparatedTabLayout.java
new file mode 100644
index 0000000..8642485
--- /dev/null
+++ b/src/com/android/wallpaper/widget/SeparatedTabLayout.java
@@ -0,0 +1,118 @@
+package com.android.wallpaper.widget;
+
+import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_DRAGGING;
+import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_IDLE;
+import static androidx.viewpager2.widget.ViewPager2.SCROLL_STATE_SETTLING;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.viewpager2.widget.ViewPager2;
+import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback;
+
+import com.android.wallpaper.R;
+
+import com.google.android.material.tabs.TabLayout;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Custom {@link TabLayout} for separated tabs.
+ *
+ * <p>Don't use {@code TabLayoutMediator} for the tab layout, which binds the tab scrolling
+ * animation that is unwanted for the separated tab design. Uses {@link
+ * SeparatedTabLayout#setViewPager} to bind a {@link ViewPager2} to use the proper tab effect.
+ */
+public final class SeparatedTabLayout extends TabLayout {
+
+ public SeparatedTabLayout(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ @NonNull
+ public Tab newTab() {
+ Tab tab = super.newTab();
+ tab.view.setBackgroundResource(R.drawable.separated_tabs_ripple_mask);
+ return tab;
+ }
+
+ /** Binds the given {@code viewPager} to the {@link SeparatedTabLayout}. */
+ public void setViewPager(ViewPager2 viewPager) {
+ viewPager.registerOnPageChangeCallback(new SeparatedTabLayoutOnPageChangeCallback(this));
+ addOnTabSelectedListener(new SeparatedTabLayoutOnTabSelectedListener(viewPager));
+ }
+
+ private static class SeparatedTabLayoutOnTabSelectedListener implements
+ OnTabSelectedListener {
+ private final WeakReference<ViewPager2> mViewPagerRef;
+
+ private SeparatedTabLayoutOnTabSelectedListener(ViewPager2 viewPager) {
+ mViewPagerRef = new WeakReference<>(viewPager);
+ }
+
+ @Override
+ public void onTabSelected(Tab tab) {
+ ViewPager2 viewPager = mViewPagerRef.get();
+ if (viewPager != null && viewPager.getCurrentItem() != tab.getPosition()) {
+ viewPager.setCurrentItem(tab.getPosition());
+ }
+ }
+
+ @Override
+ public void onTabUnselected(Tab tab) {}
+
+ @Override
+ public void onTabReselected(Tab tab) {}
+ }
+
+ private static class SeparatedTabLayoutOnPageChangeCallback extends OnPageChangeCallback {
+ private final WeakReference<TabLayout> mTabLayoutRef;
+ private int mPreviousScrollState = SCROLL_STATE_IDLE;
+ private int mScrollState = SCROLL_STATE_IDLE;
+
+ private SeparatedTabLayoutOnPageChangeCallback(TabLayout tabLayout) {
+ mTabLayoutRef = new WeakReference<>(tabLayout);
+ }
+
+ @Override
+ public void onPageSelected(final int position) {
+ if (isUserDragging()) {
+ // Don't update tab position here, wait for page scrolling done to update the tabs.
+ return;
+ }
+ // ViewPager2#setCurrentItem would run into here.
+ updateTabPositionIfNeeded(position);
+ }
+
+ @Override
+ public void onPageScrollStateChanged(final int state) {
+ mPreviousScrollState = mScrollState;
+ mScrollState = state;
+ }
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ // Update the tab when the scrolling page is full displayed and is user dragging case.
+ if (positionOffset == 0f && isUserDragging()) {
+ updateTabPositionIfNeeded(position);
+ }
+ }
+
+ private boolean isUserDragging() {
+ return mPreviousScrollState == SCROLL_STATE_DRAGGING
+ && mScrollState == SCROLL_STATE_SETTLING;
+ }
+
+ private void updateTabPositionIfNeeded(int position) {
+ TabLayout tabLayout = mTabLayoutRef.get();
+ if (tabLayout != null
+ && tabLayout.getSelectedTabPosition() != position
+ && position < tabLayout.getTabCount()) {
+ tabLayout.selectTab(tabLayout.getTabAt(position), /* updateIndicator= */ true);
+ }
+ }
+ }
+}