Use -Xjvm-default=all instead of -Xjvm-default=enable or @JvmDefault am: 9088a4531c am: 8fc3abd355 am: 87919cd455 am: 1c2ffff125

Original change: https://android-review.googlesource.com/c/platform/packages/apps/ThemePicker/+/2666060

Change-Id: Ie9c83ac2974349effd81d66715654a49ef847f0e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bff2d76
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.iml
diff --git a/Android.bp b/Android.bp
index 3694ea0..84111af 100644
--- a/Android.bp
+++ b/Android.bp
@@ -82,6 +82,7 @@
         "androidx.lifecycle_lifecycle-viewmodel-ktx",
         "androidx.recyclerview_recyclerview",
         "SystemUICustomizationLib",
+        "hilt_android",
     ],
 
     jni_libs: [
diff --git a/res/values-h800dp/dimens.xml b/res/values-h800dp/dimens.xml
deleted file mode 100644
index 36d0d62..0000000
--- a/res/values-h800dp/dimens.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<resources>
-    <!--
-    Dimension for clock translationY when swiping clock carousel in picker,
-    copied from sysui resources
-    -->
-    <dimen name="keyguard_large_clock_top_margin">-112dp</dimen>
-</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a3e0d4a..47171e5 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -170,14 +170,4 @@
     <dimen name="clock_color_size_button_corner_radius">16dp</dimen>
     <dimen name="clock_color_size_button_icon_size">20dp</dimen>
     <dimen name="clock_color_size_button_icon_margin_end">12dp</dimen>
-
-    <!--
-    Dimension for clock translationY when swiping clock carousel in picker,
-    copied from sysui resources
-    -->
-    <dimen name="keyguard_large_clock_top_margin">-60dp</dimen>
-    <!-- Dimension for the clock view, copied from sysui resources. -->
-    <dimen name="small_clock_height">114dp</dimen>
-    <dimen name="small_clock_padding_top">28dp</dimen>
-    <dimen name="clock_padding_start">28dp</dimen>
 </resources>
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index b408a89..04d331e 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -122,7 +122,8 @@
                         wallpaperInteractor,
                         mThemedIconInteractor,
                         wallpaperManager,
-                        isTwoPaneAndSmallWidth)
+                        isTwoPaneAndSmallWidth,
+                        savedInstanceState)
                         : new PreviewWithThemeSectionController(
                                 activity,
                                 lifecycleOwner,
@@ -134,7 +135,8 @@
                                 wallpaperInteractor,
                                 mThemedIconInteractor,
                                 wallpaperManager,
-                                isTwoPaneAndSmallWidth));
+                                isTwoPaneAndSmallWidth,
+                                savedInstanceState));
 
         sectionControllers.add(
                 new ConnectedSectionController(
diff --git a/src/com/android/customization/module/StatsLogUserEventLogger.java b/src/com/android/customization/module/StatsLogUserEventLogger.java
index 32e0599..057234b 100644
--- a/src/com/android/customization/module/StatsLogUserEventLogger.java
+++ b/src/com/android/customization/module/StatsLogUserEventLogger.java
@@ -37,7 +37,6 @@
 import static com.android.wallpaper.util.LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE;
 
 import android.app.WallpaperManager;
-import android.content.Context;
 import android.content.Intent;
 import android.stats.style.StyleEnums;
 import android.text.TextUtils;
@@ -47,8 +46,6 @@
 import com.android.customization.model.color.ColorOption;
 import com.android.customization.model.grid.GridOption;
 import com.android.customization.model.theme.ThemeBundle;
-import com.android.wallpaper.module.Injector;
-import com.android.wallpaper.module.InjectorProvider;
 import com.android.wallpaper.module.NoOpUserEventLogger;
 import com.android.wallpaper.module.WallpaperPreferences;
 import com.android.wallpaper.module.WallpaperStatusChecker;
@@ -61,86 +58,59 @@
  */
 public class StatsLogUserEventLogger extends NoOpUserEventLogger implements ThemesUserEventLogger {
 
-    private static final String TAG = "StatsLogUserEventLogger";
-    private final Context mContext;
     private final WallpaperPreferences mPreferences;
     private final WallpaperStatusChecker mWallpaperStatusChecker;
 
-    public StatsLogUserEventLogger(Context appContext) {
-        mContext = appContext;
-        Injector injector = InjectorProvider.getInjector();
-        mPreferences = injector.getPreferences(appContext);
-        mWallpaperStatusChecker = injector.getWallpaperStatusChecker();
+    public StatsLogUserEventLogger(
+            WallpaperPreferences preferences,
+            WallpaperStatusChecker wallpaperStatusChecker) {
+        mPreferences = preferences;
+        mWallpaperStatusChecker = wallpaperStatusChecker;
     }
 
     @Override
     public void logAppLaunched(Intent launchSource) {
-        new SysUiStatsLogger()
-                .setAction(STYLE_UICHANGED__ACTION__APP_LAUNCHED)
+        new SysUiStatsLogger(STYLE_UICHANGED__ACTION__APP_LAUNCHED)
                 .setLaunchedPreference(getAppLaunchSource(launchSource))
                 .log();
     }
 
     @Override
     public void logResumed(boolean provisioned, boolean wallpaper) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.ONRESUME)
+        new SysUiStatsLogger(StyleEnums.ONRESUME)
                 .log();
     }
 
     @Override
     public void logStopped() {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.ONSTOP)
+        new SysUiStatsLogger(StyleEnums.ONSTOP)
                 .log();
     }
 
     @Override
     public void logActionClicked(String collectionId, int actionLabelResId) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_EXPLORE)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_EXPLORE)
                 .setWallpaperCategoryHash(getIdHashCode(collectionId))
                 .log();
     }
 
     @Override
     public void logIndividualWallpaperSelected(String collectionId) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_SELECT)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_SELECT)
                 .setWallpaperCategoryHash(getIdHashCode(collectionId))
                 .log();
     }
 
     @Override
     public void logCategorySelected(String collectionId) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_OPEN_CATEGORY)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_OPEN_CATEGORY)
                 .setWallpaperCategoryHash(getIdHashCode(collectionId))
                 .log();
     }
 
     @Override
