Merge "[TP] Reuse clock views in clock carousel" into tm-qpr-dev am: b6239929b5
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/ThemePicker/+/21303070
Change-Id: I73f2da751d10ff6bc98d978ca9f2fca25401d0fd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
index 26bd925..900431e 100644
--- a/src/com/android/customization/module/CustomizationInjector.kt
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -22,6 +22,7 @@
import com.android.customization.model.theme.ThemeManager
import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
@@ -71,4 +72,9 @@
context: Context,
clockRegistry: ClockRegistry,
): ClockCarouselViewModel
+
+ fun getClockViewFactory(
+ context: Context,
+ registry: ClockRegistry,
+ ): ClockViewFactory
}
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index ab894f8..16d4bc7 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.notifications.ui.viewmodel.NotificationSectionViewModel;
import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController;
import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider;
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController.ClockViewFactoryProvider;
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor;
import com.android.customization.picker.quickaffordance.ui.section.KeyguardQuickAffordanceSectionController;
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel;
@@ -53,6 +54,8 @@
private final ClockRegistryProvider mClockRegistryProvider;
private final PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider
mClockCarouselViewModelProvider;
+ private final PreviewWithClockCarouselSectionController.ClockViewFactoryProvider
+ mClockViewFactoryProvider;
public DefaultCustomizationSections(
KeyguardQuickAffordancePickerInteractor keyguardQuickAffordancePickerInteractor,
@@ -61,7 +64,8 @@
NotificationSectionViewModel.Factory notificationSectionViewModelFactory,
BaseFlags flags,
ClockRegistryProvider clockRegistryProvider,
- ClockCarouselViewModelProvider clockCarouselViewModelProvider) {
+ ClockCarouselViewModelProvider clockCarouselViewModelProvider,
+ ClockViewFactoryProvider clockViewFactoryProvider) {
mKeyguardQuickAffordancePickerInteractor = keyguardQuickAffordancePickerInteractor;
mKeyguardQuickAffordancePickerViewModelFactory =
keyguardQuickAffordancePickerViewModelFactory;
@@ -69,6 +73,7 @@
mFlags = flags;
mClockRegistryProvider = clockRegistryProvider;
mClockCarouselViewModelProvider = clockCarouselViewModelProvider;
+ mClockViewFactoryProvider = clockViewFactoryProvider;
}
@Override
@@ -98,7 +103,8 @@
wallpaperColorsViewModel,
displayUtils,
mClockRegistryProvider,
- mClockCarouselViewModelProvider)
+ mClockCarouselViewModelProvider,
+ mClockViewFactoryProvider)
: new ScreenPreviewSectionController(
activity,
lifecycleOwner,
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index f2ebb68..c2a6565 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -28,6 +28,7 @@
import com.android.customization.picker.clock.data.repository.ClockPickerRepositoryImpl
import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
@@ -37,7 +38,8 @@
import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
import com.android.customization.picker.notifications.domain.interactor.NotificationsSnapshotRestorer
import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
-import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController.ClockViewFactoryProvider
import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
@@ -79,6 +81,7 @@
private var clockPickerInteractor: ClockPickerInteractor? = null
private var clockSectionViewModel: ClockSectionViewModel? = null
private var clockCarouselViewModel: ClockCarouselViewModel? = null
+ private var clockViewFactory: ClockViewFactory? = null
private var notificationsInteractor: NotificationsInteractor? = null
private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null
private var colorPickerInteractor: ColorPickerInteractor? = null
@@ -94,14 +97,21 @@
),
getFlags(),
getClockRegistryProvider(activity),
- object :
- PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider {
+ object : ClockCarouselViewModelProvider {
override fun get(registry: ClockRegistry): ClockCarouselViewModel {
return getClockCarouselViewModel(
context = activity,
clockRegistry = registry,
)
}
+ },
+ object : ClockViewFactoryProvider {
+ override fun get(registry: ClockRegistry): ClockViewFactory {
+ return getClockViewFactory(
+ context = activity,
+ registry = registry,
+ )
+ }
}
)
.also { customizationSections = it }
@@ -293,6 +303,14 @@
}
}
+ override fun getClockViewFactory(
+ context: Context,
+ registry: ClockRegistry,
+ ): ClockViewFactory {
+ return clockViewFactory
+ ?: ClockViewFactory(context, registry).also { clockViewFactory = it }
+ }
+
protected fun getNotificationsInteractor(
context: Context,
): NotificationsInteractor {
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
index 1f49c55..2771b12 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -69,7 +69,11 @@
override fun populate(view: View?, index: Int) {
val viewGroup = view as ViewGroup
viewGroup.removeAllViews()
- viewGroup.addView(onGetClockPreview(clockIds[index]))
+ val clockView = onGetClockPreview(clockIds[index])
+ // The clock view might still be attached to an existing parent. Detach before adding to
+ // another parent.
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ viewGroup.addView(clockView)
}
override fun onNewItem(index: Int) {
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
new file mode 100644
index 0000000..8f4fb28
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
@@ -0,0 +1,24 @@
+package com.android.customization.picker.clock.ui.view
+
+import android.content.Context
+import android.view.View
+import com.android.systemui.plugins.ClockController
+import com.android.systemui.shared.clocks.ClockRegistry
+import java.util.HashMap
+
+class ClockViewFactory(private val context: Context, private val registry: ClockRegistry) {
+ private val clockControllers: HashMap<String, ClockController> =
+ HashMap<String, ClockController>()
+
+ fun getView(clockId: String): View {
+ return (clockControllers[clockId] ?: initClockController(clockId)).largeClock.view
+ }
+
+ private fun initClockController(clockId: String): ClockController {
+ val controller =
+ registry.createExampleClock(clockId).also { it?.initialize(context.resources, 0f, 0f) }
+ checkNotNull(controller)
+ clockControllers[clockId] = controller
+ return controller
+ }
+}
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 d90961b..f1319c6 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -25,6 +25,7 @@
import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
import com.android.customization.picker.clock.ui.binder.ClockCarouselViewBinder
import com.android.customization.picker.clock.ui.view.ClockCarouselView
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.systemui.shared.clocks.ClockRegistry
import com.android.wallpaper.R
@@ -50,6 +51,7 @@
private val displayUtils: DisplayUtils,
private val clockRegistryProvider: ClockRegistryProvider,
private val clockCarouselViewModelProvider: ClockCarouselViewModelProvider,
+ private val clockViewFactoryProvider: ClockViewFactoryProvider,
) :
ScreenPreviewSectionController(
activity,
@@ -67,13 +69,12 @@
val carouselView: ClockCarouselView = carouselViewStub.inflate() as ClockCarouselView
lifecycleOwner.lifecycleScope.launch {
val registry = withContext(Dispatchers.IO) { clockRegistryProvider.get() }
+ val clockViewFactory = clockViewFactoryProvider.get(registry)
clockCarouselBinding =
ClockCarouselViewBinder.bind(
view = carouselView,
viewModel = clockCarouselViewModelProvider.get(registry),
- clockViewFactory = { clockId ->
- registry.createExampleClock(clockId)?.largeClock?.view!!
- },
+ clockViewFactory = { clockId -> clockViewFactory.getView(clockId) },
lifecycleOwner = lifecycleOwner,
)
onScreenSwitched(
@@ -95,4 +96,8 @@
interface ClockCarouselViewModelProvider {
fun get(registry: ClockRegistry): ClockCarouselViewModel
}
+
+ interface ClockViewFactoryProvider {
+ fun get(registry: ClockRegistry): ClockViewFactory
+ }
}
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
index 3dce587..e4ceb4f 100644
--- a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -11,6 +11,7 @@
import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
@@ -47,6 +48,7 @@
private var clockRegistryProvider: ClockRegistryProvider? = null
private var clockPickerInteractor: ClockPickerInteractor? = null
private var clockSectionViewModel: ClockSectionViewModel? = null
+ private var clockViewFactory: ClockViewFactory? = null
private var colorPickerInteractor: ColorPickerInteractor? = null
private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null
private var clockCarouselViewModel: ClockCarouselViewModel? = null
@@ -191,6 +193,11 @@
}
}
+ override fun getClockViewFactory(context: Context, registry: ClockRegistry): ClockViewFactory {
+ return clockViewFactory
+ ?: ClockViewFactory(context, registry).also { clockViewFactory = it }
+ }
+
companion object {
private const val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER = 1
}