Merge "Reorder function names (2/3)" into main
diff --git a/res/layout/clock_color_option_noop_item.xml b/res/layout/clock_color_list_placeholder.xml
similarity index 77%
rename from res/layout/clock_color_option_noop_item.xml
rename to res/layout/clock_color_list_placeholder.xml
index a4ea877..d7912c1 100644
--- a/res/layout/clock_color_option_noop_item.xml
+++ b/res/layout/clock_color_list_placeholder.xml
@@ -13,23 +13,25 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<!-- Content description is set programmatically on the parent FrameLayout -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:orientation="vertical">
+
<include
layout="@layout/color_option"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size" />
+
<View
android:layout_width="match_parent"
- android:layout_height="4dp"/>
+ android:layout_height="@dimen/floating_sheet_list_item_vertical_space"/>
+
<include
layout="@layout/color_option"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size" />
</LinearLayout>
diff --git a/res/layout/clock_color_option_noop_item.xml b/res/layout/clock_style_list_placeholder.xml
similarity index 63%
copy from res/layout/clock_color_option_noop_item.xml
copy to res/layout/clock_style_list_placeholder.xml
index a4ea877..48ef9a8 100644
--- a/res/layout/clock_color_option_noop_item.xml
+++ b/res/layout/clock_style_list_placeholder.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!--
- Copyright (C) 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,23 +13,25 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<!-- Content description is set programmatically on the parent FrameLayout -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:orientation="vertical">
+
<include
- layout="@layout/color_option"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ layout="@layout/clock_style_option"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size" />
+
<View
android:layout_width="match_parent"
- android:layout_height="4dp"/>
+ android:layout_height="@dimen/floating_sheet_list_item_vertical_space"/>
+
<include
- layout="@layout/color_option"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ layout="@layout/clock_style_option"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size" />
</LinearLayout>
diff --git a/res/layout/clock_style_option.xml b/res/layout/clock_style_option.xml
new file mode 100644
index 0000000..fd72e85
--- /dev/null
+++ b/res/layout/clock_style_option.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<!-- Content description is set programmatically on the parent FrameLayout -->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/floating_sheet_clock_style_option_size"
+ android:layout_height="@dimen/floating_sheet_clock_style_option_size">
+
+ <ImageView
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@+id/foreground"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="@dimen/floating_sheet_clock_style_thumbnail_margin" />
+</FrameLayout>
+
diff --git a/res/layout/floating_sheet_clock.xml b/res/layout/floating_sheet_clock.xml
index 4f114a6..bc77300 100644
--- a/res/layout/floating_sheet_clock.xml
+++ b/res/layout/floating_sheet_clock.xml
@@ -29,12 +29,35 @@
android:clipToPadding="false"
android:clipChildren="false">
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/clock_list"
+ <FrameLayout
+ android:id="@+id/clock_floating_sheet_style_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"/>
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <!--
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/clock_style_list_placeholder"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible" />
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_style_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false"
+ android:clipToPadding="false"/>
+ </FrameLayout>
<LinearLayout
@@ -46,7 +69,6 @@
android:clipChildren="false">
<FrameLayout
- android:id="@+id/clock_color_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
@@ -54,16 +76,16 @@
android:layout_marginBottom="12dp">
<!--
- This is an invisible placeholder put in place so that the parent keeps its height
- stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
- the layout logic to keep the size of the preview container stable as well, which
- bodes well for setting up the SurfaceView for remote rendering without changing its
- size after the content is loaded into the RecyclerView.
+ This is an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows
+ the layout logic to keep the size of the preview container stable as well, which
+ bodes well for setting up the SurfaceView for remote rendering without changing its
+ size after the content is loaded into the RecyclerView.
- It's critical for any TextViews inside the included layout to have text.
- -->
+ It's critical for any TextViews inside the included layout to have text.
+ -->
<include
- layout="@layout/clock_color_option_noop_item"
+ layout="@layout/clock_color_list_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
@@ -74,8 +96,6 @@
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false" />
-
-
</FrameLayout>
@@ -162,4 +182,4 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginVertical="@dimen/floating_sheet_tab_toolbar_vertical_margin" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 7d24e3f..ed9b816 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -184,4 +184,6 @@
<dimen name="floating_sheet_list_item_vertical_space">4dp</dimen>
<dimen name="floating_sheet_clock_size_icon_size">80dp</dimen>
<dimen name="floating_sheet_clock_size_icon_margin_bottom">8dp</dimen>
+ <dimen name="floating_sheet_clock_style_option_size">82dp</dimen>
+ <dimen name="floating_sheet_clock_style_thumbnail_margin">12dp</dimen>
</resources>
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index 33cb620..e9b7b2d 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -19,6 +19,7 @@
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor;
import com.android.customization.picker.color.ui.section.ColorSectionController;
import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel;
+import com.android.customization.picker.grid.domain.interactor.GridInteractor;
import com.android.customization.picker.grid.ui.section.GridSectionController;
import com.android.customization.picker.notifications.ui.section.NotificationSectionController;
import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel;
@@ -61,6 +62,7 @@
private final ClockViewFactory mClockViewFactory;
private final ThemedIconSnapshotRestorer mThemedIconSnapshotRestorer;
private final ThemedIconInteractor mThemedIconInteractor;
+ private final GridInteractor mGridInteractor;
private final ColorPickerInteractor mColorPickerInteractor;
private final ThemesUserEventLogger mThemesUserEventLogger;
@@ -75,6 +77,7 @@
ClockViewFactory clockViewFactory,
ThemedIconSnapshotRestorer themedIconSnapshotRestorer,
ThemedIconInteractor themedIconInteractor,
+ GridInteractor gridInteractor,
ColorPickerInteractor colorPickerInteractor,
ThemesUserEventLogger themesUserEventLogger) {
mColorPickerViewModelFactory = colorPickerViewModelFactory;
@@ -86,6 +89,7 @@
mClockViewFactory = clockViewFactory;
mThemedIconSnapshotRestorer = themedIconSnapshotRestorer;
mThemedIconInteractor = themedIconInteractor;
+ mGridInteractor = gridInteractor;
mColorPickerInteractor = colorPickerInteractor;
mThemesUserEventLogger = themesUserEventLogger;
mColorContrastSectionViewModelFactory = colorContrastSectionViewModelFactory;
@@ -125,6 +129,7 @@
sectionNavigationController,
wallpaperInteractor,
mThemedIconInteractor,
+ mGridInteractor,
mColorPickerInteractor,
wallpaperManager,
isTwoPaneAndSmallWidth,
@@ -139,6 +144,7 @@
wallpaperPreviewNavigator,
wallpaperInteractor,
mThemedIconInteractor,
+ mGridInteractor,
mColorPickerInteractor,
wallpaperManager,
isTwoPaneAndSmallWidth,
@@ -210,8 +216,7 @@
new GridSectionController(
GridOptionsManager.getInstance(activity),
sectionNavigationController,
- lifecycleOwner,
- /* isRevampedUiEnabled= */ true));
+ lifecycleOwner));
break;
}
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index d26141b..4c0f216 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -142,6 +142,7 @@
clockViewFactory,
getThemedIconSnapshotRestorer(appContext),
getThemedIconInteractor(),
+ getGridInteractor(appContext),
colorPickerInteractor.get(),
getUserEventLogger(),
)
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index 6bb6596..c0a1446 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -16,6 +16,7 @@
*/
package com.android.customization.picker.clock.data.repository
+import android.graphics.drawable.Drawable
import android.provider.Settings
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
@@ -61,8 +62,18 @@
fun send() {
val activeClockId = registry.activeClockId
val allClocks =
- registry.getClocks().map {
- it.toModel(isSelected = it.clockId == activeClockId)
+ registry.getClocks().mapNotNull {
+ val clockConfig = registry.getClockPickerConfig(it.clockId)
+ if (clockConfig != null) {
+ it.toModel(
+ isSelected = it.clockId == activeClockId,
+ description = clockConfig.description,
+ thumbnail = clockConfig.thumbnail,
+ isReactiveToTone = clockConfig.isReactiveToTone,
+ )
+ } else {
+ null
+ }
}
trySend(allClocks)
@@ -93,18 +104,24 @@
fun send() {
val activeClockId = registry.activeClockId
val metadata = registry.settings?.metadata
+ val clockConfig = registry.getClockPickerConfig(activeClockId)
val model =
- registry
- .getClocks()
- .find { clockMetadata -> clockMetadata.clockId == activeClockId }
- ?.toModel(
- isSelected = true,
- selectedColorId = metadata?.getSelectedColorId(),
- colorTone =
- metadata?.getColorTone()
- ?: ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
- seedColor = registry.seedColor
- )
+ clockConfig?.let {
+ registry
+ .getClocks()
+ .find { clockMetadata -> clockMetadata.clockId == activeClockId }
+ ?.toModel(
+ isSelected = true,
+ description = it.description,
+ thumbnail = it.thumbnail,
+ isReactiveToTone = it.isReactiveToTone,
+ selectedColorId = metadata?.getSelectedColorId(),
+ colorTone =
+ metadata?.getColorTone()
+ ?: ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ seedColor = registry.seedColor,
+ )
+ }
trySend(model)
}
@@ -188,6 +205,9 @@
/** By default, [ClockMetadataModel] has no color information unless specified. */
private fun ClockMetadata.toModel(
isSelected: Boolean,
+ description: String,
+ thumbnail: Drawable,
+ isReactiveToTone: Boolean,
selectedColorId: String? = null,
@IntRange(from = 0, to = 100) colorTone: Int = 0,
@ColorInt seedColor: Int? = null,
@@ -195,6 +215,9 @@
return ClockMetadataModel(
clockId = clockId,
isSelected = isSelected,
+ description = description,
+ thumbnail = thumbnail,
+ isReactiveToTone = isReactiveToTone,
selectedColorId = selectedColorId,
colorToneProgress = colorTone,
seedColor = seedColor,
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
index b1f41c5..49227ee 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -47,6 +47,8 @@
val selectedClockId: Flow<String> =
repository.selectedClock.map { clock -> clock.clockId }.distinctUntilChanged()
+ val selectedClock: Flow<ClockMetadataModel> = repository.selectedClock
+
val selectedColorId: Flow<String?> =
repository.selectedClock.map { clock -> clock.selectedColorId }.distinctUntilChanged()
diff --git a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
index 6e2bfb3..3c8e725 100644
--- a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -17,6 +17,7 @@
package com.android.customization.picker.clock.shared.model
+import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
@@ -24,6 +25,9 @@
data class ClockMetadataModel(
val clockId: String,
val isSelected: Boolean,
+ val description: String,
+ val thumbnail: Drawable,
+ val isReactiveToTone: Boolean,
val selectedColorId: String?,
@IntRange(from = 0, to = 100) val colorToneProgress: Int,
@ColorInt val seedColor: Int?,
diff --git a/src/com/android/customization/picker/grid/data/repository/GridRepository.kt b/src/com/android/customization/picker/grid/data/repository/GridRepository.kt
index f384429..dc308db 100644
--- a/src/com/android/customization/picker/grid/data/repository/GridRepository.kt
+++ b/src/com/android/customization/picker/grid/data/repository/GridRepository.kt
@@ -30,6 +30,8 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -37,11 +39,17 @@
interface GridRepository {
suspend fun isAvailable(): Boolean
+
fun getOptionChanges(): Flow<Unit>
+
suspend fun getOptions(): GridOptionItemsModel
- fun getSelectedOption(): GridOption?
+
+ fun getSelectedOption(): StateFlow<GridOption?>
+
fun applySelectedOption(callback: Callback)
+
fun clearSelectedOption()
+
fun isSelectedOptionApplied(): Boolean
}
@@ -63,7 +71,7 @@
private var appliedOption: GridOption? = null
- override fun getSelectedOption() = selectedOption.value
+ override fun getSelectedOption() = selectedOption.asStateFlow()
override suspend fun getOptions(): GridOptionItemsModel {
return withContext(backgroundDispatcher) {
@@ -133,6 +141,7 @@
option,
object : CustomizationManager.Callback {
override fun onSuccess() {
+ selectedOption.value = option
continuation.resume(true)
}
@@ -147,7 +156,7 @@
}
override fun applySelectedOption(callback: Callback) {
- val option = getSelectedOption()
+ val option = getSelectedOption().value
manager.apply(
option,
if (isGridApplyButtonEnabled) {
diff --git a/src/com/android/customization/picker/grid/domain/interactor/GridInteractor.kt b/src/com/android/customization/picker/grid/domain/interactor/GridInteractor.kt
index 02e16dd..015bcdf 100644
--- a/src/com/android/customization/picker/grid/domain/interactor/GridInteractor.kt
+++ b/src/com/android/customization/picker/grid/domain/interactor/GridInteractor.kt
@@ -18,7 +18,6 @@
package com.android.customization.picker.grid.domain.interactor
import com.android.customization.model.CustomizationManager
-import com.android.customization.model.grid.GridOption
import com.android.customization.picker.grid.data.repository.GridRepository
import com.android.customization.picker.grid.shared.model.GridOptionItemModel
import com.android.customization.picker.grid.shared.model.GridOptionItemsModel
@@ -75,7 +74,7 @@
}
}
- fun getSelectOptionNonSuspend(): GridOption? = repository.getSelectedOption()
+ fun getSelectOptionStateFlow() = repository.getSelectedOption()
fun clearSelectedOption() = repository.clearSelectedOption()
diff --git a/src/com/android/customization/picker/grid/ui/fragment/GridFragment.kt b/src/com/android/customization/picker/grid/ui/fragment/GridFragment.kt
index b48f41a..7e2341c 100644
--- a/src/com/android/customization/picker/grid/ui/fragment/GridFragment.kt
+++ b/src/com/android/customization/picker/grid/ui/fragment/GridFragment.kt
@@ -115,7 +115,7 @@
context,
getString(
R.string.toast_of_changing_grid,
- gridInteractor.getSelectOptionNonSuspend()?.title
+ gridInteractor.getSelectOptionStateFlow().value?.title
),
Toast.LENGTH_SHORT
)
@@ -128,7 +128,7 @@
val errorMsg =
getString(
R.string.toast_of_failure_to_change_grid,
- gridInteractor.getSelectOptionNonSuspend()?.title
+ gridInteractor.getSelectOptionStateFlow().value?.title
)
Toast.makeText(context, errorMsg, Toast.LENGTH_SHORT).show()
Log.e(TAG, errorMsg, throwable)
@@ -178,7 +178,10 @@
),
initialExtrasProvider = {
val bundle = Bundle()
- bundle.putString("name", gridInteractor.getSelectOptionNonSuspend()?.name)
+ bundle.putString(
+ "name",
+ gridInteractor.getSelectOptionStateFlow().value?.name
+ )
bundle
},
wallpaperInfoProvider = {
diff --git a/src/com/android/customization/picker/grid/ui/section/GridSectionController.java b/src/com/android/customization/picker/grid/ui/section/GridSectionController.java
index 0e15609..bc66812 100644
--- a/src/com/android/customization/picker/grid/ui/section/GridSectionController.java
+++ b/src/com/android/customization/picker/grid/ui/section/GridSectionController.java
@@ -51,8 +51,7 @@
public GridSectionController(
GridOptionsManager gridOptionsManager,
CustomizationSectionNavigationController sectionNavigationController,
- LifecycleOwner lifecycleOwner,
- boolean isRevampedUiEnabled) {
+ LifecycleOwner lifecycleOwner) {
mGridOptionsManager = gridOptionsManager;
mSectionNavigationController = sectionNavigationController;
mLifecycleOwner = lifecycleOwner;
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index e1f8df2..db43f4b 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -39,6 +39,7 @@
import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.grid.domain.interactor.GridInteractor
import com.android.themepicker.R
import com.android.wallpaper.model.CustomizationSectionController
import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController
@@ -72,6 +73,7 @@
private val navigationController: CustomizationSectionNavigationController,
wallpaperInteractor: WallpaperInteractor,
themedIconInteractor: ThemedIconInteractor,
+ gridInteractor: GridInteractor,
colorPickerInteractor: ColorPickerInteractor,
wallpaperManager: WallpaperManager,
private val isTwoPaneAndSmallWidth: Boolean,
@@ -87,6 +89,7 @@
wallpaperPreviewNavigator,
wallpaperInteractor,
themedIconInteractor,
+ gridInteractor,
colorPickerInteractor,
wallpaperManager,
isTwoPaneAndSmallWidth,
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt
index 78e3745..cd3e702 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt
@@ -23,6 +23,7 @@
import androidx.lifecycle.LifecycleOwner
import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.grid.domain.interactor.GridInteractor
import com.android.customization.picker.preview.ui.viewmodel.PreviewWithThemeViewModel
import com.android.wallpaper.R
import com.android.wallpaper.model.Screen
@@ -52,6 +53,7 @@
wallpaperPreviewNavigator: WallpaperPreviewNavigator,
private val wallpaperInteractor: WallpaperInteractor,
private val themedIconInteractor: ThemedIconInteractor,
+ private val gridInteractor: GridInteractor,
private val colorPickerInteractor: ColorPickerInteractor,
wallpaperManager: WallpaperManager,
isTwoPaneAndSmallWidth: Boolean,
@@ -121,6 +123,7 @@
initialExtrasProvider = { getInitialExtras(isOnLockScreen) },
wallpaperInteractor = wallpaperInteractor,
themedIconInteractor = themedIconInteractor,
+ gridInteractor = gridInteractor,
colorPickerInteractor = colorPickerInteractor,
screen = screen,
)
diff --git a/src/com/android/customization/picker/preview/ui/viewmodel/PreviewWithThemeViewModel.kt b/src/com/android/customization/picker/preview/ui/viewmodel/PreviewWithThemeViewModel.kt
index 7877f11..331ec2e 100644
--- a/src/com/android/customization/picker/preview/ui/viewmodel/PreviewWithThemeViewModel.kt
+++ b/src/com/android/customization/picker/preview/ui/viewmodel/PreviewWithThemeViewModel.kt
@@ -21,6 +21,7 @@
import android.os.Bundle
import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.grid.domain.interactor.GridInteractor
import com.android.wallpaper.model.Screen
import com.android.wallpaper.model.WallpaperInfo
import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
@@ -28,6 +29,8 @@
import com.android.wallpaper.util.PreviewUtils
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
/** A ThemePicker version of the [ScreenPreviewViewModel] */
class PreviewWithThemeViewModel(
@@ -36,7 +39,8 @@
wallpaperInfoProvider: suspend (forceReload: Boolean) -> WallpaperInfo?,
onWallpaperColorChanged: (WallpaperColors?) -> Unit = {},
wallpaperInteractor: WallpaperInteractor,
- private val themedIconInteractor: ThemedIconInteractor? = null,
+ private val themedIconInteractor: ThemedIconInteractor,
+ private val gridInteractor: GridInteractor,
colorPickerInteractor: ColorPickerInteractor? = null,
screen: Screen,
) :
@@ -48,7 +52,11 @@
wallpaperInteractor,
screen,
) {
- override fun workspaceUpdateEvents(): Flow<Boolean>? = themedIconInteractor?.isActivated
+ override fun workspaceUpdateEvents(): Flow<Unit> =
+ merge(
+ themedIconInteractor.isActivated.map {},
+ gridInteractor.getSelectOptionStateFlow().map {}
+ )
private val wallpaperIsLoading = super.isLoading
diff --git a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
index 335d4fe..91deed8 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ClockFloatingSheetBinder.kt
@@ -23,6 +23,7 @@
import android.graphics.drawable.Drawable
import android.view.View
import android.view.ViewGroup
+import android.widget.ImageView
import android.widget.SeekBar
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.doOnLayout
@@ -32,7 +33,6 @@
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
-import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.customization.picker.color.ui.binder.ColorOptionIconBinder
import com.android.customization.picker.color.ui.view.ColorOptionIconView
@@ -92,23 +92,27 @@
setOnTabClick(TERTIARY) { viewModel.setTab(SIZE) }
}
- val container = view.requireViewById<ViewGroup>(R.id.clock_floating_sheet_content_container)
+ val floatingSheetContainer =
+ view.requireViewById<ViewGroup>(R.id.clock_floating_sheet_content_container)
// Clock style
- val clockList = view.requireViewById<View>(R.id.clock_list)
+ val clockStyleContent = view.requireViewById<View>(R.id.clock_floating_sheet_style_content)
+ val clockStyleAdapter = createClockStyleOptionItemAdapter(lifecycleOwner)
+ val clockStyleList =
+ view.requireViewById<RecyclerView>(R.id.clock_style_list).apply {
+ initStyleList(appContext, clockStyleAdapter)
+ }
// Cloc color
- val clockColorSheetContent =
- view.requireViewById<View>(R.id.clock_floating_sheet_color_content)
- val clockColorListContainer = view.requireViewById<View>(R.id.clock_color_list_container)
+ val clockColorContent = view.requireViewById<View>(R.id.clock_floating_sheet_color_content)
val clockColorAdapter =
- createOptionItemAdapter(
+ createClockColorOptionItemAdapter(
view.resources.configuration.uiMode,
lifecycleOwner,
)
val clockColorList =
- view.requireViewById<RecyclerView>(R.id.clock_color_list).also {
- it.initColorsList(appContext, clockColorAdapter)
+ view.requireViewById<RecyclerView>(R.id.clock_color_list).apply {
+ initColorList(appContext, clockColorAdapter)
}
val clockColorSlider: SeekBar = view.requireViewById(R.id.clock_color_slider)
clockColorSlider.setOnSeekBarChangeListener(
@@ -130,16 +134,15 @@
)
// Clock size
- val clockSizeContainer = view.requireViewById<View>(R.id.clock_floating_sheet_size_content)
+ val clockSizeContent = view.requireViewById<View>(R.id.clock_floating_sheet_size_content)
view.doOnLayout {
if (_clockFloatingSheetHeights.value == null) {
_clockFloatingSheetHeights.value =
ClockFloatingSheetHeightsViewModel(
- clockStyleContentHeight = clockList.height,
- clockColorContentHeight = clockColorSheetContent.height,
- clockColorListHeight = clockColorListContainer.height,
- clockSizeContentHeight = clockSizeContainer.height,
+ clockStyleContentHeight = clockStyleContent.height,
+ clockColorContentHeight = clockColorContent.height,
+ clockSizeContentHeight = clockSizeContent.height,
)
}
}
@@ -169,36 +172,38 @@
) * 2
val animationFloatingSheet =
- ValueAnimator.ofInt(container.height, targetHeight)
+ ValueAnimator.ofInt(floatingSheetContainer.height, targetHeight)
animationFloatingSheet.addUpdateListener { valueAnimator ->
val value = valueAnimator.animatedValue as Int
- container.layoutParams =
- container.layoutParams.apply { height = value }
+ floatingSheetContainer.layoutParams =
+ floatingSheetContainer.layoutParams.apply { height = value }
}
animationFloatingSheet.setDuration(ANIMATION_DURATION)
animationFloatingSheet.start()
- // For some reason the color list layout collapses when we animate the
- // parent's height. This is to make sure the height stays as it is
- // firstly
- // inflated.
- clockColorList.layoutParams =
- clockColorList.layoutParams.apply {
- height = heights.clockColorListHeight
- }
-
- clockList.isVisible = selectedTab == STYLE
- clockColorSheetContent.isVisible = selectedTab == COLOR
- clockSizeContainer.isVisible = selectedTab == SIZE
+ clockStyleContent.isVisible = selectedTab == STYLE
+ clockColorContent.isVisible = selectedTab == COLOR
+ clockSizeContent.isVisible = selectedTab == SIZE
}
}
launch {
+ viewModel.clockStyleOptions.collect { styleOptions ->
+ clockStyleAdapter.setItems(styleOptions) {
+ var indexToFocus = styleOptions.indexOfFirst { it.isSelected.value }
+ indexToFocus = if (indexToFocus < 0) 0 else indexToFocus
+ (clockStyleList.layoutManager as GridLayoutManager)
+ .scrollToPositionWithOffset(indexToFocus, 0)
+ }
+ }
+ }
+
+ launch {
viewModel.clockColorOptions.collect { colorOptions ->
clockColorAdapter.setItems(colorOptions) {
var indexToFocus = colorOptions.indexOfFirst { it.isSelected.value }
indexToFocus = if (indexToFocus < 0) 0 else indexToFocus
- (clockColorList.layoutManager as LinearLayoutManager)
+ (clockColorList.layoutManager as GridLayoutManager)
.scrollToPositionWithOffset(indexToFocus, 0)
}
}
@@ -221,7 +226,47 @@
}
}
- private fun createOptionItemAdapter(
+ private fun createClockStyleOptionItemAdapter(
+ lifecycleOwner: LifecycleOwner
+ ): OptionItemAdapter<Drawable> =
+ OptionItemAdapter(
+ layoutResourceId = R.layout.clock_style_option,
+ lifecycleOwner = lifecycleOwner,
+ bindIcon = { foregroundView: View, drawable: Drawable ->
+ (foregroundView as ImageView).setImageDrawable(drawable)
+ }
+ )
+
+ private fun RecyclerView.initStyleList(
+ context: Context,
+ adapter: OptionItemAdapter<Drawable>,
+ ) {
+ apply {
+ this.adapter = adapter
+ layoutManager =
+ GridLayoutManager(
+ context,
+ 2,
+ GridLayoutManager.HORIZONTAL,
+ false,
+ )
+ addItemDecoration(
+ DoubleRowListItemSpacing(
+ context.resources.getDimensionPixelSize(
+ R.dimen.floating_sheet_content_horizontal_padding
+ ),
+ context.resources.getDimensionPixelSize(
+ R.dimen.floating_sheet_list_item_horizontal_space
+ ),
+ context.resources.getDimensionPixelSize(
+ R.dimen.floating_sheet_list_item_vertical_space
+ ),
+ )
+ )
+ }
+ }
+
+ private fun createClockColorOptionItemAdapter(
uiMode: Int,
lifecycleOwner: LifecycleOwner
): OptionItemAdapter<ColorOptionIconViewModel> =
@@ -236,7 +281,7 @@
}
)
- private fun RecyclerView.initColorsList(
+ private fun RecyclerView.initColorList(
context: Context,
adapter: OptionItemAdapter<ColorOptionIconViewModel>,
) {
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
index 37845cd..37752af 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockFloatingSheetHeightsViewModel.kt
@@ -19,6 +19,5 @@
data class ClockFloatingSheetHeightsViewModel(
val clockStyleContentHeight: Int,
val clockColorContentHeight: Int,
- val clockColorListHeight: Int,
val clockSizeContentHeight: Int,
)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt
index dd8f5b2..cd223a0 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockOptionItemViewModel.kt
@@ -22,5 +22,5 @@
val clockId: String,
val isSelected: Boolean,
val contentDescription: String,
- val thumbnail: Drawable? = null,
+ val thumbnail: Drawable,
)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
index 3da3252..fc2b297 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ClockPickerViewModel.kt
@@ -17,6 +17,7 @@
import android.content.Context
import android.content.res.Resources
+import android.graphics.drawable.Drawable
import androidx.core.graphics.ColorUtils
import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.module.logging.ThemesUserEventLogger
@@ -87,22 +88,41 @@
}
@OptIn(ExperimentalCoroutinesApi::class)
- val allClocks: StateFlow<List<ClockOptionItemViewModel>> =
+ val clockStyleOptions: StateFlow<List<OptionItemViewModel<Drawable>>> =
clockPickerInteractor.allClocks
.mapLatest { allClocks ->
// Delay to avoid the case that the full list of clocks is not initiated.
delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
- allClocks.map {
+ allClocks.map { clockModel ->
+ val isSelectedFlow =
+ clockPickerInteractor.selectedClock
+ .map { clockModel.clockId == it.clockId }
+ .stateIn(viewModelScope)
val contentDescription =
resources.getString(
R.string.select_clock_action_description,
- // TODO (b/350718184): Get ClockConfig.description from ClockRegistry
- "description"
+ clockModel.description,
)
- ClockOptionItemViewModel(
- clockId = it.clockId,
- isSelected = it.isSelected,
- contentDescription = contentDescription,
+ OptionItemViewModel<Drawable>(
+ key = MutableStateFlow(clockModel.clockId) as StateFlow<String>,
+ payload = clockModel.thumbnail,
+ text = Text.Loaded(contentDescription),
+ isTextUserVisible = false,
+ isSelected = isSelectedFlow,
+ onClicked =
+ isSelectedFlow.map { isSelected ->
+ if (isSelected) {
+ null
+ } else {
+ {
+ viewModelScope.launch {
+ clockPickerInteractor.setSelectedClock(
+ clockModel.clockId
+ )
+ }
+ }
+ }
+ },
)
}
}
@@ -112,11 +132,6 @@
.flowOn(backgroundDispatcher.limitedParallelism(1))
.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
- val selectedClockId: StateFlow<String?> =
- clockPickerInteractor.selectedClockId
- .distinctUntilChanged()
- .stateIn(viewModelScope, SharingStarted.Eagerly, null)
-
private var setSelectedClockJob: Job? = null
fun setSelectedClock(clockId: String) {
@@ -134,12 +149,13 @@
private val sliderColorToneProgress =
MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
val isSliderEnabled: Flow<Boolean> =
- combine(selectedClockId, clockPickerInteractor.selectedColorId) { clockId, colorId ->
- if (colorId == null || clockId == null) {
+ combine(clockPickerInteractor.selectedClock, clockPickerInteractor.selectedColorId) {
+ clock,
+ colorId ->
+ if (colorId == null) {
false
} else {
- // TODO (b/350718184): Get ClockConfig.isReactiveToTone from ClockRegistry
- false
+ clock.isReactiveToTone
}
}
.distinctUntilChanged()
diff --git a/tests/robotests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt b/tests/robotests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt
index de68bf0..391e270 100644
--- a/tests/robotests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt
+++ b/tests/robotests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt
@@ -18,7 +18,6 @@
package com.android.customization.model.grid.data.repository
import com.android.customization.model.CustomizationManager
-import com.android.customization.model.grid.GridOption
import com.android.customization.picker.grid.data.repository.GridRepository
import com.android.customization.picker.grid.shared.model.GridOptionItemModel
import com.android.customization.picker.grid.shared.model.GridOptionItemsModel
@@ -54,7 +53,7 @@
return options
}
- override fun getSelectedOption(): GridOption? = null
+ override fun getSelectedOption() = MutableStateFlow(null)
override fun applySelectedOption(callback: CustomizationManager.Callback) {}
diff --git a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index 4d8f32e..0b66357 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -16,6 +16,7 @@
package com.android.customization.picker.clock.data.repository
import android.graphics.Color
+import android.graphics.drawable.ColorDrawable
import androidx.annotation.ColorInt
import androidx.annotation.IntRange
import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks
@@ -47,6 +48,9 @@
ClockMetadataModel(
clockId = selectedClock.clockId,
isSelected = true,
+ description = "description",
+ thumbnail = ColorDrawable(0),
+ isReactiveToTone = selectedClock.isReactiveToTone,
selectedColorId = selectedColor,
colorToneProgress = colorTone,
seedColor = seedColor,
@@ -81,10 +85,46 @@
const val CLOCK_ID_3 = "clock3"
val fakeClocks =
listOf(
- ClockMetadataModel(CLOCK_ID_0, true, null, 50, null),
- ClockMetadataModel(CLOCK_ID_1, false, null, 50, null),
- ClockMetadataModel(CLOCK_ID_2, false, null, 50, null),
- ClockMetadataModel(CLOCK_ID_3, false, null, 50, null),
+ ClockMetadataModel(
+ CLOCK_ID_0,
+ true,
+ "description0",
+ ColorDrawable(0),
+ true,
+ null,
+ 50,
+ null
+ ),
+ ClockMetadataModel(
+ CLOCK_ID_1,
+ false,
+ "description1",
+ ColorDrawable(0),
+ true,
+ null,
+ 50,
+ null
+ ),
+ ClockMetadataModel(
+ CLOCK_ID_2,
+ false,
+ "description2",
+ ColorDrawable(0),
+ true,
+ null,
+ 50,
+ null
+ ),
+ ClockMetadataModel(
+ CLOCK_ID_3,
+ false,
+ "description3",
+ ColorDrawable(0),
+ false,
+ null,
+ 50,
+ null
+ ),
)
const val CLOCK_COLOR_ID = "RED"
const val CLOCK_COLOR_TONE_PROGRESS = 87
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index 44a1fbe..be852ac 100644
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -15,6 +15,7 @@
*/
package com.android.customization.picker.clock.ui.viewmodel
+import android.graphics.drawable.ColorDrawable
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.customization.module.logging.TestThemesUserEventLogger
@@ -54,6 +55,9 @@
ClockMetadataModel(
clockId = FakeClockPickerRepository.CLOCK_ID_0,
isSelected = true,
+ description = "description",
+ thumbnail = ColorDrawable(0),
+ isReactiveToTone = true,
selectedColorId = null,
colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
seedColor = null,