1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.customization.module.logging 17 18 import android.app.WallpaperManager 19 import android.content.Intent 20 import android.stats.style.StyleEnums.APP_LAUNCHED 21 import android.stats.style.StyleEnums.CLOCK_APPLIED 22 import android.stats.style.StyleEnums.CLOCK_COLOR_APPLIED 23 import android.stats.style.StyleEnums.CLOCK_SIZE_APPLIED 24 import android.stats.style.StyleEnums.DARK_THEME_APPLIED 25 import android.stats.style.StyleEnums.GRID_APPLIED 26 import android.stats.style.StyleEnums.LAUNCHED_CROP_AND_SET_ACTION 27 import android.stats.style.StyleEnums.LAUNCHED_DEEP_LINK 28 import android.stats.style.StyleEnums.LAUNCHED_KEYGUARD 29 import android.stats.style.StyleEnums.LAUNCHED_LAUNCHER 30 import android.stats.style.StyleEnums.LAUNCHED_LAUNCH_ICON 31 import android.stats.style.StyleEnums.LAUNCHED_PREFERENCE_UNSPECIFIED 32 import android.stats.style.StyleEnums.LAUNCHED_SETTINGS 33 import android.stats.style.StyleEnums.LAUNCHED_SETTINGS_SEARCH 34 import android.stats.style.StyleEnums.LAUNCHED_SUW 35 import android.stats.style.StyleEnums.LAUNCHED_TIPS 36 import android.stats.style.StyleEnums.LOCK_SCREEN_NOTIFICATION_APPLIED 37 import android.stats.style.StyleEnums.RESET_APPLIED 38 import android.stats.style.StyleEnums.SHORTCUT_APPLIED 39 import android.stats.style.StyleEnums.SNAPSHOT 40 import android.stats.style.StyleEnums.THEMED_ICON_APPLIED 41 import android.stats.style.StyleEnums.THEME_COLOR_APPLIED 42 import android.stats.style.StyleEnums.WALLPAPER_APPLIED 43 import android.stats.style.StyleEnums.WALLPAPER_DESTINATION_HOME_AND_LOCK_SCREEN 44 import android.stats.style.StyleEnums.WALLPAPER_DESTINATION_HOME_SCREEN 45 import android.stats.style.StyleEnums.WALLPAPER_DESTINATION_LOCK_SCREEN 46 import android.stats.style.StyleEnums.WALLPAPER_EFFECT_APPLIED 47 import android.stats.style.StyleEnums.WALLPAPER_EFFECT_FG_DOWNLOAD 48 import android.stats.style.StyleEnums.WALLPAPER_EFFECT_PROBE 49 import android.stats.style.StyleEnums.WALLPAPER_EXPLORE 50 import android.text.TextUtils 51 import com.android.customization.model.color.ColorCustomizationManager 52 import com.android.customization.model.grid.GridOption 53 import com.android.customization.module.logging.ThemesUserEventLogger.ClockSize 54 import com.android.customization.module.logging.ThemesUserEventLogger.ColorSource 55 import com.android.wallpaper.module.WallpaperPreferences 56 import com.android.wallpaper.module.logging.UserEventLogger.EffectStatus 57 import com.android.wallpaper.module.logging.UserEventLogger.SetWallpaperEntryPoint 58 import com.android.wallpaper.module.logging.UserEventLogger.WallpaperDestination 59 import com.android.wallpaper.util.LaunchSourceUtils 60 import javax.inject.Inject 61 import javax.inject.Singleton 62 63 /** StatsLog-backed implementation of [ThemesUserEventLogger]. */ 64 @Singleton 65 class ThemesUserEventLoggerImpl 66 @Inject 67 constructor( 68 private val preferences: WallpaperPreferences, 69 private val colorManager: ColorCustomizationManager, 70 private val appSessionId: AppSessionId, 71 ) : ThemesUserEventLogger { 72 logSnapshotnull73 override fun logSnapshot() { 74 SysUiStatsLogger(SNAPSHOT) 75 .setWallpaperCategoryHash(preferences.getHomeCategoryHash()) 76 .setWallpaperIdHash(preferences.getHomeWallpaperIdHash()) 77 .setEffectIdHash(preferences.getHomeWallpaperEffectsIdHash()) 78 .setLockWallpaperCategoryHash(preferences.getLockCategoryHash()) 79 .setLockWallpaperIdHash(preferences.getLockWallpaperIdHash()) 80 .setLockEffectIdHash(preferences.getLockWallpaperEffectsIdHash()) 81 .setColorSource(colorManager.currentColorSourceForLogging) 82 .setColorVariant(colorManager.currentStyleForLogging) 83 .setSeedColor(colorManager.currentSeedColorForLogging) 84 .log() 85 } 86 logAppLaunchednull87 override fun logAppLaunched(launchSource: Intent) { 88 SysUiStatsLogger(APP_LAUNCHED) 89 .setAppSessionId(appSessionId.createNewId().getId()) 90 .setLaunchedPreference(launchSource.getAppLaunchSource()) 91 .log() 92 } 93 logWallpaperAppliednull94 override fun logWallpaperApplied( 95 collectionId: String?, 96 wallpaperId: String?, 97 effects: String?, 98 @SetWallpaperEntryPoint setWallpaperEntryPoint: Int, 99 @WallpaperDestination destination: Int, 100 ) { 101 val categoryHash = getIdHashCode(collectionId) 102 val wallpaperIdHash = getIdHashCode(wallpaperId) 103 val isHomeWallpaperSet = 104 destination == WALLPAPER_DESTINATION_HOME_SCREEN || 105 destination == WALLPAPER_DESTINATION_HOME_AND_LOCK_SCREEN 106 val isLockWallpaperSet = 107 destination == WALLPAPER_DESTINATION_LOCK_SCREEN || 108 destination == WALLPAPER_DESTINATION_HOME_AND_LOCK_SCREEN 109 SysUiStatsLogger(WALLPAPER_APPLIED) 110 .setAppSessionId(appSessionId.getId()) 111 .setWallpaperCategoryHash(if (isHomeWallpaperSet) categoryHash else 0) 112 .setWallpaperIdHash(if (isHomeWallpaperSet) wallpaperIdHash else 0) 113 .setEffectIdHash(if (isHomeWallpaperSet) getIdHashCode(effects) else 0) 114 .setLockWallpaperCategoryHash(if (isLockWallpaperSet) categoryHash else 0) 115 .setLockWallpaperIdHash(if (isLockWallpaperSet) wallpaperIdHash else 0) 116 .setLockEffectIdHash(if (isLockWallpaperSet) getIdHashCode(effects) else 0) 117 .setSetWallpaperEntryPoint(setWallpaperEntryPoint) 118 .setWallpaperDestination(destination) 119 .log() 120 } 121 logEffectApplynull122 override fun logEffectApply( 123 effect: String, 124 @EffectStatus status: Int, 125 timeElapsedMillis: Long, 126 resultCode: Int, 127 ) { 128 SysUiStatsLogger(WALLPAPER_EFFECT_APPLIED) 129 .setAppSessionId(appSessionId.getId()) 130 .setEffectPreference(status) 131 .setEffectIdHash(getIdHashCode(effect)) 132 .setTimeElapsed(timeElapsedMillis) 133 .setEffectResultCode(resultCode) 134 .log() 135 } 136 logEffectProbenull137 override fun logEffectProbe(effect: String, @EffectStatus status: Int) { 138 SysUiStatsLogger(WALLPAPER_EFFECT_PROBE) 139 .setAppSessionId(appSessionId.getId()) 140 .setEffectPreference(status) 141 .setEffectIdHash(getIdHashCode(effect)) 142 .log() 143 } 144 logEffectForegroundDownloadnull145 override fun logEffectForegroundDownload( 146 effect: String, 147 @EffectStatus status: Int, 148 timeElapsedMillis: Long, 149 ) { 150 SysUiStatsLogger(WALLPAPER_EFFECT_FG_DOWNLOAD) 151 .setAppSessionId(appSessionId.getId()) 152 .setEffectPreference(status) 153 .setEffectIdHash(getIdHashCode(effect)) 154 .setTimeElapsed(timeElapsedMillis) 155 .log() 156 } 157 logResetAppliednull158 override fun logResetApplied() { 159 SysUiStatsLogger(RESET_APPLIED).setAppSessionId(appSessionId.getId()).log() 160 } 161 logWallpaperExploreButtonClickednull162 override fun logWallpaperExploreButtonClicked() { 163 SysUiStatsLogger(WALLPAPER_EXPLORE).setAppSessionId(appSessionId.getId()).log() 164 } 165 logThemeColorAppliednull166 override fun logThemeColorApplied(@ColorSource source: Int, style: Int, seedColor: Int) { 167 SysUiStatsLogger(THEME_COLOR_APPLIED) 168 .setAppSessionId(appSessionId.getId()) 169 .setColorSource(source) 170 .setColorVariant(style) 171 .setSeedColor(seedColor) 172 .log() 173 } 174 logGridAppliednull175 override fun logGridApplied(grid: GridOption) { 176 SysUiStatsLogger(GRID_APPLIED) 177 .setAppSessionId(appSessionId.getId()) 178 .setLauncherGrid(grid.getLauncherGridInt()) 179 .log() 180 } 181 logClockAppliednull182 override fun logClockApplied(clockId: String) { 183 SysUiStatsLogger(CLOCK_APPLIED) 184 .setAppSessionId(appSessionId.getId()) 185 .setClockPackageHash(getIdHashCode(clockId)) 186 .log() 187 } 188 logClockColorAppliednull189 override fun logClockColorApplied(seedColor: Int) { 190 SysUiStatsLogger(CLOCK_COLOR_APPLIED) 191 .setAppSessionId(appSessionId.getId()) 192 .setSeedColor(seedColor) 193 .log() 194 } 195 logClockSizeAppliednull196 override fun logClockSizeApplied(@ClockSize clockSize: Int) { 197 SysUiStatsLogger(CLOCK_SIZE_APPLIED) 198 .setAppSessionId(appSessionId.getId()) 199 .setClockSize(clockSize) 200 .log() 201 } 202 logThemedIconAppliednull203 override fun logThemedIconApplied(useThemeIcon: Boolean) { 204 SysUiStatsLogger(THEMED_ICON_APPLIED) 205 .setAppSessionId(appSessionId.getId()) 206 .setToggleOn(useThemeIcon) 207 .log() 208 } 209 logLockScreenNotificationAppliednull210 override fun logLockScreenNotificationApplied(showLockScreenNotifications: Boolean) { 211 SysUiStatsLogger(LOCK_SCREEN_NOTIFICATION_APPLIED) 212 .setAppSessionId(appSessionId.getId()) 213 .setToggleOn(showLockScreenNotifications) 214 .log() 215 } 216 logShortcutAppliednull217 override fun logShortcutApplied(shortcut: String, shortcutSlotId: String) { 218 SysUiStatsLogger(SHORTCUT_APPLIED) 219 .setAppSessionId(appSessionId.getId()) 220 .setShortcut(shortcut) 221 .setShortcutSlotId(shortcutSlotId) 222 .log() 223 } 224 logDarkThemeAppliednull225 override fun logDarkThemeApplied(useDarkTheme: Boolean) { 226 SysUiStatsLogger(DARK_THEME_APPLIED) 227 .setAppSessionId(appSessionId.getId()) 228 .setToggleOn(useDarkTheme) 229 .log() 230 } 231 232 /** 233 * The grid integer depends on the column and row numbers. For example: 4x5 is 405 13x37 is 1337 234 * The upper limit for the column / row count is 99. 235 */ GridOptionnull236 private fun GridOption.getLauncherGridInt(): Int { 237 return cols * 100 + rows 238 } 239 getAppLaunchSourcenull240 private fun Intent.getAppLaunchSource(): Int { 241 return if (hasExtra(LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE)) { 242 when (getStringExtra(LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE)) { 243 LaunchSourceUtils.LAUNCH_SOURCE_LAUNCHER -> LAUNCHED_LAUNCHER 244 LaunchSourceUtils.LAUNCH_SOURCE_SETTINGS -> LAUNCHED_SETTINGS 245 LaunchSourceUtils.LAUNCH_SOURCE_SUW -> LAUNCHED_SUW 246 LaunchSourceUtils.LAUNCH_SOURCE_TIPS -> LAUNCHED_TIPS 247 LaunchSourceUtils.LAUNCH_SOURCE_DEEP_LINK -> LAUNCHED_DEEP_LINK 248 LaunchSourceUtils.LAUNCH_SOURCE_KEYGUARD -> LAUNCHED_KEYGUARD 249 LaunchSourceUtils.LAUNCH_SOURCE_SETTINGS_SEARCH -> LAUNCHED_SETTINGS_SEARCH 250 else -> LAUNCHED_PREFERENCE_UNSPECIFIED 251 } 252 } else if (action != null && action == WallpaperManager.ACTION_CROP_AND_SET_WALLPAPER) { 253 LAUNCHED_CROP_AND_SET_ACTION 254 } else if (categories != null && categories.contains(Intent.CATEGORY_LAUNCHER)) { 255 LAUNCHED_LAUNCH_ICON 256 } else { 257 LAUNCHED_PREFERENCE_UNSPECIFIED 258 } 259 } 260 261 /** If not set, the output hash is 0. */ WallpaperPreferencesnull262 private fun WallpaperPreferences.getHomeCategoryHash(): Int { 263 return getIdHashCode(getHomeWallpaperCollectionId()) 264 } 265 266 /** If not set, the output hash is 0. */ WallpaperPreferencesnull267 private fun WallpaperPreferences.getHomeWallpaperIdHash(): Int { 268 val remoteId = getHomeWallpaperRemoteId() 269 val wallpaperId = 270 if (!TextUtils.isEmpty(remoteId)) remoteId else getHomeWallpaperServiceName() 271 return getIdHashCode(wallpaperId) 272 } 273 274 /** If not set, the output hash is 0. */ WallpaperPreferencesnull275 private fun WallpaperPreferences.getLockCategoryHash(): Int { 276 return getIdHashCode(getLockWallpaperCollectionId()) 277 } 278 279 /** If not set, the output hash is 0. */ WallpaperPreferencesnull280 private fun WallpaperPreferences.getLockWallpaperIdHash(): Int { 281 val remoteId = getLockWallpaperRemoteId() 282 val wallpaperId = 283 if (!TextUtils.isEmpty(remoteId)) remoteId else getLockWallpaperServiceName() 284 return getIdHashCode(wallpaperId) 285 } 286 287 /** If not set, the output hash is 0. */ WallpaperPreferencesnull288 private fun WallpaperPreferences.getHomeWallpaperEffectsIdHash(): Int { 289 return getIdHashCode(getHomeWallpaperEffects()) 290 } 291 292 /** If not set, the output hash is 0. */ getLockWallpaperEffectsIdHashnull293 private fun WallpaperPreferences.getLockWallpaperEffectsIdHash(): Int { 294 return getIdHashCode(getLockWallpaperEffects()) 295 } 296 getIdHashCodenull297 private fun getIdHashCode(id: String?): Int { 298 return id?.hashCode() ?: 0 299 } 300 } 301