19eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalpackage com.android.launcher3.util;
29eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
39eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.app.WallpaperManager;
49eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.os.IBinder;
59eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.util.Log;
69eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.view.Choreographer;
79eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.view.animation.DecelerateInterpolator;
89eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport android.view.animation.Interpolator;
99eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
109eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport com.android.launcher3.Utilities;
119eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalimport com.android.launcher3.Workspace;
129eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
139eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal/**
149eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal * Utility class to handle wallpaper scrolling along with workspace.
159eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal */
169eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyalpublic class WallpaperOffsetInterpolator implements Choreographer.FrameCallback {
179eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private static final String TAG = "WPOffsetInterpolator";
189eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private static final int ANIMATION_DURATION = 250;
199eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
209eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    // Don't use all the wallpaper for parallax until you have at least this many pages
21d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson    private static final int MIN_PARALLAX_PAGE_SPAN = 4;
229eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
239eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private final Choreographer mChoreographer;
249eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private final Interpolator mInterpolator;
259eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private final WallpaperManager mWallpaperManager;
269eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private final Workspace mWorkspace;
279eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private final boolean mIsRtl;
289eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
299eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private IBinder mWindowToken;
309eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private boolean mWallpaperIsLiveWallpaper;
319eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private float mLastSetWallpaperOffsetSteps = 0;
329eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
339eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private float mFinalOffset = 0.0f;
349eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private float mCurrentOffset = 0.5f; // to force an initial update
359eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private boolean mWaitingForUpdate;
36c7d2e83c15e85b2695e016213549d08e63c923b3Winson    private boolean mLockedToDefaultPage;
379eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
389eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private boolean mAnimating;
399eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private long mAnimationStartTime;
409eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private float mAnimationStartOffset;
419eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    int mNumScreens;
429eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    int mNumPagesForWallpaperParallax;
439eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
449eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public WallpaperOffsetInterpolator(Workspace workspace) {
459eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mChoreographer = Choreographer.getInstance();
469eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mInterpolator = new DecelerateInterpolator(1.5f);
479eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
489eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mWorkspace = workspace;
499eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mWallpaperManager = WallpaperManager.getInstance(workspace.getContext());
509eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mIsRtl = Utilities.isRtl(workspace.getResources());
519eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
529eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
539eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    @Override
549eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void doFrame(long frameTimeNanos) {
559eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        updateOffset(false);
569eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
579eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
589eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private void updateOffset(boolean force) {
599eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (mWaitingForUpdate || force) {
609eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mWaitingForUpdate = false;
619eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            if (computeScrollOffset() && mWindowToken != null) {
629eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                try {
639eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                    mWallpaperManager.setWallpaperOffsets(mWindowToken, getCurrX(), 0.5f);
649eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                    setWallpaperOffsetSteps();
659eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                } catch (IllegalArgumentException e) {
669eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                    Log.e(TAG, "Error updating wallpaper offset: " + e);
679eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                }
689eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            }
699eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
709eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
719eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
72c7d2e83c15e85b2695e016213549d08e63c923b3Winson    /**
73c7d2e83c15e85b2695e016213549d08e63c923b3Winson     * Locks the wallpaper offset to the offset in the default state of Launcher.
74c7d2e83c15e85b2695e016213549d08e63c923b3Winson     */
75c7d2e83c15e85b2695e016213549d08e63c923b3Winson    public void setLockToDefaultPage(boolean lockToDefaultPage) {
76c7d2e83c15e85b2695e016213549d08e63c923b3Winson        mLockedToDefaultPage = lockToDefaultPage;
77c7d2e83c15e85b2695e016213549d08e63c923b3Winson    }
78c7d2e83c15e85b2695e016213549d08e63c923b3Winson
79c7d2e83c15e85b2695e016213549d08e63c923b3Winson    public boolean isLockedToDefaultPage() {
80c7d2e83c15e85b2695e016213549d08e63c923b3Winson        return mLockedToDefaultPage;
81c7d2e83c15e85b2695e016213549d08e63c923b3Winson    }
82c7d2e83c15e85b2695e016213549d08e63c923b3Winson
839eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public boolean computeScrollOffset() {
849eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        final float oldOffset = mCurrentOffset;
859eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (mAnimating) {
869eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            long durationSinceAnimation = System.currentTimeMillis() - mAnimationStartTime;
879eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            float t0 = durationSinceAnimation / (float) ANIMATION_DURATION;
889eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            float t1 = mInterpolator.getInterpolation(t0);
899eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mCurrentOffset = mAnimationStartOffset +
909eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                    (mFinalOffset - mAnimationStartOffset) * t1;
919eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mAnimating = durationSinceAnimation < ANIMATION_DURATION;
929eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        } else {
939eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mCurrentOffset = mFinalOffset;
949eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
959eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
969eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (Math.abs(mCurrentOffset - mFinalOffset) > 0.0000001f) {
979eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            scheduleUpdate();
989eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
999eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
1009eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            return true;
1019eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
1029eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        return false;
1039eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1049eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
105d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson    /**
106d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson     * TODO: do different behavior if it's  a live wallpaper?
107d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson     */
1089eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public float wallpaperOffsetForScroll(int scroll) {
109d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // To match the default wallpaper behavior in the system, we default to either the left
110d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // or right edge on initialization
1119eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        int numScrollingPages = getNumScreensExcludingEmptyAndCustom();
112c7d2e83c15e85b2695e016213549d08e63c923b3Winson        if (mLockedToDefaultPage || numScrollingPages <= 1) {
113d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            return mIsRtl ? 1f : 0f;
1149eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
1159eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
116d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // Distribute the wallpaper parallax over a minimum of MIN_PARALLAX_PAGE_SPAN workspace
117d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // screens, not including the custom screen, and empty screens (if > MIN_PARALLAX_PAGE_SPAN)
118d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        if (mWallpaperIsLiveWallpaper) {
119d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            mNumPagesForWallpaperParallax = numScrollingPages;
120d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        } else {
121d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            mNumPagesForWallpaperParallax = Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages);
1229eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
1239eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
124d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // Offset by the custom screen
125d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int leftPageIndex;
126d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int rightPageIndex;
1279eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (mIsRtl) {
128d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            rightPageIndex = mWorkspace.numCustomPages();
129d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            leftPageIndex = rightPageIndex + numScrollingPages - 1;
130d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        } else {
131d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            leftPageIndex = mWorkspace.numCustomPages();
132d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            rightPageIndex = leftPageIndex + numScrollingPages - 1;
1339eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
1349eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
135d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // Calculate the scroll range
136d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int leftPageScrollX = mWorkspace.getScrollForPage(leftPageIndex);
137d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int rightPageScrollX = mWorkspace.getScrollForPage(rightPageIndex);
138d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int scrollRange = rightPageScrollX - leftPageScrollX;
1399eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (scrollRange == 0) {
140d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            return 0f;
141d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        }
142d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson
143d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // Sometimes the left parameter of the pages is animated during a layout transition;
144d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // this parameter offsets it to keep the wallpaper from animating as well
145d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        int adjustedScroll = scroll - leftPageScrollX -
146d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson                mWorkspace.getLayoutTransitionOffsetForPage(0);
147d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        float offset = Utilities.boundToRange((float) adjustedScroll / scrollRange, 0f, 1f);
148d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson
149d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // The offset is now distributed 0..1 between the left and right pages that we care about,
150d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        // so we just map that between the pages that we are using for parallax
151d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        float rtlOffset = 0;
152d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        if (mIsRtl) {
153d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            // In RTL, the pages are right aligned, so adjust the offset from the end
154d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson            rtlOffset = (float) ((mNumPagesForWallpaperParallax - 1) - (numScrollingPages - 1)) /
155d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson                    (mNumPagesForWallpaperParallax - 1);
1569eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
157d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        return rtlOffset + offset *
158d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson                ((float) (numScrollingPages - 1) / (mNumPagesForWallpaperParallax - 1));
1599eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1609eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1619eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private float wallpaperOffsetForCurrentScroll() {
1629eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        return wallpaperOffsetForScroll(mWorkspace.getScrollX());
1639eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1649eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1659eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private int numEmptyScreensToIgnore() {
1669eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        int numScrollingPages = mWorkspace.getChildCount() - mWorkspace.numCustomPages();
1679eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreen()) {
1689eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            return 1;
1699eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        } else {
1709eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            return 0;
1719eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
1729eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1739eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1749eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private int getNumScreensExcludingEmptyAndCustom() {
1759eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        return mWorkspace.getChildCount() - numEmptyScreensToIgnore() - mWorkspace.numCustomPages();
1769eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1779eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1789eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void syncWithScroll() {
1799eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        float offset = wallpaperOffsetForCurrentScroll();
1809eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        setFinalX(offset);
1819eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        updateOffset(true);
1829eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1839eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1849eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public float getCurrX() {
1859eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        return mCurrentOffset;
1869eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1879eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1889eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public float getFinalX() {
1899eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        return mFinalOffset;
1909eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1919eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1929eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private void animateToFinal() {
1939eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mAnimating = true;
1949eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mAnimationStartOffset = mCurrentOffset;
1959eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mAnimationStartTime = System.currentTimeMillis();
1969eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
1979eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
1989eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private void setWallpaperOffsetSteps() {
1999eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        // Set wallpaper offset steps (1 / (number of screens - 1))
200d96fa1336921cc8c8bb4d773b2229b62df86e6eaWinson        float xOffset = 1.0f / (mNumPagesForWallpaperParallax - 1);
2019eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (xOffset != mLastSetWallpaperOffsetSteps) {
2029eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mWallpaperManager.setWallpaperOffsetSteps(xOffset, 1.0f);
2039eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mLastSetWallpaperOffsetSteps = xOffset;
2049eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
2059eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2069eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
2079eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void setFinalX(float x) {
2089eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        scheduleUpdate();
209c7d2e83c15e85b2695e016213549d08e63c923b3Winson        mFinalOffset = Math.max(0f, Math.min(x, 1f));
2109eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (getNumScreensExcludingEmptyAndCustom() != mNumScreens) {
2115bc2827488a53dad60e3b66a27c6deda78f3d83fWinson            if (mNumScreens > 0 && Float.compare(mCurrentOffset, mFinalOffset) != 0) {
2125bc2827488a53dad60e3b66a27c6deda78f3d83fWinson                // Don't animate if we're going from 0 screens, or if the final offset is the same
2135bc2827488a53dad60e3b66a27c6deda78f3d83fWinson                // as the current offset
2149eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal                animateToFinal();
2159eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            }
2169eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mNumScreens = getNumScreensExcludingEmptyAndCustom();
2179eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
2189eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2199eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
2209eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    private void scheduleUpdate() {
2219eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        if (!mWaitingForUpdate) {
2229eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mChoreographer.postFrameCallback(this);
2239eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal            mWaitingForUpdate = true;
2249eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        }
2259eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2269eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
2279eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void jumpToFinal() {
2289eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mCurrentOffset = mFinalOffset;
2299eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2309eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
2319eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void onResume() {
2329eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mWallpaperIsLiveWallpaper = mWallpaperManager.getWallpaperInfo() != null;
2339eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        // Force the wallpaper offset steps to be set again, because another app might have changed
2349eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        // them
2359eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mLastSetWallpaperOffsetSteps = 0f;
2369eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2379eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal
2389eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    public void setWindowToken(IBinder token) {
2399eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal        mWindowToken = token;
2409eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal    }
2419eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal}