Add content handling support to B&R

Fixes: 376172272
Flag: android.app.live_wallpaper_content_handling
Test: manually verified correct B&R with flag enabled and disabled
Change-Id: I752d4efa724a039af433820794e5159dbaec440a
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index b8e0d42..b0c0c3a 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -48,7 +48,9 @@
     static_libs: [
         "androidx.test.core",
         "androidx.test.rules",
+        "flag-junit",
         "mockito-target-minus-junit4",
+        "platform-test-annotations",
         "truth",
     ],
     resource_dirs: ["test/res"],
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 44ea9a2..a80a64d 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -16,6 +16,7 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.liveWallpaperContentHandling;
 import static android.app.WallpaperManager.FLAG_LOCK;
 import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
@@ -27,6 +28,7 @@
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
 import static com.android.window.flags.Flags.multiCrop;
 
+import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.app.WallpaperManager;
 import android.app.backup.BackupAgent;
@@ -35,6 +37,7 @@
 import android.app.backup.BackupManager;
 import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
 import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -493,11 +496,13 @@
 
             // 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;
+            Pair<ComponentName, WallpaperDescription> wpService = parseWallpaperComponent(infoStage,
+                    "wp");
+            mSystemHasLiveComponent = wpService.first != null;
 
-            ComponentName kwpService = parseWallpaperComponent(infoStage, "kwp");
-            mLockHasLiveComponent = kwpService != null;
+            Pair<ComponentName, WallpaperDescription> kwpService = parseWallpaperComponent(
+                    infoStage, "kwp");
+            mLockHasLiveComponent = kwpService.first != null;
             boolean separateLockWallpaper = mLockHasLiveComponent || lockImageStage.exists();
 
             // if there's no separate lock wallpaper, apply the system wallpaper to both screens.
@@ -586,25 +591,39 @@
     }
 
     @VisibleForTesting
