Unified screen preview section (2/3).

Implementation of a new section where we show the preview of the lock
screen and home screen and switch between them.

Fix: 263507648
Test: manually verified that switching between the lock screen and home
screen tabs properly updates the preview. Also, scrolling up and down
faithfully moves the preview view on on the screen without rendering
artifacts.

Change-Id: I59a2d70f4a1dee8dda12fdc94a1df03fe5fd4e72
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index 1540a09..1097a71 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -23,7 +23,9 @@
 import com.android.wallpaper.model.WallpaperPreviewNavigator;
 import com.android.wallpaper.model.WallpaperSectionController;
 import com.android.wallpaper.model.WorkspaceViewModel;
+import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
 import com.android.wallpaper.module.CustomizationSections;
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewSectionController;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -54,14 +56,18 @@
             PermissionRequester permissionRequester,
             WallpaperPreviewNavigator wallpaperPreviewNavigator,
             CustomizationSectionNavigationController sectionNavigationController,
-            @Nullable Bundle savedInstanceState) {
+            @Nullable Bundle savedInstanceState,
+            CurrentWallpaperInfoFactory wallpaperInfoFactory) {
         List<CustomizationSectionController<?>> sectionControllers = new ArrayList<>();
 
         // Wallpaper section.
-        sectionControllers.add(new WallpaperSectionController(
-                activity, lifecycleOwner, permissionRequester, wallpaperColorsViewModel,
-                workspaceViewModel, sectionNavigationController, wallpaperPreviewNavigator,
-                savedInstanceState));
+        sectionControllers.add(
+                new ScreenPreviewSectionController(
+                        activity,
+                        lifecycleOwner,
+                        screen,
+                        wallpaperInfoFactory,
+                        wallpaperColorsViewModel));
 
         // Theme color section.
         sectionControllers.add(new ColorSectionController(
diff --git a/src/com/android/customization/module/ThemePickerInjector.java b/src/com/android/customization/module/ThemePickerInjector.java
index 93c4d5f..a33541c 100644
--- a/src/com/android/customization/module/ThemePickerInjector.java
+++ b/src/com/android/customization/module/ThemePickerInjector.java
@@ -170,7 +170,8 @@
                     new KeyguardQuickAffordancePickerViewModel.Factory(
                             context,
                             getKeyguardQuickAffordancePickerInteractor(context),
-                            getUndoInteractor(context));
+                            getUndoInteractor(context),
+                            getCurrentWallpaperInfoFactory(context));
         }
         return mKeyguardQuickAffordancePickerViewModelFactory;
     }
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
index c6cdcaa..c8fea0f 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
@@ -27,7 +27,6 @@
 import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
 import com.android.wallpaper.R
-import com.android.wallpaper.model.WallpaperInfo
 import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder
 import kotlinx.coroutines.launch
 
@@ -40,7 +39,6 @@
         previewView: CardView,
         viewModel: KeyguardQuickAffordancePickerViewModel,
         lifecycleOwner: LifecycleOwner,
