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.ActivityUtils 60 import com.android.wallpaper.util.LaunchSourceUtils 61 import javax.inject.Inject 62 import javax.inject.Singleton 63 64 /** StatsLog-backed implementation of [ThemesUserEventLogger]. */ 65 @Singleton 66 class ThemesUserEventLoggerImpl 67 @Inject 68 constructor( 69 private val preferences: WallpaperPreferences, 70 private val colorManager: ColorCustomizationManager, 71 private val appSessionId: AppSessionId, 72 ) : ThemesUserEventLogger { 73 logSnapshotnull74 override fun logSnapshot() { 75 SysUiStatsLogger(SNAPSHOT) 76 .setWallpaperCategoryHash(preferences.getHomeCategoryHash()) 77 .setWallpaperIdHash(preferences.getHomeWallpaperIdHash()) 78 .setEffectIdHash(preferences.getHomeWallpaperEffectsIdHash()) 79 .setLockWallpaperCategoryHash(preferences.getLockCategoryHash()) 80 .setLockWallpaperIdHash(preferences.getLockWallpaperIdHash()) 81 .setLockEffectIdHash(preferences.getLockWallpaperEffectsIdHash()) 82 .setColorSource(colorManager.currentColorSourceForLogging) 83 .setColorVariant(colorManager.currentStyleForLogging) 84 .setSeedColor(colorManager.currentSeedColorForLogging) 85 .log() 86 } 87 logAppLaunchednull88 override fun logAppLaunched(launchSource: Intent) { 89 SysUiStatsLogger(APP_LAUNCHED) 90 .setAppSessionId(appSessionId.createNewId().getId()) 91 .setLaunchedPreference(launchSource.getAppLaunchSource()) 92 .log() 93 } 94 logWallpaperAppliednull95 override fun logWallpaperApplied( 96 collectionId: String?, 97 wallpaperId: String?, 98 effects: String?, 99 @SetWallpaperEntryPoint setWallpaperEntryPoint: Int, 100 @WallpaperDestination destination: Int, 101 ) { 102 val categoryHash = getIdHashCode(collectionId) 103 val wallpaperIdHash = getIdHashCode(wallpaperId) 104 val isHomeWallpaperSet = 105 destination == WALLPAPER_DESTINATION_HOME_SCREEN || 106 destination == WALLPAPER_DESTINATION_HOME_AND_LOCK_SCREEN 107 val isLockWallpaperSet = 108 destination == WALLPAPER_DESTINATION_LOCK_SCREEN || 109 destination == WALLPAPER_DESTINATION_HOME_AND_LOCK_SCREEN 110 SysUiStatsLogger(WALLPAPER_APPLIED) 111 .setAppSessionId(appSessionId.getId()) 112 .setWallpaperCategoryHash(if (isHomeWallpaperSet) categoryHash else 0) 113 .setWallpaperIdHash(if (isHomeWallpaperSet) wallpaperIdHash else 0) 114 .setEffectIdHash(if (isHomeWallpaperSet) getIdHashCode(effects) else 0) 115 .setLockWallpaperCategoryHash(if (isLockWallpaperSet) categoryHash else 0) 116 .setLockWallpaperIdHash(if (isLockWallpaperSet) wallpaperIdHash else 0) 117 .setLockEffectIdHash(if (isLockWallpaperSet) getIdHashCode(effects) else 0) 118 .setSetWallpaperEntryPoint(setWallpaperEntryPoint) 119 .setWallpaperDestination(destination) 120 .log() 121 } 122 logEffectApplynull123 override fun logEffectApply( 124 effect: String, 125 @EffectStatus status: Int, 126 timeElapsedMillis: Long, 127 resultCode: Int 128 ) { 129 SysUiStatsLogger(WALLPAPER_EFFECT_APPLIED) 130 .setAppSessionId(appSessionId.getId()) 131 .setEffectPreference(status) 132 .setEffectIdHash(getIdHashCode(effect)) 133 .setTimeElapsed(timeElapsedMillis) 134 .setEffectResultCode(resultCode) 135 .log() 136 } 137 logEffectProbenull138 override fun logEffectProbe(effect: String, @EffectStatus status: Int) { 139 SysUiStatsLogger(WALLPAPER_EFFECT_PROBE) 140 .setAppSessionId(appSessionId.getId()) 141 .setEffectPreference(status) 142 .setEffectIdHash(getIdHashCode(effect)) 143 .log() 144 } 145 logEffectForegroundDownloadnull146 override fun logEffectForegroundDownload( 147 effect: String, 148 @EffectStatus status: Int, 149 timeElapsedMillis: Long 150 ) { 151 SysUiStatsLogger(WALLPAPER_EFFECT_FG_DOWNLOAD) 152 .setAppSessionId(appSessionId.getId()) 153 .setEffectPreference(status) 154 .setEffectIdHash(getIdHashCode(effect)) 155 .setTimeElapsed(timeElapsedMillis) 156 .log() 157 } 158 logResetAppliednull159 override fun logResetApplied() { 160 SysUiStatsLogger(RESET_APPLIED).setAppSessionId(appSessionId.getId()).log() 161 } 162 logWallpaperExploreButtonClickednull163 override fun logWallpaperExploreButtonClicked() { 164 SysUiStatsLogger(WALLPAPER_EXPLORE).setAppSessionId(appSessionId.getId()).log() 165 } 166 logThemeColorAppliednull167 override fun logThemeColorApplied( 168 @ColorSource source: Int, 169 style: Int, 170 seedColor: Int, 171 ) { 172 SysUiStatsLogger(THEME_COLOR_APPLIED) 173 .setAppSessionId(appSessionId.getId()) 174 .setColorSource(source) 175 .setColorVariant(style) 176 .setSeedColor(seedColor) 177 .log() 178 } 179 logGridAppliednull180 override fun logGridApplied(grid: GridOption) { 181 SysUiStatsLogger(GRID_APPLIED) 182 .setAppSessionId(appSessionId.getId()) 183 .setLauncherGrid(grid.getLauncherGridInt()) 184 .log() 185 } 186 logClockAppliednull187 override fun logClockApplied(clockId: String) { 188 SysUiStatsLogger(CLOCK_APPLIED) 189 .setAppSessionId(appSessionId.getId()) 190 .setClockPackageHash(getIdHashCode(clockId)) 191 .log() 192 } 193 logClockColorAppliednull194 override fun logClockColorApplied(seedColor: Int) { 195 SysUiStatsLogger(CLOCK_COLOR_APPLIED) 196 .setAppSessionId(appSessionId.getId()) 197 .setSeedColor(seedColor) 198 .log() 199 } 200 logClockSizeAppliednull201 override fun logClockSizeApplied(@ClockSize clockSize: Int) { 202 SysUiStatsLogger(CLOCK_SIZE_APPLIED) 203 .setAppSessionId(appSessionId.getId()) 204 .setClockSize(clockSize) 205 .log() 206 } 207 logThemedIconAppliednull208 override fun logThemedIconApplied(useThemeIcon: Boolean) { 209 SysUiStatsLogger(THEMED_ICON_APPLIED) 210 .setAppSessionId(appSessionId.getId()) 211 .setToggleOn(useThemeIcon) 212 .log() 213 } 214 logLockScreenNotificationAppliednull215 override fun logLockScreenNotificationApplied(showLockScreenNotifications: Boolean) { 216 SysUiStatsLogger(LOCK_SCREEN_NOTIFICATION_APPLIED) 217 .setAppSessionId(appSessionId.getId()) 218 .setToggleOn(showLockScreenNotifications) 219 .log() 220 } 221 logShortcutAppliednull222 override fun logShortcutApplied(shortcut: String, shortcutSlotId: String) { 223 SysUiStatsLogger(SHORTCUT_APPLIED) 224 .setAppSessionId(appSessionId.getId()) 225 .setShortcut(shortcut) 226 .setShortcutSlotId(shortcutSlotId) 227 .log() 228 } 229 logDarkThemeAppliednull230 override fun logDarkThemeApplied(useDarkTheme: Boolean) { 231 SysUiStatsLogger(DARK_THEME_APPLIED) 232 .setAppSessionId(appSessionId.getId()) 233 .setToggleOn(useDarkTheme) 234 .log() 235 } 236 237 /** 238 * The grid integer depends on the column and row numbers. For example: 4x5 is 405 13x37 is 1337 239 * The upper limit for the column / row count is 99. 240 */ GridOptionnull241 private fun GridOption.getLauncherGridInt(): Int { 242 return cols * 100 + rows 243 } 244 getAppLaunchSourcenull245 private fun Intent.getAppLaunchSource(): Int { 246 return if (hasExtra(LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE)) { 247 when (getStringExtra(LaunchSourceUtils.WALLPAPER_LAUNCH_SOURCE)) { 248 LaunchSourceUtils.LAUNCH_SOURCE_LAUNCHER -> LAUNCHED_LAUNCHER 249 LaunchSourceUtils.LAUNCH_SOURCE_SETTINGS -> LAUNCHED_SETTINGS 250 LaunchSourceUtils.LAUNCH_SOURCE_SUW -> LAUNCHED_SUW 251 LaunchSourceUtils.LAUNCH_SOURCE_TIPS -> LAUNCHED_TIPS 252 LaunchSourceUtils.LAUNCH_SOURCE_DEEP_LINK -> LAUNCHED_DEEP_LINK 253 LaunchSourceUtils.LAUNCH_SOURCE_KEYGUARD -> LAUNCHED_KEYGUARD 254 else -> LAUNCHED_PREFERENCE_UNSPECIFIED 255 } 256 } else if (ActivityUtils.isLaunchedFromSettingsSearch(this)) { 257 LAUNCHED_SETTINGS_SEARCH 258 } else if (action != null && action == WallpaperManager.ACTION_CROP_AND_SET_WALLPAPER) { 259 LAUNCHED_CROP_AND_SET_ACTION 260 } else if (categories != null && categories.contains(Intent.CATEGORY_LAUNCHER)) { 261 LAUNCHED_LAUNCH_ICON 262 } else { 263 LAUNCHED_PREFERENCE_UNSPECIFIED 264 } 265 } 266 267 /** If not set, the output hash is 0. */ WallpaperPreferencesnull268 private fun WallpaperPreferences.getHomeCategoryHash(): Int { 269 return getIdHashCode(getHomeWallpaperCollectionId()) 270 } 271 272 /** If not set, the output hash is 0. */ WallpaperPreferencesnull273 private fun WallpaperPreferences.getHomeWallpaperIdHash(): Int { 274 val remoteId = getHomeWallpaperRemoteId() 275 val wallpaperId = 276 if (!TextUtils.isEmpty(remoteId)) remoteId else getHomeWallpaperServiceName() 277 return getIdHashCode(wallpaperId) 278 } 279 280 /** If not set, the output hash is 0. */ WallpaperPreferencesnull281 private fun WallpaperPreferences.getLockCategoryHash(): Int { 282 return getIdHashCode(getLockWallpaperCollectionId()) 283 } 284 285 /** If not set, the output hash is 0. */ WallpaperPreferencesnull286 private fun WallpaperPreferences.getLockWallpaperIdHash(): Int { 287 val remoteId = getLockWallpaperRemoteId() 288 val wallpaperId = 289 if (!TextUtils.isEmpty(remoteId)) remoteId else getLockWallpaperServiceName() 290 return getIdHashCode(wallpaperId) 291 } 292 293 /** If not set, the output hash is 0. */ WallpaperPreferencesnull294 private fun WallpaperPreferences.getHomeWallpaperEffectsIdHash(): Int { 295 return getIdHashCode(getHomeWallpaperEffects()) 296 } 297 298 /** If not set, the output hash is 0. */ getLockWallpaperEffectsIdHashnull299 private fun WallpaperPreferences.getLockWallpaperEffectsIdHash(): Int { 300 return getIdHashCode(getLockWallpaperEffects()) 301 } 302 getIdHashCodenull303 private fun getIdHashCode(id: String?): Int { 304 return id?.hashCode() ?: 0 305 } 306 } 307