-    void updateWallpaperComponent(ComponentName wpService, int which)
+    void updateWallpaperComponent(Pair<ComponentName, WallpaperDescription> wpService, int which)
             throws IOException {
-        if (servicePackageExists(wpService)) {
-            Slog.i(TAG, "Using wallpaper service " + wpService);
-            mWallpaperManager.setWallpaperComponentWithFlags(wpService, which);
-            if ((which & FLAG_LOCK) != 0) {
-                mEventLogger.onLockLiveWallpaperRestored(wpService);
-            }
-            if ((which & FLAG_SYSTEM) != 0) {
-                mEventLogger.onSystemLiveWallpaperRestored(wpService);
+        WallpaperDescription description = wpService.second;
+        boolean hasDescription = (liveWallpaperContentHandling() && description != null);
+        ComponentName component = hasDescription ? description.getComponent() : wpService.first;
+        if (servicePackageExists(component)) {
+            if (hasDescription) {
+                Slog.i(TAG, "Using wallpaper description " + description);
+                mWallpaperManager.setWallpaperComponentWithDescription(description, which);
+                if ((which & FLAG_LOCK) != 0) {
+                    mEventLogger.onLockLiveWallpaperRestoredWithDescription(description);
+                }
+                if ((which & FLAG_SYSTEM) != 0) {
+                    mEventLogger.onSystemLiveWallpaperRestoredWithDescription(description);
+                }
+            } else {
+                Slog.i(TAG, "Using wallpaper service " + component);
+                mWallpaperManager.setWallpaperComponentWithFlags(component, which);
+                if ((which & FLAG_LOCK) != 0) {
+                    mEventLogger.onLockLiveWallpaperRestored(component);
+                }
+                if ((which & FLAG_SYSTEM) != 0) {
+                    mEventLogger.onSystemLiveWallpaperRestored(component);
+                }
             }
         } else {
             // 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
             // in reports from users
-            if (wpService != null) {
+            if (component != null) {
                 // TODO(b/268471749): Handle delayed case
-                applyComponentAtInstall(wpService, which);
-                Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. "
+                applyComponentAtInstall(component, description, which);
+                Slog.w(TAG, "Wallpaper service " + component + " isn't available. "
                         + " Will try to apply later");
             }
         }
@@ -697,7 +716,6 @@
      * (thereby preserving the center point). Then finally, adding any leftover image real-estate
      * (i.e. space left over on the horizontal axis) to add parallax effect. Parallax is only added
      * if was present in the old device's settings.
-     *
      */
     private Rect findNewCropfromOldCrop(Rect oldCrop, Point oldDisplaySize, boolean oldRtl,
             Point newDisplaySize, Point bitmapSize, boolean newRtl) {
@@ -976,10 +994,12 @@
         return cropHints;
     }
 
-    private ComponentName parseWallpaperComponent(File wallpaperInfo, String sectionTag) {
+    private Pair<ComponentName, WallpaperDescription> parseWallpaperComponent(File wallpaperInfo,
+            String sectionTag) {
         ComponentName name = null;
+        WallpaperDescription description = null;
         try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
-            final XmlPullParser parser = Xml.resolvePullParser(stream);
+            final TypedXmlPullParser parser = Xml.resolvePullParser(stream);
 
             int type;
             do {
@@ -991,6 +1011,7 @@
                         name = (parsedName != null)
                                 ? ComponentName.unflattenFromString(parsedName)
                                 : null;
+                        description = parseWallpaperDescription(parser, name);
                         break;
                     }
                 }
@@ -998,9 +1019,30 @@
         } catch (Exception e) {
             // Whoops; can't process the info file at all.  Report failure.
             Slog.w(TAG, "Failed to parse restored component: " + e.getMessage());
-            return null;
+            return new Pair<>(null, null);
         }
-        return name;
+        return new Pair<>(name, description);
+    }
+
+    // Copied from com.android.server.wallpaper.WallpaperDataParser
+    private WallpaperDescription parseWallpaperDescription(TypedXmlPullParser parser,
+            ComponentName component) throws XmlPullParserException, IOException {
+
+        WallpaperDescription description = null;
+        int type = parser.next();
+        if (type == XmlPullParser.START_TAG && "description".equals(parser.getName())) {
+            // Always read the description if it's there - there may be one from a previous save
+            // with content handling enabled even if it's enabled now
+            description = WallpaperDescription.restoreFromXml(parser);
+            if (liveWallpaperContentHandling()) {
+                // null component means that wallpaper was last saved without content handling, so
+                // populate description from saved component
+                if (description.getComponent() == null) {
+                    description = description.toBuilder().setComponent(component).build();
+                }
+            }
+        }
+        return description;
     }
 
     private int getAttributeInt(XmlPullParser parser, String name, int defValue) {
@@ -1037,14 +1079,16 @@
         // Intentionally blank
     }
 
-    private void applyComponentAtInstall(ComponentName componentName, int which) {
-        PackageMonitor packageMonitor = getWallpaperPackageMonitor(
-                componentName, which);
+    private void applyComponentAtInstall(ComponentName componentName,
+            @Nullable WallpaperDescription description, int which) {
+        PackageMonitor packageMonitor = getWallpaperPackageMonitor(componentName, description,
+                which);
         packageMonitor.register(getBaseContext(), null, UserHandle.ALL, true);
     }
 
     @VisibleForTesting
-    PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
+    PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+            @Nullable WallpaperDescription description, int which) {
         return new PackageMonitor() {
             @Override
             public void onPackageAdded(String packageName, int uid) {
@@ -1068,7 +1112,33 @@
                     return;
                 }
 
-                if (componentName.getPackageName().equals(packageName)) {
+                boolean useDescription = (liveWallpaperContentHandling() && description != null
+                        && description.getComponent() != null);
+                if (useDescription && description.getComponent().getPackageName().equals(
+                        packageName)) {
+                    Slog.d(TAG, "Applying description " + description);
+                    boolean success = mWallpaperManager.setWallpaperComponentWithDescription(
+                            description, which);
+                    WallpaperEventLogger logger = new WallpaperEventLogger(
+                            mBackupManager.getDelayedRestoreLogger());
+                    if (success) {
+                        if ((which & FLAG_SYSTEM) != 0) {
+                            logger.onSystemLiveWallpaperRestoredWithDescription(description);
+                        }
+                        if ((which & FLAG_LOCK) != 0) {
+                            logger.onLockLiveWallpaperRestoredWithDescription(description);
+                        }
+                    } else {
+                        if ((which & FLAG_SYSTEM) != 0) {
+                            logger.onSystemLiveWallpaperRestoreFailed(
+                                    WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+                        }
+                        if ((which & FLAG_LOCK) != 0) {
+                            logger.onLockLiveWallpaperRestoreFailed(
+                                    WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+                        }
+                    }
+                } else if (componentName.getPackageName().equals(packageName)) {
                     Slog.d(TAG, "Applying component " + componentName);
                     boolean success = mWallpaperManager.setWallpaperComponentWithFlags(
                             componentName, which);
@@ -1191,4 +1261,4 @@
     void setBackupManagerForTesting(BackupManager backupManager) {
         mBackupManager = backupManager;
     }
-}
\ No newline at end of file
+}
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
index b25f95a..69469e4 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
@@ -16,12 +16,14 @@
 
 package com.android.wallpaperbackup;
 
+import android.annotation.NonNull;
 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 android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -53,6 +55,16 @@
     @VisibleForTesting
     static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock";
 
+    /* Live component used as system (or home) screen wallpaper */
+    @BackupRestoreDataType
+    @VisibleForTesting
+    static final String WALLPAPER_DESCRIPTION_SYSTEM = "wlp_description_system";
+
+    /* Live component used as lock screen wallpaper */
+    @BackupRestoreDataType
+    @VisibleForTesting
+    static final String WALLPAPER_DESCRIPTION_LOCK = "wlp_description_lock";
+
     @BackupRestoreError
     static final String ERROR_INELIGIBLE = "ineligible";
     @BackupRestoreError
@@ -64,6 +76,8 @@
     @BackupRestoreError
     static final String ERROR_SET_COMPONENT_EXCEPTION = "exception_in_set_component";
     @BackupRestoreError
+    static final String ERROR_SET_DESCRIPTION_EXCEPTION = "exception_in_set_description";
+    @BackupRestoreError
     static final String ERROR_LIVE_PACKAGE_NOT_INSTALLED = "live_pkg_not_installed_in_restore";
 
     private final BackupRestoreEventLogger mLogger;
@@ -115,11 +129,11 @@
     }
 
     void onSystemImageWallpaperRestored() {
-        logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null);
+        logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, (ComponentName) null);
     }
 
     void onLockImageWallpaperRestored() {
-        logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null);
+        logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, (ComponentName) null);
     }
 
     void onSystemLiveWallpaperRestored(ComponentName wpService) {
@@ -146,6 +160,13 @@
         logRestoreFailureInternal(WALLPAPER_LIVE_LOCK, error);
     }
 
+    void onSystemLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+        logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_SYSTEM, description);
+    }
+
+    void onLockLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+        logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_LOCK, description);
+    }
 
 
     /**
@@ -168,15 +189,17 @@
      */
     void onRestoreException(Exception exception) {
         String error = exception.getClass().getName();
-        if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains(
-                WALLPAPER_LIVE_SYSTEM)) {
+        if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) || mProcessedDataTypes.contains(
+                WALLPAPER_LIVE_SYSTEM) || mProcessedDataTypes.contains(
+                WALLPAPER_DESCRIPTION_SYSTEM))) {
             mLogger.logItemsRestoreFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error);
         }
