Merge "Fixing folders to always show in view, removing old assets and references to LauncherModel count." into jb-ub-gel-agar
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a78e313..477c4e1 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -91,19 +91,9 @@
         </activity>
 
         <activity
-            android:name="com.android.launcher3.WidgetAdder"
-            android:label="@string/widget_adder"
-            android:icon="@mipmap/ic_launcher_home">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
-        <activity
             android:name="com.android.launcher3.ToggleWeightWatcher"
             android:label="@string/toggle_weight_watcher"
+            android:enabled="@bool/debug_memory_enabled"
             android:icon="@mipmap/ic_launcher_home">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
index f0e3bbf..030acf6 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/qsb_bar.xml
@@ -20,13 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <!-- Search buttons container -->
-    <include android:id="@+id/qsb_search_bar"
-        layout="@layout/search_bar"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center" />
-
     <!-- Drag specific targets container -->
     <LinearLayout
         style="@style/SearchDropTargetBar"
diff --git a/res/values/config.xml b/res/values/config.xml
index 14e5a56..2027640 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -80,5 +80,5 @@
     <bool name="hotseat_transpose_layout_with_orientation">true</bool>
 
     <!-- Memory debugging, including a memory dump icon -->
-    <bool name="debug_memory_enabled">true</bool>
+    <bool name="debug_memory_enabled">false</bool>
 </resources>
diff --git a/src/com/android/launcher3/DrawableStateProxyView.java b/src/com/android/launcher3/DrawableStateProxyView.java
index 196e2f2..0758de1 100644
--- a/src/com/android/launcher3/DrawableStateProxyView.java
+++ b/src/com/android/launcher3/DrawableStateProxyView.java
@@ -58,8 +58,10 @@
             View parent = (View) getParent();
             mView = parent.findViewById(mViewId);
         }
-        mView.setPressed(isPressed());
-        mView.setHovered(isHovered());
+        if (mView != null) {
+            mView.setPressed(isPressed());
+            mView.setHovered(isHovered());
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 16af648..0a56117 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -345,7 +345,7 @@
         searchBarSpace.setLayoutParams(lp);
 
         // Layout the search bar
-        View searchBar = searchBarSpace.findViewById(R.id.qsb_search_bar);
+        View searchBar = launcher.getQsbBar();
         lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
         lp.width = LayoutParams.MATCH_PARENT;
         lp.height = LayoutParams.MATCH_PARENT;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 7fc7033..8240356 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -241,6 +241,7 @@
     private AppsCustomizeTabHost mAppsCustomizeTabHost;
     private AppsCustomizePagedView mAppsCustomizeContent;
     private boolean mAutoAdvanceRunning = false;
+    private View mQsbBar;
 
     private Bundle mSavedState;
     // We set the state in both onCreate and then onNewIntent in some cases, which causes both
@@ -412,8 +413,8 @@
 
         checkForLocaleChange();
         setContentView(R.layout.launcher);
-        grid.layout(this);
         setupViews();
+        grid.layout(this);
         showFirstRunWorkspaceCling();
 
         registerContentObservers();
@@ -3233,7 +3234,14 @@
         }
     }
 
-    private boolean updateGlobalSearchIcon() {
+    public View getQsbBar() {
+        if (mQsbBar == null) {
+            mQsbBar = mInflater.inflate(R.layout.qsb_bar, mSearchDropTargetBar);
+        }
+        return mQsbBar;
+    }
+
+    protected boolean updateGlobalSearchIcon() {
         final View searchButtonContainer = findViewById(R.id.search_button_container);
         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
@@ -3268,14 +3276,14 @@
         }
     }
 
-    private void updateGlobalSearchIcon(Drawable.ConstantState d) {
+    protected void updateGlobalSearchIcon(Drawable.ConstantState d) {
         final View searchButtonContainer = findViewById(R.id.search_button_container);
         final View searchButton = (ImageView) findViewById(R.id.search_button);
         updateButtonWithDrawable(R.id.search_button, d);
         invalidatePressedFocusedStates(searchButtonContainer, searchButton);
     }
 
-    private boolean updateVoiceSearchIcon(boolean searchVisible) {
+    protected boolean updateVoiceSearchIcon(boolean searchVisible) {
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
 
@@ -3321,7 +3329,7 @@
         }
     }
 
-    private void updateVoiceSearchIcon(Drawable.ConstantState d) {
+    protected void updateVoiceSearchIcon(Drawable.ConstantState d) {
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
         updateButtonWithDrawable(R.id.voice_button, d);
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index 8f1b5d2..0a0861f 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -23,6 +23,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
@@ -71,6 +72,14 @@
         dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
         mInfoDropTarget.setLauncher(launcher);
         mDeleteDropTarget.setLauncher(launcher);
+        mQSBSearchBar = launcher.getQsbBar();
+        if (mEnableDropDownDropTargets) {
+            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
+                    -mBarHeight);
+        } else {
+            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
+        }
+        setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
     }
 
     private void prepareStartAnimation(View v) {
@@ -95,7 +104,6 @@
         super.onFinishInflate();
 
         // Get the individual components
-        mQSBSearchBar = findViewById(R.id.qsb_search_bar);
         mDropTargetBar = findViewById(R.id.drag_target_bar);
         mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target_text);
         mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target_text);
