Add ability to pass WallpaperColors as argument to workspace preview

Bug: 185198554
Test: manual
Change-Id: I7b37999a9d71ef53a72507d0fdfaeabcc5ccfef4
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index 7e99797..2ecd05f 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -94,10 +94,10 @@
     private TouchForwardingLayout mTouchForwardingLayout;
     private ConstraintLayout mContainer;
     private SurfaceView mWorkspaceSurface;
-    private WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
     private SurfaceView mWallpaperSurface;
     private WallpaperInfoView mWallpaperInfoView;
 
+    protected WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
     protected ViewGroup mLockPreviewContainer;
     protected LockScreenPreviewer2 mLockScreenPreviewer;
 
@@ -141,8 +141,7 @@
         set.applyTo(mContainer);
 
         mWorkspaceSurface = mContainer.findViewById(R.id.workspace_surface);
-        mWorkspaceSurfaceCallback = new WorkspaceSurfaceHolderCallback(mWorkspaceSurface,
-                getContext());
+        mWorkspaceSurfaceCallback = createWorkspaceSurfaceCallback(mWorkspaceSurface);
         mWallpaperSurface = mContainer.findViewById(R.id.wallpaper_surface);
         mLockPreviewContainer = mContainer.findViewById(R.id.lock_screen_preview_container);
         mLockScreenPreviewer = new LockScreenPreviewer2(getLifecycle(), getContext(),
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index a033500..308ff7a 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -110,11 +110,11 @@
     private Point mScreenSize;
     private ViewGroup mPreviewContainer;
     private TouchForwardingLayout mTouchForwardingLayout;
-    private SurfaceView mWorkspaceSurface;
     private SurfaceView mWallpaperSurface;
-    private WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
     private WallpaperSurfaceCallback mWallpaperSurfaceCallback;
 
+    protected SurfaceView mWorkspaceSurface;
+    protected WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
     protected ViewGroup mLockPreviewContainer;
     protected LockScreenPreviewer2 mLockScreenPreviewer;
 
@@ -196,8 +196,7 @@
         mWallpaperSurface = mHomePreviewCard.findViewById(R.id.wallpaper_surface);
         mWorkspaceSurface = mHomePreviewCard.findViewById(R.id.workspace_surface);
 
-        mWorkspaceSurfaceCallback = new WorkspaceSurfaceHolderCallback(
-                mWorkspaceSurface, getContext());
+        mWorkspaceSurfaceCallback = createWorkspaceSurfaceCallback(mWorkspaceSurface);
         mWallpaperSurfaceCallback = new WallpaperSurfaceCallback(getContext(),
                 mHomePreview, mWallpaperSurface);
 
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index cac9819..0ff4423 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
+import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Toast;
@@ -205,6 +206,11 @@
         return android.R.style.Theme_DeviceDefault;
     }
 
