Merge "Makes Studio and Soong kotlin+mockito behavior the same" into main
diff --git a/src/com/android/customization/model/color/ColorOption.java b/src/com/android/customization/model/color/ColorOption.java
index 5d2e995..3035221 100644
--- a/src/com/android/customization/model/color/ColorOption.java
+++ b/src/com/android/customization/model/color/ColorOption.java
@@ -19,6 +19,7 @@
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE;
import android.content.Context;
+import android.graphics.Color;
import android.text.TextUtils;
import android.util.Log;
@@ -27,6 +28,7 @@
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.customization.model.color.ColorOptionsProvider.ColorSource;
+import com.android.customization.module.logging.ThemesUserEventLogger;
import com.android.systemui.monet.Style;
import com.android.wallpaper.R;
@@ -101,6 +103,19 @@
}
/**
+ * Gets the seed color from the overlay packages for logging.
+ *
+ * @return an int representing the seed color, or NULL_SEED_COLOR
+ */
+ public int getSeedColorForLogging() {
+ String seedColor = mPackagesByCategory.get(OVERLAY_CATEGORY_SYSTEM_PALETTE);
+ if (seedColor == null || seedColor.isEmpty()) {
+ return ThemesUserEventLogger.NULL_SEED_COLOR;
+ }
+ return Color.parseColor(seedColor);
+ }
+
+ /**
* This is similar to #equals() but it only compares this theme's packages with the other, that
* is, it will return true if applying this theme has the same effect of applying the given one.
*/
@@ -209,6 +224,12 @@
public abstract String getSource();
/**
+ * @return the source of this color option for logging
+ */
+ @ThemesUserEventLogger.ColorSource
+ public abstract int getSourceForLogging();
+
+ /**
* @return the style of this color option
*/
public Style getStyle() {
diff --git a/src/com/android/customization/model/color/ColorOptionImpl.kt b/src/com/android/customization/model/color/ColorOptionImpl.kt
index 3273ce2..461d2a3 100644
--- a/src/com/android/customization/model/color/ColorOptionImpl.kt
+++ b/src/com/android/customization/model/color/ColorOptionImpl.kt
@@ -17,6 +17,7 @@
package com.android.customization.model.color
import android.content.Context
+import android.stats.style.StyleEnums
import android.view.View
import androidx.annotation.ColorInt
import com.android.customization.model.color.ColorOptionsProvider.ColorSource
@@ -68,6 +69,15 @@
return source
}
+ override fun getSourceForLogging(): Int {
+ return when (getSource()) {
+ ColorOptionsProvider.COLOR_SOURCE_PRESET -> StyleEnums.COLOR_SOURCE_PRESET_COLOR
+ ColorOptionsProvider.COLOR_SOURCE_HOME -> StyleEnums.COLOR_SOURCE_HOME_SCREEN_WALLPAPER
+ ColorOptionsProvider.COLOR_SOURCE_LOCK -> StyleEnums.COLOR_SOURCE_LOCK_SCREEN_WALLPAPER
+ else -> StyleEnums.COLOR_SOURCE_UNSPECIFIED
+ }
+ }
+
class Builder {
var title: String? = null
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index d2781c2..4b2c899 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -423,6 +423,7 @@
?: ColorPickerViewModel.Factory(
context.applicationContext,
getColorPickerInteractor(context, wallpaperColorsRepository),
+ userEventLogger,
)
.also { colorPickerViewModelFactory = it }
}
diff --git a/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
index bb2ef9d..f35d934 100644
--- a/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
+++ b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
@@ -19,10 +19,12 @@
import android.content.Context
import android.graphics.Color
import android.text.TextUtils
+import com.android.customization.model.ResourceConstants
import com.android.customization.model.color.ColorOptionImpl
import com.android.customization.model.color.ColorOptionsProvider
import com.android.customization.picker.color.shared.model.ColorOptionModel
import com.android.customization.picker.color.shared.model.ColorType
+import com.android.systemui.monet.Style
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -49,6 +51,53 @@
}
fun setOptions(
+ wallpaperOptions: List<ColorOptionImpl>,
+ presetOptions: List<ColorOptionImpl>,
+ selectedColorOptionType: ColorType,
+ selectedColorOptionIndex: Int
+ ) {
+ _colorOptions.value =
+ mapOf(
+ ColorType.WALLPAPER_COLOR to
+ buildList {
+ for ((index, colorOption) in wallpaperOptions.withIndex()) {
+ val isSelected =
+ selectedColorOptionType == ColorType.WALLPAPER_COLOR &&
+ selectedColorOptionIndex == index
+ val colorOptionModel =
+ ColorOptionModel(
+ key = "${ColorType.WALLPAPER_COLOR}::$index",
+ colorOption = colorOption,
+ isSelected = isSelected
+ )
+ if (isSelected) {
+ selectedColorOption = colorOptionModel
+ }
+ add(colorOptionModel)
+ }
+ },
+ ColorType.PRESET_COLOR to
+ buildList {
+ for ((index, colorOption) in presetOptions.withIndex()) {
+ val isSelected =
+ selectedColorOptionType == ColorType.PRESET_COLOR &&
+ selectedColorOptionIndex == index
+ val colorOptionModel =
+ ColorOptionModel(
+ key = "${ColorType.PRESET_COLOR}::$index",
+ colorOption = colorOption,
+ isSelected = isSelected
+ )
+ if (isSelected) {
+ selectedColorOption = colorOptionModel
+ }
+ add(colorOptionModel)
+ }
+ },
+ )
+ }
+
+ fun setOptions(
numWallpaperOptions: Int,
numPresetOptions: Int,
selectedColorOptionType: ColorType,
@@ -111,6 +160,22 @@
return builder.build()
}
+ fun buildPresetOption(style: Style, seedColor: String): ColorOptionImpl {
+ val builder = ColorOptionImpl.Builder()
+ builder.lightColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.darkColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.type = ColorType.PRESET_COLOR
+ builder.source = ColorOptionsProvider.COLOR_SOURCE_PRESET
+ builder.style = style
+ builder.title = "Preset"
+ builder
+ .addOverlayPackage("TEST_PACKAGE_TYPE", "preset_color")
+ .addOverlayPackage(ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE, seedColor)
+ return builder.build()
+ }
+
private fun buildWallpaperOption(index: Int): ColorOptionImpl {
val builder = ColorOptionImpl.Builder()
builder.lightColors =
@@ -127,6 +192,22 @@
return builder.build()
}
+ fun buildWallpaperOption(source: String, style: Style, seedColor: String): ColorOptionImpl {
+ val builder = ColorOptionImpl.Builder()
+ builder.lightColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.darkColors =
+ intArrayOf(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT)
+ builder.type = ColorType.WALLPAPER_COLOR
+ builder.source = source
+ builder.style = style
+ builder.title = "Dynamic"
+ builder
+ .addOverlayPackage("TEST_PACKAGE_TYPE", "wallpaper_color")
+ .addOverlayPackage(ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE, seedColor)
+ return builder.build()
+ }
+
override suspend fun select(colorOptionModel: ColorOptionModel) {
val colorOptions = _colorOptions.value
val wallpaperColorOptions = colorOptions[ColorType.WALLPAPER_COLOR]!!
diff --git a/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
index 67c6838..3c3d114 100644
--- a/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
@@ -21,6 +21,7 @@
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import com.android.customization.model.color.ColorOptionImpl
+import com.android.customization.module.logging.ThemesUserEventLogger
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
import com.android.customization.picker.color.shared.model.ColorType
import com.android.wallpaper.R
@@ -43,6 +44,7 @@
private constructor(
context: Context,
private val interactor: ColorPickerInteractor,
+ private val logger: ThemesUserEventLogger,
) : ViewModel() {
private val selectedColorTypeTabId = MutableStateFlow<ColorType?>(null)
@@ -142,6 +144,14 @@
{
viewModelScope.launch {
interactor.select(colorOptionModel)
+ logger.logThemeColorApplied(
+ colorOptionModel.colorOption
+ .sourceForLogging,
+ colorOptionModel.colorOption.style
+ .ordinal + 1,
+ colorOptionModel.colorOption
+ .seedColorForLogging,
+ )
}
}
}
@@ -205,12 +215,14 @@
class Factory(
private val context: Context,
private val interactor: ColorPickerInteractor,
+ private val logger: ThemesUserEventLogger,
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return ColorPickerViewModel(
context = context,
interactor = interactor,
+ logger = logger,
)
as T
}
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 10149f0..bb49ff0 100644
--- a/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt
+++ b/tests/common/src/com/android/customization/module/logging/TestThemesUserEventLogger.kt
@@ -28,8 +28,19 @@
class TestThemesUserEventLogger @Inject constructor() :
TestUserEventLogger(), ThemesUserEventLogger {
@ClockSize private var clockSize: Int = StyleEnums.CLOCK_SIZE_UNSPECIFIED
+ @ColorSource
+ var themeColorSource: Int = StyleEnums.COLOR_SOURCE_UNSPECIFIED
+ private set
+ var themeColorVariant: Int = -1
+ private set
+ var themeSeedColor: Int = -1
+ private set
- override fun logThemeColorApplied(@ColorSource source: Int, variant: Int, seedColor: Int) {}
+ override fun logThemeColorApplied(@ColorSource source: Int, variant: Int, seedColor: Int) {
+ this.themeColorSource = source
+ this.themeColorVariant = variant
+ this.themeSeedColor = seedColor
+ }
override fun logGridApplied(grid: GridOption) {}
diff --git a/tests/robotests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt b/tests/robotests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
index 9968c5f..c841267 100644
--- a/tests/robotests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
@@ -17,8 +17,12 @@
package com.android.customization.model.picker.color.ui.viewmodel
import android.content.Context
+import android.graphics.Color
+import android.stats.style.StyleEnums
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.model.color.ColorOptionsProvider
+import com.android.customization.module.logging.TestThemesUserEventLogger
import com.android.customization.picker.color.data.repository.FakeColorPickerRepository
import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
@@ -26,6 +30,7 @@
import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
import com.android.customization.picker.color.ui.viewmodel.ColorTypeTabViewModel
+import com.android.systemui.monet.Style
import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
import com.android.wallpaper.testing.FakeSnapshotStore
import com.android.wallpaper.testing.collectLastValue
@@ -36,6 +41,7 @@
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
@@ -49,6 +55,7 @@
@SmallTest
@RunWith(RobolectricTestRunner::class)
class ColorPickerViewModelTest {
+ private val logger = TestThemesUserEventLogger()
private lateinit var underTest: ColorPickerViewModel
private lateinit var repository: FakeColorPickerRepository
private lateinit var interactor: ColorPickerInteractor
@@ -77,7 +84,11 @@
)
underTest =
- ColorPickerViewModel.Factory(context = context, interactor = interactor)
+ ColorPickerViewModel.Factory(
+ context = context,
+ interactor = interactor,
+ logger = logger
+ )
.create(ColorPickerViewModel::class.java)
repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 0)
@@ -112,6 +123,67 @@
}
@Test
+ fun `Log selected wallpaper color`() =
+ testScope.runTest {
+ repository.setOptions(
+ listOf(
+ repository.buildWallpaperOption(
+ ColorOptionsProvider.COLOR_SOURCE_LOCK,
+ Style.EXPRESSIVE,
+ "#121212"
+ )
+ ),
+ listOf(repository.buildPresetOption(Style.FRUIT_SALAD, "#ABCDEF")),
+ ColorType.PRESET_COLOR,
+ 0
+ )
+
+ val colorTypes = collectLastValue(underTest.colorTypeTabs)
+ val colorOptions = collectLastValue(underTest.colorOptions)
+
+ // Select "Wallpaper colors" tab
+ colorTypes()?.get(ColorType.WALLPAPER_COLOR)?.onClick?.invoke()
+ // Select a color option
+ selectColorOption(colorOptions, 0)
+ advanceUntilIdle()
+
+ assertThat(logger.themeColorSource)
+ .isEqualTo(StyleEnums.COLOR_SOURCE_LOCK_SCREEN_WALLPAPER)
+ assertThat(logger.themeColorVariant).isEqualTo(Style.EXPRESSIVE.ordinal + 1)
+ assertThat(logger.themeSeedColor).isEqualTo(Color.parseColor("#121212"))
+ }
+
+ @Test
+ fun `Log selected preset color`() =
+ testScope.runTest {
+ repository.setOptions(
+ listOf(
+ repository.buildWallpaperOption(
+ ColorOptionsProvider.COLOR_SOURCE_LOCK,
+ Style.EXPRESSIVE,
+ "#121212"
+ )
+ ),
+ listOf(repository.buildPresetOption(Style.FRUIT_SALAD, "#ABCDEF")),
+ ColorType.WALLPAPER_COLOR,
+ 0
+ )
+
+ val colorTypes = collectLastValue(underTest.colorTypeTabs)
+ val colorOptions = collectLastValue(underTest.colorOptions)
+
+ // Select "Wallpaper colors" tab
+ colorTypes()?.get(ColorType.PRESET_COLOR)?.onClick?.invoke()
+ // Select a color option
+ selectColorOption(colorOptions, 0)
+ advanceUntilIdle()
+
+ assertThat(logger.themeColorSource).isEqualTo(StyleEnums.COLOR_SOURCE_PRESET_COLOR)
+ assertThat(logger.themeColorVariant).isEqualTo(Style.FRUIT_SALAD.ordinal + 1)
+ assertThat(logger.themeSeedColor).isEqualTo(Color.parseColor("#ABCDEF"))
+ }
+
+ @Test
fun `Select a preset color`() =
testScope.runTest {
val colorTypes = collectLastValue(underTest.colorTypeTabs)