@@ -114,15 +122,12 @@
             mDropTargetBar.setTranslationY(-mBarHeight);
             mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "translationY",
                     -mBarHeight, 0f);
-            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
-                    -mBarHeight);
+
         } else {
             mDropTargetBar.setAlpha(0f);
             mDropTargetBarAnim = LauncherAnimUtils.ofFloat(mDropTargetBar, "alpha", 0f, 1f);
-            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
         }
         setupAnimation(mDropTargetBarAnim, mDropTargetBar);
-        setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
     }
 
     public void finishAnimations() {
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index 087785e..2978c85 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -47,9 +47,6 @@
 public class WallpaperCropActivity extends Activity {
     private static final String LOGTAG = "Launcher3.CropActivity";
 
-    private int mOutputX = 0;
-    private int mOutputY = 0;
-
     protected static final String WALLPAPER_WIDTH_KEY = "wallpaper.width";
     protected static final String WALLPAPER_HEIGHT_KEY = "wallpaper.height";
     private static final int DEFAULT_COMPRESS_QUALITY = 90;
@@ -183,14 +180,14 @@
                     failure = true;
                     return false;
                 }
-                if (mOutputX > 0 && mOutputY > 0) {
+                if (mOutWidth > 0 && mOutHeight > 0) {
                     Matrix m = new Matrix();
                     RectF cropRect = new RectF(0, 0, crop.getWidth(), crop.getHeight());
                     if (mRotation > 0) {
                         m.setRotate(mRotation);
                         m.mapRect(cropRect);
                     }
-                    RectF returnRect = new RectF(0, 0, mOutputX, mOutputY);
+                    RectF returnRect = new RectF(0, 0, mOutWidth, mOutHeight);
                     m.setRectToRect(cropRect, returnRect, Matrix.ScaleToFit.FILL);
                     m.preRotate(mRotation);
                     Bitmap tmp = Bitmap.createBitmap((int) returnRect.width(),
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/src/com/android/launcher3/WallpaperPickerActivity.java
index bad8460..a1c74d2 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -398,6 +398,7 @@
                 // If we have saved a wallpaper width/height, use that instead
                 int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWidth);
                 int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultHeight);
+                wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight);
             }
         }.start();
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ba18b8d..2218023 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -45,12 +45,13 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Choreographer;
 import android.view.Display;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.DecelerateInterpolator;
-import android.widget.ImageView;
+import android.view.animation.Interpolator;
 import android.widget.TextView;
 
 import com.android.launcher3.FolderIcon.FolderRingAnimator;
@@ -189,7 +190,6 @@
     private boolean mWorkspaceFadeInAdjacentScreens;
 
     WallpaperOffsetInterpolator mWallpaperOffset;
-    boolean mUpdateWallpaperOffsetImmediately = false;
     private Runnable mDelayedResizeRunnable;
     private Runnable mDelayedSnapToPageRunnable;
     private Point mDisplaySize = new Point();
@@ -940,38 +940,16 @@
                 mLauncher.getSharedPrefs(), mLauncher.getWindowManager(), mWallpaperManager);
     }
 
-    private void syncWallpaperOffsetWithScroll() {
-        final boolean enableWallpaperEffects = isHardwareAccelerated();
-        if (enableWallpaperEffects) {
-            // TODO: figure out what to do about parallax, for now disable it
-            //mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
-        }
-    }
 
-    public void updateWallpaperOffsetImmediately() {
-        mUpdateWallpaperOffsetImmediately = true;
-    }
+    private float wallpaperOffsetForCurrentScroll() {
+        // Set wallpaper offset steps (1 / (number of screens - 1))
+        mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 1.0f);
+        if (mMaxScrollX == 0) {
+            return 0;
+        }
 
-    private void updateWallpaperOffsets() {
-        boolean updateNow = false;
-        boolean keepUpdating = true;
-        if (mUpdateWallpaperOffsetImmediately) {
-            updateNow = true;
-            keepUpdating = false;
-            mWallpaperOffset.jumpToFinal();
-            mUpdateWallpaperOffsetImmediately = false;
-        } else {
-            updateNow = keepUpdating = mWallpaperOffset.computeScrollOffset();
-        }
-        if (updateNow) {
-            if (mWindowToken != null) {
-                mWallpaperManager.setWallpaperOffsets(mWindowToken,
-                        mWallpaperOffset.getCurrX(), mWallpaperOffset.getCurrY());
-            }
-        }
-        if (keepUpdating) {
-            invalidate();
-        }
+        // do different behavior if it's  alive wallpaper?
+        return getScrollX() / (float) mMaxScrollX;
     }
 
     protected void snapToPage(int whichPage, Runnable r) {
@@ -986,114 +964,88 @@
         snapToPage(getPageIndexForScreenId(screenId), r);
     }
 
