Fix go back picker from full preview screen will crash

- Monitor package changed when the surface was already created
  before and currently was in the background.

- Reset surface's image view which is prepared for next
  surfaceCreated() time.

Bug: 167949512
Test: Manual
Change-Id: I2119949a7f6027d6aa242f0ac56379b44cf596a0
(cherry picked from commit 2bf0f35a1f8a215aa5a0c794e3098fddc40d8d6f)
diff --git a/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java b/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
index 64f13bd..1b39007 100644
--- a/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
+++ b/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
@@ -19,6 +19,7 @@
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 
 import android.content.Context;
+import android.service.wallpaper.WallpaperService;
 import android.view.Surface;
 import android.view.SurfaceControlViewHost;
 import android.view.SurfaceHolder;
@@ -29,6 +30,9 @@
 import androidx.core.content.ContextCompat;
 
 import com.android.wallpaper.R;
+import com.android.wallpaper.module.Injector;
+import com.android.wallpaper.module.InjectorProvider;
+import com.android.wallpaper.module.PackageStatusNotifier;
 
 /**
  * Default implementation of {@link SurfaceHolder.Callback} to render a static wallpaper when the
@@ -56,6 +60,10 @@
     private final SurfaceView mWallpaperSurface;
     @Nullable
     private final SurfaceListener mListener;
+    private boolean mSurfaceCreated;
+
+    private PackageStatusNotifier.Listener mAppStatusListener;
+    private PackageStatusNotifier mPackageStatusNotifier;
 
     public WallpaperSurfaceCallback(Context context, ImageView homePreview,
             SurfaceView wallpaperSurface, @Nullable  SurfaceListener listener) {
@@ -63,6 +71,18 @@
         mHomePreview = homePreview;
         mWallpaperSurface = wallpaperSurface;
         mListener = listener;
+
+        // Notify WallpaperSurface to reset image wallpaper when encountered live wallpaper's
+        // package been changed in background.
+        Injector injector = InjectorProvider.getInjector();
+        mPackageStatusNotifier = injector.getPackageStatusNotifier(context);
+        mAppStatusListener = (packageName, status) -> {
+            if (status != PackageStatusNotifier.PackageStatus.REMOVED) {
+                resetHomeImageWallpaper();
+            }
+        };
+        mPackageStatusNotifier.addListener(mAppStatusListener,
+                WallpaperService.SERVICE_INTERFACE);
     }
 
     public WallpaperSurfaceCallback(Context context, ImageView homePreview,
@@ -74,42 +94,69 @@
     public void surfaceCreated(SurfaceHolder holder) {
         if (mLastSurface != holder.getSurface()) {
             mLastSurface = holder.getSurface();
-            mHomeImageWallpaper = new ImageView(mContext);
-            mHomeImageWallpaper.setBackgroundColor(
-                    ContextCompat.getColor(mContext, R.color.primary_color));
-            mHomeImageWallpaper.measure(makeMeasureSpec(mHomePreview.getWidth(), EXACTLY),
-                    makeMeasureSpec(mHomePreview.getHeight(), EXACTLY));
-            mHomeImageWallpaper.layout(0, 0, mHomePreview.getWidth(),
-                    mHomePreview.getHeight());
-
-            cleanUp();
-            mHost = new SurfaceControlViewHost(mContext,
-                    mContext.getDisplay(), mWallpaperSurface.getHostToken());
-            mHost.setView(mHomeImageWallpaper, mHomeImageWallpaper.getWidth(),
-                    mHomeImageWallpaper.getHeight());
-            mWallpaperSurface.setChildSurfacePackage(mHost.getSurfacePackage());
+            setupSurfaceWallpaper(/* forceClean= */ true);
         }
         if (mListener != null) {
             mListener.onSurfaceCreated();
         }
+        mSurfaceCreated = true;
     }
 
     @Override
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
 
     @Override
-    public void surfaceDestroyed(SurfaceHolder holder) { }
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        mSurfaceCreated = false;
+    }
 
     /**
-     * Call to release resources.
+     * Call to release resources and app status listener.
      */
     public void cleanUp() {
+        releaseHost();
+        mPackageStatusNotifier.removeListener(mAppStatusListener);
+    }
+
+    private void releaseHost() {
         if (mHost != null) {
             mHost.release();
             mHost = null;
         }
     }
 
+    /**
+     * Reset existing image wallpaper by creating a new ImageView for SurfaceControlViewHost
+     * if surface state is not created.
+     */
+    private void resetHomeImageWallpaper() {
+        if (mSurfaceCreated) {
+            return;
+        }
+
+        if (mHost != null) {
+            setupSurfaceWallpaper(/* forceClean= */ false);
+        }
+    }
+
+    private void setupSurfaceWallpaper(boolean forceClean) {
+        mHomeImageWallpaper = new ImageView(mContext);
+        mHomeImageWallpaper.setBackgroundColor(
+                ContextCompat.getColor(mContext, R.color.primary_color));
+        mHomeImageWallpaper.measure(makeMeasureSpec(mHomePreview.getWidth(), EXACTLY),
+                makeMeasureSpec(mHomePreview.getHeight(), EXACTLY));
+        mHomeImageWallpaper.layout(0, 0, mHomePreview.getWidth(),
+                mHomePreview.getHeight());
+        if (forceClean) {
+            releaseHost();
+            mHost = new SurfaceControlViewHost(mContext,
+                    mContext.getDisplay(), mWallpaperSurface.getHostToken());
+        }
+        mHost.setView(mHomeImageWallpaper, mHomeImageWallpaper.getWidth(),
+                mHomeImageWallpaper.getHeight());
+        mWallpaperSurface.setChildSurfacePackage(mHost.getSurfacePackage());
+    }
+
     @Nullable
     public ImageView getHomeImageWallpaper() {
         return mHomeImageWallpaper;