Merge "Fit and finish for navbar camera affordance" into klp-dev
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
index 0539e82..d9f9471 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -23,7 +23,6 @@
         SlidingChallengeLayout.OnChallengeScrolledListener,
         ChallengeLayout.OnBouncerStateChangedListener {
 
-    private static final int WARP_FADE_DURATION = 250;
     private KeyguardWidgetPager mKeyguardWidgetPager;
     private ChallengeLayout mChallengeLayout;
     private KeyguardHostView mKeyguardHostView;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
index 8d2f21b..f7dc058 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -494,6 +494,9 @@
     }
 
     public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
+        if (getPageWarpIndex() != -1) {
+            return index == getPageWarpIndex() ? 1.0f : 0.0f;
+        }
         if (showSidePages) {
             return 1f;
         } else {
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
index cbf7946..b6279d0 100644
--- a/packages/Keyguard/src/com/android/keyguard/PagedView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -64,6 +64,8 @@
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_WARP = false;
     protected static final int INVALID_PAGE = -1;
+    private static final int WARP_PEEK_ANIMATION_DURATION = 250;
+    private static final float WARP_ANIMATE_AMOUNT = -40.0f; // in dip
 
     // the min drag distance for a fling to register, to prevent random page shifts
     private static final int MIN_LENGTH_FOR_FLING = 25;
@@ -253,8 +255,11 @@
     private boolean mTopAlignPageWhenShrinkingForBouncer = false;
 
     // Page warping
-    private int mPageSwapIndex = -1;
+    private int mPageSwapIndex = -1; // the page we swapped out if needed
+    private int mPageWarpIndex = -1; // the page we intend to warp
+
     private boolean mIsCameraEvent;
+    private float mWarpPeekAmount;
 
     public interface PageSwitchListener {
         void onPageSwitching(View newPage, int newPageIndex);
@@ -303,10 +308,10 @@
         mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mDensity = getResources().getDisplayMetrics().density;
+        mWarpPeekAmount = mDensity * WARP_ANIMATE_AMOUNT;
 
         // Scale the fling-to-delete threshold by the density
-        mFlingToDeleteThresholdVelocity =
-                (int) (mFlingToDeleteThresholdVelocity * mDensity);
+        mFlingToDeleteThresholdVelocity = (int) (mFlingToDeleteThresholdVelocity * mDensity);
 
         mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * mDensity);
         mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * mDensity);
@@ -478,9 +483,11 @@
         if (DEBUG_WARP) Log.v(TAG, "pageBeginMoving(" + mIsPageMoving + ")");
         if (!mIsPageMoving) {
             mIsPageMoving = true;
-            if (mPageSwapIndex != -1) {
+            if (mPageWarpIndex != -1) {
                 onPageBeginWarp();
-                swapPages(mPageSwapIndex, getPageCount() - 1);
+                if (mPageSwapIndex != -1) {
+                    swapPages(mPageSwapIndex, mPageWarpIndex);
+                }
             }
             onPageBeginMoving();
         }
@@ -490,15 +497,23 @@
         if (DEBUG_WARP) Log.v(TAG, "pageEndMoving(" + mIsPageMoving + ")");
         if (mIsPageMoving) {
             mIsPageMoving = false;
-            if (mPageSwapIndex != -1) {
-                swapPages(mPageSwapIndex, getPageCount() - 1);
+            if (mPageWarpIndex != -1) {
+                if (mPageSwapIndex != -1) {
+                    swapPages(mPageSwapIndex, mPageWarpIndex);
+                    resetPageWarp();
+                }
                 onPageEndWarp();
-                mPageSwapIndex = -1;
             }
             onPageEndMoving();
         }
     }
 
+    private void resetPageWarp() {
+        // TODO: Verify pages have been reset correctly
+        mPageSwapIndex = -1;
+        mPageWarpIndex = -1;
+    }
+
     protected boolean isPageMoving() {
         return mIsPageMoving;
     }
@@ -757,7 +772,7 @@
         // If a page was swapped when we rebuilt the layout, swap it again now.
         if (mPageSwapIndex  != -1) {
             if (DEBUG_WARP) Log.v(TAG, "onLayout: swapping pages");
-            swapPages(mPageSwapIndex, getPageCount() - 1);
+            swapPages(mPageSwapIndex, mPageWarpIndex);
         }
     }
 