+    protected WorkspaceSurfaceHolderCallback createWorkspaceSurfaceCallback(
+            SurfaceView workspaceSurface) {
+        return new WorkspaceSurfaceHolderCallback(workspaceSurface, getContext());
+    }
+
     @Override
     public void onResume() {
         super.onResume();
diff --git a/src/com/android/wallpaper/picker/WorkspaceSurfaceHolderCallback.java b/src/com/android/wallpaper/picker/WorkspaceSurfaceHolderCallback.java
index 91aae6a..3844d02 100644
--- a/src/com/android/wallpaper/picker/WorkspaceSurfaceHolderCallback.java
+++ b/src/com/android/wallpaper/picker/WorkspaceSurfaceHolderCallback.java
@@ -15,6 +15,7 @@
  */
 package com.android.wallpaper.picker;
 
+import android.app.WallpaperColors;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.Message;
@@ -23,6 +24,8 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
+import androidx.annotation.Nullable;
+
 import com.android.wallpaper.R;
 import com.android.wallpaper.util.PreviewUtils;
 import com.android.wallpaper.util.SurfaceViewUtils;
@@ -30,33 +33,72 @@
 /** A surface holder callback that renders user's workspace on the passed in surface view. */
 public class WorkspaceSurfaceHolderCallback implements SurfaceHolder.Callback {
 
+    private static final String KEY_WALLPAPER_COLORS = "wallpaper_colors";
     private final SurfaceView mWorkspaceSurface;
     private final PreviewUtils mPreviewUtils;
+    private final boolean mShouldUseWallpaperColors;
 
+    private WallpaperColors mWallpaperColors;
+    private boolean mIsWallpaperColorsReady;
     private Surface mLastSurface;
     private Message mCallback;
 
     private boolean mNeedsToCleanUp;
 
     public WorkspaceSurfaceHolderCallback(SurfaceView workspaceSurface, Context context) {
+        this(workspaceSurface, context, false);
+    }
+
+    /**
+     * Creates a new instance of {@link WorkspaceSurfaceHolderCallback} specifying if wallpaper
+     * colors should be used to preview the workspace.
+     *
+     * @param shouldUseWallpaperColors if true, the workspace preview won't be requested until both
+     *                                 the surface is created and wallpaper colors are set via
+     *                                 {@link #setWallpaperColors(WallpaperColors)}
+     */
+    public WorkspaceSurfaceHolderCallback(SurfaceView workspaceSurface, Context context,
+            boolean shouldUseWallpaperColors) {
         mWorkspaceSurface = workspaceSurface;
         mPreviewUtils = new PreviewUtils(context,
                 context.getString(R.string.grid_control_metadata_name));
+        mShouldUseWallpaperColors = shouldUseWallpaperColors;
     }
 
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
         if (mPreviewUtils.supportsPreview() && mLastSurface != holder.getSurface()) {
             mLastSurface = holder.getSurface();
-            Bundle result = renderPreview(mWorkspaceSurface);
-            if (result != null) {
-                mWorkspaceSurface.setChildSurfacePackage(
-                        SurfaceViewUtils.getSurfacePackage(result));
-                mCallback = SurfaceViewUtils.getCallback(result);
+            maybeRenderPreview();
+        }
+    }
 
-                if (mNeedsToCleanUp) {
-                    cleanUp();
-                }
+    /**
+     * Set the current wallpaper's colors. This method must be called  if this instance was created
+     * with shouldUseWallpaperColors = true (even with {@code null} colors).
+     *
+     * @param colors WallpaperColors extracted from the current wallpaper preview, or {@code null}
+     *               if none are available.
+     * @see #WorkspaceSurfaceHolderCallback(SurfaceView, Context, boolean)
+     */
+    public void setWallpaperColors(@Nullable WallpaperColors colors) {
+        mWallpaperColors = colors;
+        mIsWallpaperColorsReady = true;
+        maybeRenderPreview();
+    }
+
+    private void maybeRenderPreview() {
+        if ((mShouldUseWallpaperColors && !mIsWallpaperColorsReady) || mLastSurface == null) {
+            return;
+        }
+        Bundle result = requestPreview(mWorkspaceSurface);
+        if (result != null) {
+            mWorkspaceSurface.setChildSurfacePackage(
+                    SurfaceViewUtils.getSurfacePackage(result));
+            mCallback = SurfaceViewUtils.getCallback(result);
+
+            if (mNeedsToCleanUp) {
+                cleanUp();
             }
         }
     }
@@ -85,8 +127,11 @@
         mLastSurface = null;
     }
 
-    protected Bundle renderPreview(SurfaceView workspaceSurface) {
-        return mPreviewUtils.renderPreview(
-                SurfaceViewUtils.createSurfaceViewRequest(workspaceSurface));
+    protected Bundle requestPreview(SurfaceView workspaceSurface) {
+        Bundle request = SurfaceViewUtils.createSurfaceViewRequest(workspaceSurface);
+        if (mWallpaperColors != null) {
+            request.putParcelable(KEY_WALLPAPER_COLORS, mWallpaperColors);
+        }
+        return mPreviewUtils.renderPreview(request);
     }
 }