Merge "Import translations. DO NOT MERGE ANYWHERE" into main
diff --git a/res/layout/clock_host_view.xml b/res/layout/clock_host_view.xml
index 33cca01..d6f5275 100644
--- a/res/layout/clock_host_view.xml
+++ b/res/layout/clock_host_view.xml
@@ -13,7 +13,7 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<com.android.customization.picker.clock.ui.view.ClockHostView2
+<com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/clock_host_view"
     android:importantForAccessibility="noHideDescendants"
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index b634df0..a022d00 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -65,13 +65,22 @@
 import com.android.wallpaper.config.BaseFlags
 import com.android.wallpaper.module.CustomizationSections
 import com.android.wallpaper.module.FragmentFactory
+import com.android.wallpaper.module.NetworkStatusNotifier
+import com.android.wallpaper.module.PartnerProvider
 import com.android.wallpaper.module.WallpaperPicker2Injector
+import com.android.wallpaper.module.WallpaperPreferences
+import com.android.wallpaper.module.logging.UserEventLogger
+import com.android.wallpaper.network.Requester
 import com.android.wallpaper.picker.CustomizationPickerActivity
+import com.android.wallpaper.picker.category.wrapper.WallpaperCategoryWrapper
+import com.android.wallpaper.picker.customization.data.content.WallpaperClient
 import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository
 import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
 import com.android.wallpaper.picker.di.modules.BackgroundDispatcher
 import com.android.wallpaper.picker.di.modules.MainDispatcher
 import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.system.UiModeManagerWrapper
+import com.android.wallpaper.util.DisplayUtils
 import dagger.Lazy
 import javax.inject.Inject
 import javax.inject.Singleton
@@ -85,7 +94,46 @@
     @MainDispatcher private val mainScope: CoroutineScope,
     @BackgroundDispatcher private val bgScope: CoroutineScope,
     @BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
