Merge f9301fbc3153765047b6bf4278ae74e5ee353d93 on remote branch

Change-Id: I5c358e81255042caca7873f483a5b5bea76c86ef
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index c827b5a..1ea49f0 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -40,6 +40,7 @@
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
@@ -378,8 +379,8 @@
      */
     private void setDefaultWallpaperZoomAndScroll(boolean offsetToFarLeft) {
         // Determine minimum zoom to fit maximum visible area of wallpaper on crop surface.
-        int cropWidth = mWorkspaceSurface.getMeasuredWidth();
-        int cropHeight = mWorkspaceSurface.getMeasuredHeight();
+        int cropWidth = mWallpaperSurface.getMeasuredWidth();
+        int cropHeight = mWallpaperSurface.getMeasuredHeight();
         Point crop = new Point(cropWidth, cropHeight);
         Rect visibleRawWallpaperRect =
                 WallpaperCropUtils.calculateVisibleRect(mRawWallpaperSize, crop);
@@ -387,8 +388,8 @@
             visibleRawWallpaperRect.offsetTo(/* newLeft= */ 0, visibleRawWallpaperRect.top);
         }
 
-        final PointF centerPosition = WallpaperCropUtils.calculateDefaultCenter(requireContext(),
-                mRawWallpaperSize, visibleRawWallpaperRect);
+        final PointF centerPosition = new PointF(visibleRawWallpaperRect.centerX(),
+                visibleRawWallpaperRect.centerY());
 
         Point visibleRawWallpaperSize = new Point(visibleRawWallpaperRect.width(),
                 visibleRawWallpaperRect.height());
@@ -413,18 +414,14 @@
         Rect visibleFileRect = new Rect();
         mFullResImageView.visibleFileRect(visibleFileRect);
 
-        int cropWidth = mWorkspaceSurface.getMeasuredWidth();
-        int cropHeight = mWorkspaceSurface.getMeasuredHeight();
+        int cropWidth = mWallpaperSurface.getMeasuredWidth();
+        int cropHeight = mWallpaperSurface.getMeasuredHeight();
         int maxCrop = Math.max(cropWidth, cropHeight);
         int minCrop = Math.min(cropWidth, cropHeight);
         Point hostViewSize = new Point(cropWidth, cropHeight);
 
         Resources res = context.getResources();
         Point cropSurfaceSize = WallpaperCropUtils.calculateCropSurfaceSize(res, maxCrop, minCrop);
-        WallpaperCropUtils.scaleSize(context, hostViewSize);
-        WallpaperCropUtils.scaleSize(context, cropSurfaceSize);
-
-        WallpaperCropUtils.adjustCropRect(context, visibleFileRect, false);
 
         Rect cropRect = WallpaperCropUtils.calculateCropRect(context, hostViewSize,
                 cropSurfaceSize, mRawWallpaperSize, visibleFileRect, wallpaperZoom);
@@ -469,10 +466,34 @@
                 if (mFullResImageView != null) {
                     mFullResImageView.recycle();
                 }
-                View wallpaperPreviewContainer = LayoutInflater.from(getContext()).inflate(
+                Context context = getContext();
+                View wallpaperPreviewContainer = LayoutInflater.from(context).inflate(
                         R.layout.fullscreen_wallpaper_preview, null);
                 mFullResImageView = wallpaperPreviewContainer.findViewById(R.id.full_res_image);
                 mLowResImageView = wallpaperPreviewContainer.findViewById(R.id.low_res_image);
+                // Scale the mWallpaperSurface based on system zoom's scale so that the wallpaper is
+                // rendered in a larger surface than what preview shows, simulating the behavior of
+                // the actual wallpaper surface.
+                float scale = WallpaperCropUtils.getSystemWallpaperMaximumScale(context);
+                int origWidth = mWallpaperSurface.getWidth();
+                int width = (int) (origWidth * scale);
+                int origHeight = mWallpaperSurface.getHeight();
+                int height = (int) (origHeight * scale);
+                int left = (origWidth - width) / 2;
+                int top = (origHeight - height) / 2;
+
+                if (WallpaperCropUtils.isRtl(context)) {
+                    left *= -1;
+                }
+
+                LayoutParams params = mWallpaperSurface.getLayoutParams();
+                params.width = width;
+                params.height = height;
+                mWallpaperSurface.setX(left);
+                mWallpaperSurface.setY(top);
+                mWallpaperSurface.setLayoutParams(params);
+                mWallpaperSurface.requestLayout();
+
                 // Load a low-res placeholder image if there's a thumbnail available from the asset
                 // that can be shown to the user more quickly than the full-sized image.
                 if (mWallpaperAsset.hasLowResDataSource()) {
@@ -482,15 +503,14 @@
                                     activity.getApplicationContext(), isRtl()));
                 }
                 wallpaperPreviewContainer.measure(
-                        makeMeasureSpec(mWallpaperSurface.getWidth(), EXACTLY),
-                        makeMeasureSpec(mWallpaperSurface.getHeight(), EXACTLY));
-                wallpaperPreviewContainer.layout(0, 0, mWallpaperSurface.getWidth(),
-                        mWallpaperSurface.getHeight());
+                        makeMeasureSpec(width, EXACTLY),
+                        makeMeasureSpec(height, EXACTLY));
+                wallpaperPreviewContainer.layout(0, 0, width, height);
                 mTouchForwardingLayout.setTargetView(mFullResImageView);
 
                 cleanUp();
-                mHost = new SurfaceControlViewHost(getContext(),
-                        getContext().getDisplay(), mWallpaperSurface.getHostToken());
+                mHost = new SurfaceControlViewHost(context,
+                        context.getDisplay(), mWallpaperSurface.getHostToken());
                 mHost.setView(wallpaperPreviewContainer, wallpaperPreviewContainer.getWidth(),
                         wallpaperPreviewContainer.getHeight());
                 mWallpaperSurface.setChildSurfacePackage(mHost.getSurfacePackage());
diff --git a/src/com/android/wallpaper/util/WallpaperCropUtils.java b/src/com/android/wallpaper/util/WallpaperCropUtils.java
index a13ed55..bff7a67 100755
--- a/src/com/android/wallpaper/util/WallpaperCropUtils.java
+++ b/src/com/android/wallpaper/util/WallpaperCropUtils.java
@@ -347,7 +347,7 @@
      * Returns whether layout direction is RTL (or false for LTR). Since native RTL layout support
      * was added in API 17, returns false for versions lower than 17.
      */
-    private static boolean isRtl(Context context) {
+    public static boolean isRtl(Context context) {
         return context.getResources().getConfiguration().getLayoutDirection()
                 == View.LAYOUT_DIRECTION_RTL;
     }
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;