-        if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains(
-                WALLPAPER_LIVE_LOCK)) {
+        if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) || mProcessedDataTypes.contains(
+                WALLPAPER_LIVE_LOCK) || mProcessedDataTypes.contains(WALLPAPER_DESCRIPTION_LOCK))) {
             mLogger.logItemsRestoreFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error);
         }
     }
+
     private void logBackupSuccessInternal(@BackupRestoreDataType String which,
             @Nullable WallpaperInfo liveComponentWallpaperInfo) {
         mLogger.logItemsBackedUp(which, /* count */ 1);
@@ -197,6 +220,13 @@
         mProcessedDataTypes.add(which);
     }
 
+    private void logRestoreSuccessInternal(@BackupRestoreDataType String which,
+            @NonNull WallpaperDescription description) {
+        mLogger.logItemsRestored(which, /* count */ 1);
+        logRestoredLiveWallpaperDescription(which, description);
+        mProcessedDataTypes.add(which);
+    }
+
     private void logRestoreFailureInternal(@BackupRestoreDataType String which,
             @BackupRestoreError String error) {
         mLogger.logItemsRestoreFailed(which, /* count */ 1, error);
@@ -216,4 +246,11 @@
             mLogger.logRestoreMetadata(wallpaperType, wpService.getClassName());
         }
     }