-) : WallpaperPicker2Injector(mainScope), CustomizationInjector {
+    private val colorContrastSectionViewModelFactory: Lazy<ColorContrastSectionViewModel.Factory>,
+    private val keyguardQuickAffordancePickerInteractor:
+        Lazy<KeyguardQuickAffordancePickerInteractor>,
+    private val keyguardQuickAffordanceSnapshotRestorer:
+        Lazy<KeyguardQuickAffordanceSnapshotRestorer>,
+    private val themesUserEventLogger: Lazy<ThemesUserEventLogger>,
+    private val colorPickerInteractor: Lazy<ColorPickerInteractor>,
+    private val colorPickerSnapshotRestorer: Lazy<ColorPickerSnapshotRestorer>,
+    private val clockRegistry: Lazy<ClockRegistry>,
+    private val secureSettingsRepository: Lazy<SecureSettingsRepository>,
+    private val systemSettingsRepository: Lazy<SystemSettingsRepository>,
+    private val clockPickerInteractor: Lazy<ClockPickerInteractor>,
+    private val clockPickerSnapshotRestorer: Lazy<ClockPickerSnapshotRestorer>,
+    displayUtils: Lazy<DisplayUtils>,
+    requester: Lazy<Requester>,
+    networkStatusNotifier: Lazy<NetworkStatusNotifier>,
+    partnerProvider: Lazy<PartnerProvider>,
+    val uiModeManager: Lazy<UiModeManagerWrapper>,
+    userEventLogger: Lazy<UserEventLogger>,
+    injectedWallpaperClient: Lazy<WallpaperClient>,
+    private val injectedWallpaperInteractor: Lazy<WallpaperInteractor>,
+    prefs: Lazy<WallpaperPreferences>,
+    wallpaperColorsRepository: Lazy<WallpaperColorsRepository>,
+    defaultWallpaperCategoryWrapper: Lazy<WallpaperCategoryWrapper>,
+) :
+    WallpaperPicker2Injector(
+        mainScope,
+        displayUtils,
+        requester,
+        networkStatusNotifier,
+        partnerProvider,
+        uiModeManager,
+        userEventLogger,
+        injectedWallpaperClient,
+        injectedWallpaperInteractor,
+        prefs,
+        wallpaperColorsRepository,
+        defaultWallpaperCategoryWrapper,
+    ),
+    CustomizationInjector {
     private var customizationSections: CustomizationSections? = null
     private var keyguardQuickAffordancePickerViewModelFactory:
         KeyguardQuickAffordancePickerViewModel.Factory? =
@@ -106,24 +154,6 @@
     private var gridSnapshotRestorer: GridSnapshotRestorer? = null
     private var gridScreenViewModelFactory: GridScreenViewModel.Factory? = null
 
-    // Injected objects, sorted by type
-    @Inject
-    lateinit var colorContrastSectionViewModelFactory: Lazy<ColorContrastSectionViewModel.Factory>
-    @Inject
-    lateinit var keyguardQuickAffordancePickerInteractor:
-        Lazy<KeyguardQuickAffordancePickerInteractor>
-    @Inject
-    lateinit var keyguardQuickAffordanceSnapshotRestorer:
-        Lazy<KeyguardQuickAffordanceSnapshotRestorer>
-    @Inject lateinit var themesUserEventLogger: Lazy<ThemesUserEventLogger>
-    @Inject lateinit var colorPickerInteractor: Lazy<ColorPickerInteractor>
-    @Inject lateinit var colorPickerSnapshotRestorer: Lazy<ColorPickerSnapshotRestorer>
-    @Inject lateinit var clockRegistry: Lazy<ClockRegistry>
-    @Inject lateinit var secureSettingsRepository: Lazy<SecureSettingsRepository>
-    @Inject lateinit var systemSettingsRepository: Lazy<SystemSettingsRepository>
-    @Inject lateinit var clockPickerInteractor: Lazy<ClockPickerInteractor>
-    @Inject lateinit var clockPickerSnapshotRestorer: Lazy<ClockPickerSnapshotRestorer>
-
     override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections {
         val appContext = activity.applicationContext
         val clockViewFactory = getClockViewFactory(activity)
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
index 99dfc26..764c671 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -41,10 +41,10 @@
 import com.android.customization.picker.clock.shared.ClockSize
 import com.android.customization.picker.clock.ui.adapter.ClockSettingsTabAdapter
 import com.android.customization.picker.clock.ui.view.ClockCarouselView
-import com.android.customization.picker.clock.ui.view.ClockHostView
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
 import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
 import com.android.customization.picker.color.ui.binder.ColorOptionIconBinder
+import com.android.systemui.shared.Flags
 import com.android.themepicker.R
 import com.android.wallpaper.picker.common.ui.view.ItemSpacing
 import com.android.wallpaper.picker.option.ui.binder.OptionItemBinder
@@ -64,7 +64,10 @@
         clockViewFactory: ClockViewFactory,
         lifecycleOwner: LifecycleOwner,
     ) {
-        val clockHostView: ClockHostView = view.requireViewById(R.id.clock_host_view)
+        if (Flags.newCustomizationPickerUi()) {
+            return
+        }
+        val clockHostView: ViewGroup = view.requireViewById(R.id.clock_host_view)
         val tabView: RecyclerView = view.requireViewById(R.id.tabs)
         val tabAdapter = ClockSettingsTabAdapter()
         tabView.adapter = tabAdapter
@@ -204,10 +207,11 @@
                                     ClockSize.DYNAMIC -> clockViewFactory.getLargeView(clockId)
                                     ClockSize.SMALL -> clockViewFactory.getSmallView(clockId)
                                 }
-                            // The clock view might still be attached to an existing parent. Detach
-                            // before adding to another parent.
+                            // The clock view might still be attached to an existing parent.
+                            // Detach before adding to another parent.
                             (clockView.parent as? ViewGroup)?.removeView(clockView)
                             clockHostView.addView(clockView)
+
                             when (size) {
                                 ClockSize.DYNAMIC -> {
                                     // When clock size data flow emits clock size signal, we want
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt b/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt
new file mode 100644
index 0000000..de5fbd5
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockConstraintLayoutHostView.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.picker.clock.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.view.View.MeasureSpec.EXACTLY
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintLayout
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.systemui.plugins.clocks.ClockController
+import com.android.wallpaper.util.ScreenSizeCalculator
+
+/**
+ * Parent view for the clock view. We will calculate the current display size and the preview size
+ * and scale down the clock view to fit in the preview.
+ */
+class ClockConstraintLayoutHostView(context: Context, attrs: AttributeSet?) :
+    ConstraintLayout(context, attrs) {
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
+        super.onMeasure(
+            MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
+            MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
+        )
+        val ratio = MeasureSpec.getSize(widthMeasureSpec) / screenSize.x.toFloat()
+        scaleX = ratio
+        scaleY = ratio
+    }
+
+    companion object {
+        fun addClockViews(
+            clockController: ClockController,
+            rootView: ClockConstraintLayoutHostView,
+            size: ClockSize,
+        ) {
+            clockController.let { clock ->
+                when (size) {
+                    ClockSize.DYNAMIC -> {
+                        clock.largeClock.layout.views.forEach {
+                            if (it.parent != null) {
+                                (it.parent as ViewGroup).removeView(it)
+                            }
+                            rootView.addView(it).apply { it.visibility = View.VISIBLE }
+                        }
+                    }
+
+                    ClockSize.SMALL -> {
+                        clock.smallClock.layout.views.forEach {
+                            if (it.parent != null) {
+                                (it.parent as ViewGroup).removeView(it)
+                            }
+                            rootView.addView(it).apply { it.visibility = View.VISIBLE }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
index 512fcd1..2db52f1 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
@@ -12,10 +12,7 @@
  * same size of lockscreen to layout clock and scale down it to the size in picker carousel
  * according to ratio of preview to LS
  */
-class ClockHostView(
-    context: Context,
-    attrs: AttributeSet?,
-) : FrameLayout(context, attrs) {
+class ClockHostView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
     private var previewRatio: Float = 1F
         set(value) {
             if (field != value) {
@@ -41,15 +38,16 @@
         parentWidthMeasureSpec: Int,
         widthUsed: Int,
         parentHeightMeasureSpec: Int,
-        heightUsed: Int
+        heightUsed: Int,
     ) {
+
         val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
         super.measureChildWithMargins(
             child,
             MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
             widthUsed,
             MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
-            heightUsed
+            heightUsed,
         )
     }
 }
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt b/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt
deleted file mode 100644
index be2e53d..0000000
--- a/src/com/android/customization/picker/clock/ui/view/ClockHostView2.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.customization.picker.clock.ui.view
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-import android.view.View.MeasureSpec.EXACTLY
-import android.widget.FrameLayout
-import com.android.customization.picker.clock.shared.ClockSize
-import com.android.wallpaper.util.ScreenSizeCalculator
-
-/**
- * Parent view for the clock view. We will calculate the current display size and the preview size
- * and scale down the clock view to fit in the preview.
- */
-class ClockHostView2(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
-
-    var clockSize: ClockSize = ClockSize.DYNAMIC
-        set(value) {
-            if (field != value) {
-                field = value
-                updatePivotAndScale()
-                invalidate()
-            }
-        }
-
-    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
-        super.onLayout(changed, left, top, right, bottom)
-        updatePivotAndScale()
-    }
-
-    override fun measureChildWithMargins(
-        child: View?,
-        parentWidthMeasureSpec: Int,
-        widthUsed: Int,
-        parentHeightMeasureSpec: Int,
-        heightUsed: Int,
-    ) {
-        val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
-        super.measureChildWithMargins(
-            child,
-            MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
-            widthUsed,
-            MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
-            heightUsed,
-        )
-    }
-
-    private fun updatePivotAndScale() {
-        when (clockSize) {
-            ClockSize.DYNAMIC -> {
-                resetPivot()
-            }
-            ClockSize.SMALL -> {
-                pivotX = getCenteredHostViewPivotX(this)
-                pivotY = 0F
-            }
-        }
-        val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
-        val ratio = measuredWidth / screenSize.x.toFloat()
-        scaleX = ratio
-        scaleY = ratio
-    }
-
-    companion object {
-        fun getCenteredHostViewPivotX(hostView: View): Float {
-            return if (hostView.isLayoutRtl) hostView.width.toFloat() else 0F
-        }
-    }
-}
diff --git a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
index 6cb9acb..72b0f19 100644
--- a/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ThemePickerClockViewFactory.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.WeatherData
+import com.android.systemui.shared.Flags
 import com.android.systemui.shared.clocks.ClockRegistry
 import com.android.wallpaper.util.ScreenSizeCalculator
 import com.android.wallpaper.util.TimeUtils.TimeTicker
@@ -64,6 +65,7 @@
      * configs, e.g. animation state, might change during the reuse of the clock view in the app.
      */
     override fun getLargeView(clockId: String): View {
+        assert(!Flags.newCustomizationPickerUi())
         return getController(clockId).largeClock.let {
             it.animations.onPickerCarouselSwiping(1F)
             it.view
@@ -75,6 +77,7 @@
      * configs, e.g. translation X, might change during the reuse of the clock view in the app.
      */
     override fun getSmallView(clockId: String): View {
+        assert(!Flags.newCustomizationPickerUi())
         val smallClockFrame =
             smallClockFrames[clockId]
                 ?: createSmallClockFrame().also {
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 db43f4b..32b28ad 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -97,11 +97,7 @@
     ) {
 
     private val viewModel =
-        ViewModelProvider(
-                activity,
-                clockCarouselViewModelFactory,
-            )
-            .get() as ClockCarouselViewModel
+        ViewModelProvider(activity, clockCarouselViewModelFactory).get() as ClockCarouselViewModel
 
     private var clockColorAndSizeButton: View? = null
 
@@ -184,7 +180,7 @@
                                 )
                                 if (onAttachStateChangeListener != null) {
                                     carouselView.carousel.removeOnAttachStateChangeListener(
-                                        onAttachStateChangeListener,
+                                        onAttachStateChangeListener
                                     )
                                 }
                             }
diff --git a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
index dd283c2..469db6d 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ThemePickerCustomizationOptionBinder.kt
@@ -16,10 +16,12 @@
 
 package com.android.wallpaper.customization.ui.binder
 
+import android.content.Context
 import android.view.View
 import android.view.ViewGroup
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintSet
 import androidx.core.content.ContextCompat
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
@@ -27,10 +29,12 @@
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.customization.picker.clock.shared.ClockSize
-import com.android.customization.picker.clock.ui.view.ClockHostView2
+import com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView
+import com.android.customization.picker.clock.ui.view.ClockConstraintLayoutHostView.Companion.addClockViews
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
 import com.android.customization.picker.grid.ui.binder.GridIconViewBinder
 import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.shared.Flags
 import com.android.themepicker.R
 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerHomeCustomizationOption
 import com.android.wallpaper.customization.ui.util.ThemePickerCustomizationOptionUtil.ThemePickerLockCustomizationOption
@@ -231,12 +235,13 @@
     }
 
     override fun bindClockPreview(
+        context: Context,
         clockHostView: View,
         viewModel: CustomizationPickerViewModel2,
         lifecycleOwner: LifecycleOwner,
         clockViewFactory: ClockViewFactory,
     ) {
-        clockHostView as ClockHostView2
+        clockHostView as ClockConstraintLayoutHostView
         val clockPickerViewModel =
             (viewModel.customizationOptionsViewModel as ThemePickerCustomizationOptionsViewModel)
                 .clockPickerViewModel
@@ -252,17 +257,36 @@
                         }
                         .collect { (clock, size) ->
                             clockHostView.removeAllViews()
-                            val clockView =
-                                when (size) {
-                                    ClockSize.DYNAMIC ->
-                                        clockViewFactory.getLargeView(clock.clockId)
-                                    ClockSize.SMALL -> clockViewFactory.getSmallView(clock.clockId)
+                            // For new customization picker, we should get views from clocklayout
+                            if (Flags.newCustomizationPickerUi()) {
+                                clockViewFactory.getController(clock.clockId).let { clockController
+                                    ->
+                                    addClockViews(clockController, clockHostView, size)
+                                    val cs = ConstraintSet()
+                                    clockController.largeClock.layout.applyPreviewConstraints(
+                                        context,
+                                        cs,
+                                    )
+                                    clockController.smallClock.layout.applyPreviewConstraints(
+                                        context,
+                                        cs,
+                                    )
+                                    cs.applyTo(clockHostView)
                                 }
-                            // The clock view might still be attached to an existing parent. Detach
-                            // before adding to another parent.
-                            (clockView.parent as? ViewGroup)?.removeView(clockView)
-                            clockHostView.addView(clockView)
-                            clockHostView.clockSize = size
+                            } else {
+                                val clockView =
+                                    when (size) {
+                                        ClockSize.DYNAMIC ->
+                                            clockViewFactory.getLargeView(clock.clockId)
+                                        ClockSize.SMALL ->
+                                            clockViewFactory.getSmallView(clock.clockId)
+                                    }
+                                // The clock view might still be attached to an existing parent.
+                                // Detach
+                                // before adding to another parent.
+                                (clockView.parent as? ViewGroup)?.removeView(clockView)
+                                clockHostView.addView(clockView)
+                            }
                         }
                 }
 
diff --git a/src/com/android/wallpaper/picker/common/preview/ui/binder/ThemePickerWorkspaceCallbackBinder.kt b/src/com/android/wallpaper/picker/common/preview/ui/binder/ThemePickerWorkspaceCallbackBinder.kt
index bf612c2..0656696 100644
--- a/src/com/android/wallpaper/picker/common/preview/ui/binder/ThemePickerWorkspaceCallbackBinder.kt
+++ b/src/com/android/wallpaper/picker/common/preview/ui/binder/ThemePickerWorkspaceCallbackBinder.kt
@@ -16,7 +16,6 @@
 
 package com.android.wallpaper.picker.common.preview.ui.binder
 
-import android.app.WallpaperManager
 import android.os.Bundle
 import android.os.Message
 import androidx.core.os.bundleOf
@@ -43,13 +42,13 @@
 import com.android.wallpaper.picker.customization.ui.viewmodel.CustomizationOptionsViewModel
 import javax.inject.Inject
 import javax.inject.Singleton
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
 @Singleton
 class ThemePickerWorkspaceCallbackBinder
 @Inject
 constructor(
-    private val wallpaperManager: WallpaperManager,
     private val defaultWorkspaceCallbackBinder: DefaultWorkspaceCallbackBinder,
     private val materialColorsGenerator: MaterialColorsGenerator,
 ) : WorkspaceCallbackBinder {
@@ -157,25 +156,28 @@
                         }
 
                         launch {
-                            viewModel.colorPickerViewModel2.previewingColorOption.collect {
-                                if (it == null) {
-                                    workspaceCallback.sendMessage(MESSAGE_ID_UPDATE_COLOR, Bundle())
-                                    return@collect
-                                }
-                                val seedColor = it.colorOption.seedColor
-                                val (ids, colors) =
-                                    materialColorsGenerator.generate(
-                                        seedColor,
-                                        it.colorOption.style,
-                                    )
-                                workspaceCallback.sendMessage(
-                                    MESSAGE_ID_UPDATE_COLOR,
-                                    Bundle().apply {
-                                        putIntArray(KEY_COLOR_RESOURCE_IDS, ids)
-                                        putIntArray(KEY_COLOR_VALUES, colors)
-                                    },
+                            combine(
+                                    viewModel.colorPickerViewModel2.previewingColorOption,
+                                    viewModel.darkModeViewModel.previewingIsDarkMode,
+                                    ::Pair,
                                 )
-                            }
+                                .collect { (colorModel, darkMode) ->
+                                    val bundle =
+                                        Bundle().apply {
+                                            if (colorModel != null) {
+                                                val (ids, colors) =
+                                                    materialColorsGenerator.generate(
+                                                        colorModel.colorOption.seedColor,
+                                                        colorModel.colorOption.style,
+                                                    )
+                                                putIntArray(KEY_COLOR_RESOURCE_IDS, ids)
+                                                putIntArray(KEY_COLOR_VALUES, colors)
+                                            }
+
+                                            putBoolean(KEY_DARK_MODE, darkMode)
+                                        }
+                                    workspaceCallback.sendMessage(MESSAGE_ID_UPDATE_COLOR, bundle)
+                                }
                         }
                     }
                 }
@@ -189,5 +191,6 @@
         const val MESSAGE_ID_UPDATE_COLOR = 856
         const val KEY_COLOR_RESOURCE_IDS: String = "color_resource_ids"
         const val KEY_COLOR_VALUES: String = "color_values"
+        const val KEY_DARK_MODE: String = "use_dark_mode"
     }
 }
diff --git a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
index 4e97599..a550119 100644
--- a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -14,10 +14,17 @@
 import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
 import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.wallpaper.module.NetworkStatusNotifier
+import com.android.wallpaper.module.PartnerProvider
+import com.android.wallpaper.module.WallpaperPreferences
 import com.android.wallpaper.module.logging.UserEventLogger
+import com.android.wallpaper.network.Requester
 import com.android.wallpaper.picker.category.wrapper.WallpaperCategoryWrapper
 import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
+import com.android.wallpaper.testing.FakeWallpaperClient
 import com.android.wallpaper.testing.TestInjector
+import com.android.wallpaper.util.DisplayUtils
 import javax.inject.Inject
 import javax.inject.Singleton
 
@@ -27,7 +34,27 @@
 constructor(
     private val customPrefs: TestDefaultCustomizationPreferences,
     private val themesUserEventLogger: ThemesUserEventLogger,
-) : TestInjector(themesUserEventLogger), CustomizationInjector {
+    displayUtils: DisplayUtils,
+    requester: Requester,
+    networkStatusNotifier: NetworkStatusNotifier,
+    partnerProvider: PartnerProvider,
+    wallpaperClient: FakeWallpaperClient,
+    injectedWallpaperInteractor: WallpaperInteractor,
+    prefs: WallpaperPreferences,
+    private val fakeWallpaperCategoryWrapper: WallpaperCategoryWrapper,
+) :
+    TestInjector(
+        themesUserEventLogger,
+        displayUtils,
+        requester,
+        networkStatusNotifier,
+        partnerProvider,
+        wallpaperClient,
+        injectedWallpaperInteractor,
+        prefs,
+        fakeWallpaperCategoryWrapper,
+    ),
+    CustomizationInjector {
     /////////////////
     // CustomizationInjector implementations
     /////////////////
@@ -82,6 +109,6 @@
     }
 
     override fun getWallpaperCategoryWrapper(): WallpaperCategoryWrapper {
-        return super.fakeWallpaperCategoryWrapper
+        return fakeWallpaperCategoryWrapper
     }
 }
diff --git a/tests/robotests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt b/tests/robotests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
index 870d9f5..63c27ed 100644
--- a/tests/robotests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
@@ -33,6 +33,11 @@
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import com.android.themepicker.R
 import com.android.wallpaper.module.InjectorProvider
+import com.android.wallpaper.module.NetworkStatusNotifier
+import com.android.wallpaper.module.PartnerProvider
+import com.android.wallpaper.module.WallpaperPreferences
+import com.android.wallpaper.network.Requester
+import com.android.wallpaper.picker.category.wrapper.WallpaperCategoryWrapper
 import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
 import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
 import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository
@@ -43,6 +48,8 @@
 import com.android.wallpaper.testing.TestInjector
 import com.android.wallpaper.testing.TestWallpaperPreferences
 import com.android.wallpaper.testing.collectLastValue
+import com.android.wallpaper.util.DisplayUtils
+import com.android.wallpaper.util.DisplaysProvider
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import kotlinx.coroutines.Dispatchers
@@ -56,6 +63,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
 import org.robolectric.RobolectricTestRunner
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -75,7 +83,6 @@
 
     @Before
     fun setUp() {
-        InjectorProvider.setInjector(TestInjector(logger))
         context = ApplicationProvider.getApplicationContext()
         val testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)
@@ -100,8 +107,21 @@
                         client = FakeWallpaperClient(),
                         wallpaperPreferences = TestWallpaperPreferences(),
                         backgroundDispatcher = testDispatcher,
-                    ),
+                    )
             )
+        InjectorProvider.setInjector(
+            TestInjector(
+                logger,
+                DisplayUtils(context, mock(DisplaysProvider::class.java)),
+                mock(Requester::class.java),
+                mock(NetworkStatusNotifier::class.java),
+                mock(PartnerProvider::class.java),
+                FakeWallpaperClient(),
+                wallpaperInteractor,
+                mock(WallpaperPreferences::class.java),
+                mock(WallpaperCategoryWrapper::class.java),
+            )
+        )
         underTest =
             KeyguardQuickAffordancePickerViewModel.Factory(
                     context = context,
@@ -348,12 +368,12 @@
                         icon1 =
                             Icon.Loaded(
                                 FakeCustomizationProviderClient.ICON_1,
-                                Text.Loaded("Left shortcut")
+                                Text.Loaded("Left shortcut"),
                             ),
                         icon2 =
                             Icon.Loaded(
                                 FakeCustomizationProviderClient.ICON_3,
-                                Text.Loaded("Right shortcut")
+                                Text.Loaded("Right shortcut"),
                             ),
                     )
                 )
@@ -376,7 +396,7 @@
                         icon1 =
                             Icon.Loaded(
                                 FakeCustomizationProviderClient.ICON_1,
-                                Text.Loaded("Left shortcut")
+                                Text.Loaded("Left shortcut"),
                             ),
                         icon2 = null,
                     )
@@ -404,7 +424,7 @@
                         icon2 =
                             Icon.Loaded(
                                 FakeCustomizationProviderClient.ICON_3,
-                                Text.Loaded("Right shortcut")
+                                Text.Loaded("Right shortcut"),
                             ),
                     )
                 )
@@ -465,11 +485,7 @@
         assertThat(affordances).isNotNull()
         affordances?.forEach { affordance ->
             val nameMatchesSelectedName =
-                Text.evaluationEquals(
-                    context,
-                    affordance.text,
-                    Text.Loaded(selectedAffordanceText),
-                )
+                Text.evaluationEquals(context, affordance.text, Text.Loaded(selectedAffordanceText))
             val isSelected: Boolean? = collectLastValue(affordance.isSelected).invoke()
             assertWithMessage(
                     "Expected affordance with name \"${affordance.text}\" to have" +