-        wallpaperInfoProvider: suspend () -> WallpaperInfo?,
     ) {
         val binding =
             ScreenPreviewBinder.bind(
@@ -48,7 +46,6 @@
                 previewView = previewView,
                 viewModel = viewModel.preview,
                 lifecycleOwner = lifecycleOwner,
-                wallpaperInfoProvider = wallpaperInfoProvider,
             )
 
         previewView.contentDescription =
diff --git a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
index f37b246..d2245db 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
@@ -32,7 +32,6 @@
 import com.android.wallpaper.picker.AppbarFragment
 import com.android.wallpaper.picker.undo.ui.binder.RevertToolbarButtonBinder
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.suspendCancellableCoroutine
 
 @OptIn(ExperimentalCoroutinesApi::class)
 class KeyguardQuickAffordancePickerFragment : AppbarFragment() {
@@ -57,7 +56,6 @@
             )
         setUpToolbar(view)
         val injector = InjectorProvider.getInjector() as ThemePickerInjector
-        val wallpaperInfoFactory = injector.getCurrentWallpaperInfoFactory(requireContext())
         val viewModel: KeyguardQuickAffordancePickerViewModel =
             ViewModelProvider(
                     requireActivity(),
@@ -76,16 +74,6 @@
             previewView = view.requireViewById(R.id.preview),
             viewModel = viewModel,
             lifecycleOwner = this,
-            wallpaperInfoProvider = {
-                suspendCancellableCoroutine { continuation ->
-                    wallpaperInfoFactory.createCurrentWallpaperInfos(
-                        { homeWallpaper, lockWallpaper, _ ->
-                            continuation.resume(lockWallpaper ?: homeWallpaper, null)
-                        },
-                        /* forceRefresh= */ true,
-                    )
-                }
-            },
         )
         KeyguardQuickAffordancePickerBinder.bind(
             view = view,
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
index aa64d9b..f87c099 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
@@ -31,9 +31,11 @@
 import com.android.systemui.shared.quickaffordance.data.content.KeyguardQuickAffordanceProviderContract as Contract
 import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
 import com.android.wallpaper.R
+import com.android.wallpaper.module.CurrentWallpaperInfoFactory
 import com.android.wallpaper.picker.customization.ui.viewmodel.ScreenPreviewViewModel
 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
 import com.android.wallpaper.picker.undo.ui.viewmodel.UndoViewModel
+import com.android.wallpaper.util.PreviewUtils
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -42,6 +44,7 @@
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
 
 /** Models UI state for a lock screen quick affordance picker experience. */
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -50,25 +53,40 @@
     context: Context,
     private val quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor,
     undoInteractor: UndoInteractor,
+    private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
 ) : ViewModel() {
 
     @SuppressLint("StaticFieldLeak") private val applicationContext = context.applicationContext
 
-    val preview: ScreenPreviewViewModel
-        get() =
-            ScreenPreviewViewModel(
-                contentProviderAuthorityProvider = {
-                    applicationContext.getString(R.string.lock_screen_preview_provider_authority)
-                },
-                initialExtrasProvider = {
-                    Bundle().apply {
-                        putString(
-                            KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
-                            selectedSlotId.value,
-                        )
-                    }
-                },
-            )
+    val preview =
+        ScreenPreviewViewModel(
+            previewUtils =
+                PreviewUtils(
+                    context = applicationContext,
+                    authority =
+                        applicationContext.getString(
+                            R.string.lock_screen_preview_provider_authority,
+                        ),
+                ),
+            initialExtrasProvider = {
+                Bundle().apply {
+                    putString(
+                        KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
+                        selectedSlotId.value,
+                    )
+                }
+            },
+            wallpaperInfoProvider = {
+                suspendCancellableCoroutine { continuation ->
+                    wallpaperInfoFactory.createCurrentWallpaperInfos(
+                        { homeWallpaper, lockWallpaper, _ ->
+                            continuation.resume(lockWallpaper ?: homeWallpaper, null)
+                        },
+                        /* forceRefresh= */ true,
+                    )
+                }
+            },
+        )
 
     val undo: UndoViewModel =
         UndoViewModel(
@@ -349,6 +367,7 @@
         private val context: Context,
         private val quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor,
         private val undoInteractor: UndoInteractor,
+        private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
     ) : ViewModelProvider.Factory {
         override fun <T : ViewModel> create(modelClass: Class<T>): T {
             @Suppress("UNCHECKED_CAST")
@@ -356,6 +375,7 @@
                 context = context,
                 quickAffordanceInteractor = quickAffordanceInteractor,
                 undoInteractor = undoInteractor,
+                wallpaperInfoFactory = wallpaperInfoFactory,
             )
                 as T
         }
diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
index 3ec893a..9c3e87c 100644
--- a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
@@ -33,6 +33,7 @@
 import com.android.wallpaper.picker.undo.data.repository.UndoRepository
 import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
 import com.android.wallpaper.testing.FAKE_RESTORERS
+import com.android.wallpaper.testing.TestCurrentWallpaperInfoFactory
 import com.android.wallpaper.testing.collectLastValue
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
@@ -97,6 +98,7 @@
                     context = context,
                     quickAffordanceInteractor = quickAffordanceInteractor,
                     undoInteractor = undoInteractor,
+                    wallpaperInfoFactory = TestCurrentWallpaperInfoFactory(context),
                 )
                 .create(KeyguardQuickAffordancePickerViewModel::class.java)
     }