+
+    private void logRestoredLiveWallpaperDescription(@BackupRestoreDataType String wallpaperType,
+            WallpaperDescription description) {
+        if (description != null) {
+            mLogger.logRestoreMetadata(wallpaperType, description.toString());
+        }
+    }
 }
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index 2fc9a88..c9f1b58 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -16,6 +16,7 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
 import static android.app.WallpaperManager.FLAG_LOCK;
 import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
@@ -27,6 +28,8 @@
 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 static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -54,6 +57,7 @@
 import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
 import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -63,7 +67,10 @@
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.wallpaper.WallpaperService;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.Xml;
 
@@ -79,6 +86,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -113,12 +121,15 @@
     @Mock
     private BackupManager mBackupManager;
 
-    @Rule
-    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
     private ContextWithServiceOverrides mContext;
     private IsolatedWallpaperBackupAgent mWallpaperBackupAgent;
     private ComponentName mWallpaperComponent;
+    private WallpaperDescription mWallpaperDescription;
+
+    private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
+    @Rule
+    public RuleChain mRuleChain = RuleChain.outerRule(new SetFlagsRule()).around(mTemporaryFolder);
 
     @Before
     public void setUp() {
@@ -135,6 +146,8 @@
                 BackupAnnotations.OperationType.BACKUP);
 
         mWallpaperComponent = new ComponentName(TEST_WALLPAPER_PACKAGE, "");
+        mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+                mWallpaperComponent).setId("id").build();
     }
 
     @After
@@ -369,7 +382,7 @@
     public void testUpdateWallpaperComponent_immediate_systemAndLock() throws IOException {
         mWallpaperBackupAgent.mPackageExists = true;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
@@ -387,7 +400,7 @@
             throws IOException {
         mWallpaperBackupAgent.mPackageExists = true;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_SYSTEM);
 
         assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
@@ -401,10 +414,92 @@
     }
 
     @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_immediate_systemAndLock()
+            throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+                FLAG_LOCK | FLAG_SYSTEM);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_immediate_systemOnly() throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_systemAndLock()
+            throws IOException {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+                FLAG_LOCK | FLAG_SYSTEM);
+
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_systemOnly() throws IOException {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
     public void testUpdateWallpaperComponent_delayed_systemAndLock() throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -423,7 +518,7 @@
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -443,7 +538,7 @@
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate wallpaper component installation.
@@ -459,7 +554,7 @@
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate "wrong" wallpaper component installation.
@@ -788,7 +883,7 @@
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -804,6 +899,33 @@
 
 
     @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_succeeds_logsSuccess() throws Exception {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        when(mWallpaperManager.setWallpaperComponentWithDescription(any(),
+                eq(FLAG_LOCK | FLAG_SYSTEM))).thenReturn(true);
+        BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+                BackupAnnotations.OperationType.RESTORE);
+        when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+        mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+                /* which */ FLAG_LOCK | FLAG_SYSTEM);
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        DataTypeResult system = getLoggingResult(WALLPAPER_DESCRIPTION_SYSTEM,
+                logger.getLoggingResults());
+        DataTypeResult lock = getLoggingResult(WALLPAPER_DESCRIPTION_LOCK,
+                logger.getLoggingResults());
+        assertThat(system).isNotNull();
+        assertThat(system.getSuccessCount()).isEqualTo(1);
+        assertThat(lock).isNotNull();
+        assertThat(lock.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
     public void testUpdateWallpaperComponent_delayed_fails_logsFailure() throws Exception {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
         BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
@@ -811,7 +933,7 @@
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -825,6 +947,28 @@
     }
 
     @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_fails_logsFailure() throws Exception {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+                BackupAnnotations.OperationType.RESTORE);
+        when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+        mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+                /* which */ FLAG_LOCK | FLAG_SYSTEM);
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults());
+        assertThat(system).isNotNull();
+        assertThat(system.getFailCount()).isEqualTo(1);
+        assertThat(system.getErrors()).containsKey(
+                WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+    }
+
+    @Test
     public void testUpdateWallpaperComponent_delayed_packageNotInstalled_logsFailure()
             throws Exception {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
@@ -833,7 +977,7 @@
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate wallpaper component installation.
@@ -1041,9 +1185,11 @@
         }
 
         @Override
