diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml index df32626e5c..29779a711e 100644 --- a/quickstep/res/values/override.xml +++ b/quickstep/res/values/override.xml @@ -35,4 +35,6 @@ + com.android.quickstep.LauncherRestoreEventLoggerImpl + diff --git a/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt new file mode 100644 index 0000000000..645ecf41a1 --- /dev/null +++ b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt @@ -0,0 +1,136 @@ +package com.android.quickstep + +import android.app.backup.BackupManager +import android.app.backup.BackupRestoreEventLogger +import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType +import android.app.backup.BackupRestoreEventLogger.BackupRestoreError +import android.content.Context +import com.android.launcher3.Flags +import com.android.launcher3.LauncherSettings.Favorites +import com.android.launcher3.backuprestore.LauncherRestoreEventLogger + +/** + * Concrete implementation for wrapper to log Restore event metrics for both success and failure to + * restore Launcher workspace from a backup. This implementation accesses SystemApis so is only + * available to QuickStep/NexusLauncher. + */ +class LauncherRestoreEventLoggerImpl(val context: Context) : LauncherRestoreEventLogger() { + companion object { + const val TAG = "LauncherRestoreEventLoggerImpl" + + // Generic type for any possible workspace items, when specific type is not known. + @BackupRestoreDataType private const val DATA_TYPE_LAUNCHER_ITEM = "launcher_item" + // Specific workspace item types, based off of Favorites Table. + @BackupRestoreDataType private const val DATA_TYPE_APPLICATION = "application" + @BackupRestoreDataType private const val DATA_TYPE_FOLDER = "folder" + @BackupRestoreDataType private const val DATA_TYPE_APPWIDGET = "widget" + @BackupRestoreDataType private const val DATA_TYPE_CUSTOM_APPWIDGET = "custom_widget" + @BackupRestoreDataType private const val DATA_TYPE_DEEP_SHORTCUT = "deep_shortcut" + @BackupRestoreDataType private const val DATA_TYPE_APP_PAIR = "app_pair" + } + + private val backupManager: BackupManager = BackupManager(context) + private val restoreEventLogger: BackupRestoreEventLogger = backupManager.delayedRestoreLogger + + /** + * For logging when multiple items of a given data type failed to restore. + * + * @param dataType The data type that was not restored. + * @param count the number of data items that were not restored. + * @param error error type for why the data was not restored. + */ + override fun logLauncherItemsRestoreFailed( + @BackupRestoreDataType dataType: String, + count: Int, + @BackupRestoreError error: String? + ) { + if (Flags.enableLauncherBrMetrics()) { + restoreEventLogger.logItemsRestoreFailed(dataType, count, error) + } + } + + /** + * For logging when multiple items of a given data type were successfully restored. + * + * @param dataType The data type that was restored. + * @param count the number of data items restored. + */ + override fun logLauncherItemsRestored(@BackupRestoreDataType dataType: String, count: Int) { + if (Flags.enableLauncherBrMetrics()) { + restoreEventLogger.logItemsRestored(dataType, count) + } + } + + /** + * Helper to log successfully restoring a single item from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was restored. + */ + override fun logSingleFavoritesItemRestored(favoritesId: Int) { + if (Flags.enableLauncherBrMetrics()) { + restoreEventLogger.logItemsRestored(favoritesIdToDataType(favoritesId), 1) + } + } + + /** + * Helper to log a failure to restore a single item from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was not restored. + * @param error error type for why the data was not restored. + */ + override fun logSingleFavoritesItemRestoreFailed( + favoritesId: Int, + @BackupRestoreError error: String? + ) { + if (Flags.enableLauncherBrMetrics()) { + restoreEventLogger.logItemsRestoreFailed(favoritesIdToDataType(favoritesId), 1, error) + } + } + + /** + * Helper to log a failure to restore items from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was not restored. + * @param count number of items that failed to restore. + * @param error error type for why the data was not restored. + */ + override fun logFavoritesItemsRestoreFailed( + favoritesId: Int, + count: Int, + @BackupRestoreError error: String? + ) { + if (Flags.enableLauncherBrMetrics()) { + restoreEventLogger.logItemsRestoreFailed( + favoritesIdToDataType(favoritesId), + count, + error + ) + } + } + + /** + * Uses the current [restoreEventLogger] to report its results to the [backupManager]. Use when + * done restoring items for Launcher. + */ + override fun reportLauncherRestoreResults() { + if (Flags.enableLauncherBrMetrics()) { + backupManager.reportDelayedRestoreResult(restoreEventLogger) + } + } + + /** + * Helper method to convert item types from [Favorites] to B&R data types for logging. Also to + * avoid direct usage of @BackupRestoreDataType which is protected under @SystemApi. + */ + @BackupRestoreDataType + private fun favoritesIdToDataType(favoritesId: Int): String = + when (favoritesId) { + Favorites.ITEM_TYPE_APPLICATION -> DATA_TYPE_APPLICATION + Favorites.ITEM_TYPE_FOLDER -> DATA_TYPE_FOLDER + Favorites.ITEM_TYPE_APPWIDGET -> DATA_TYPE_APPWIDGET + Favorites.ITEM_TYPE_CUSTOM_APPWIDGET -> DATA_TYPE_CUSTOM_APPWIDGET + Favorites.ITEM_TYPE_DEEP_SHORTCUT -> DATA_TYPE_DEEP_SHORTCUT + Favorites.ITEM_TYPE_APP_PAIR -> DATA_TYPE_APP_PAIR + else -> DATA_TYPE_LAUNCHER_ITEM + } +} diff --git a/res/values/config.xml b/res/values/config.xml index 154312ad4b..2980635634 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -86,6 +86,7 @@ + diff --git a/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt b/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt new file mode 100644 index 0000000000..16b185495a --- /dev/null +++ b/src/com/android/launcher3/backuprestore/LauncherRestoreEventLogger.kt @@ -0,0 +1,84 @@ +package com.android.launcher3.backuprestore + +import android.content.Context +import com.android.launcher3.LauncherSettings.Favorites +import com.android.launcher3.R +import com.android.launcher3.util.ResourceBasedOverride + +/** + * Wrapper for logging Restore event metrics for both success and failure to restore the Launcher + * workspace from a backup. + */ +open class LauncherRestoreEventLogger : ResourceBasedOverride { + + companion object { + const val TAG = "LauncherRestoreEventLogger" + + fun newInstance(context: Context?): LauncherRestoreEventLogger { + return ResourceBasedOverride.Overrides.getObject( + LauncherRestoreEventLogger::class.java, + context, + R.string.launcher_restore_event_logger_class + ) + } + } + + /** + * For logging when multiple items of a given data type failed to restore. + * + * @param dataType The data type that was not restored. + * @param count the number of data items that were not restored. + * @param error error type for why the data was not restored. + */ + open fun logLauncherItemsRestoreFailed(dataType: String, count: Int, error: String?) { + // no-op + } + + /** + * For logging when multiple items of a given data type were successfully restored. + * + * @param dataType The data type that was restored. + * @param count the number of data items restored. + */ + open fun logLauncherItemsRestored(dataType: String, count: Int) { + // no-op + } + + /** + * Helper to log successfully restoring a single item from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was restored. + */ + open fun logSingleFavoritesItemRestored(favoritesId: Int) { + // no-op + } + + /** + * Helper to log a failure to restore a single item from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was not restored. + * @param error error type for why the data was not restored. + */ + open fun logSingleFavoritesItemRestoreFailed(favoritesId: Int, error: String?) { + // no-op + } + + /** + * Helper to log a failure to restore items from the Favorites table. + * + * @param favoritesId The id of the item type from [Favorites] that was not restored. + * @param count number of items that failed to restore. + * @param error error type for why the data was not restored. + */ + open fun logFavoritesItemsRestoreFailed(favoritesId: Int, count: Int, error: String?) { + // no-op + } + + /** + * Uses the current [restoreEventLogger] to report its results to the [backupManager]. Use when + * done restoring items for Launcher. + */ + open fun reportLauncherRestoreResults() { + // no-op + } +}