-    public void logLiveWallpaperInfoSelected(String collectionId, @Nullable String wallpaperId) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.LIVE_WALLPAPER_INFO_SELECT)
-                .setWallpaperCategoryHash(getIdHashCode(collectionId))
-                .setWallpaperIdHash(getIdHashCode(wallpaperId))
-                .log();
-    }
-
-    @Override
-    public void logLiveWallpaperCustomizeSelected(String collectionId,
-            @Nullable String wallpaperId) {
-        new SysUiStatsLogger().setAction(StyleEnums.LIVE_WALLPAPER_CUSTOMIZE_SELECT)
-                .setWallpaperCategoryHash(getIdHashCode(collectionId))
-                .setWallpaperIdHash(getIdHashCode(wallpaperId))
-                .log();
-
-    }
-
-    @Override
     public void logSnapshot() {
-        final boolean isLockWallpaperSet = mWallpaperStatusChecker.isLockWallpaperSet(mContext);
+        final boolean isLockWallpaperSet = mWallpaperStatusChecker.isLockWallpaperSet();
         final String homeCollectionId = mPreferences.getHomeWallpaperCollectionId();
         final String homeRemoteId = mPreferences.getHomeWallpaperRemoteId();
         final String effects = mPreferences.getHomeWallpaperEffects();
@@ -151,7 +121,7 @@
         String lockWallpaperId = isLockWallpaperSet ? mPreferences.getLockWallpaperRemoteId()
                 : homeWallpaperId;
 
-        new SysUiStatsLogger().setAction(StyleEnums.SNAPSHOT)
+        new SysUiStatsLogger(StyleEnums.SNAPSHOT)
                 .setWallpaperCategoryHash(getIdHashCode(homeCollectionId))
                 .setWallpaperIdHash(getIdHashCode(homeWallpaperId))
                 .setLockWallpaperCategoryHash(getIdHashCode(lockCollectionId))
@@ -167,8 +137,7 @@
     @Override
     public void logWallpaperSet(String collectionId, @Nullable String wallpaperId,
             @Nullable String effects) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_APPLIED)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_APPLIED)
                 .setWallpaperCategoryHash(getIdHashCode(collectionId))
                 .setWallpaperIdHash(getIdHashCode(wallpaperId))
                 .setEffectIdHash(getIdHashCode(effects))
@@ -178,8 +147,7 @@
     @Override
     public void logEffectApply(String effect, @EffectStatus int status, long timeElapsedMillis,
             int resultCode) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_EFFECT_APPLIED)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_EFFECT_APPLIED)
                 .setEffectPreference(status)
                 .setEffectIdHash(getIdHashCode(effect))
                 .setTimeElapsed(timeElapsedMillis)
@@ -189,8 +157,7 @@
 
     @Override
     public void logEffectProbe(String effect, @EffectStatus int status) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.WALLPAPER_EFFECT_PROBE)
+        new SysUiStatsLogger(StyleEnums.WALLPAPER_EFFECT_PROBE)
                 .setEffectPreference(status)
                 .setEffectIdHash(getIdHashCode(effect))
                 .log();
@@ -204,8 +171,7 @@
 
     @Override
     public void logThemeSelected(ThemeBundle theme, boolean isCustomTheme) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.PICKER_SELECT)
+        new SysUiStatsLogger(StyleEnums.PICKER_SELECT)
                 .setColorPackageHash(
                         Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_COLOR)))
                 .setFontPackageHash(Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_FONT)))
@@ -216,8 +182,7 @@
 
     @Override
     public void logThemeApplied(ThemeBundle theme, boolean isCustomTheme) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.PICKER_APPLIED)
+        new SysUiStatsLogger(StyleEnums.PICKER_APPLIED)
                 .setColorPackageHash(
                         Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_COLOR)))
                 .setFontPackageHash(Objects.hashCode(getThemePackage(theme, OVERLAY_CATEGORY_FONT)))
@@ -228,8 +193,7 @@
 
     @Override
     public void logColorApplied(int action, ColorOption colorOption) {
-        new SysUiStatsLogger()
-                .setAction(action)
+        new SysUiStatsLogger(action)
                 .setColorPreference(colorOption.getIndex())
                 .setColorVariant(colorOption.getStyle().ordinal() + 1)
                 .log();
@@ -237,16 +201,14 @@
 
     @Override
     public void logGridSelected(GridOption grid) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.PICKER_SELECT)