-    class WallpaperOffsetInterpolator {
-        float mFinalHorizontalWallpaperOffset = 0.0f;
-        float mFinalVerticalWallpaperOffset = 0.5f;
-        float mHorizontalWallpaperOffset = 0.0f;
-        float mVerticalWallpaperOffset = 0.5f;
-        long mLastWallpaperOffsetUpdateTime;
-        boolean mIsMovingFast;
-        boolean mOverrideHorizontalCatchupConstant;
-        float mHorizontalCatchupConstant = 0.35f;
-        float mVerticalCatchupConstant = 0.35f;
+    class WallpaperOffsetInterpolator implements Choreographer.FrameCallback {
+        float mFinalOffset = 0.0f;
+        float mCurrentOffset = 0.0f;
+        //long mLastWallpaperOffsetUpdateTime;
+        boolean mWaitingForCallback;
+        Choreographer mChoreographer;
+        Interpolator mInterpolator;
+        boolean mAnimating;
+        long mAnimationStartTime;
+        float mAnimationStartOffset;
+        final int ANIMATION_DURATION = 250;
+        int mNumScreens;
 
         public WallpaperOffsetInterpolator() {
+            mChoreographer = Choreographer.getInstance();
+            mInterpolator = new DecelerateInterpolator(1.5f);
         }
 
-        public void setOverrideHorizontalCatchupConstant(boolean override) {
-            mOverrideHorizontalCatchupConstant = override;
-        }
-
-        public void setHorizontalCatchupConstant(float f) {
-            mHorizontalCatchupConstant = f;
-        }
-
-        public void setVerticalCatchupConstant(float f) {
-            mVerticalCatchupConstant = f;
+        @Override
+        public void doFrame(long frameTimeNanos) {
+            mWaitingForCallback = false;
+            if (computeScrollOffset()) {
+                mWallpaperManager.setWallpaperOffsets(mWindowToken,
+                        mWallpaperOffset.getCurrX(), 0f);
+            }
         }
 
         public boolean computeScrollOffset() {
-            if (Float.compare(mHorizontalWallpaperOffset, mFinalHorizontalWallpaperOffset) == 0 &&
-                    Float.compare(mVerticalWallpaperOffset, mFinalVerticalWallpaperOffset) == 0) {
-                mIsMovingFast = false;
-                return false;
-            }
-            boolean isLandscape = mDisplaySize.x > mDisplaySize.y;
-
-            long currentTime = System.currentTimeMillis();
-            long timeSinceLastUpdate = currentTime - mLastWallpaperOffsetUpdateTime;
-            timeSinceLastUpdate = Math.min((long) (1000/30f), timeSinceLastUpdate);
-            timeSinceLastUpdate = Math.max(1L, timeSinceLastUpdate);
-
-            float xdiff = Math.abs(mFinalHorizontalWallpaperOffset - mHorizontalWallpaperOffset);
-            if (!mIsMovingFast && xdiff > 0.07) {
-                mIsMovingFast = true;
-            }
-
-            float fractionToCatchUpIn1MsHorizontal;
-            if (mOverrideHorizontalCatchupConstant) {
-                fractionToCatchUpIn1MsHorizontal = mHorizontalCatchupConstant;
-            } else if (mIsMovingFast) {
-                fractionToCatchUpIn1MsHorizontal = isLandscape ? 0.5f : 0.75f;
+            final float oldOffset = mCurrentOffset;
+            if (mAnimating) {
+                long durationSinceAnimation = System.currentTimeMillis() - mAnimationStartTime;
+                float t0 = durationSinceAnimation / (float) ANIMATION_DURATION;
+                float t1 = mInterpolator.getInterpolation(t0);
+                mCurrentOffset = mAnimationStartOffset +
+                        (mFinalOffset - mAnimationStartOffset) * t1;
+                mAnimating = durationSinceAnimation < ANIMATION_DURATION;
             } else {
-                // slow
-                fractionToCatchUpIn1MsHorizontal = isLandscape ? 0.27f : 0.5f;
-            }
-            float fractionToCatchUpIn1MsVertical = mVerticalCatchupConstant;
-
-            fractionToCatchUpIn1MsHorizontal /= 33f;
-            fractionToCatchUpIn1MsVertical /= 33f;
-
-            final float UPDATE_THRESHOLD = 0.00001f;
-            float hOffsetDelta = mFinalHorizontalWallpaperOffset - mHorizontalWallpaperOffset;
-            float vOffsetDelta = mFinalVerticalWallpaperOffset - mVerticalWallpaperOffset;
-            boolean jumpToFinalValue = Math.abs(hOffsetDelta) < UPDATE_THRESHOLD &&
-                Math.abs(vOffsetDelta) < UPDATE_THRESHOLD;
-
-            // Don't have any lag between workspace and wallpaper on non-large devices
-            if (!LauncherAppState.getInstance().isScreenLarge() || jumpToFinalValue) {
-                mHorizontalWallpaperOffset = mFinalHorizontalWallpaperOffset;
-                mVerticalWallpaperOffset = mFinalVerticalWallpaperOffset;
-            } else {
-                float percentToCatchUpVertical =
-                    Math.min(1.0f, timeSinceLastUpdate * fractionToCatchUpIn1MsVertical);
-                float percentToCatchUpHorizontal =
-                    Math.min(1.0f, timeSinceLastUpdate * fractionToCatchUpIn1MsHorizontal);
-                mHorizontalWallpaperOffset += percentToCatchUpHorizontal * hOffsetDelta;
-                mVerticalWallpaperOffset += percentToCatchUpVertical * vOffsetDelta;
+                mCurrentOffset = mFinalOffset;
             }
 
-            mLastWallpaperOffsetUpdateTime = System.currentTimeMillis();
-            return true;
+            if (Math.abs(oldOffset - mCurrentOffset) > 0.0000001f) {
+                scheduleCallback();
+                return true;
+            }
+            return false;
         }
 
         public float getCurrX() {
-            return mHorizontalWallpaperOffset;
+            return mCurrentOffset;
         }
 
         public float getFinalX() {
-            return mFinalHorizontalWallpaperOffset;
+            return mFinalOffset;
         }
 
-        public float getCurrY() {
-            return mVerticalWallpaperOffset;
-        }
-
-        public float getFinalY() {
-            return mFinalVerticalWallpaperOffset;
+        private void animateToFinal() {
+            mAnimating = true;
+            mAnimationStartOffset = mCurrentOffset;
+            mAnimationStartTime = System.currentTimeMillis();
         }
 
         public void setFinalX(float x) {
-            mFinalHorizontalWallpaperOffset = Math.max(0f, Math.min(x, 1.0f));
+            scheduleCallback();
+            mFinalOffset = Math.max(0f, Math.min(x, 1.0f));
+            if (getChildCount() != mNumScreens) {
+                if (mNumScreens > 0) {
+                    // Don't animate if we're going from 0 screens
+                    animateToFinal();
+                }
+                mNumScreens = getChildCount();
+            }
         }
 
-        public void setFinalY(float y) {
-            mFinalVerticalWallpaperOffset = Math.max(0f, Math.min(y, 1.0f));
+        private void scheduleCallback() {
+            if (!mWaitingForCallback) {
+                mChoreographer.postFrameCallback(this);
+                mWaitingForCallback = true;
+            }
         }
 
         public void jumpToFinal() {
-            mHorizontalWallpaperOffset = mFinalHorizontalWallpaperOffset;
-            mVerticalWallpaperOffset = mFinalVerticalWallpaperOffset;
+            mCurrentOffset = mFinalOffset;
         }
     }
 
@@ -1103,6 +1055,10 @@
         syncWallpaperOffsetWithScroll();
     }
 
+    private void syncWallpaperOffsetWithScroll() {
+        mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
+    }
+
     void showOutlines() {
         if (!isSmall() && !mIsSwitchingState) {
             if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel();
@@ -1339,15 +1295,14 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
-            mUpdateWallpaperOffsetImmediately = true;
+            syncWallpaperOffsetWithScroll();
+            mWallpaperOffset.jumpToFinal();
         }
         super.onLayout(changed, left, top, right, bottom);
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
-        updateWallpaperOffsets();
-
         // Draw the background gradient if necessary
         if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) {
             int alpha = (int) (mBackgroundAlpha * 255);
@@ -1899,7 +1854,6 @@
     @Override
     public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
         mIsSwitchingState = false;
-        mWallpaperOffset.setOverrideHorizontalCatchupConstant(false);
         updateChildrenLayersEnabled(false);
         // The code in getChangeStateAnimation to determine initialAlpha and finalAlpha will ensure
         // ensure that only the current page is visible during (and subsequently, after) the
@@ -2057,8 +2011,6 @@
     }
 
     public void beginDragShared(View child, DragSource source) {
-        Resources r = getResources();
-
         // The drag bitmap follows the touch point around on the screen
         final Bitmap b = createDragBitmap(child, new Canvas(), DRAG_BITMAP_PADDING);