Merge "Remove ClockSectionViewModel (2/2)" into main
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index 0a0a5e4..749048a 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -37,7 +37,6 @@
 import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
 import com.android.customization.model.themedicon.domain.interactor.ThemedIconSnapshotRestorer
 import com.android.customization.module.logging.ThemesUserEventLogger
-import com.android.customization.module.logging.ThemesUserEventLoggerImpl
 import com.android.customization.picker.clock.data.repository.ClockPickerRepositoryImpl
 import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
 import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
@@ -71,7 +70,6 @@
 import com.android.wallpaper.module.CustomizationSections
 import com.android.wallpaper.module.FragmentFactory
 import com.android.wallpaper.module.WallpaperPicker2Injector
-import com.android.wallpaper.module.logging.UserEventLogger
 import com.android.wallpaper.picker.CustomizationPickerActivity
 import com.android.wallpaper.picker.customization.data.content.WallpaperClientImpl
 import com.android.wallpaper.picker.customization.data.repository.WallpaperColorsRepository
@@ -91,9 +89,9 @@
     @MainDispatcher private val mainScope: CoroutineScope,
     @MainDispatcher private val mainDispatcher: CoroutineDispatcher,
     @BackgroundDispatcher private val bgDispatcher: CoroutineDispatcher,
-) : WallpaperPicker2Injector(mainScope, bgDispatcher), CustomizationInjector {
+    private val userEventLogger: ThemesUserEventLogger,
+) : WallpaperPicker2Injector(mainScope, bgDispatcher, userEventLogger), CustomizationInjector {
     private var customizationSections: CustomizationSections? = null
-    private var userEventLogger: UserEventLogger? = null
     private var wallpaperInteractor: WallpaperInteractor? = null
     private var keyguardQuickAffordancePickerInteractor: KeyguardQuickAffordancePickerInteractor? =
         null
@@ -164,10 +162,7 @@
 
     @Synchronized
     override fun getUserEventLogger(context: Context): ThemesUserEventLogger {
-        return userEventLogger as? ThemesUserEventLogger
-            ?: ThemesUserEventLoggerImpl(getPreferences(context.applicationContext)).also {
-                userEventLogger = it
-            }
+        return userEventLogger
     }
 
     override fun getFragmentFactory(): FragmentFactory? {
diff --git a/src/com/android/customization/module/logging/AppSessionId.kt b/src/com/android/customization/module/logging/AppSessionId.kt
new file mode 100644
index 0000000..c831f22
--- /dev/null
+++ b/src/com/android/customization/module/logging/AppSessionId.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+package com.android.customization.module.logging
+
+import com.android.internal.logging.InstanceId
+import com.android.internal.logging.InstanceIdSequence
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class AppSessionId @Inject constructor() {
+
+    private var sessionId: InstanceId = newInstanceId()
+
+    fun createNewId(): AppSessionId {
+        sessionId = newInstanceId()
+        return this
+    }
+
+    fun getId(): Int {
+        return sessionId.hashCode()
+    }
+
+    private fun newInstanceId(): InstanceId = InstanceIdSequence(INSTANCE_ID_MAX).newInstanceId()
+
+    companion object {
+        // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
+        private const val INSTANCE_ID_MAX = 1 shl 20
+    }
+}
diff --git a/src/com/android/customization/module/logging/SysUiStatsLogger.kt b/src/com/android/customization/module/logging/SysUiStatsLogger.kt
index 14f0be6..6c55df8 100644
--- a/src/com/android/customization/module/logging/SysUiStatsLogger.kt
+++ b/src/com/android/customization/module/logging/SysUiStatsLogger.kt
@@ -53,7 +53,7 @@
     private var colorVariant = 0
     private var timeElapsedMillis = 0L
     private var effectResultCode = -1
-    private var sessionId = 0
+    private var appSessionId = 0
     private var setWallpaperEntryPoint =
         STYLE_UICHANGED__SET_WALLPAPER_ENTRY_POINT__SET_WALLPAPER_ENTRY_POINT_UNSPECIFIED
     private var wallpaperDestination =
@@ -133,7 +133,7 @@
         this.effectResultCode = effectResultCode
     }
 
-    fun setSessionId(sessionId: Int) = apply { this.sessionId = sessionId }
+    fun setAppSessionId(sessionId: Int) = apply { this.appSessionId = sessionId }
 
     fun setSetWallpaperEntryPoint(@SetWallpaperEntryPoint setWallpaperEntryPoint: Int) = apply {
         this.setWallpaperEntryPoint = setWallpaperEntryPoint
@@ -180,7 +180,7 @@
             colorVariant,
             timeElapsedMillis,
             effectResultCode,
-            sessionId,
+            appSessionId,
             setWallpaperEntryPoint,
             wallpaperDestination,
             colorSource,
diff --git a/src/com/android/customization/module/logging/ThemesUserEventLoggerImpl.kt b/src/com/android/customization/module/logging/ThemesUserEventLoggerImpl.kt
index 78b5ca7..e4b8c8b 100644
--- a/src/com/android/customization/module/logging/ThemesUserEventLoggerImpl.kt
+++ b/src/com/android/customization/module/logging/ThemesUserEventLoggerImpl.kt
@@ -31,10 +31,17 @@
 import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint
 import com.android.wallpaper.module.logging.UserEventLogger.WallpaperDestination
 import com.android.wallpaper.util.LaunchSourceUtils
+import javax.inject.Inject
+import javax.inject.Singleton
 
 /** StatsLog-backed implementation of [ThemesUserEventLogger]. */
-class ThemesUserEventLoggerImpl(private val preferences: WallpaperPreferences) :
-    ThemesUserEventLogger {
+@Singleton
+class ThemesUserEventLoggerImpl
+@Inject
+constructor(
+    private val preferences: WallpaperPreferences,
+    private val appSessionId: AppSessionId,
+) : ThemesUserEventLogger {
 
     override fun logSnapshot() {
         SysUiStatsLogger(StyleEnums.SNAPSHOT)
@@ -48,6 +55,7 @@
 
     override fun logAppLaunched(launchSource: Intent) {
         SysUiStatsLogger(StyleEnums.APP_LAUNCHED)
+            .setAppSessionId(appSessionId.createNewId().getId())
             .setLaunchedPreference(launchSource.getAppLaunchSource())
             .log()
     }
@@ -64,6 +72,7 @@
         val isHomeWallpaperSet = destination == DEST_HOME_SCREEN || destination == DEST_BOTH
         val isLockWallpaperSet = destination == DEST_LOCK_SCREEN || destination == DEST_BOTH
         SysUiStatsLogger(StyleEnums.WALLPAPER_APPLIED)
+            .setAppSessionId(appSessionId.getId())
             .setWallpaperCategoryHash(if (isHomeWallpaperSet) categoryHash else 0)
             .setWallpaperIdHash(if (isHomeWallpaperSet) wallpaperIdHash else 0)
             .setLockWallpaperCategoryHash(if (isLockWallpaperSet) categoryHash else 0)
@@ -81,6 +90,7 @@
         resultCode: Int
     ) {
         SysUiStatsLogger(StyleEnums.WALLPAPER_EFFECT_APPLIED)
+            .setAppSessionId(appSessionId.getId())
             .setEffectPreference(status)
             .setEffectIdHash(getIdHashCode(effect))
             .setTimeElapsed(timeElapsedMillis)
@@ -90,6 +100,7 @@
 
     override fun logEffectProbe(effect: String, @EffectStatus status: Int) {
         SysUiStatsLogger(StyleEnums.WALLPAPER_EFFECT_PROBE)
+            .setAppSessionId(appSessionId.getId())
             .setEffectPreference(status)
             .setEffectIdHash(getIdHashCode(effect))
             .log()
@@ -101,6 +112,7 @@
         timeElapsedMillis: Long
     ) {
         SysUiStatsLogger(StyleEnums.WALLPAPER_EFFECT_FG_DOWNLOAD)
+            .setAppSessionId(appSessionId.getId())
             .setEffectPreference(status)
             .setEffectIdHash(getIdHashCode(effect))
             .setTimeElapsed(timeElapsedMillis)
@@ -108,11 +120,11 @@
     }
 
     override fun logResetApplied() {
-        SysUiStatsLogger(StyleEnums.RESET_APPLIED).log()
+        SysUiStatsLogger(StyleEnums.RESET_APPLIED).setAppSessionId(appSessionId.getId()).log()
     }
 
     override fun logWallpaperExploreButtonClicked() {
-        SysUiStatsLogger(StyleEnums.WALLPAPER_EXPLORE).log()
+        SysUiStatsLogger(StyleEnums.WALLPAPER_EXPLORE).setAppSessionId(appSessionId.getId()).log()
     }
 
     override fun logThemeColorApplied(
@@ -121,6 +133,7 @@
         seedColor: Int,
     ) {
         SysUiStatsLogger(StyleEnums.THEME_COLOR_APPLIED)
+            .setAppSessionId(appSessionId.getId())
             .setColorSource(source)
             .setColorVariant(variant)
             .setSeedColor(seedColor)
@@ -128,40 +141,60 @@
     }
 
     override fun logGridApplied(grid: GridOption) {
-        SysUiStatsLogger(StyleEnums.GRID_APPLIED).setLauncherGrid(grid.getLauncherGridInt()).log()
+        SysUiStatsLogger(StyleEnums.GRID_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setLauncherGrid(grid.getLauncherGridInt())
+            .log()
     }
 
     override fun logClockApplied(clockId: String) {
-        SysUiStatsLogger(StyleEnums.CLOCK_APPLIED).setClockPackageHash(getIdHashCode(clockId)).log()
+        SysUiStatsLogger(StyleEnums.CLOCK_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setClockPackageHash(getIdHashCode(clockId))
+            .log()
     }
 
     override fun logClockColorApplied(seedColor: Int) {
-        SysUiStatsLogger(StyleEnums.CLOCK_COLOR_APPLIED).setSeedColor(seedColor).log()
+        SysUiStatsLogger(StyleEnums.CLOCK_COLOR_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setSeedColor(seedColor)
+            .log()
     }
 
     override fun logClockSizeApplied(@ClockSize clockSize: Int) {
-        SysUiStatsLogger(StyleEnums.CLOCK_SIZE_APPLIED).setClockSize(clockSize).log()
+        SysUiStatsLogger(StyleEnums.CLOCK_SIZE_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setClockSize(clockSize)
+            .log()
     }
 
     override fun logThemedIconApplied(useThemeIcon: Boolean) {
-        SysUiStatsLogger(StyleEnums.THEMED_ICON_APPLIED).setToggleOn(useThemeIcon).log()
+        SysUiStatsLogger(StyleEnums.THEMED_ICON_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setToggleOn(useThemeIcon)
+            .log()
     }
 
     override fun logLockScreenNotificationApplied(showLockScreenNotifications: Boolean) {
         SysUiStatsLogger(StyleEnums.LOCK_SCREEN_NOTIFICATION_APPLIED)
+            .setAppSessionId(appSessionId.getId())
             .setToggleOn(showLockScreenNotifications)
             .log()
     }
 
     override fun logShortcutApplied(shortcut: String, shortcutSlotId: String) {
         SysUiStatsLogger(StyleEnums.SHORTCUT_APPLIED)
+            .setAppSessionId(appSessionId.getId())
             .setShortcut(shortcut)
             .setShortcutSlotId(shortcutSlotId)
             .log()
     }
 
     override fun logDarkThemeApplied(useDarkTheme: Boolean) {
-        SysUiStatsLogger(StyleEnums.DARK_THEME_APPLIED).setToggleOn(useDarkTheme).log()
+        SysUiStatsLogger(StyleEnums.DARK_THEME_APPLIED)
+            .setAppSessionId(appSessionId.getId())
+            .setToggleOn(useDarkTheme)
+            .log()
     }
 
     /**
diff --git a/src_override/com/android/wallpaper/module/AppModule.kt b/src_override/com/android/wallpaper/module/AppModule.kt
index 95da101..187b00b 100644
--- a/src_override/com/android/wallpaper/module/AppModule.kt
+++ b/src_override/com/android/wallpaper/module/AppModule.kt
@@ -19,6 +19,9 @@
 import com.android.customization.module.CustomizationInjector
 import com.android.customization.module.DefaultCustomizationPreferences
 import com.android.customization.module.ThemePickerInjector
+import com.android.customization.module.logging.ThemesUserEventLogger
+import com.android.customization.module.logging.ThemesUserEventLoggerImpl
+import com.android.wallpaper.module.logging.UserEventLogger
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -32,6 +35,14 @@
 abstract class AppModule {
     @Binds @Singleton abstract fun bindInjector(impl: ThemePickerInjector): CustomizationInjector
 
+    @Binds
+    @Singleton
+    abstract fun bindUserEventLogger(impl: ThemesUserEventLoggerImpl): UserEventLogger
+
+    @Binds
+    @Singleton
+    abstract fun bindThemesUserEventLogger(impl: ThemesUserEventLoggerImpl): ThemesUserEventLogger
+
     companion object {
         @Provides
         @Singleton
diff --git a/tests/common/Android.bp b/tests/common/Android.bp
index 0961886..9215ba6 100644
--- a/tests/common/Android.bp
+++ b/tests/common/Android.bp
@@ -32,7 +32,7 @@
         "WallpaperPicker2TestLib",
         "androidx.annotation_annotation",
         "kotlinx_coroutines_test",
-        "truth-prebuilt",
+        "truth",
     ],
 
     platform_apis: true,
diff --git a/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt b/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt
index a8989c5..e1f4178 100644
--- a/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt
+++ b/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt
@@ -18,9 +18,13 @@
 import com.android.customization.model.grid.GridOption
 import com.android.customization.module.logging.ThemesUserEventLogger.ColorSource
 import com.android.wallpaper.module.logging.TestUserEventLogger
+import javax.inject.Inject
+import javax.inject.Singleton
 
 /** Test implementation of [ThemesUserEventLogger]. */
-class TestThemesUserEventLogger : TestUserEventLogger(), ThemesUserEventLogger {
+@Singleton
+class TestThemesUserEventLogger @Inject constructor() :
+    TestUserEventLogger(), ThemesUserEventLogger {
 
     override fun logThemeColorApplied(@ColorSource source: Int, variant: Int, seedColor: Int) {}
 
diff --git a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
index 7566233..065a1f0 100644
--- a/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/common/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -5,7 +5,6 @@
 import androidx.activity.ComponentActivity
 import com.android.customization.module.CustomizationInjector
 import com.android.customization.module.CustomizationPreferences
-import com.android.customization.module.logging.TestThemesUserEventLogger
 import com.android.customization.module.logging.ThemesUserEventLogger
 import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
@@ -24,10 +23,10 @@
 @Singleton
 open class TestCustomizationInjector
 @Inject
-constructor(private val customPrefs: TestDefaultCustomizationPreferences) :
-    TestInjector(), CustomizationInjector {
-    private var themesUserEventLogger: ThemesUserEventLogger? = null
-
+constructor(
+    private val customPrefs: TestDefaultCustomizationPreferences,
+    private val themesUserEventLogger: ThemesUserEventLogger
+) : TestInjector(themesUserEventLogger), CustomizationInjector {
     /////////////////
     // CustomizationInjector implementations
     /////////////////
@@ -90,6 +89,5 @@
 
     override fun getUserEventLogger(context: Context): UserEventLogger {
         return themesUserEventLogger
-            ?: TestThemesUserEventLogger().also { themesUserEventLogger = it }
     }
 }
diff --git a/tests/module/src/com/android/customization/TestModule.kt b/tests/module/src/com/android/customization/TestModule.kt
index d35c89a..79a91c3 100644
--- a/tests/module/src/com/android/customization/TestModule.kt
+++ b/tests/module/src/com/android/customization/TestModule.kt
@@ -2,11 +2,15 @@
 
 import com.android.customization.module.CustomizationInjector
 import com.android.customization.module.CustomizationPreferences
+import com.android.customization.module.logging.TestThemesUserEventLogger
+import com.android.customization.module.logging.ThemesUserEventLogger
 import com.android.customization.testing.TestCustomizationInjector
 import com.android.customization.testing.TestDefaultCustomizationPreferences
 import com.android.wallpaper.module.AppModule
 import com.android.wallpaper.module.Injector
 import com.android.wallpaper.module.WallpaperPreferences
+import com.android.wallpaper.module.logging.TestUserEventLogger
+import com.android.wallpaper.module.logging.UserEventLogger
 import com.android.wallpaper.testing.TestInjector
 import com.android.wallpaper.testing.TestWallpaperPreferences
 import dagger.Binds
@@ -22,6 +26,12 @@
 
     @Binds @Singleton abstract fun bindInjector(impl: TestCustomizationInjector): Injector
 
+    @Binds @Singleton abstract fun bindUserEventLogger(impl: TestUserEventLogger): UserEventLogger
+
+    @Binds
+    @Singleton
+    abstract fun bindThemesUserEventLogger(impl: TestThemesUserEventLogger): ThemesUserEventLogger
+
     @Binds
     @Singleton
     abstract fun bindWallpaperPrefs(impl: TestDefaultCustomizationPreferences): WallpaperPreferences
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index ed684f4..c34ed2c 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -1,4 +1,3 @@
-
 package {
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
@@ -17,7 +16,7 @@
         "androidx.test.rules",
         "junit",
         "kotlinx_coroutines_test",
-        "truth-prebuilt",
+        "truth",
     ],
     libs: [
         "androidx.test.core",
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 43b872e..a9da1c3 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
@@ -21,6 +21,7 @@
 import android.content.Intent
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.filters.SmallTest
+import com.android.customization.module.logging.TestThemesUserEventLogger
 import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
@@ -64,6 +65,8 @@
 @RunWith(RobolectricTestRunner::class)
 class KeyguardQuickAffordancePickerViewModelTest {
 
+    private val logger = TestThemesUserEventLogger()
+
     private lateinit var underTest: KeyguardQuickAffordancePickerViewModel
 
     private lateinit var context: Context
@@ -74,7 +77,7 @@
 
     @Before
     fun setUp() {
-        InjectorProvider.setInjector(TestInjector())
+        InjectorProvider.setInjector(TestInjector(logger))
         context = ApplicationProvider.getApplicationContext()
         val testDispatcher = StandardTestDispatcher()
         testScope = TestScope(testDispatcher)