+        new SysUiStatsLogger(StyleEnums.PICKER_SELECT)
                 .setLauncherGrid(grid.cols)
                 .log();
     }
 
     @Override
     public void logGridApplied(GridOption grid) {
-        new SysUiStatsLogger()
-                .setAction(StyleEnums.PICKER_APPLIED)
+        new SysUiStatsLogger(StyleEnums.PICKER_APPLIED)
                 .setLauncherGrid(grid.cols)
                 .log();
     }
diff --git a/src/com/android/customization/module/SysUiStatsLogger.kt b/src/com/android/customization/module/SysUiStatsLogger.kt
index 318bf1f..8e97b0b 100644
--- a/src/com/android/customization/module/SysUiStatsLogger.kt
+++ b/src/com/android/customization/module/SysUiStatsLogger.kt
@@ -20,10 +20,8 @@
 import com.android.systemui.shared.system.SysUiStatsLog.STYLE_UI_CHANGED
 
 /** The builder for [SysUiStatsLog]. */
-class SysUiStatsLogger {
+class SysUiStatsLogger(val action: Int) {
 
-    private var atom = STYLE_UI_CHANGED
-    private var action = StyleEnums.DEFAULT_ACTION
     private var colorPackageHash = 0
     private var fontPackageHash = 0
     private var shapePackageHash = 0
@@ -46,85 +44,83 @@
     private var timeElapsedMillis = 0L
     private var effectResultCode = -1
 
-    fun setAction(action: Int) = apply { this.action = action }
-
-    fun setColorPackageHash(color_package_hash: Int) = apply {
-        this.colorPackageHash = color_package_hash
+    fun setColorPackageHash(colorPackageHash: Int) = apply {
+        this.colorPackageHash = colorPackageHash
     }
 
-    fun setFontPackageHash(font_package_hash: Int) = apply {
-        this.fontPackageHash = font_package_hash
+    fun setFontPackageHash(fontPackageHash: Int) = apply {
+        this.fontPackageHash = fontPackageHash
     }
 
-    fun setShapePackageHash(shape_package_hash: Int) = apply {
-        this.shapePackageHash = shape_package_hash
+    fun setShapePackageHash(shapePackageHash: Int) = apply {
+        this.shapePackageHash = shapePackageHash
     }
 
-    fun setClockPackageHash(clock_package_hash: Int) = apply {
-        this.clockPackageHash = clock_package_hash
+    fun setClockPackageHash(clockPackageHash: Int) = apply {
+        this.clockPackageHash = clockPackageHash
     }
 
-    fun setLauncherGrid(launcher_grid: Int) = apply { this.launcherGrid = launcher_grid }
+    fun setLauncherGrid(launcherGrid: Int) = apply { this.launcherGrid = launcherGrid }
 
-    fun setWallpaperCategoryHash(wallpaper_category_hash: Int) = apply {
-        this.wallpaperCategoryHash = wallpaper_category_hash
+    fun setWallpaperCategoryHash(wallpaperCategoryHash: Int) = apply {
+        this.wallpaperCategoryHash = wallpaperCategoryHash
     }
 
-    fun setWallpaperIdHash(wallpaper_id_hash: Int) = apply {
-        this.wallpaperIdHash = wallpaper_id_hash
+    fun setWallpaperIdHash(wallpaperIdHash: Int) = apply {
+        this.wallpaperIdHash = wallpaperIdHash
     }
 
-    fun setColorPreference(color_preference: Int) = apply {
-        this.colorPreference = color_preference
+    fun setColorPreference(colorPreference: Int) = apply {
+        this.colorPreference = colorPreference
     }
 
-    fun setLocationPreference(location_preference: Int) = apply {
-        this.locationPreference = location_preference
+    fun setLocationPreference(locationPreference: Int) = apply {
+        this.locationPreference = locationPreference
     }
 
-    fun setDatePreference(date_preference: Int) = apply { this.datePreference = date_preference }
+    fun setDatePreference(datePreference: Int) = apply { this.datePreference = datePreference }
 
-    fun setLaunchedPreference(launched_preference: Int) = apply {
-        this.launchedPreference = launched_preference
+    fun setLaunchedPreference(launchedPreference: Int) = apply {
+        this.launchedPreference = launchedPreference
     }
 
-    fun setEffectPreference(effect_preference: Int) = apply {
-        this.effectPreference = effect_preference
+    fun setEffectPreference(effectPreference: Int) = apply {
+        this.effectPreference = effectPreference
     }
 
-    fun setEffectIdHash(effect_id_hash: Int) = apply { this.effectIdHash = effect_id_hash }
+    fun setEffectIdHash(effectIdHash: Int) = apply { this.effectIdHash = effectIdHash }
 
-    fun setLockWallpaperCategoryHash(lock_wallpaper_category_hash: Int) = apply {
-        this.lockWallpaperCategoryHash = lock_wallpaper_category_hash
+    fun setLockWallpaperCategoryHash(lockWallpaperCategoryHash: Int) = apply {
+        this.lockWallpaperCategoryHash = lockWallpaperCategoryHash
     }
 
-    fun setLockWallpaperIdHash(lock_wallpaper_id_hash: Int) = apply {
-        this.lockWallpaperIdHash = lock_wallpaper_id_hash
+    fun setLockWallpaperIdHash(lockWallpaperIdHash: Int) = apply {
+        this.lockWallpaperIdHash = lockWallpaperIdHash
     }
 
-    fun setFirstLaunchDateSinceSetup(first_launch_date_since_setup: Int) = apply {
-        this.firstLaunchDateSinceSetup = first_launch_date_since_setup
+    fun setFirstLaunchDateSinceSetup(firstLaunchDateSinceSetup: Int) = apply {
+        this.firstLaunchDateSinceSetup = firstLaunchDateSinceSetup
     }
 
-    fun setFirstWallpaperApplyDateSinceSetup(first_wallpaper_apply_date_since_setup: Int) = apply {
-        this.firstWallpaperApplyDateSinceSetup = first_wallpaper_apply_date_since_setup
+    fun setFirstWallpaperApplyDateSinceSetup(firstWallpaperApplyDateSinceSetup: Int) = apply {
+        this.firstWallpaperApplyDateSinceSetup = firstWallpaperApplyDateSinceSetup
     }
 
-    fun setAppLaunchCount(app_launch_count: Int) = apply { this.appLaunchCount = app_launch_count }
+    fun setAppLaunchCount(appLaunchCount: Int) = apply { this.appLaunchCount = appLaunchCount }
 
-    fun setColorVariant(color_variant: Int) = apply { this.colorVariant = color_variant }
+    fun setColorVariant(colorVariant: Int) = apply { this.colorVariant = colorVariant }
 
-    fun setTimeElapsed(time_elapsed_millis: Long) = apply {
-      this.timeElapsedMillis = time_elapsed_millis
+    fun setTimeElapsed(timeElapsedMillis: Long) = apply {
+      this.timeElapsedMillis = timeElapsedMillis
     }
 
-    fun setEffectResultCode(effect_result_code: Int) = apply {
-        this.effectResultCode = effect_result_code
+    fun setEffectResultCode(effectResultCode: Int) = apply {
+        this.effectResultCode = effectResultCode
     }
 
     fun log() {
         SysUiStatsLog.write(
-            atom,
+            STYLE_UI_CHANGED,
             action,
             colorPackageHash,
             fontPackageHash,
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index cceb896..0c7294f 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -183,8 +183,12 @@
 
     @Synchronized
     override fun getUserEventLogger(context: Context): ThemesUserEventLogger {
-        return if (userEventLogger != null) userEventLogger as ThemesUserEventLogger
-        else StatsLogUserEventLogger(context.applicationContext).also { userEventLogger = it }
+        return userEventLogger as? ThemesUserEventLogger
+            ?: StatsLogUserEventLogger(
+                    getPreferences(context.applicationContext),
+                    getWallpaperStatusChecker(context.applicationContext),
+                )
+                .also { userEventLogger = it }
     }
 
     @Synchronized
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 be6c6cb..aeed45e 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -33,6 +33,7 @@
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapLatest
@@ -56,7 +57,7 @@
                         registry
                             .getClocks()
                             .filter { "NOT_IN_USE" !in it.clockId }
-                            .map { it.toModel() }
+                            .map { it.toModel(isSelected = it.clockId == registry.currentClockId) }
                     trySend(allClocks)
                 }
 
@@ -90,6 +91,7 @@
                             .getClocks()
                             .find { clockMetadata -> clockMetadata.clockId == currentClockId }
                             ?.toModel(
+                                isSelected = true,
                                 selectedColorId = metadata?.getSelectedColorId(),
                                 colorTone = metadata?.getColorTone()
                                         ?: ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
@@ -146,9 +148,10 @@
             )
             .map { setting -> setting == 1 }
             .map { isDynamic -> if (isDynamic) ClockSize.DYNAMIC else ClockSize.SMALL }
+            .distinctUntilChanged()
             .shareIn(
                 scope = scope,
-                started = SharingStarted.WhileSubscribed(),
+                started = SharingStarted.Eagerly,
                 replay = 1,
             )
 
@@ -176,6 +179,7 @@
 
     /** By default, [ClockMetadataModel] has no color information unless specified. */
     private fun ClockMetadata.toModel(
+        isSelected: Boolean,
         selectedColorId: String? = null,
         @IntRange(from = 0, to = 100) colorTone: Int = 0,
         @ColorInt seedColor: Int? = null,
@@ -183,6 +187,7 @@
         return ClockMetadataModel(
             clockId = clockId,
             name = name,
+            isSelected = isSelected,
             selectedColorId = selectedColorId,
             colorToneProgress = colorTone,
             seedColor = seedColor,
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt b/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt
index 652ffdd..b197edf 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.shared.plugins.PluginManagerImpl
 import com.android.systemui.shared.plugins.PluginPrefs
 import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager_Factory
+import com.android.wallpaper.module.InjectorProvider
 import java.util.concurrent.Executors
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
@@ -55,6 +56,8 @@
             DefaultClockProvider(context, LayoutInflater.from(context), context.resources),
             keepAllLoaded = true,
             subTag = "Picker",
+            isTransitClockEnabled =
+                InjectorProvider.getInjector().getFlags().isTransitClockEnabled(context)
         )
     }
 
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 bd87ba6..2522507 100644
--- a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -24,6 +24,7 @@
 data class ClockMetadataModel(
     val clockId: String,
     val name: String,
+    val isSelected: Boolean,
     val selectedColorId: String?,
     @IntRange(from = 0, to = 100) val colorToneProgress: Int,
     @ColorInt val seedColor: Int?,
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 4f4bd1b..6e745d5 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -33,6 +33,7 @@
 import androidx.recyclerview.widget.RecyclerView
 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.ClockSizeRadioButtonGroup
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
@@ -199,7 +200,7 @@
                                     sizeOptions.radioButtonDynamic.isChecked = false
                                     sizeOptions.radioButtonSmall.isChecked = true
                                     clockHostView.doOnPreDraw {
-                                        it.pivotX = 0F
+                                        it.pivotX = ClockCarouselView.getCenteredHostViewPivotX(it)
                                         it.pivotY = 0F
                                     }
                                 }
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
deleted file mode 100644
index f138d6a..0000000
--- a/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.android.customization.picker.clock.ui.fragment
-
-import android.content.Context
-import android.os.Bundle
-import android.util.TypedValue
-import android.view.ContextThemeWrapper
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.widget.FrameLayout
-import android.widget.TextView
-import android.widget.Toast
-import androidx.core.view.setPadding
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.customization.module.ThemePickerInjector
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.shared.clocks.ClockRegistry
-import com.android.wallpaper.R
-import com.android.wallpaper.module.InjectorProvider
-import com.android.wallpaper.picker.AppbarFragment
-
-class ClockCustomDemoFragment : AppbarFragment() {
-    @VisibleForTesting lateinit var recyclerView: RecyclerView
-    @VisibleForTesting lateinit var clockRegistry: ClockRegistry
-
-    override fun onCreateView(
-        inflater: LayoutInflater,
-        container: ViewGroup?,
-        savedInstanceState: Bundle?
-    ): View {
-        val view = inflater.inflate(R.layout.fragment_clock_custom_picker_demo, container, false)
-        setUpToolbar(view)
-        clockRegistry =
-            (InjectorProvider.getInjector() as ThemePickerInjector).getClockRegistry(
-                requireContext(),
-            )
-        val listInUse = clockRegistry.getClocks().filter { "NOT_IN_USE" !in it.clockId }
-
-        recyclerView = view.requireViewById(R.id.clock_preview_card_list_demo)
-        recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
-        recyclerView.adapter =
-            ClockRecyclerAdapter(listInUse, requireContext()) {
-                clockRegistry.currentClockId = it.clockId
-                Toast.makeText(context, "${it.name} selected", Toast.LENGTH_SHORT).show()
-            }
-        return view
-    }
-
-    override fun getDefaultTitle(): CharSequence {
-        return getString(R.string.clock_title)
-    }
-
-    internal class ClockRecyclerAdapter(
-        val list: List<ClockMetadata>,
-        val context: Context,
-        val onClockSelected: (ClockMetadata) -> Unit
-    ) : RecyclerView.Adapter<ClockRecyclerAdapter.ViewHolder>() {
-        class ViewHolder(val view: View, val textView: TextView, val onItemClicked: (Int) -> Unit) :
-            RecyclerView.ViewHolder(view) {
-            init {
-                itemView.setOnClickListener { onItemClicked(absoluteAdapterPosition) }
-            }
-        }
-
-        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
-            val rootView = FrameLayout(viewGroup.context)
-            val textView =
-                TextView(ContextThemeWrapper(viewGroup.context, R.style.SectionTitleTextStyle))
-            textView.setPadding(ITEM_PADDING)
-            rootView.addView(textView)
-            val outValue = TypedValue()
-            context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
-            rootView.setBackgroundResource(outValue.resourceId)
-            val lp = RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
-            rootView.layoutParams = lp
-            return ViewHolder(rootView, textView) { onClockSelected(list[it]) }
-        }
-
-        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
-            viewHolder.textView.text = list[position].name
-        }
-
-        override fun getItemCount() = list.size
-
-        companion object {
-            val ITEM_PADDING = 40
-        }
-    }
-}
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 8764e54..aa6cc91 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -71,17 +71,31 @@
         clockViewFactory = factory
     }
 
+    // This function is for the custom accessibility action to trigger a transition to the next
+    // carousel item. If the current item is the last item in the carousel, the next item
+    // will be the first item.
     fun transitionToNext() {
-        val index = (carousel.currentIndex + 1) % carousel.count
-        if (index < carousel.count && index > 0) {
-            carousel.transitionToIndex(index, 0)
+        if (carousel.count != 0) {
+            val index = (carousel.currentIndex + 1) % carousel.count
+            carousel.jumpToIndex(index)
+            // Explicitly called this since using transitionToIndex(index) leads to
+            // race-condition between announcement of content description of the correct clock-face
+            // and the selection of clock face itself
+            adapter.onNewItem(index)
         }
     }
 
+    // This function is for the custom accessibility action to trigger a transition to
+    // the previous carousel item. If the current item is the first item in the carousel,
+    // the previous item will be the last item.
     fun transitionToPrevious() {
-        val index = (carousel.currentIndex - 1) % carousel.count
-        if (index < carousel.count && index > 0) {
-            carousel.transitionToIndex(index, 0)
+        if (carousel.count != 0) {
+            val index = (carousel.currentIndex + carousel.count - 1) % carousel.count
+            carousel.jumpToIndex(index)
+            // Explicitly called this since using transitionToIndex(index) leads to
+            // race-condition between announcement of content description of the correct clock-face
+            // and the selection of clock face itself
+            adapter.onNewItem(index)
         }
     }
 
@@ -101,7 +115,13 @@
 
         adapter = ClockCarouselAdapter(clockSize, clocks, clockViewFactory, onClockSelected)
         carousel.setAdapter(adapter)
-        carousel.refresh()
+        val indexOfSelectedClock =
+            clocks
+                .indexOfFirst { it.isSelected }
+                // If not found, default to the first clock as selected:
+                .takeIf { it != -1 }
+                ?: 0
+        carousel.jumpToIndex(indexOfSelectedClock)
         motionLayout.setTransitionListener(
             object : MotionLayout.TransitionListener {
 
@@ -211,11 +231,13 @@
                         }
                             ?: return
                     offCenterClockHostView.doOnPreDraw {
-                        it.pivotX = progress * it.width / 2
+                        it.pivotX =
+                            progress * it.width / 2 + (1 - progress) * getCenteredHostViewPivotX(it)
                         it.pivotY = progress * it.height / 2
                     }
                     toCenterClockHostView.doOnPreDraw {
-                        it.pivotX = (1 - progress) * it.width / 2
+                        it.pivotX =
+                            (1 - progress) * it.width / 2 + progress * getCenteredHostViewPivotX(it)
                         it.pivotY = (1 - progress) * it.height / 2
                     }
                     offCenterClockFrame.translationX =
@@ -265,9 +287,11 @@
     fun setSelectedClockIndex(
         index: Int,
     ) {
-        // jumpToIndex to the same position can cause the views unnecessarily populate again.
-        // Only call jumpToIndex when the jump-to index is different from the current carousel.
-        if (index != carousel.currentIndex) {
+        // 1. setUpClockCarouselView() can possibly not be called before setSelectedClockIndex().
+        //    We need to check if index out of bound.
+        // 2. jumpToIndex() to the same position can cause the views unnecessarily populate again.
+        //    We only call jumpToIndex when the index is different from the current carousel.
+        if (index < carousel.count && index != carousel.currentIndex) {
             carousel.jumpToIndex(index)
         }
     }
@@ -417,7 +441,7 @@
         ) {
             clockHostView.doOnPreDraw {
                 if (isMiddleView) {
-                    it.pivotX = 0F
+                    it.pivotX = getCenteredHostViewPivotX(it)
                     it.pivotY = 0F
                     clockView.translationX = 0F
                     clockView.translationY = 0F
@@ -507,6 +531,10 @@
             return rootViewId == R.id.item_view_2
         }
 
+        fun getCenteredHostViewPivotX(hostView: View): Float {
+            return if (hostView.isLayoutRtl) hostView.width.toFloat() else 0F
+        }
+
         private fun getTranslationDistance(
             hostLength: Int,
             frameLength: Int,
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselItemViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselItemViewModel.kt
index 708fa2f..ea2f776 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselItemViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselItemViewModel.kt
@@ -20,7 +20,7 @@
 import com.android.wallpaper.R
 import com.android.wallpaper.module.InjectorProvider
 
-class ClockCarouselItemViewModel(val clockId: String) {
+class ClockCarouselItemViewModel(val clockId: String, val isSelected: Boolean) {
 
     /** Description for accessibility purposes when a clock is selected. */
     fun getContentDescription(resources: Resources): String {
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
index a4f9cc4..7922054 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
@@ -50,7 +50,7 @@
             .mapLatest { allClocks ->
                 // Delay to avoid the case that the full list of clocks is not initiated.
                 delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
-                allClocks.map { ClockCarouselItemViewModel(it.clockId) }
+                allClocks.map { ClockCarouselItemViewModel(it.clockId, it.isSelected) }
             }
             .stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
 
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 8e91798..7cf3550 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -20,6 +20,7 @@
 import android.app.WallpaperManager
 import android.content.Context
 import android.graphics.Rect
+import android.os.Bundle
 import android.view.TouchDelegate
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
@@ -72,6 +73,7 @@
     themedIconInteractor: ThemedIconInteractor,
     wallpaperManager: WallpaperManager,
     private val isTwoPaneAndSmallWidth: Boolean,
+    savedInstanceState: Bundle?,
 ) :
     PreviewWithThemeSectionController(
         activity,
@@ -85,6 +87,7 @@
         themedIconInteractor,
         wallpaperManager,
         isTwoPaneAndSmallWidth,
+        savedInstanceState,
     ) {
 
     private val viewModel =
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 56c6c30..ba48b53 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithThemeSectionController.kt
@@ -20,6 +20,7 @@
 import android.app.Activity
 import android.app.WallpaperManager
 import android.content.Context
+import android.os.Bundle
 import androidx.lifecycle.LifecycleOwner
 import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
 import com.android.customization.picker.preview.ui.viewmodel.PreviewWithThemeViewModel
@@ -51,6 +52,7 @@
     private val themedIconInteractor: ThemedIconInteractor,
     wallpaperManager: WallpaperManager,
     isTwoPaneAndSmallWidth: Boolean,
+    savedInstanceState: Bundle?,
 ) :
     ScreenPreviewSectionController(
         activity,
@@ -62,7 +64,8 @@
         wallpaperPreviewNavigator,
         wallpaperInteractor,
         wallpaperManager,
-        isTwoPaneAndSmallWidth
+        isTwoPaneAndSmallWidth,
+        savedInstanceState,
     ) {
     override fun createScreenPreviewViewModel(context: Context): ScreenPreviewViewModel {
         return PreviewWithThemeViewModel(
diff --git a/src/com/android/customization/picker/CustomizationPickerApplication.java b/src_override/com/android/customization/picker/CustomizationPickerApplication.java
similarity index 80%
rename from src/com/android/customization/picker/CustomizationPickerApplication.java
rename to src_override/com/android/customization/picker/CustomizationPickerApplication.java
index 178cfbf..2e549ff 100644
--- a/src/com/android/customization/picker/CustomizationPickerApplication.java
+++ b/src_override/com/android/customization/picker/CustomizationPickerApplication.java
@@ -20,7 +20,13 @@
 import com.android.customization.module.ThemePickerInjector;
 import com.android.wallpaper.module.InjectorProvider;
 
-public class CustomizationPickerApplication extends Application {
+import dagger.hilt.android.HiltAndroidApp;
+
+/**
+ * Application subclass that initializes the injector.
+ */
+@HiltAndroidApp(Application.class)
+public class CustomizationPickerApplication extends Hilt_CustomizationPickerApplication {
     @Override
     public void onCreate() {
         super.onCreate();
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
new file mode 100644
index 0000000..2904fad
--- /dev/null
+++ b/tests/common/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 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.
+//
+
+//
+// Build rule for WallpaperPicker2 tests
+//
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_library {
+    name: "ThemePickerTestLib",
+
+    defaults: ["ThemePicker_defaults"],
+    srcs: [
+        "src/com/android/customization/testing/**/*.java",
+        "src/com/android/customization/testing/**/*.kt",
+    ],
+    static_libs: [
+        "WallpaperPicker2TestLib",
+        "androidx.annotation_annotation",
+        "kotlinx_coroutines_test",
+        "truth-prebuilt",
+    ],
+
+    platform_apis: true,
+}
diff --git a/tests/common/AndroidManifest.xml b/tests/common/AndroidManifest.xml
new file mode 100644
index 0000000..81a2f03
--- /dev/null
+++ b/tests/common/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.wallpaper">
+
+  <application>
+  </application>
+</manifest>
diff --git a/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java b/tests/common/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
similarity index 61%
rename from tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
rename to tests/common/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
index bcf5a5f..81890f0 100644
--- a/tests/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
+++ b/tests/common/src/com/android/customization/testing/TestDefaultCustomizationPreferences.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import android.content.Context;
diff --git a/tests/common/src/com/android/customization/testing/TestDrawableLayerResolver.java b/tests/common/src/com/android/customization/testing/TestDrawableLayerResolver.java
new file mode 100644
index 0000000..8b16299
--- /dev/null
+++ b/tests/common/src/com/android/customization/testing/TestDrawableLayerResolver.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.testing;
+
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+
+import com.android.wallpaper.module.DrawableLayerResolver;
+
+/**
+ * Test implementation of {@link DrawableLayerResolver}.
+ */
+public class TestDrawableLayerResolver implements DrawableLayerResolver {
+    @Override
+    public Drawable resolveLayer(LayerDrawable layerDrawable) {
+        return layerDrawable.getDrawable(0);
+    }
+}
diff --git a/tests/common/src/com/android/customization/testing/TestPackageStatusNotifier.java b/tests/common/src/com/android/customization/testing/TestPackageStatusNotifier.java
new file mode 100644
index 0000000..2aadae8
--- /dev/null
+++ b/tests/common/src/com/android/customization/testing/TestPackageStatusNotifier.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2019 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.testing;
+
+import com.android.wallpaper.module.PackageStatusNotifier;
+
+/**
+ * Test implementation of {@link PackageStatusNotifier}.
+ */
+public class TestPackageStatusNotifier implements PackageStatusNotifier {
+    @Override
+    public void addListener(Listener listener, String action) {
+        // Do nothing
+    }
+
+    @Override
+    public void removeListener(Listener listener) {
+        // Do nothing
+    }
+}
diff --git a/tests/src/com/android/customization/testing/TestPluginManager.kt b/tests/common/src/com/android/customization/testing/TestPluginManager.kt
similarity index 100%
rename from tests/src/com/android/customization/testing/TestPluginManager.kt
rename to tests/common/src/com/android/customization/testing/TestPluginManager.kt
diff --git a/tests/src/com/android/customization/testing/TestThemeManager.java b/tests/common/src/com/android/customization/testing/TestThemeManager.java
similarity index 60%
rename from tests/src/com/android/customization/testing/TestThemeManager.java
rename to tests/common/src/com/android/customization/testing/TestThemeManager.java
index c4d25fb..5175b24 100644
--- a/tests/src/com/android/customization/testing/TestThemeManager.java
+++ b/tests/common/src/com/android/customization/testing/TestThemeManager.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import androidx.fragment.app.FragmentActivity;
diff --git a/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java b/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
similarity index 63%
rename from tests/src/com/android/customization/testing/TestThemesUserEventLogger.java
rename to tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
index 2bb2082..22a5b94 100644
--- a/tests/src/com/android/customization/testing/TestThemesUserEventLogger.java
+++ b/tests/common/src/com/android/customization/testing/TestThemesUserEventLogger.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2019 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.testing;
 
 import com.android.customization.model.color.ColorOption;
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
deleted file mode 100644
index 0a54312..0000000
--- a/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.android.customization.picker.clock.ui.fragment
-
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.plugins.ClockSettings
-import com.android.systemui.plugins.PluginManager
-import com.android.systemui.shared.clocks.ClockRegistry
-import org.junit.Assert
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
-import org.robolectric.Robolectric
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
-
-/** Tests of [ClockCustomDemoFragment]. */
-@RunWith(RobolectricTestRunner::class)
-@Config(manifest = Config.NONE)
-@Ignore("b/270606895")
-class ClockCustomDemoFragmentTest {
-    private lateinit var mActivity: AppCompatActivity
-    private var mClockCustomDemoFragment: ClockCustomDemoFragment? = null
-    @Mock private lateinit var registry: ClockRegistry
-    @Mock private lateinit var mockPluginManager: PluginManager
-
-    private var settingValue: ClockSettings? = null
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        mActivity = Robolectric.buildActivity(AppCompatActivity::class.java).get()
-        mClockCustomDemoFragment = ClockCustomDemoFragment()
-        whenever(registry.getClocks())
-            .thenReturn(
-                listOf(
-                    ClockMetadata("CLOCK_1", "Clock 1"),
-                    ClockMetadata("CLOCK_2", "Clock 2"),
-                    ClockMetadata("CLOCK_NOT_IN_USE", "Clock not in use")
-                )
-            )
-
-        mClockCustomDemoFragment!!.clockRegistry = registry
-        mClockCustomDemoFragment!!.recyclerView = RecyclerView(mActivity)
-        mClockCustomDemoFragment!!.recyclerView.layoutManager =
-            LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false)
-    }
-
-    @Test
-    fun testItemCount_getCorrectClockCount() {
-        Assert.assertEquals(3, mClockCustomDemoFragment!!.recyclerView.adapter!!.itemCount)
-    }
-
-    @Test
-    fun testClick_setCorrectClockId() {
-        mClockCustomDemoFragment!!
-            .recyclerView
-            .measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
-        mClockCustomDemoFragment!!.recyclerView.layout(0, 0, 100, 10000)
-        val testPosition = 1
-        mClockCustomDemoFragment!!
-            .recyclerView
-            .findViewHolderForAdapterPosition(testPosition)
-            ?.itemView
-            ?.performClick()
-        verify(registry).currentClockId = "CLOCK_1"
-    }
-}
diff --git a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index bf2766d..95d7e35 100644
--- a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -45,11 +45,12 @@
             val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId }
             checkNotNull(selectedClock)
             ClockMetadataModel(
-                selectedClock.clockId,
-                selectedClock.name,
-                selectedColor,
-                colorTone,
-                seedColor,
+                clockId = selectedClock.clockId,
+                name = selectedClock.name,
+                isSelected = true,
+                selectedColorId = selectedColor,
+                colorToneProgress = colorTone,
+                seedColor = seedColor,
             )
         }
 
@@ -81,10 +82,10 @@
         const val CLOCK_ID_3 = "clock3"
         val fakeClocks =
             listOf(
-                ClockMetadataModel(CLOCK_ID_0, "clock0", null, 50, null),
-                ClockMetadataModel(CLOCK_ID_1, "clock1", null, 50, null),
-                ClockMetadataModel(CLOCK_ID_2, "clock2", null, 50, null),
-                ClockMetadataModel(CLOCK_ID_3, "clock3", null, 50, null),
+                ClockMetadataModel(CLOCK_ID_0, "clock0", true, null, 50, null),
+                ClockMetadataModel(CLOCK_ID_1, "clock1", false, null, 50, null),
+                ClockMetadataModel(CLOCK_ID_2, "clock2", false, null, 50, null),
+                ClockMetadataModel(CLOCK_ID_3, "clock3", false, null, 50, null),
             )
         const val CLOCK_COLOR_ID = "RED"
         const val CLOCK_COLOR_TONE_PROGRESS = 87
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
index c5eb796..0dfc9ee 100644
--- a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -48,11 +48,12 @@
         FakeClockPickerRepository(
             listOf(
                 ClockMetadataModel(
-                    "clock0",
-                    "clock0",
-                    null,
-                    ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
-                    null,
+                    clockId = "clock0",
+                    name = "clock0",
+                    isSelected = true,
+                    selectedColorId = null,
+                    colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+                    seedColor = null,
                 ),
             )
         )
diff --git a/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java b/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java
deleted file mode 100644
index e507221..0000000
--- a/tests/src/com/android/customization/testing/TestDrawableLayerResolver.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.android.customization.testing;
-
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-
-import com.android.wallpaper.module.DrawableLayerResolver;
-
-/**
- * Test implementation of {@link DrawableLayerResolver}.
- */
-public class TestDrawableLayerResolver implements DrawableLayerResolver {
-    @Override
-    public Drawable resolveLayer(LayerDrawable layerDrawable) {
-        return layerDrawable.getDrawable(0);
-    }
-}
diff --git a/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java b/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java
deleted file mode 100644
index 1e6a1a2..0000000
--- a/tests/src/com/android/customization/testing/TestPackageStatusNotifier.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.android.customization.testing;
-
-import com.android.wallpaper.module.PackageStatusNotifier;
-
-/**
- * Test implementation of {@link PackageStatusNotifier}.
- */
-public class TestPackageStatusNotifier implements PackageStatusNotifier {
-    @Override
-    public void addListener(Listener listener, String action) {
-        // Do nothing
-    }
-
-    @Override
-    public void removeListener(Listener listener) {
-        // Do nothing
-    }
-}