Fade from wallpaper picker activity back to homescreen.

If a wallpaper preview is going to look exactly the same as the actual wallpaper
on the homescreen page that is being returned to, fading looks much nicer than
the default activity exit animation.

Bug: 23568800
Change-Id: Id7c2b5483c5535d59be2f8a459ce7788e3c8318a
diff --git a/WallpaperPicker/res/anim/fade_out.xml b/WallpaperPicker/res/anim/fade_out.xml
new file mode 100644
index 0000000..7737cf5
--- /dev/null
+++ b/WallpaperPicker/res/anim/fade_out.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- startOffset is the same as the duration of the wallpaper_enter animation. We have this delay so
+    that we don't see the wallpaper changing before fading back to the home screen. -->
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+    android:startOffset="@android:integer/config_longAnimTime"
+    android:duration="@android:integer/config_mediumAnimTime"
+    android:fromAlpha="1"
+    android:toAlpha="0"/>
\ No newline at end of file
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
index 45118bf..1d8e37d 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
@@ -45,6 +45,10 @@
         public void onBitmapCropped(byte[] imageBytes);
     }
 
+    public interface OnEndCropHandler {
+        public void run(boolean cropSucceeded);
+    }
+
     private static final int DEFAULT_COMPRESS_QUALITY = 90;
     private static final String LOGTAG = "BitmapCropTask";
 
@@ -59,56 +63,56 @@
     boolean mSetWallpaper;
     boolean mSaveCroppedBitmap;
     Bitmap mCroppedBitmap;
-    Runnable mOnEndRunnable;
+    BitmapCropTask.OnEndCropHandler mOnEndCropHandler;
     Resources mResources;
     BitmapCropTask.OnBitmapCroppedHandler mOnBitmapCroppedHandler;
     boolean mNoCrop;
 
     public BitmapCropTask(Context c, String filePath,
             RectF cropBounds, int rotation, int outWidth, int outHeight,
-            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
         mContext = c;
         mInFilePath = filePath;
         init(cropBounds, rotation,
-                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndCropHandler);
     }
 
     public BitmapCropTask(byte[] imageBytes,
             RectF cropBounds, int rotation, int outWidth, int outHeight,
-            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
         mInImageBytes = imageBytes;
         init(cropBounds, rotation,
-                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndCropHandler);
     }
 
     public BitmapCropTask(Context c, Uri inUri,
             RectF cropBounds, int rotation, int outWidth, int outHeight,
-            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
         mContext = c;
         mInUri = inUri;
         init(cropBounds, rotation,
-                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndCropHandler);
     }
 
     public BitmapCropTask(Context c, Resources res, int inResId,
             RectF cropBounds, int rotation, int outWidth, int outHeight,
-            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
         mContext = c;
         mInResId = inResId;
         mResources = res;
         init(cropBounds, rotation,
-                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
+                outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndCropHandler);
     }
 
     private void init(RectF cropBounds, int rotation, int outWidth, int outHeight,
-            boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
+            boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
         mCropBounds = cropBounds;
         mRotation = rotation;
         mOutWidth = outWidth;
         mOutHeight = outHeight;
         mSetWallpaper = setWallpaper;
         mSaveCroppedBitmap = saveCroppedBitmap;
-        mOnEndRunnable = onEndRunnable;
+        mOnEndCropHandler = onEndCropHandler;
     }
 
     public void setOnBitmapCropped(BitmapCropTask.OnBitmapCroppedHandler handler) {
@@ -119,8 +123,8 @@
         mNoCrop = value;
     }
 
-    public void setOnEndRunnable(Runnable onEndRunnable) {
-        mOnEndRunnable = onEndRunnable;
+    public void setOnEndCropHandler(OnEndCropHandler onEndCropHandler) {
+        mOnEndCropHandler = onEndCropHandler;
     }
 
     // Helper to setup input stream
@@ -398,8 +402,8 @@
 
     @Override
     protected void onPostExecute(Boolean result) {
-        if (mOnEndRunnable != null) {
-            mOnEndRunnable.run();
+        if (mOnEndCropHandler != null) {
+            mOnEndCropHandler.run(result);
         }
     }
 }
\ No newline at end of file
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index efa1181..b562fbf 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -108,7 +108,9 @@
                 new View.OnClickListener() {
                     @Override
                     public void onClick(View v) {
-                        cropImageAndSetWallpaper(imageUri, null);
+                        // Never fade on finish because we return to the app that started us (e.g.
+                        // Photos), not the home screen.
+                        cropImageAndSetWallpaper(imageUri, null, false /* shouldFadeOutOnFinish */);
                     }
                 });
         mSetWallpaperButton = findViewById(R.id.set_wallpaper_button);
@@ -306,17 +308,18 @@
         return getResources().getBoolean(R.bool.allow_rotation);
     }
 