-        PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
+        PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+                WallpaperDescription description, int which) {
             mGetPackageMonitorCallCount++;
-            mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, which);
+            mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, description,
+                    which);
             return mWallpaperPackageMonitor;
         }
 
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
index 383bf2f..09aa23e 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
@@ -16,6 +16,10 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -31,16 +35,20 @@
 import android.app.backup.BackupAnnotations;
 import android.app.backup.BackupManager;
 import android.app.backup.BackupRestoreEventLogger;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.wallpaper.WallpaperService;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -63,6 +71,10 @@
 
     private WallpaperEventLogger mWallpaperEventLogger;
     private WallpaperInfo mWallpaperInfo;
+    private WallpaperDescription mWallpaperDescription;
+
+    @Rule
+    public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     @Before
     public void setUp() throws Exception {
@@ -73,6 +85,8 @@
 
         mWallpaperInfo = getWallpaperInfo();
         mWallpaperEventLogger = new WallpaperEventLogger(mMockBackupManager, mMockBackupAgent);
+        mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+                mWallpaperInfo.getComponent()).build();
     }
 
     @Test
@@ -263,6 +277,19 @@
     }
 
     @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemLiveWallpaperRestoredWithDescription_logsSuccess() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+                WALLPAPER_DESCRIPTION_SYSTEM);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
     public void onLockLiveWallpaperRestored_logsSuccess() {
         setUpLoggerForRestore();
 
@@ -274,6 +301,17 @@
     }
 
     @Test
+    public void onLockLiveWallpaperRestoredWithDescription_logsSuccess() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_DESCRIPTION_LOCK);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
     public void onImgWallpaperRestored_nullInfo_doesNotLogMetadata() {
         setUpLoggerForRestore();
 
@@ -286,7 +324,7 @@
 
 
     @Test
-    public void onLiveWallpaperRestored_logsMetadata() {
+    public void onSystemLiveWallpaperRestored_logsMetadata() {
         setUpLoggerForRestore();
 
         mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
@@ -296,6 +334,19 @@
         assertThat(result.getMetadataHash()).isNotNull();
     }
 
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemLiveWallpaperRestoredDescription_logsMetadata() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+                WALLPAPER_DESCRIPTION_SYSTEM);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getMetadataHash()).isNotNull();
+    }
+
 
     @Test
     public void onSystemImgWallpaperRestoreFailed_logsFail() {
@@ -373,7 +424,7 @@
     }
 
     @Test
-    public void onWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+    public void onSystemWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
         setUpLoggerForRestore();
         mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
 
@@ -383,6 +434,41 @@
         assertThat(result).isNull();
     }
 
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_SYSTEM);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void onLockWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onLockLiveWallpaperRestored(mWallpaperInfo.getComponent());
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onLockWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+        assertThat(result).isNull();
+    }
+
     private BackupRestoreEventLogger.DataTypeResult getLogsForType(String dataType) {
         for (BackupRestoreEventLogger.DataTypeResult result :  mEventLogger.getLoggingResults()) {
             if ((result.getDataType()).equals(dataType)) {