Loading packages/WallpaperBackup/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ android_test { srcs: [ // Include the app source code because the app runs as the system user on-device. "src/**/*.java", "test/src/**/*.java" "test/src/**/*.java", ], libs: [ "android.test.base", Loading @@ -54,7 +54,8 @@ android_test { "mockito-target-minus-junit4", "truth-prebuilt", ], resource_dirs: ["test/res"], certificate: "platform", platform_apis: true, test_suites: ["device-tests"] test_suites: ["device-tests"], } packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +61 −0 Original line number Diff line number Diff line Loading @@ -19,11 +19,18 @@ package com.android.wallpaperbackup; import static android.app.WallpaperManager.FLAG_LOCK; import static android.app.WallpaperManager.FLAG_SYSTEM; 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_QUOTA_EXCEEDED; import android.app.AppGlobals; import android.app.WallpaperManager; import android.app.backup.BackupAgent; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.app.backup.FullBackupDataOutput; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -103,6 +110,10 @@ public class WallpaperBackupAgent extends BackupAgent { private boolean mQuotaExceeded; private WallpaperManager mWallpaperManager; private WallpaperEventLogger mEventLogger; private boolean mSystemHasLiveComponent; private boolean mLockHasLiveComponent; @Override public void onCreate() { Loading @@ -117,6 +128,9 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) { Slog.v(TAG, "quota file " + mQuotaFile.getPath() + " exists=" + mQuotaExceeded); } BackupManager backupManager = new BackupManager(getApplicationContext()); mEventLogger = new WallpaperEventLogger(backupManager, /* wallpaperAgent */ this); } @Override Loading Loading @@ -149,11 +163,18 @@ public class WallpaperBackupAgent extends BackupAgent { Slog.v(TAG, "lockGen=" + lockGeneration + " : lockChanged=" + lockChanged); } // Due to the way image vs live wallpaper backup logic is intermingled, for logging // purposes first check if we have live components for each wallpaper to avoid // over-reporting errors. mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null; mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null; backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data); backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data); backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data); } catch (Exception e) { Slog.e(TAG, "Unable to back up wallpaper", e); mEventLogger.onBackupException(e); } finally { // Even if this time we had to back off on attempting to store the lock image // due to exceeding the data quota, try again next time. This will alternate Loading @@ -170,6 +191,14 @@ public class WallpaperBackupAgent extends BackupAgent { if (wallpaperInfoFd == null) { Slog.w(TAG, "Wallpaper metadata file doesn't exist"); // If we have live components, getting the file to back up somehow failed, so log it // as an error. if (mSystemHasLiveComponent) { mEventLogger.onSystemLiveWallpaperBackupFailed(ERROR_NO_METADATA); } if (mLockHasLiveComponent) { mEventLogger.onLockLiveWallpaperBackupFailed(ERROR_NO_METADATA); } return; } Loading @@ -182,12 +211,22 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing wallpaper metadata"); backupFile(infoStage, data); // We've backed up the info file which contains the live component, so log it as success if (mSystemHasLiveComponent) { mEventLogger.onSystemLiveWallpaperBackedUp( mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)); } if (mLockHasLiveComponent) { mEventLogger.onLockLiveWallpaperBackedUp(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)); } } private void backupSystemWallpaperFile(SharedPreferences sharedPrefs, boolean sysChanged, int sysGeneration, FullBackupDataOutput data) throws IOException { if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_SYSTEM)) { Slog.d(TAG, "System wallpaper ineligible for backup"); logSystemImageErrorIfNoLiveComponent(ERROR_INELIGIBLE); return; } Loading @@ -197,6 +236,7 @@ public class WallpaperBackupAgent extends BackupAgent { if (systemWallpaperImageFd == null) { Slog.w(TAG, "System wallpaper doesn't exist"); logSystemImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } Loading @@ -210,8 +250,17 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing system wallpaper image"); backupFile(imageStage, data); sharedPrefs.edit().putInt(SYSTEM_GENERATION, sysGeneration).apply(); mEventLogger.onSystemImageWallpaperBackedUp(); } private void logSystemImageErrorIfNoLiveComponent(@BackupRestoreError String error) { if (mSystemHasLiveComponent) { return; } mEventLogger.onSystemImageWallpaperBackupFailed(error); } private void backupLockWallpaperFileIfItExists(SharedPreferences sharedPrefs, boolean lockChanged, int lockGeneration, FullBackupDataOutput data) throws IOException { final File lockImageStage = new File(getFilesDir(), LOCK_WALLPAPER_STAGE); Loading @@ -224,11 +273,13 @@ public class WallpaperBackupAgent extends BackupAgent { } Slog.d(TAG, "No lockscreen wallpaper set, add nothing to backup"); sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply(); logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_LOCK)) { Slog.d(TAG, "Lock screen wallpaper ineligible for backup"); logLockImageErrorIfNoLiveComponent(ERROR_INELIGIBLE); return; } Loading @@ -239,11 +290,13 @@ public class WallpaperBackupAgent extends BackupAgent { // set, but we can't find it. if (lockWallpaperFd == null) { Slog.w(TAG, "Lock wallpaper doesn't exist"); logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } if (mQuotaExceeded) { Slog.w(TAG, "Not backing up lock screen wallpaper. Quota was exceeded last time"); logLockImageErrorIfNoLiveComponent(ERROR_QUOTA_EXCEEDED); return; } Loading @@ -255,6 +308,14 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing lock wallpaper image"); backupFile(lockImageStage, data); sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply(); mEventLogger.onLockImageWallpaperBackedUp(); } private void logLockImageErrorIfNoLiveComponent(@BackupRestoreError String error) { if (mLockHasLiveComponent) { return; } mEventLogger.onLockImageWallpaperBackupFailed(error); } /** Loading packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wallpaperbackup; import android.annotation.Nullable; import android.app.WallpaperInfo; import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import com.android.internal.annotations.VisibleForTesting; import java.util.HashSet; import java.util.Set; /** * Log backup / restore related events using {@link BackupRestoreEventLogger}. */ public class WallpaperEventLogger { /* Static image used as system (or home) screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_IMG_SYSTEM = "wlp_img_system"; /* Static image used as lock screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_IMG_LOCK = "wlp_img_lock"; /* Live component used as system (or home) screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_LIVE_SYSTEM = "wlp_live_system"; /* Live component used as lock screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock"; @BackupRestoreError static final String ERROR_INELIGIBLE = "ineligible"; @BackupRestoreError static final String ERROR_NO_METADATA = "no_metadata"; @BackupRestoreError static final String ERROR_NO_WALLPAPER = "no_wallpaper"; @BackupRestoreError static final String ERROR_QUOTA_EXCEEDED = "quota_exceeded"; private final BackupRestoreEventLogger mLogger; private final Set<String> mProcessedDataTypes = new HashSet<>(); WallpaperEventLogger(BackupManager backupManager, WallpaperBackupAgent wallpaperAgent) { mLogger = backupManager.getBackupRestoreEventLogger(/* backupAgent */ wallpaperAgent); } void onSystemImageWallpaperBackedUp() { logBackupSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null); } void onLockImageWallpaperBackedUp() { logBackupSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null); } void onSystemLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) { logBackupSuccessInternal(WALLPAPER_LIVE_SYSTEM, wallpaperInfo); } void onLockLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) { logBackupSuccessInternal(WALLPAPER_LIVE_LOCK, wallpaperInfo); } void onSystemImageWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_IMG_SYSTEM, error); } void onLockImageWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_IMG_LOCK, error); } void onSystemLiveWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_LIVE_SYSTEM, error); } void onLockLiveWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); } /** * Called when the whole backup flow is interrupted by an exception. */ void onBackupException(Exception exception) { String error = exception.getClass().getName(); if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_SYSTEM)) { mLogger.logItemsBackupFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error); } if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_LOCK)) { mLogger.logItemsBackupFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error); } } private void logBackupSuccessInternal(@BackupRestoreDataType String which, @Nullable WallpaperInfo liveComponentWallpaperInfo) { mLogger.logItemsBackedUp(which, /* count */ 1); logLiveWallpaperNameIfPresent(which, liveComponentWallpaperInfo); mProcessedDataTypes.add(which); } private void logBackupFailureInternal(@BackupRestoreDataType String which, @BackupRestoreError String error) { mLogger.logItemsBackupFailed(which, /* count */ 1, error); mProcessedDataTypes.add(which); } private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, WallpaperInfo wallpaperInfo) { if (wallpaperInfo != null) { mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); } } } packages/WallpaperBackup/test/AndroidManifest.xml +15 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,21 @@ <application android:label="WallpaperBackup Tests"> <uses-library android:name="android.test.runner" /> <service android:name="com.android.wallpaperbackup.utils.TestWallpaperService" android:enabled="true" android:directBootAware="true" android:label="Test wallpaper" android:permission="android.permission.BIND_WALLPAPER" android:exported="true"> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <!-- Link to XML that defines the wallpaper info. --> <meta-data android:name="android.service.wallpaper" android:resource="@xml/livewallpaper"/> </service> </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" Loading packages/WallpaperBackup/test/res/xml/livewallpaper.xml 0 → 100644 +17 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2023 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License --> <wallpaper/> Loading
packages/WallpaperBackup/Android.bp +3 −2 Original line number Diff line number Diff line Loading @@ -42,7 +42,7 @@ android_test { srcs: [ // Include the app source code because the app runs as the system user on-device. "src/**/*.java", "test/src/**/*.java" "test/src/**/*.java", ], libs: [ "android.test.base", Loading @@ -54,7 +54,8 @@ android_test { "mockito-target-minus-junit4", "truth-prebuilt", ], resource_dirs: ["test/res"], certificate: "platform", platform_apis: true, test_suites: ["device-tests"] test_suites: ["device-tests"], }
packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java +61 −0 Original line number Diff line number Diff line Loading @@ -19,11 +19,18 @@ package com.android.wallpaperbackup; import static android.app.WallpaperManager.FLAG_LOCK; import static android.app.WallpaperManager.FLAG_SYSTEM; 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_QUOTA_EXCEEDED; import android.app.AppGlobals; import android.app.WallpaperManager; import android.app.backup.BackupAgent; import android.app.backup.BackupDataInput; import android.app.backup.BackupDataOutput; import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import android.app.backup.FullBackupDataOutput; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -103,6 +110,10 @@ public class WallpaperBackupAgent extends BackupAgent { private boolean mQuotaExceeded; private WallpaperManager mWallpaperManager; private WallpaperEventLogger mEventLogger; private boolean mSystemHasLiveComponent; private boolean mLockHasLiveComponent; @Override public void onCreate() { Loading @@ -117,6 +128,9 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) { Slog.v(TAG, "quota file " + mQuotaFile.getPath() + " exists=" + mQuotaExceeded); } BackupManager backupManager = new BackupManager(getApplicationContext()); mEventLogger = new WallpaperEventLogger(backupManager, /* wallpaperAgent */ this); } @Override Loading Loading @@ -149,11 +163,18 @@ public class WallpaperBackupAgent extends BackupAgent { Slog.v(TAG, "lockGen=" + lockGeneration + " : lockChanged=" + lockChanged); } // Due to the way image vs live wallpaper backup logic is intermingled, for logging // purposes first check if we have live components for each wallpaper to avoid // over-reporting errors. mSystemHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) != null; mLockHasLiveComponent = mWallpaperManager.getWallpaperInfo(FLAG_LOCK) != null; backupWallpaperInfoFile(/* sysOrLockChanged= */ sysChanged || lockChanged, data); backupSystemWallpaperFile(sharedPrefs, sysChanged, sysGeneration, data); backupLockWallpaperFileIfItExists(sharedPrefs, lockChanged, lockGeneration, data); } catch (Exception e) { Slog.e(TAG, "Unable to back up wallpaper", e); mEventLogger.onBackupException(e); } finally { // Even if this time we had to back off on attempting to store the lock image // due to exceeding the data quota, try again next time. This will alternate Loading @@ -170,6 +191,14 @@ public class WallpaperBackupAgent extends BackupAgent { if (wallpaperInfoFd == null) { Slog.w(TAG, "Wallpaper metadata file doesn't exist"); // If we have live components, getting the file to back up somehow failed, so log it // as an error. if (mSystemHasLiveComponent) { mEventLogger.onSystemLiveWallpaperBackupFailed(ERROR_NO_METADATA); } if (mLockHasLiveComponent) { mEventLogger.onLockLiveWallpaperBackupFailed(ERROR_NO_METADATA); } return; } Loading @@ -182,12 +211,22 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing wallpaper metadata"); backupFile(infoStage, data); // We've backed up the info file which contains the live component, so log it as success if (mSystemHasLiveComponent) { mEventLogger.onSystemLiveWallpaperBackedUp( mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)); } if (mLockHasLiveComponent) { mEventLogger.onLockLiveWallpaperBackedUp(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)); } } private void backupSystemWallpaperFile(SharedPreferences sharedPrefs, boolean sysChanged, int sysGeneration, FullBackupDataOutput data) throws IOException { if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_SYSTEM)) { Slog.d(TAG, "System wallpaper ineligible for backup"); logSystemImageErrorIfNoLiveComponent(ERROR_INELIGIBLE); return; } Loading @@ -197,6 +236,7 @@ public class WallpaperBackupAgent extends BackupAgent { if (systemWallpaperImageFd == null) { Slog.w(TAG, "System wallpaper doesn't exist"); logSystemImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } Loading @@ -210,8 +250,17 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing system wallpaper image"); backupFile(imageStage, data); sharedPrefs.edit().putInt(SYSTEM_GENERATION, sysGeneration).apply(); mEventLogger.onSystemImageWallpaperBackedUp(); } private void logSystemImageErrorIfNoLiveComponent(@BackupRestoreError String error) { if (mSystemHasLiveComponent) { return; } mEventLogger.onSystemImageWallpaperBackupFailed(error); } private void backupLockWallpaperFileIfItExists(SharedPreferences sharedPrefs, boolean lockChanged, int lockGeneration, FullBackupDataOutput data) throws IOException { final File lockImageStage = new File(getFilesDir(), LOCK_WALLPAPER_STAGE); Loading @@ -224,11 +273,13 @@ public class WallpaperBackupAgent extends BackupAgent { } Slog.d(TAG, "No lockscreen wallpaper set, add nothing to backup"); sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply(); logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } if (!mWallpaperManager.isWallpaperBackupEligible(FLAG_LOCK)) { Slog.d(TAG, "Lock screen wallpaper ineligible for backup"); logLockImageErrorIfNoLiveComponent(ERROR_INELIGIBLE); return; } Loading @@ -239,11 +290,13 @@ public class WallpaperBackupAgent extends BackupAgent { // set, but we can't find it. if (lockWallpaperFd == null) { Slog.w(TAG, "Lock wallpaper doesn't exist"); logLockImageErrorIfNoLiveComponent(ERROR_NO_WALLPAPER); return; } if (mQuotaExceeded) { Slog.w(TAG, "Not backing up lock screen wallpaper. Quota was exceeded last time"); logLockImageErrorIfNoLiveComponent(ERROR_QUOTA_EXCEEDED); return; } Loading @@ -255,6 +308,14 @@ public class WallpaperBackupAgent extends BackupAgent { if (DEBUG) Slog.v(TAG, "Storing lock wallpaper image"); backupFile(lockImageStage, data); sharedPrefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply(); mEventLogger.onLockImageWallpaperBackedUp(); } private void logLockImageErrorIfNoLiveComponent(@BackupRestoreError String error) { if (mLockHasLiveComponent) { return; } mEventLogger.onLockImageWallpaperBackupFailed(error); } /** Loading
packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java 0 → 100644 +139 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wallpaperbackup; import android.annotation.Nullable; import android.app.WallpaperInfo; import android.app.backup.BackupManager; import android.app.backup.BackupRestoreEventLogger; import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType; import android.app.backup.BackupRestoreEventLogger.BackupRestoreError; import com.android.internal.annotations.VisibleForTesting; import java.util.HashSet; import java.util.Set; /** * Log backup / restore related events using {@link BackupRestoreEventLogger}. */ public class WallpaperEventLogger { /* Static image used as system (or home) screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_IMG_SYSTEM = "wlp_img_system"; /* Static image used as lock screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_IMG_LOCK = "wlp_img_lock"; /* Live component used as system (or home) screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_LIVE_SYSTEM = "wlp_live_system"; /* Live component used as lock screen wallpaper */ @BackupRestoreDataType @VisibleForTesting static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock"; @BackupRestoreError static final String ERROR_INELIGIBLE = "ineligible"; @BackupRestoreError static final String ERROR_NO_METADATA = "no_metadata"; @BackupRestoreError static final String ERROR_NO_WALLPAPER = "no_wallpaper"; @BackupRestoreError static final String ERROR_QUOTA_EXCEEDED = "quota_exceeded"; private final BackupRestoreEventLogger mLogger; private final Set<String> mProcessedDataTypes = new HashSet<>(); WallpaperEventLogger(BackupManager backupManager, WallpaperBackupAgent wallpaperAgent) { mLogger = backupManager.getBackupRestoreEventLogger(/* backupAgent */ wallpaperAgent); } void onSystemImageWallpaperBackedUp() { logBackupSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null); } void onLockImageWallpaperBackedUp() { logBackupSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null); } void onSystemLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) { logBackupSuccessInternal(WALLPAPER_LIVE_SYSTEM, wallpaperInfo); } void onLockLiveWallpaperBackedUp(WallpaperInfo wallpaperInfo) { logBackupSuccessInternal(WALLPAPER_LIVE_LOCK, wallpaperInfo); } void onSystemImageWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_IMG_SYSTEM, error); } void onLockImageWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_IMG_LOCK, error); } void onSystemLiveWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_LIVE_SYSTEM, error); } void onLockLiveWallpaperBackupFailed(@BackupRestoreError String error) { logBackupFailureInternal(WALLPAPER_LIVE_LOCK, error); } /** * Called when the whole backup flow is interrupted by an exception. */ void onBackupException(Exception exception) { String error = exception.getClass().getName(); if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_SYSTEM)) { mLogger.logItemsBackupFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error); } if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains( WALLPAPER_LIVE_LOCK)) { mLogger.logItemsBackupFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error); } } private void logBackupSuccessInternal(@BackupRestoreDataType String which, @Nullable WallpaperInfo liveComponentWallpaperInfo) { mLogger.logItemsBackedUp(which, /* count */ 1); logLiveWallpaperNameIfPresent(which, liveComponentWallpaperInfo); mProcessedDataTypes.add(which); } private void logBackupFailureInternal(@BackupRestoreDataType String which, @BackupRestoreError String error) { mLogger.logItemsBackupFailed(which, /* count */ 1, error); mProcessedDataTypes.add(which); } private void logLiveWallpaperNameIfPresent(@BackupRestoreDataType String wallpaperType, WallpaperInfo wallpaperInfo) { if (wallpaperInfo != null) { mLogger.logBackupMetadata(wallpaperType, wallpaperInfo.getComponent().getClassName()); } } }
packages/WallpaperBackup/test/AndroidManifest.xml +15 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,21 @@ <application android:label="WallpaperBackup Tests"> <uses-library android:name="android.test.runner" /> <service android:name="com.android.wallpaperbackup.utils.TestWallpaperService" android:enabled="true" android:directBootAware="true" android:label="Test wallpaper" android:permission="android.permission.BIND_WALLPAPER" android:exported="true"> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <!-- Link to XML that defines the wallpaper info. --> <meta-data android:name="android.service.wallpaper" android:resource="@xml/livewallpaper"/> </service> </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" Loading
packages/WallpaperBackup/test/res/xml/livewallpaper.xml 0 → 100644 +17 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2023 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License --> <wallpaper/>