-    public void setWallpaper(Uri uri) {
+    public void setWallpaper(Uri uri, boolean shouldFadeOutOnFinish) {
         int rotation = BitmapUtils.getRotationFromExif(getContext(), uri);
         BitmapCropTask cropTask = new BitmapCropTask(
                 getContext(), uri, null, rotation, 0, 0, true, false, null);
-        CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(cropTask.getImageBounds());
-        cropTask.setOnEndRunnable(onEndCrop);
+        BitmapCropTask.OnEndCropHandler onEndCrop = new CropAndFinishHandler(
+                cropTask.getImageBounds(), shouldFadeOutOnFinish);
+        cropTask.setOnEndCropHandler(onEndCrop);
         cropTask.setNoCrop(true);
         cropTask.execute();
     }
 
-    public void cropImageAndSetWallpaper(Resources res, int resId) {
+    public void cropImageAndSetWallpaper(Resources res, int resId, boolean shouldFadeOutOnFinish) {
         // crop this image and scale it down to the default wallpaper size for
         // this device
         int rotation = BitmapUtils.getRotationFromExif(res, resId, this);
@@ -327,7 +330,8 @@
                 inSize.x, inSize.y, outSize.x, outSize.y, false);
         // Passing 0, 0 will cause launcher to revert to using the
         // default wallpaper size
-        CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(new Point(0, 0));
+        CropAndFinishHandler onEndCrop = new CropAndFinishHandler(new Point(0, 0),
+                shouldFadeOutOnFinish);
         BitmapCropTask cropTask = new BitmapCropTask(getContext(), res, resId,
                 crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
         cropTask.execute();
@@ -335,7 +339,8 @@
 
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     public void cropImageAndSetWallpaper(Uri uri,
-            BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler) {
+            BitmapCropTask.OnBitmapCroppedHandler onBitmapCroppedHandler,
+            boolean shouldFadeOutOnFinish) {
         boolean centerCrop = getResources().getBoolean(R.bool.center_crop);
         // Get the crop
         boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
@@ -411,7 +416,8 @@
 
         final int outWidth = (int) Math.round(cropRect.width() * cropScale);
         final int outHeight = (int) Math.round(cropRect.height() * cropScale);
-        CropAndFinishRunnable onEndCrop = new CropAndFinishRunnable(new Point(outWidth, outHeight));
+        CropAndFinishHandler onEndCrop = new CropAndFinishHandler(new Point(outWidth, outHeight),
+                shouldFadeOutOnFinish);
 
         BitmapCropTask cropTask = new BitmapCropTask(getContext(), uri,
                 cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
@@ -421,19 +427,29 @@
         cropTask.execute();
     }
 
-    private class CropAndFinishRunnable implements Runnable {
+    public class CropAndFinishHandler implements BitmapCropTask.OnEndCropHandler {
         private final Point mBounds;
+        private boolean mShouldFadeOutOnFinish;
 
-        public CropAndFinishRunnable(Point bounds) {
+        /**
+         * @param shouldFadeOutOnFinish Whether the wallpaper picker should override the default
+         * exit animation to fade out instead. This should only be set to true if the wallpaper
+         * preview will exactly match the actual wallpaper on the page we are returning to.
+         */
+        public CropAndFinishHandler(Point bounds, boolean shouldFadeOutOnFinish) {
             mBounds = bounds;
+            mShouldFadeOutOnFinish = shouldFadeOutOnFinish;
         }
 
         @Override
-        public void run() {
+        public void run(boolean cropSucceeded) {
             WallpaperUtils.saveWallpaperDimensions(mBounds.x, mBounds.y,
                     WallpaperCropActivity.this);
             setResult(Activity.RESULT_OK);
             finish();
+            if (cropSucceeded && mShouldFadeOutOnFinish) {
+                overridePendingTransition(0, R.anim.fade_out);
+            }
         }
     }
 
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 89ff04f..27d60f8 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -169,7 +169,7 @@
 
         // Populate the third-party wallpaper pickers
         populateWallpapers((LinearLayout) findViewById(R.id.third_party_wallpaper_list),
-                ThirdPartyWallpaperInfo.getAll(this), false);
+                ThirdPartyWallpaperInfo.getAll(this), false /* addLongPressHandler */);
 
         // Add a tile for the Gallery
         LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java
index be93e13..f6a46fc 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/FileWallpaperInfo.java
@@ -36,7 +36,8 @@
 
     @Override
     public void onSave(WallpaperPickerActivity a) {
-        a.setWallpaper(Uri.fromFile(mFile));
+        boolean shouldFadeOutOnFinish = a.getWallpaperParallaxOffset() == 0f;
+        a.setWallpaper(Uri.fromFile(mFile), shouldFadeOutOnFinish);
     }
 
     @Override
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
index a5becf1..d63714c 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
@@ -50,7 +50,7 @@
 
     @Override
     public void onSave(WallpaperPickerActivity a) {
-        a.cropImageAndSetWallpaper(mResources, mResId);
+        a.cropImageAndSetWallpaper(mResources, mResId, true /* shouldFadeOutOnFinish */);
     }
 
     @Override
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java
index e7ea511..5e2538f 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ThirdPartyWallpaperInfo.java
@@ -34,7 +34,9 @@
         final ComponentName itemComponentName = new ComponentName(
                 mResolveInfo.activityInfo.packageName, mResolveInfo.activityInfo.name);
         Intent launchIntent = new Intent(Intent.ACTION_SET_WALLPAPER)
-            .setComponent(itemComponentName);
+            .setComponent(itemComponentName)
+            .putExtra(WallpaperPickerActivity.EXTRA_WALLPAPER_OFFSET,
+                    a.getWallpaperParallaxOffset());
         a.startActivityForResultSafely(
                 launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY);
     }
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java
index 3e76fb8..180eb93 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/UriWallpaperInfo.java
@@ -60,7 +60,8 @@
                 a.getSavedImages().writeImage(thumb, imageBytes);
             }
         };
-        a.cropImageAndSetWallpaper(mUri, h);
+        boolean shouldFadeOutOnFinish = a.getWallpaperParallaxOffset() == 0f;
+        a.cropImageAndSetWallpaper(mUri, h, shouldFadeOutOnFinish);
     }
 
     @Override