@@ -1106,6 +1121,9 @@
             }
 
             case MotionEvent.ACTION_DOWN: {
+                if (mIsCameraEvent) {
+                    animateWarpPageOnScreen();
+                }
                 // Remember where the motion event started
                 saveDownState(ev);
 
@@ -1372,6 +1390,8 @@
 
             if (mTouchState == TOUCH_STATE_SCROLLING) {
                 pageBeginMoving();
+            } else {
+                animateWarpPageOnScreen();
             }
             break;
 
@@ -1855,14 +1875,17 @@
 
     protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
         if (mPageSwapIndex != -1 && whichPage == mPageSwapIndex) {
-            // jump to the last page
-            mNextPage = getPageCount() - 1;
+            mNextPage = mPageWarpIndex; // jump to the warp page
             if (DEBUG_WARP) Log.v(TAG, "snapToPage(" + whichPage + ") : reset mPageSwapIndex");
-            mPageSwapIndex = -1;
         } else {
             mNextPage = whichPage;
         }
 
+        if (mPageWarpIndex != -1) {
+            animateWarpPageOffScreen();
+            resetPageWarp();
+        }
+
         notifyPageSwitching(whichPage);
         View focusedChild = getFocusedChild();
         if (focusedChild != null && whichPage != mCurrentPage &&
@@ -2613,6 +2636,24 @@
         mIsCameraEvent = false;
     }
 
+    private void animateWarpPageOnScreen() {
+        if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOnScreen()");
+        if (mPageWarpIndex != -1) {
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+            if (DEBUG_WARP) Log.v(TAG, "moving page on screen: Tx=" + v.getTranslationX());
+            v.animate().translationX(mWarpPeekAmount).setDuration(WARP_PEEK_ANIMATION_DURATION);
+        }
+    }
+
+    private void animateWarpPageOffScreen() {
+        if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOffScreen()");
+        if (mPageWarpIndex != -1) {
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+            if (DEBUG_WARP) Log.v(TAG, "moving page off screen: Tx=" + v.getTranslationX());
+            v.animate().translationX(0.0f).setDuration(WARP_PEEK_ANIMATION_DURATION);
+        }
+    }
+
     /**
      * Swaps the position of the views by setting the left and right edges appropriately.
      */
@@ -2631,6 +2672,11 @@
         if (pageIndex != mCurrentPage + 1) {
             mPageSwapIndex = mCurrentPage + 1;
         }
+        mPageWarpIndex = pageIndex;
+    }
+
+    protected int getPageWarpIndex() {
+        return mPageWarpIndex;
     }
 
     public void endWarp() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
index 900e1e0..3a5524d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java
@@ -35,6 +35,7 @@
     RectF mInitialTouch = new RectF();
     private boolean mStarted;
     private boolean mSwapXY = false;
+    private boolean mDisabled;
 
     public DelegateViewHelper(View sourceView) {
         setSourceView(sourceView);
@@ -49,7 +50,7 @@
     }
 
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (mSourceView == null || mDelegateView == null
+        if (mSourceView == null || mDelegateView == null || mDisabled
                 || mBar.shouldDisableNavbarGestures()) {
             return false;
         }
@@ -142,4 +143,8 @@
     public void setSwapXY(boolean swap) {
         mSwapXY = swap;
     }
+
+    public void setDisabled(boolean disabled) {
+        mDisabled = disabled;
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 03f7fab..24e27b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -51,6 +51,7 @@
 import java.io.PrintWriter;
 
 public class NavigationBarView extends LinearLayout {
+    private static final int CAMERA_BUTTON_FADE_DURATION = 200;
     final static boolean DEBUG = false;
     final static String TAG = "PhoneStatusBar/NavigationBarView";
 
@@ -89,7 +90,26 @@
 
     private final OnTouchListener mCameraTouchListener = new OnTouchListener() {
         @Override
-        public boolean onTouch(View v, MotionEvent event) {
+        public boolean onTouch(View cameraButtonView, MotionEvent event) {
+            View searchLight = getSearchLight();
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    // disable search gesture while interacting with camera
+                    mDelegateHelper.setDisabled(true);
+                    cameraButtonView.animate().alpha(0.0f).setDuration(CAMERA_BUTTON_FADE_DURATION);
+                    if (searchLight != null) {
+                        searchLight.animate().alpha(0.0f).setDuration(CAMERA_BUTTON_FADE_DURATION);
+                    }
+                    break;
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    mDelegateHelper.setDisabled(false);
+                    cameraButtonView.animate().alpha(1.0f).setDuration(CAMERA_BUTTON_FADE_DURATION);
+                    if (searchLight != null) {
+                        searchLight.animate().alpha(1.0f).setDuration(CAMERA_BUTTON_FADE_DURATION);
+                    }
+                    break;
+            }
             return mTouchDelegate.dispatch(event);
         }
     };