Loading packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +33 −1 Original line number Original line Diff line number Diff line Loading @@ -365,6 +365,11 @@ public class WallpaperBackupAgent extends BackupAgent { final int sysWhich = FLAG_SYSTEM | (lockImageStage.exists() ? 0 : FLAG_LOCK); final int sysWhich = FLAG_SYSTEM | (lockImageStage.exists() ? 0 : FLAG_LOCK); try { try { // First parse the live component name so that we know for logging if we care about // logging errors with the image restore. ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); mSystemHasLiveComponent = wpService != null; // It is valid for the imagery to be absent; it means that we were not permitted // It is valid for the imagery to be absent; it means that we were not permitted // to back up the original image on the source device, or there was no user-supplied // to back up the original image on the source device, or there was no user-supplied // wallpaper image present. // wallpaper image present. Loading @@ -372,10 +377,10 @@ public class WallpaperBackupAgent extends BackupAgent { restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK); restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK); // And reset to the wallpaper service we should be using // And reset to the wallpaper service we should be using ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); updateWallpaperComponent(wpService, !lockImageStage.exists()); updateWallpaperComponent(wpService, !lockImageStage.exists()); } catch (Exception e) { } catch (Exception e) { Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage()); Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage()); mEventLogger.onRestoreException(e); } finally { } finally { Slog.v(TAG, "Restore finished; clearing backup bookkeeping"); Slog.v(TAG, "Restore finished; clearing backup bookkeeping"); infoStage.delete(); infoStage.delete(); Loading @@ -399,12 +404,15 @@ public class WallpaperBackupAgent extends BackupAgent { // We have a live wallpaper and no static lock image, // We have a live wallpaper and no static lock image, // allow live wallpaper to show "through" on lock screen. // allow live wallpaper to show "through" on lock screen. mWallpaperManager.clear(FLAG_LOCK); mWallpaperManager.clear(FLAG_LOCK); mEventLogger.onLockLiveWallpaperRestored(wpService); } } mEventLogger.onSystemLiveWallpaperRestored(wpService); } else { } else { // If we've restored a live wallpaper, but the component doesn't exist, // If we've restored a live wallpaper, but the component doesn't exist, // we should log it as an error so we can easily identify the problem // we should log it as an error so we can easily identify the problem // in reports from users // in reports from users if (wpService != null) { if (wpService != null) { // TODO(b/268471749): Handle delayed case applyComponentAtInstall(wpService, applyToLock); applyComponentAtInstall(wpService, applyToLock); Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. " Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. " + " Will try to apply later"); + " Will try to apply later"); Loading @@ -424,13 +432,37 @@ public class WallpaperBackupAgent extends BackupAgent { try (FileInputStream in = new FileInputStream(stage)) { try (FileInputStream in = new FileInputStream(stage)) { mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true, mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true, which); which); // And log the success if ((which & FLAG_SYSTEM) > 0) { mEventLogger.onSystemImageWallpaperRestored(); } else { mEventLogger.onLockImageWallpaperRestored(); } } } } else { logRestoreError(which, ERROR_NO_METADATA); } } } else { } else { Slog.d(TAG, "Restore data doesn't exist for file " + stage.getPath()); Slog.d(TAG, "Restore data doesn't exist for file " + stage.getPath()); logRestoreErrorIfNoLiveComponent(which, ERROR_NO_WALLPAPER); } } } } private void logRestoreErrorIfNoLiveComponent(int which, String error) { if (mSystemHasLiveComponent) { return; } logRestoreError(which, error); } private void logRestoreError(int which, String error) { if ((which & FLAG_SYSTEM) == FLAG_SYSTEM) { mEventLogger.onSystemImageWallpaperRestoreFailed(error); } else if ((which & FLAG_LOCK) == FLAG_LOCK) { mEventLogger.onLockImageWallpaperRestoreFailed(error); } } private Rect parseCropHint(File wallpaperInfo, String sectionTag) { private Rect parseCropHint(File wallpaperInfo, String sectionTag) { Rect cropHint = new Rect(); Rect cropHint = new Rect(); try (FileInputStream stream = new FileInputStream(wallpaperInfo)) { try (FileInputStream stream = new FileInputStream(wallpaperInfo)) { Loading packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java +68 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.content.ComponentName; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -101,6 +102,39 @@ public class WallpaperEventLogger { logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); } } void onSystemImageWallpaperRestored() { logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null); } void onLockImageWallpaperRestored() { logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null); } void onSystemLiveWallpaperRestored(ComponentName wpService) { logRestoreSuccessInternal(WALLPAPER_LIVE_SYSTEM, wpService); } void onLockLiveWallpaperRestored(ComponentName wpService) { logRestoreSuccessInternal(WALLPAPER_LIVE_LOCK, wpService); } void onSystemImageWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_IMG_SYSTEM, error); } void onLockImageWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_IMG_LOCK, error); } void onSystemLiveWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_LIVE_SYSTEM, error); } void onLockLiveWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_LIVE_LOCK, error); } /** /** * Called when the whole backup flow is interrupted by an exception. * Called when the whole backup flow is interrupted by an exception. Loading @@ -117,6 +151,20 @@ public class WallpaperEventLogger { } } } } /** * Called when the whole restore flow is interrupted by an exception. */ void onRestoreException(Exception exception) { String error = exception.getClass().getName(); if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_SYSTEM)) { mLogger.logItemsRestoreFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error); } if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_LOCK)) { mLogger.logItemsRestoreFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error); } } private void logBackupSuccessInternal(@BackupRestoreDataType String which, private void logBackupSuccessInternal(@BackupRestoreDataType String which, @Nullable WallpaperInfo liveComponentWallpaperInfo) { @Nullable WallpaperInfo liveComponentWallpaperInfo) { mLogger.logItemsBackedUp(which, /* count */ 1); mLogger.logItemsBackedUp(which, /* count */ 1); Loading @@ -130,10 +178,30 @@ public class WallpaperEventLogger { mProcessedDataTypes.add(which); mProcessedDataTypes.add(which); } } private void logRestoreSuccessInternal(@BackupRestoreDataType String which, @Nullable ComponentName liveComponentWallpaperInfo) { mLogger.logItemsRestored(which, /* count */ 1); logRestoredLiveWallpaperNameIfPresent(which, liveComponentWallpaperInfo); mProcessedDataTypes.add(which); } private void logRestoreFailureInternal(@BackupRestoreDataType String which, @BackupRestoreError String error) { mLogger.logItemsRestoreFailed(which, /* count */ 1, error); mProcessedDataTypes.add(which); } private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, WallpaperInfo wallpaperInfo) { WallpaperInfo wallpaperInfo) { if (wallpaperInfo != null) { if (wallpaperInfo != null) { mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); } } } } private void logRestoredLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, ComponentName wpService) { if (wpService != null) { mLogger.logRestoreMetadata(wallpaperType, wpService.getClassName()); } } } } packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java +143 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.wallpaperbackup.WallpaperBackupAgent.LOCK_WALLPAPER_ST import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED; import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK; import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK; Loading @@ -34,6 +35,8 @@ import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_SY import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; Loading @@ -55,12 +58,14 @@ import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserHandle; import android.service.wallpaper.WallpaperService; import android.service.wallpaper.WallpaperService; import android.util.Xml; import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry; import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.content.PackageMonitor; import com.android.modules.utils.TypedXmlSerializer; import com.android.wallpaperbackup.utils.ContextWithServiceOverrides; import com.android.wallpaperbackup.utils.ContextWithServiceOverrides; import org.junit.After; import org.junit.After; Loading Loading @@ -592,6 +597,123 @@ public class WallpaperBackupAgentTest { assertThat(result.getSuccessCount()).isEqualTo(1); assertThat(result.getSuccessCount()).isEqualTo(1); } } @Test public void testOnRestore_systemWallpaperImgSuccess_logsSuccess() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getSuccessCount()).isEqualTo(1); } @Test public void testOnRestore_lockWallpaperImgSuccess_logsSuccess() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getSuccessCount()).isEqualTo(1); } @Test public void testOnRestore_systemWallpaperImgMissingAndNoLive_logsFailure() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); } @Test public void testOnRestore_lockWallpaperImgMissingAndNoLive_logsFailure() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); } @Test public void testOnRestore_wallpaperInfoMissing_logsFailure() throws Exception { mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_METADATA); } @Test public void testOnRestore_imgMissingButWallpaperInfoHasLive_doesNotLogImg() throws Exception { mockRestoredLiveWallpaperFile(); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(system).isNull(); assertThat(lock).isNull(); } @Test public void testOnRestore_throwsException_logsErrors() throws Exception { when(mWallpaperManager.setStream(any(), any(), anyBoolean(), anyInt())).thenThrow( new RuntimeException()); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(system).isNotNull(); assertThat(system.getFailCount()).isEqualTo(1); assertThat(system.getErrors()).containsKey(RuntimeException.class.getName()); assertThat(lock).isNotNull(); assertThat(lock.getFailCount()).isEqualTo(1); assertThat(lock.getErrors()).containsKey(RuntimeException.class.getName()); } private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) { private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) { when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId); Loading Loading @@ -636,6 +758,27 @@ public class WallpaperBackupAgentTest { ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY)); ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY)); } } private void mockStagedWallpaperFile(String location) throws Exception { File wallpaperFile = new File(mContext.getFilesDir(), location); wallpaperFile.createNewFile(); } private void mockRestoredLiveWallpaperFile() throws Exception { File wallpaperFile = new File(mContext.getFilesDir(), WALLPAPER_INFO_STAGE); wallpaperFile.createNewFile(); FileOutputStream fstream = new FileOutputStream(wallpaperFile, false); TypedXmlSerializer out = Xml.resolveSerializer(fstream); out.startDocument(null, true); out.startTag(null, "wp"); out.attribute(null, "component", getFakeWallpaperInfo().getComponent().flattenToShortString()); out.endTag(null, "wp"); out.endDocument(); fstream.flush(); FileUtils.sync(fstream); fstream.close(); } private WallpaperInfo getFakeWallpaperInfo() throws Exception { private WallpaperInfo getFakeWallpaperInfo() throws Exception { Context context = InstrumentationRegistry.getTargetContext(); Context context = InstrumentationRegistry.getTargetContext(); Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); Loading packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java +253 −34 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +33 −1 Original line number Original line Diff line number Diff line Loading @@ -365,6 +365,11 @@ public class WallpaperBackupAgent extends BackupAgent { final int sysWhich = FLAG_SYSTEM | (lockImageStage.exists() ? 0 : FLAG_LOCK); final int sysWhich = FLAG_SYSTEM | (lockImageStage.exists() ? 0 : FLAG_LOCK); try { try { // First parse the live component name so that we know for logging if we care about // logging errors with the image restore. ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); mSystemHasLiveComponent = wpService != null; // It is valid for the imagery to be absent; it means that we were not permitted // It is valid for the imagery to be absent; it means that we were not permitted // to back up the original image on the source device, or there was no user-supplied // to back up the original image on the source device, or there was no user-supplied // wallpaper image present. // wallpaper image present. Loading @@ -372,10 +377,10 @@ public class WallpaperBackupAgent extends BackupAgent { restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK); restoreFromStage(lockImageStage, infoStage, "kwp", FLAG_LOCK); // And reset to the wallpaper service we should be using // And reset to the wallpaper service we should be using ComponentName wpService = parseWallpaperComponent(infoStage, "wp"); updateWallpaperComponent(wpService, !lockImageStage.exists()); updateWallpaperComponent(wpService, !lockImageStage.exists()); } catch (Exception e) { } catch (Exception e) { Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage()); Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage()); mEventLogger.onRestoreException(e); } finally { } finally { Slog.v(TAG, "Restore finished; clearing backup bookkeeping"); Slog.v(TAG, "Restore finished; clearing backup bookkeeping"); infoStage.delete(); infoStage.delete(); Loading @@ -399,12 +404,15 @@ public class WallpaperBackupAgent extends BackupAgent { // We have a live wallpaper and no static lock image, // We have a live wallpaper and no static lock image, // allow live wallpaper to show "through" on lock screen. // allow live wallpaper to show "through" on lock screen. mWallpaperManager.clear(FLAG_LOCK); mWallpaperManager.clear(FLAG_LOCK); mEventLogger.onLockLiveWallpaperRestored(wpService); } } mEventLogger.onSystemLiveWallpaperRestored(wpService); } else { } else { // If we've restored a live wallpaper, but the component doesn't exist, // If we've restored a live wallpaper, but the component doesn't exist, // we should log it as an error so we can easily identify the problem // we should log it as an error so we can easily identify the problem // in reports from users // in reports from users if (wpService != null) { if (wpService != null) { // TODO(b/268471749): Handle delayed case applyComponentAtInstall(wpService, applyToLock); applyComponentAtInstall(wpService, applyToLock); Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. " Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. " + " Will try to apply later"); + " Will try to apply later"); Loading @@ -424,13 +432,37 @@ public class WallpaperBackupAgent extends BackupAgent { try (FileInputStream in = new FileInputStream(stage)) { try (FileInputStream in = new FileInputStream(stage)) { mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true, mWallpaperManager.setStream(in, cropHint.isEmpty() ? null : cropHint, true, which); which); // And log the success if ((which & FLAG_SYSTEM) > 0) { mEventLogger.onSystemImageWallpaperRestored(); } else { mEventLogger.onLockImageWallpaperRestored(); } } } } else { logRestoreError(which, ERROR_NO_METADATA); } } } else { } else { Slog.d(TAG, "Restore data doesn't exist for file " + stage.getPath()); Slog.d(TAG, "Restore data doesn't exist for file " + stage.getPath()); logRestoreErrorIfNoLiveComponent(which, ERROR_NO_WALLPAPER); } } } } private void logRestoreErrorIfNoLiveComponent(int which, String error) { if (mSystemHasLiveComponent) { return; } logRestoreError(which, error); } private void logRestoreError(int which, String error) { if ((which & FLAG_SYSTEM) == FLAG_SYSTEM) { mEventLogger.onSystemImageWallpaperRestoreFailed(error); } else if ((which & FLAG_LOCK) == FLAG_LOCK) { mEventLogger.onLockImageWallpaperRestoreFailed(error); } } private Rect parseCropHint(File wallpaperInfo, String sectionTag) { private Rect parseCropHint(File wallpaperInfo, String sectionTag) { Rect cropHint = new Rect(); Rect cropHint = new Rect(); try (FileInputStream stream = new FileInputStream(wallpaperInfo)) { try (FileInputStream stream = new FileInputStream(wallpaperInfo)) { Loading
packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java +68 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.content.ComponentName; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -101,6 +102,39 @@ public class WallpaperEventLogger { logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); } } void onSystemImageWallpaperRestored() { logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null); } void onLockImageWallpaperRestored() { logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null); } void onSystemLiveWallpaperRestored(ComponentName wpService) { logRestoreSuccessInternal(WALLPAPER_LIVE_SYSTEM, wpService); } void onLockLiveWallpaperRestored(ComponentName wpService) { logRestoreSuccessInternal(WALLPAPER_LIVE_LOCK, wpService); } void onSystemImageWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_IMG_SYSTEM, error); } void onLockImageWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_IMG_LOCK, error); } void onSystemLiveWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_LIVE_SYSTEM, error); } void onLockLiveWallpaperRestoreFailed(@BackupRestoreError String error) { logRestoreFailureInternal(WALLPAPER_LIVE_LOCK, error); } /** /** * Called when the whole backup flow is interrupted by an exception. * Called when the whole backup flow is interrupted by an exception. Loading @@ -117,6 +151,20 @@ public class WallpaperEventLogger { } } } } /** * Called when the whole restore flow is interrupted by an exception. */ void onRestoreException(Exception exception) { String error = exception.getClass().getName(); if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_SYSTEM)) { mLogger.logItemsRestoreFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error); } if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_LOCK)) { mLogger.logItemsRestoreFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error); } } private void logBackupSuccessInternal(@BackupRestoreDataType String which, private void logBackupSuccessInternal(@BackupRestoreDataType String which, @Nullable WallpaperInfo liveComponentWallpaperInfo) { @Nullable WallpaperInfo liveComponentWallpaperInfo) { mLogger.logItemsBackedUp(which, /* count */ 1); mLogger.logItemsBackedUp(which, /* count */ 1); Loading @@ -130,10 +178,30 @@ public class WallpaperEventLogger { mProcessedDataTypes.add(which); mProcessedDataTypes.add(which); } } private void logRestoreSuccessInternal(@BackupRestoreDataType String which, @Nullable ComponentName liveComponentWallpaperInfo) { mLogger.logItemsRestored(which, /* count */ 1); logRestoredLiveWallpaperNameIfPresent(which, liveComponentWallpaperInfo); mProcessedDataTypes.add(which); } private void logRestoreFailureInternal(@BackupRestoreDataType String which, @BackupRestoreError String error) { mLogger.logItemsRestoreFailed(which, /* count */ 1, error); mProcessedDataTypes.add(which); } private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, WallpaperInfo wallpaperInfo) { WallpaperInfo wallpaperInfo) { if (wallpaperInfo != null) { if (wallpaperInfo != null) { mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); } } } } private void logRestoredLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, ComponentName wpService) { if (wpService != null) { mLogger.logRestoreMetadata(wallpaperType, wpService.getClassName()); } } } }
packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java +143 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.wallpaperbackup.WallpaperBackupAgent.LOCK_WALLPAPER_ST import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE; import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED; import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED; import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK; import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK; Loading @@ -34,6 +35,8 @@ import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_SY import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; import static org.mockito.Mockito.never; Loading @@ -55,12 +58,14 @@ import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor; import android.os.UserHandle; import android.os.UserHandle; import android.service.wallpaper.WallpaperService; import android.service.wallpaper.WallpaperService; import android.util.Xml; import androidx.test.InstrumentationRegistry; import androidx.test.InstrumentationRegistry; import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider; import androidx.test.runner.AndroidJUnit4; import androidx.test.runner.AndroidJUnit4; import com.android.internal.content.PackageMonitor; import com.android.internal.content.PackageMonitor; import com.android.modules.utils.TypedXmlSerializer; import com.android.wallpaperbackup.utils.ContextWithServiceOverrides; import com.android.wallpaperbackup.utils.ContextWithServiceOverrides; import org.junit.After; import org.junit.After; Loading Loading @@ -592,6 +597,123 @@ public class WallpaperBackupAgentTest { assertThat(result.getSuccessCount()).isEqualTo(1); assertThat(result.getSuccessCount()).isEqualTo(1); } } @Test public void testOnRestore_systemWallpaperImgSuccess_logsSuccess() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getSuccessCount()).isEqualTo(1); } @Test public void testOnRestore_lockWallpaperImgSuccess_logsSuccess() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getSuccessCount()).isEqualTo(1); } @Test public void testOnRestore_systemWallpaperImgMissingAndNoLive_logsFailure() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); } @Test public void testOnRestore_lockWallpaperImgMissingAndNoLive_logsFailure() throws Exception { mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); } @Test public void testOnRestore_wallpaperInfoMissing_logsFailure() throws Exception { mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(result).isNotNull(); assertThat(result.getFailCount()).isEqualTo(1); assertThat(result.getErrors()).containsKey(ERROR_NO_METADATA); } @Test public void testOnRestore_imgMissingButWallpaperInfoHasLive_doesNotLogImg() throws Exception { mockRestoredLiveWallpaperFile(); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(system).isNull(); assertThat(lock).isNull(); } @Test public void testOnRestore_throwsException_logsErrors() throws Exception { when(mWallpaperManager.setStream(any(), any(), anyBoolean(), anyInt())).thenThrow( new RuntimeException()); mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, BackupAnnotations.OperationType.RESTORE); mWallpaperBackupAgent.onRestoreFinished(); DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); assertThat(system).isNotNull(); assertThat(system.getFailCount()).isEqualTo(1); assertThat(system.getErrors()).containsKey(RuntimeException.class.getName()); assertThat(lock).isNotNull(); assertThat(lock.getFailCount()).isEqualTo(1); assertThat(lock.getErrors()).containsKey(RuntimeException.class.getName()); } private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) { private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) { when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId); when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId); Loading Loading @@ -636,6 +758,27 @@ public class WallpaperBackupAgentTest { ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY)); ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY)); } } private void mockStagedWallpaperFile(String location) throws Exception { File wallpaperFile = new File(mContext.getFilesDir(), location); wallpaperFile.createNewFile(); } private void mockRestoredLiveWallpaperFile() throws Exception { File wallpaperFile = new File(mContext.getFilesDir(), WALLPAPER_INFO_STAGE); wallpaperFile.createNewFile(); FileOutputStream fstream = new FileOutputStream(wallpaperFile, false); TypedXmlSerializer out = Xml.resolveSerializer(fstream); out.startDocument(null, true); out.startTag(null, "wp"); out.attribute(null, "component", getFakeWallpaperInfo().getComponent().flattenToShortString()); out.endTag(null, "wp"); out.endDocument(); fstream.flush(); FileUtils.sync(fstream); fstream.close(); } private WallpaperInfo getFakeWallpaperInfo() throws Exception { private WallpaperInfo getFakeWallpaperInfo() throws Exception { Context context = InstrumentationRegistry.getTargetContext(); Context context = InstrumentationRegistry.getTargetContext(); Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); Loading
packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java +253 −34 File changed.Preview size limit exceeded, changes collapsed. Show changes