Previews in the wallpaper picker are offset to match the homescreen parallax.

When "Wallpapers" is selected from the overlay, the current wallpaper parallax
offset is sent to the WallpaperPickerActivity as an Intent extra. The CropView
then uses that offset when previewing new wallpapers to ensure the preview looks
exactly the same as the actual wallpaper will when set.

Note that this fix doesn't seem to work for DefaultWallpaperInfo - that will
come in a future CL.

Bug: 23568800
Change-Id: I41c5bbbfdabfeb4e20d77e9b5804842a03211edf
diff --git a/WallpaperPicker/src/com/android/launcher3/CropView.java b/WallpaperPicker/src/com/android/launcher3/CropView.java
index 50f779a..34c7084 100644
--- a/WallpaperPicker/src/com/android/launcher3/CropView.java
+++ b/WallpaperPicker/src/com/android/launcher3/CropView.java
@@ -27,7 +27,6 @@
 import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-
 import com.android.photos.views.TiledImageRenderer.TileSource;
 import com.android.photos.views.TiledImageView;
 
@@ -189,6 +188,16 @@
     public void onScaleEnd(ScaleGestureDetector detector) {
     }
 
+    /**
+     * Offsets wallpaper preview according to the state it will be displayed in upon returning home.
+     * @param offset Ranges from 0 to 1, where 0 is the leftmost parallax and 1 is the rightmost.
+     */
+    public void addParallaxOffset(float offset) {
+        offset = Math.max(0, Math.min(offset, 1)); // Make sure the offset is in the correct range.
+        mCenterX += offset * (getSourceDimensions().x - getWidth() / mRenderer.scale);
+        updateCenter();
+    }
+
     public void moveToLeft() {
         if (getWidth() == 0 || getHeight() == 0) {
             final ViewTreeObserver observer = getViewTreeObserver();
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 2cfc9bf..b3a81ae 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -22,7 +22,6 @@
 import android.app.WallpaperManager;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
@@ -250,8 +249,9 @@
             if (req.moveToLeft) {
                 mCropView.moveToLeft();
             }
-            if (req.scaleProvider != null) {
-                mCropView.setScale(req.scaleProvider.getScale(req.result));
+            if (req.scaleAndOffsetProvider != null) {
+                mCropView.setScale(req.scaleAndOffsetProvider.getScale(req.result));
+                mCropView.addParallaxOffset(req.scaleAndOffsetProvider.getParallaxOffset());
             }
 
             // Free last image
@@ -270,13 +270,14 @@
 
     @TargetApi(Build.VERSION_CODES.KITKAT)
     public final void setCropViewTileSource(BitmapSource bitmapSource, boolean touchEnabled,
-            boolean moveToLeft, CropViewScaleProvider scaleProvider, Runnable postExecute) {
+            boolean moveToLeft, CropViewScaleAndOffsetProvider scaleAndOffsetProvider,
+            Runnable postExecute) {
         final LoadRequest req = new LoadRequest();
         req.moveToLeft = moveToLeft;
         req.src = bitmapSource;
         req.touchEnabled = touchEnabled;
         req.postExecute = postExecute;
-        req.scaleProvider = scaleProvider;
+        req.scaleAndOffsetProvider = scaleAndOffsetProvider;
         mCurrentLoadRequest = req;
 
         // Remove any pending requests
@@ -436,12 +437,13 @@
         boolean touchEnabled;
         boolean moveToLeft;
         Runnable postExecute;
-        CropViewScaleProvider scaleProvider;
+        CropViewScaleAndOffsetProvider scaleAndOffsetProvider;
 
         TileSource result;
     }
 
-    public interface CropViewScaleProvider {
+    public interface CropViewScaleAndOffsetProvider {
         float getScale(TileSource src);
+        float getParallaxOffset();
     }
 }
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 63c31e8..89ff04f 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -46,6 +46,7 @@
 import android.view.WindowManager;
 import android.widget.HorizontalScrollView;
 import android.widget.LinearLayout;
+
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.wallpapertileinfo.DefaultWallpaperInfo;
 import com.android.launcher3.wallpapertileinfo.FileWallpaperInfo;
@@ -55,6 +56,7 @@
 import com.android.launcher3.wallpapertileinfo.ThirdPartyWallpaperInfo;
 import com.android.launcher3.wallpapertileinfo.UriWallpaperInfo;
 import com.android.launcher3.wallpapertileinfo.WallpaperTileInfo;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
@@ -65,11 +67,14 @@
 
     public static final int IMAGE_PICK = 5;
     public static final int PICK_WALLPAPER_THIRD_PARTY_ACTIVITY = 6;
+    /** An Intent extra used when opening the wallpaper picker from the workspace overlay. */
+    public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
     private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
     private static final String SELECTED_INDEX = "SELECTED_INDEX";
     private static final int FLAG_POST_DELAY_MILLIS = 200;
 
-    @Thunk View mSelectedTile;
+    @Thunk
+    View mSelectedTile;
 
     @Thunk LinearLayout mWallpapersView;
     @Thunk HorizontalScrollView mWallpaperScrollContainer;
@@ -80,6 +85,8 @@
     ArrayList<Uri> mTempWallpaperTiles = new ArrayList<Uri>();
     private SavedWallpaperImages mSavedImages;
     @Thunk int mSelectedIndex = -1;
+    private float mWallpaperParallaxOffset;
+
     /**
      * shows the system wallpaper behind the window and hides the {@link #mCropView} if visible
      * @param visible should the system wallpaper be shown
@@ -137,6 +144,8 @@
         mWallpaperStrip = findViewById(R.id.wallpaper_strip);
         mCropView.setTouchCallback(new ToggleOnTapCallback(mWallpaperStrip));
 
+        mWallpaperParallaxOffset = getIntent().getFloatExtra(EXTRA_WALLPAPER_OFFSET, 0);
+
         mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);
         // Populate the saved wallpapers
         mSavedImages = new SavedWallpaperImages(getContext());
@@ -266,6 +275,10 @@
         mSetWallpaperButton.setEnabled(enabled);
     }
 
+    public float getWallpaperParallaxOffset() {
+        return mWallpaperParallaxOffset;
+    }
+
     public void selectTile(View v) {
         if (mSelectedTile != null) {
             mSelectedTile.setSelected(false);
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
index 49310b0..2b508f1 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/DefaultWallpaperInfo.java
@@ -17,7 +17,7 @@
 import com.android.gallery3d.common.BitmapUtils;
 import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.WallpaperCropActivity.CropViewScaleProvider;
+import com.android.launcher3.WallpaperCropActivity.CropViewScaleAndOffsetProvider;
 import com.android.launcher3.WallpaperPickerActivity;
 import com.android.photos.views.TiledImageRenderer.TileSource;
 
@@ -35,12 +35,17 @@
 
     @Override
     public void onClick(WallpaperPickerActivity a) {
-        a.setCropViewTileSource(null, false, false, new CropViewScaleProvider() {
+        a.setCropViewTileSource(null, false, false, new CropViewScaleAndOffsetProvider() {
 
             @Override
             public float getScale(TileSource src) {
                 return 1f;
             }
+
+            @Override
+            public float getParallaxOffset() {
+                return 0;
+            }
         }, null);
     }
 
diff --git a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
index 6f28311..9180c46 100644
--- a/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
+++ b/WallpaperPicker/src/com/android/launcher3/wallpapertileinfo/ResourceWallpaperInfo.java
@@ -4,9 +4,8 @@
 import android.graphics.Point;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
-
 import com.android.gallery3d.common.Utils;
-import com.android.launcher3.WallpaperCropActivity.CropViewScaleProvider;
+import com.android.launcher3.WallpaperCropActivity.CropViewScaleAndOffsetProvider;
 import com.android.launcher3.WallpaperPickerActivity;
 import com.android.launcher3.util.WallpaperUtils;
 import com.android.photos.BitmapRegionTileSource;
@@ -29,7 +28,7 @@
         a.setWallpaperButtonEnabled(false);
         final BitmapRegionTileSource.ResourceBitmapSource bitmapSource =
                 new BitmapRegionTileSource.ResourceBitmapSource(mResources, mResId, a);
-        a.setCropViewTileSource(bitmapSource, false, false, new CropViewScaleProvider() {
+        a.setCropViewTileSource(bitmapSource, false, true, new CropViewScaleAndOffsetProvider() {
 
             @Override
             public float getScale(TileSource src) {
@@ -40,6 +39,11 @@
                         wallpaperSize.x, wallpaperSize.y, false);
                 return wallpaperSize.x / crop.width();
             }
+
+            @Override
+            public float getParallaxOffset() {
+                return a.getWallpaperParallaxOffset();
+            }
         }, new Runnable() {
 
             @Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3c9c5f7..17a619b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2675,7 +2675,10 @@
      */
     protected void onClickWallpaperPicker(View v) {
         if (LOGD) Log.d(TAG, "onClickWallpaperPicker");
-        startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),
+        int pageScroll = mWorkspace.getScrollForPage(mWorkspace.getPageNearestToCenterOfScreen());
+        float offset = mWorkspace.mWallpaperOffset.wallpaperOffsetForScroll(pageScroll);
+        startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName())
+                        .putExtra(WallpaperPickerActivity.EXTRA_WALLPAPER_OFFSET, offset),
                 REQUEST_PICK_WALLPAPER);
 
         if (mLauncherCallbacks != null) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index eb3d6dbc..e742ea0 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1401,7 +1401,7 @@
             return false;
         }
 
-        private float wallpaperOffsetForCurrentScroll() {
+        public float wallpaperOffsetForScroll(int scroll) {
             // TODO: do different behavior if it's  a live wallpaper?
             // Don't use up all the wallpaper parallax until you have at least
             // MIN_PARALLAX_PAGE_SPAN pages
@@ -1440,7 +1440,7 @@
                 // Sometimes the left parameter of the pages is animated during a layout transition;
                 // this parameter offsets it to keep the wallpaper from animating as well
                 int adjustedScroll =
-                        getScrollX() - firstPageScrollX - getLayoutTransitionOffsetForPage(0);
+                        scroll - firstPageScrollX - getLayoutTransitionOffsetForPage(0);
                 float offset = Math.min(1, adjustedScroll / (float) scrollRange);
                 offset = Math.max(0, offset);
 
@@ -1454,6 +1454,10 @@
             }
         }
 
+        private float wallpaperOffsetForCurrentScroll() {
+            return wallpaperOffsetForScroll(getScrollX());
+        }
+
         private int numEmptyScreensToIgnore() {
             int numScrollingPages = getChildCount() - numCustomPages();
             if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && hasExtraEmptyScreen()) {