From caf24fc2c4bb9747eb80138bf3ce0be067851749 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Tue, 10 Sep 2013 18:37:01 -0700 Subject: [PATCH] Add camera affordance to navigation bar on phones This adds a camera button on phones that can be used to show and launch the camera. - Minor refactoring of touch event dispatch in PagedView. - Disables usability hints when keyguard loads. - Only add a touch handler for camera icon once during layout. - Update after review. - Updated with latest UX camera and camera background assets Change-Id: I09cd5cb0e501fd0f4659bea96d00c92b07f805c4 --- .../internal/policy/IKeyguardService.aidl | 3 + .../drawable-hdpi/kg_widget_bg_padded.9.png | Bin 3272 -> 591 bytes .../drawable-mdpi/kg_widget_bg_padded.9.png | Bin 3149 -> 535 bytes .../drawable-xhdpi/kg_widget_bg_padded.9.png | Bin 3474 -> 621 bytes .../drawable-xxhdpi/kg_widget_bg_padded.9.png | Bin 0 -> 1163 bytes .../android/keyguard/KeyguardHostView.java | 5 + .../com/android/keyguard/KeyguardService.java | 5 + .../android/keyguard/KeyguardViewManager.java | 7 + .../keyguard/KeyguardViewMediator.java | 14 ++ .../keyguard/KeyguardViewStateManager.java | 16 +- .../android/keyguard/KeyguardWidgetPager.java | 33 +++ .../src/com/android/keyguard/PagedView.java | 220 ++++++++++++------ packages/SystemUI/AndroidManifest.xml | 5 +- .../res/drawable-hdpi/ic_sysbar_camera.png | Bin 0 -> 1988 bytes .../res/drawable-mdpi/ic_sysbar_camera.png | Bin 0 -> 1406 bytes .../res/drawable-xhdpi/ic_sysbar_camera.png | Bin 0 -> 2596 bytes .../res/drawable-xxhdpi/ic_sysbar_camera.png | Bin 0 -> 2885 bytes .../SystemUI/res/layout/navigation_bar.xml | 35 ++- .../phone/KeyguardTouchDelegate.java | 106 +++++++++ .../phone/NavigationBarTransitions.java | 1 + .../statusbar/phone/NavigationBarView.java | 76 +++++- .../keyguard/KeyguardServiceDelegate.java | 6 +- .../impl/keyguard/KeyguardServiceWrapper.java | 5 + 23 files changed, 454 insertions(+), 83 deletions(-) create mode 100644 packages/Keyguard/res/drawable-xxhdpi/kg_widget_bg_padded.9.png create mode 100644 packages/SystemUI/res/drawable-hdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_camera.png create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index d1f7fa3b2394a..dd2e0066a0368 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -15,6 +15,8 @@ */ package com.android.internal.policy; +import android.view.MotionEvent; + import com.android.internal.policy.IKeyguardShowCallback; import com.android.internal.policy.IKeyguardExitCallback; @@ -39,4 +41,5 @@ interface IKeyguardService { oneway void doKeyguardTimeout(in Bundle options); oneway void setCurrentUser(int userId); oneway void showAssistant(); + oneway void dispatch(in MotionEvent event); } diff --git a/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-hdpi/kg_widget_bg_padded.9.png index dff1dfaf9d27a648c5c9c25260f8548e0b4847d6..c697f44f94a8dc0a762472c1d329cbb91df7af0f 100644 GIT binary patch literal 591 zcmeAS@N?(olHy`uVBq!ia0vp@K+MO%1|+}KPrC%9SkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffz zx4R3&e-K=-cll(X2xoyuWHFHT0Ash4*>*tV-Lp07$owV1B*-@l*|IE9x<(;l| z2TWf6sbuG#oiTg+MqZCqdpzTubXY#h9=W8Ov*_rFQ%9fNIFrO8{HT$8y7BijbE+j& z3}yIi9k$<=4G%3fp6loBxo_R;m`iDjoa&qpcq~|zE-=_0_$Vz`QFhMu=dN|!4_GwL ztPxL^VPtpsvA9q5sb3IZ%reJ~tZCC)1@5smH-6rHbB)KIWcD*>nCJUmj`{JkrjB>d zaS7vZhfhsU{mC#zvE}Q$MQ8M~`rh@9OO=rJ&CA`kgt@>Mc-_nz{ zfc434C4awt4YzGfc?(j~jEvvk=@0g75xAzv!oJ5(ZF1@FUcN@b4-@rn-0^o{Eol%} z*w$|MwwSMH@{Xrg2V_6oD7ycJr>1mfl-71&n5mYyMwFx^mZVxG7o`Fz1|tJQV_gGF zT|KJ?Go1=Ju3vLQG>t)x7$D3!r6 iB|j-u!8128JvAsbF{QHbWGX0P89ZJ6T-G@yGywqhj@JVK literal 3272 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 b6Vp?JQWH}u3s0tkB8b7$)z4*}Q$iB}YBa-* literal 3149 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 AI{*Lx diff --git a/packages/Keyguard/res/drawable-xxhdpi/kg_widget_bg_padded.9.png b/packages/Keyguard/res/drawable-xxhdpi/kg_widget_bg_padded.9.png new file mode 100644 index 0000000000000000000000000000000000000000..8d31feea4618b91678badd6cfd5ec819810a0e57 GIT binary patch literal 1163 zcmbVMU1-x>7!J0|oKE}@{F&l+j0m6D=C{q#xNbI0rXA}nUC}ZTOp~)UZ22)c``Q&z zQHO{k-iYAU5Cj?iO%N0jCl1sLue?zaRPaJj6z_H+%#*F1UJNe`NzOTM-sgG$b0*ij zyQR6cnIMRk%pN6=*H-*&YFdWh$JX3>iI)vXEuubW097;(5-GzeL6EVuL70b{F?#qp zY$u3N*(?-MG20{QjzwvK4pp^Wj3$Wo&Z?{FLlA)y95n4D`R&0Y5|~Dk+#k;}SvL*K z=AN1d`)a)fy*8vL46?HWv{xleU_qpTsx@r;QZ-4=@k)3fh-nhcsi2`GIqy_4n*(Xb zgCI`vQJrB~AP5v2iwgo90UX0}G=py;%EqL)AaQM=ev#OkXADSrrK@fWpOR!5Ay=a5 zN~J)<#*0IVTu~OQD8gjgX;|w=C zAXj#f}+RU!OVB9iC~K-g|teb@lAY z4XZ+zcU^C~bE2iwkl`*db3_&sFQUgf5I=)_MS!g-JY literal 0 HcmV?d00001 diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java index fbe3a9c59e859..07872863e983d 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java @@ -1650,4 +1650,9 @@ public class KeyguardHostView extends KeyguardViewBase { mActivityLauncher.launchActivityWithAnimation( intent, false, opts.toBundle(), null, null); } + + public void dispatch(MotionEvent event) { + mAppWidgetContainer.handleExternalCameraEvent(event); + } + } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java index a70e5bdc44d8f..77006c5fef83e 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java @@ -28,6 +28,7 @@ import android.os.Bundle; import android.os.Debug; import android.os.IBinder; import android.util.Log; +import android.view.MotionEvent; import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.IKeyguardExitCallback; @@ -132,6 +133,10 @@ public class KeyguardService extends Service { checkPermission(); mKeyguardViewMediator.showAssistant(); } + public void dispatch(MotionEvent event) { + checkPermission(); + mKeyguardViewMediator.dispatch(event); + } }; } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java index 35bea268b836a..483745848f28c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java @@ -38,6 +38,7 @@ import android.util.Slog; import android.util.SparseArray; import android.view.KeyEvent; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewManager; @@ -425,4 +426,10 @@ public class KeyguardViewManager { mKeyguardView.showAssistant(); } } + + public void dispatch(MotionEvent event) { + if (mKeyguardView != null) { + mKeyguardView.dispatch(event); + } + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java index e746f72f22361..478096cc0acb5 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java @@ -49,6 +49,7 @@ import android.util.EventLog; import android.util.Log; import android.util.Slog; import android.view.KeyEvent; +import android.view.MotionEvent; import android.view.WindowManager; import android.view.WindowManagerPolicy; @@ -120,6 +121,7 @@ public class KeyguardViewMediator { private static final int SET_HIDDEN = 12; private static final int KEYGUARD_TIMEOUT = 13; private static final int SHOW_ASSISTANT = 14; + private static final int DISPATCH_EVENT = 15; /** * The default amount of time we stay awake (used for all key input) @@ -1066,6 +1068,9 @@ public class KeyguardViewMediator { case SHOW_ASSISTANT: handleShowAssistant(); break; + case DISPATCH_EVENT: + handleDispatchEvent((MotionEvent) msg.obj); + break; } } }; @@ -1102,6 +1107,10 @@ public class KeyguardViewMediator { sendUserPresentBroadcast(); } + protected void handleDispatchEvent(MotionEvent event) { + mKeyguardViewManager.dispatch(event); + } + private void sendUserPresentBroadcast() { final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser()); mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser); @@ -1327,4 +1336,9 @@ public class KeyguardViewMediator { public static MultiUserAvatarCache getAvatarCache() { return sMultiUserAvatarCache; } + + public void dispatch(MotionEvent event) { + Message msg = mHandler.obtainMessage(DISPATCH_EVENT, event); + mHandler.sendMessage(msg); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java index e85f6dfeff67c..0539e827113de 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java @@ -23,6 +23,7 @@ public class KeyguardViewStateManager implements SlidingChallengeLayout.OnChallengeScrolledListener, ChallengeLayout.OnBouncerStateChangedListener { + private static final int WARP_FADE_DURATION = 250; private KeyguardWidgetPager mKeyguardWidgetPager; private ChallengeLayout mChallengeLayout; private KeyguardHostView mKeyguardHostView; @@ -32,6 +33,7 @@ public class KeyguardViewStateManager implements private KeyguardSecurityView mKeyguardSecurityContainer; private static final int SCREEN_ON_HINT_DURATION = 1000; private static final int SCREEN_ON_RING_HINT_DELAY = 300; + private static final boolean SHOW_INITIAL_PAGE_HINTS = false; Handler mMainQueue = new Handler(Looper.myLooper()); int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE; @@ -167,6 +169,16 @@ public class KeyguardViewStateManager implements mCurrentPage = newPageIndex; } + public void onPageBeginWarp() { + // fadeOutSecurity(WARP_FADE_DURATION); + // mKeyguardWidgetPager.showNonWarpViews(WARP_FADE_DURATION, false); + } + + public void onPageEndWarp() { + // fadeInSecurity(WARP_FADE_DURATION); + // mKeyguardWidgetPager.showNonWarpViews(WARP_FADE_DURATION, true); + } + private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) { mTmpPoint[0] = 0; mTmpPoint[1] = top; @@ -296,7 +308,9 @@ public class KeyguardViewStateManager implements mKeyguardSecurityContainer.showUsabilityHint(); } } , SCREEN_ON_RING_HINT_DELAY); - mKeyguardWidgetPager.showInitialPageHints(); + if (SHOW_INITIAL_PAGE_HINTS) { + mKeyguardWidgetPager.showInitialPageHints(); + } if (mHideHintsRunnable != null) { mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION); } diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java index c5664571df6e8..8d2f21b3c20d3 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java @@ -185,6 +185,16 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit } } + @Override + public void onPageBeginWarp() { + mViewStateManager.onPageBeginWarp(); + } + + @Override + public void onPageEndWarp() { + mViewStateManager.onPageEndWarp(); + } + @Override public void sendAccessibilityEvent(int eventType) { if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) { @@ -923,4 +933,27 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit return flags; } + + public void handleExternalCameraEvent(MotionEvent event) { + beginCameraEvent(); + int cameraPage = getPageCount() - 1; + boolean endWarp = false; + if (isCameraPage(cameraPage)) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + userActivity(); + startWarp(cameraPage); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + endWarp = true; + break; + } + dispatchTouchEvent(event); + // This has to happen after the event has been handled by the real widget pager + if (endWarp) endWarp(); + } + endCameraEvent(); + } + } diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java index 881d14d8e5ff7..cbf7946ab6ab7 100644 --- a/packages/Keyguard/src/com/android/keyguard/PagedView.java +++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java @@ -62,6 +62,7 @@ import java.util.ArrayList; public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener { private static final String TAG = "WidgetPagedView"; private static final boolean DEBUG = false; + private static final boolean DEBUG_WARP = false; protected static final int INVALID_PAGE = -1; // the min drag distance for a fling to register, to prevent random page shifts @@ -130,6 +131,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected final static int TOUCH_STATE_REORDERING = 4; protected final static float ALPHA_QUANTIZE_LEVEL = 0.0001f; + protected final static float TOUCH_SLOP_SCALE = 1.0f; protected int mTouchState = TOUCH_STATE_REST; protected boolean mForceScreenScrolled = false; @@ -250,6 +252,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc // Bouncer private boolean mTopAlignPageWhenShrinkingForBouncer = false; + // Page warping + private int mPageSwapIndex = -1; + private boolean mIsCameraEvent; + public interface PageSwitchListener { void onPageSwitching(View newPage, int newPageIndex); void onPageSwitched(View newPage, int newPageIndex); @@ -469,15 +475,26 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } protected void pageBeginMoving() { + if (DEBUG_WARP) Log.v(TAG, "pageBeginMoving(" + mIsPageMoving + ")"); if (!mIsPageMoving) { mIsPageMoving = true; + if (mPageSwapIndex != -1) { + onPageBeginWarp(); + swapPages(mPageSwapIndex, getPageCount() - 1); + } onPageBeginMoving(); } } protected void pageEndMoving() { + if (DEBUG_WARP) Log.v(TAG, "pageEndMoving(" + mIsPageMoving + ")"); if (mIsPageMoving) { mIsPageMoving = false; + if (mPageSwapIndex != -1) { + swapPages(mPageSwapIndex, getPageCount() - 1); + onPageEndWarp(); + mPageSwapIndex = -1; + } onPageEndMoving(); } } @@ -737,6 +754,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc setHorizontalScrollBarEnabled(true); mFirstLayout = false; } + // 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); + } } protected void screenScrolled(int screenCenter) { @@ -1071,7 +1093,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc * whether the user has moved far enough from his original down touch. */ if (mActivePointerId != INVALID_POINTER) { - determineScrollingStart(ev); + if (mIsCameraEvent || determineScrollingStart(ev)) { + startScrolling(ev); + } break; } // if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN @@ -1082,27 +1106,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } case MotionEvent.ACTION_DOWN: { - final float x = ev.getX(); - final float y = ev.getY(); - // Remember location of down touch - mDownMotionX = x; - mDownMotionY = y; - mDownScrollX = getScrollX(); - mLastMotionX = x; - mLastMotionY = y; - float[] p = mapPointFromViewToParent(this, x, y); - mParentDownMotionX = p[0]; - mParentDownMotionY = p[1]; - mLastMotionXRemainder = 0; - mTotalMotionX = 0; - mActivePointerId = ev.getPointerId(0); - - // Determine if the down event is within the threshold to be an edge swipe - int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize; - int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize; - if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) { - mDownEventOnEdge = true; - } + // Remember where the motion event started + saveDownState(ev); /* * If being flinged and user touches the screen, initiate drag; @@ -1112,25 +1117,29 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX()); final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop); if (finishedScrolling) { - mTouchState = TOUCH_STATE_REST; + setTouchState(TOUCH_STATE_REST); mScroller.abortAnimation(); } else { - if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) { - mTouchState = TOUCH_STATE_SCROLLING; + if (mIsCameraEvent || isTouchPointInViewportWithBuffer( + (int) mDownMotionX, (int) mDownMotionY)) { + setTouchState(TOUCH_STATE_SCROLLING); } else { - mTouchState = TOUCH_STATE_REST; + setTouchState(TOUCH_STATE_REST); } } // check if this can be the beginning of a tap on the side of the pages // to scroll the current page if (!DISABLE_TOUCH_SIDE_PAGES) { - if (mTouchState != TOUCH_STATE_PREV_PAGE && mTouchState != TOUCH_STATE_NEXT_PAGE) { + if (mTouchState != TOUCH_STATE_PREV_PAGE + && mTouchState != TOUCH_STATE_NEXT_PAGE) { if (getChildCount() > 0) { + float x = ev.getX(); + float y = ev.getY(); if (hitsPreviousPage(x, y)) { - mTouchState = TOUCH_STATE_PREV_PAGE; + setTouchState(TOUCH_STATE_PREV_PAGE); } else if (hitsNextPage(x, y)) { - mTouchState = TOUCH_STATE_NEXT_PAGE; + setTouchState(TOUCH_STATE_NEXT_PAGE); } } } @@ -1160,48 +1169,85 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc return mTouchState != TOUCH_STATE_REST; } - protected void determineScrollingStart(MotionEvent ev) { - determineScrollingStart(ev, 1.0f); + private void setTouchState(int touchState) { + if (mTouchState != touchState) { + onTouchStateChanged(touchState); + mTouchState = touchState; + } + } + + void onTouchStateChanged(int newTouchState) { + if (DEBUG) { + Log.v(TAG, "onTouchStateChanged(old="+ mTouchState + ", new=" + newTouchState + ")"); + } + } + + /** + * Save the state when we get {@link MotionEvent#ACTION_DOWN} + * @param ev + */ + private void saveDownState(MotionEvent ev) { + // Remember where the motion event started + mDownMotionX = mLastMotionX = ev.getX(); + mDownMotionY = mLastMotionY = ev.getY(); + mDownScrollX = getScrollX(); + float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); + mParentDownMotionX = p[0]; + mParentDownMotionY = p[1]; + mLastMotionXRemainder = 0; + mTotalMotionX = 0; + mActivePointerId = ev.getPointerId(0); + + // Determine if the down event is within the threshold to be an edge swipe + int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize; + int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize; + if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) { + mDownEventOnEdge = true; + } } /* * Determines if we should change the touch state to start scrolling after the * user moves their touch point too far. */ - protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) { + protected boolean determineScrollingStart(MotionEvent ev) { // Disallow scrolling if we don't have a valid pointer index final int pointerIndex = ev.findPointerIndex(mActivePointerId); - if (pointerIndex == -1) return; + if (pointerIndex == -1) return false; // Disallow scrolling if we started the gesture from outside the viewport final float x = ev.getX(pointerIndex); final float y = ev.getY(pointerIndex); - if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return; + if (!isTouchPointInViewportWithBuffer((int) x, (int) y)) return false; // If we're only allowing edge swipes, we break out early if the down event wasn't // at the edge. - if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return; + if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return false; final int xDiff = (int) Math.abs(x - mLastMotionX); final int yDiff = (int) Math.abs(y - mLastMotionY); - final int touchSlop = Math.round(touchSlopScale * mTouchSlop); + final int touchSlop = Math.round(TOUCH_SLOP_SCALE * mTouchSlop); boolean xPaged = xDiff > mPagingTouchSlop; boolean xMoved = xDiff > touchSlop; boolean yMoved = yDiff > touchSlop; - if (xMoved || xPaged || yMoved) { - if (mUsePagingTouchSlop ? xPaged : xMoved) { - // Scroll if the user moved far enough along the X axis - mTouchState = TOUCH_STATE_SCROLLING; - mTotalMotionX += Math.abs(mLastMotionX - x); - mLastMotionX = x; - mLastMotionXRemainder = 0; - mTouchX = getViewportOffsetX() + getScrollX(); - mSmoothingTime = System.nanoTime() / NANOTIME_DIV; - pageBeginMoving(); - } - } + return (xMoved || xPaged || yMoved) && (mUsePagingTouchSlop ? xPaged : xMoved); + } + + private void startScrolling(MotionEvent ev) { + // Ignore if we don't have a valid pointer index + final int pointerIndex = ev.findPointerIndex(mActivePointerId); + if (pointerIndex == -1) return; + + final float x = ev.getX(pointerIndex); + setTouchState(TOUCH_STATE_SCROLLING); + mTotalMotionX += Math.abs(mLastMotionX - x); + mLastMotionX = x; + mLastMotionXRemainder = 0; + mTouchX = getViewportOffsetX() + getScrollX(); + mSmoothingTime = System.nanoTime() / NANOTIME_DIV; + pageBeginMoving(); } protected float getMaxScrollProgress() { @@ -1322,22 +1368,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } // Remember where the motion event started - mDownMotionX = mLastMotionX = ev.getX(); - mDownMotionY = mLastMotionY = ev.getY(); - mDownScrollX = getScrollX(); - float[] p = mapPointFromViewToParent(this, mLastMotionX, mLastMotionY); - mParentDownMotionX = p[0]; - mParentDownMotionY = p[1]; - mLastMotionXRemainder = 0; - mTotalMotionX = 0; - mActivePointerId = ev.getPointerId(0); - - // Determine if the down event is within the threshold to be an edge swipe - int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize; - int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize; - if ((mDownMotionX <= leftEdgeBoundary || mDownMotionX >= rightEdgeBoundary)) { - mDownEventOnEdge = true; - } + saveDownState(ev); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); @@ -1479,8 +1510,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc removeCallbacks(mSidePageHoverRunnable); mSidePageHoverIndex = -1; } - } else { - determineScrollingStart(ev); + } else if (mIsCameraEvent || determineScrollingStart(ev)) { + startScrolling(ev); } break; @@ -1604,7 +1635,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc private void resetTouchState() { releaseVelocityTracker(); endReordering(); - mTouchState = TOUCH_STATE_REST; + setTouchState(TOUCH_STATE_REST); mActivePointerId = INVALID_POINTER; mDownEventOnEdge = false; } @@ -1821,8 +1852,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc protected void snapToPage(int whichPage, int delta, int duration) { snapToPage(whichPage, delta, duration, false); } + protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) { - mNextPage = whichPage; + if (mPageSwapIndex != -1 && whichPage == mPageSwapIndex) { + // jump to the last page + mNextPage = getPageCount() - 1; + if (DEBUG_WARP) Log.v(TAG, "snapToPage(" + whichPage + ") : reset mPageSwapIndex"); + mPageSwapIndex = -1; + } else { + mNextPage = whichPage; + } + notifyPageSwitching(whichPage); View focusedChild = getFocusedChild(); if (focusedChild != null && whichPage != mCurrentPage && @@ -2102,7 +2142,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc } // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.) - mTouchState = TOUCH_STATE_REORDERING; + setTouchState(TOUCH_STATE_REORDERING); mIsReordering = true; // Mark all the non-widget pages as invisible @@ -2564,4 +2604,46 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc public boolean onHoverEvent(android.view.MotionEvent event) { return true; } + + void beginCameraEvent() { + mIsCameraEvent = true; + } + + void endCameraEvent() { + mIsCameraEvent = false; + } + + /** + * Swaps the position of the views by setting the left and right edges appropriately. + */ + void swapPages(int indexA, int indexB) { + View viewA = getPageAt(indexA); + View viewB = getPageAt(indexB); + if (viewA != viewB && viewA != null && viewB != null) { + int deltaX = viewA.getLeft() - viewB.getLeft(); + viewA.offsetLeftAndRight(-deltaX); + viewB.offsetLeftAndRight(deltaX); + } + } + + public void startWarp(int pageIndex) { + if (DEBUG_WARP) Log.v(TAG, "START WARP"); + if (pageIndex != mCurrentPage + 1) { + mPageSwapIndex = mCurrentPage + 1; + } + } + + public void endWarp() { + if (DEBUG_WARP) Log.v(TAG, "END WARP"); + // mPageSwapIndex is reset in snapToPage() after the scroll animation completes + } + + public void onPageBeginWarp() { + + } + + public void onPageEndWarp() { + + } + } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index fa5c769077677..fb73d397f970d 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -52,7 +52,7 @@ - + @@ -68,6 +68,9 @@ + + + qL51|zlqrp+j7Yze7BT}qP5}|4#%w| zRDMh`rcN%&C5a!ZjV>-M z>gXj$irn|0kn))4pwE(n0>i=G0f75i%Bw+&@*EcJ<+2Y{_vlT@6HKtHmpcH7CICQb z04&Q(&?Eq{cmSqp0NCXMpv}&IZb7#aJ z`ILa_=x~_%cIM{s+dfVk+f!Haqi5Y;T3PVGTC-x4!3lUWnJUpug}cHyYX{f2o5Wq*{j6I zEhRwUzz?VB$7{rIUR1nY*HI38jtB$>2y@C&5-J$EDNO84+m6pg_`>tyfnOh=Cx-0( z2%mt9CIFJhJK$AIMrPN_fFlbi&JA%*T z9sSp_=mJ-Zb!$n`i&`@&nr1qevkUzKP9+7HI6mE5mHkR+Ily&pcgGm!eUDz9orQ$Z z8}Ti1wrmf&LCN1Nth^=(=^q4X>*T@isWd3(t}j)zq6GFxAkiY#5|dX24~4IAuZwXs z^*QWt<}vVE=_K$)DCd5i79C@ zZ(1&!8$*1pzoJ@yBvbaqG918kmFo1*f=oO#A7GTu=qZ znoOrv7Zu9O`%kyf?xgCnm7{c<49L5*9wSMA4A*UywJ3KoaSl5zJ?6Rbh0Uid4a&E=_`)cr=-ii7>0wp;juJ36n{8nIzn zrD&t?%X_{q3vV6lzs&!km~5kT1$#1yJh@j_9SWqTk9>|NPsS9)P8Z%RHIRKim0}SYUCmE8J>M}8Jq_9MY`fH~$CN^{^pX0#R{9e$A$S*=V7u`T@fh5M zW}b*SRCj42;ET+UI)a^YEbWh_wi}BK!|2!QiN?u?#d=ChkS`3+_+DH3lnY3Uw*0{7 zV}8Aw<+!N?YOP@D${m^LK>yV3-Y^*SDyd`sw&E&||BYkB-lm25PRC-_8F#BwZZAnj z;ejvV(7m&|thH9M#*vjBt36M9sMww|QakL%l^H@ZVCA-9L05yEW7 zPNW%_2p<_WN9k)bck5-=ozEZ$U6QrS<6!p+g7yE>7Fa_W+^Xig7l!IdSyCP@V;e>} zA|g|*xm*FT6L{M+d)>w7Qlw5lHeF;jY6w-%H?_c1GTZQF;LPRGzBJC0o1}#FRlgPC z)6IzH-Y|stAgpC0cR}g>r8F>{Wp3pR# z0dwb41NcU*ir$f3eK;`qGrX;*<1MYvsdI2inDV%6r9(Ti6J0N<)5ouX)TAw?>$5v$Z2`gc}H zW5MPuSa0ZS&11RxCX*$vzxkub*m`kMs{4Wj#>8qtmzp|hJ=Zvl((ggdD6Vh&^o7)R z9j#`H1qL4i^GA-iGL!zP@sC~>ilMgB`S|EN3z}`u#VT<^G<2S%w z#&=4srJfH~p|YlkK;ljYGi=V_LCB>#D!WqtJe-T@WuB&2@-rE#@oHqq{;)ge;~`Uf z1j;9wyoftSUfVNw024Dckw!06);V{pIRa8=qf2HQYFn>0#ACm`C$ddnL~t89T?JKm zeS4#sjR3jNOl&7p87H`oiOvp-%No{_YjzQdlapl`9&lO+JlB0;%$N7UecFZ>r{BWq zR{^5}74POkJbLRxKrOdO$T1l)Zp8A@S?^(oTHnkdW~CCR#LyPxscymzk zO4@HnOg^4889h*7*eLaJzA@e6Fy>3%Svbl6HoSjZO3?=Gn#O^$zjeW`YjSH@DcR}% z1#^yEsElKr{9{6bV(50kr|5D31iU5D0&iUYG&?!1_2w|O|W2liq47wLRC?tW?N&ls$ Nfa>JoSiO(N`w#9Qb_4(b literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..b76709870e819a2430d266887fdb4a81701e52cd GIT binary patch literal 1406 zcmZ8heK^wz9RF?e&O(hb(iA#*o3|}H$AgW{TUnA4Ha2nIc4mgimYbK5;t5%!)2gdf zB!sXcXW`0Q-i}lfvP|Wa8@qM)*WL4dKHtyt`Fx+x^ZDNxo|@Jnxf}!U;D&Hvp(FR+mx~5wdAS33em7i{3uGjLrGWfxT4Jt&!7&uuu34-vlnb4Jy;5YkkPfb>u`g$INug{Nkbb-E7}D?nSI z1n;>*JM)*ld^F2@=+^rTfB*A zyv?`QD8dg+4wOxZ*M&a9cA>fuJ-d7AHt)}I55w~a8?#N-!jR2BnlE3J?8O|A`{1cbeL$OAGH+x*LlIkk$Fbaa2vf*0CC#d z&6~b388_3>Gf^KKr71zuAI~TrH;>^7#3diV*3GL}TfILtA4aWQ4LuUp(5B|_9`SXY z6(`0LPnz=Ytz2x}YbrkPz~{-1a&nY^Y|gR79`h5`k;qQtuH>;m+1xk}o(XvmmWcHc1rS&m*bsf8P;R6F%)N;LjSm<}1C z#=z9kGiK@BcMC0btfZv9O6Ue|F~}<}PA#>21K%+W`oUY{3XsbQUsSBj=P)U*kn6Rb zMh{YaPmO(H3TxNkzEu{H5oG=(Q3igqj&j~Mez*rinCTX7M8uYCfhF)aJFjH9s!9_! zuZeu#9)K-dqT)AqaXg$*UA@I$k?mKi%_^T{fzf+ftENgN~6}er|z(XtFf9o{3|08pv+nY~2Hx|`6 zcVp^H!W6Yn=<3;D+D_f~%e_?wM6;-qFd6M^72E8c9y&x(zng0!F28SzS@9%x7O6CP zbj4r9>7_S)56N)vZ#`R~`%WBFsq}2f!ZNnIRu(kt5rGa0)UGbq7dY$Jt9=2dVx699 zxku+}`R8h3KU@1lQgecvo&|x9;TzI~v3W+Xj=sk8%9COHJ)~nOpIT?5=7FzIZq*1( z$_Nk@cJgvx??-ZoC{^dSGGxEwY{)Hv<$}#I zIH*N)bNhZk>b6#64c&HFHpAo;Ko5k?e?-dKUafSUB1ywX)*}$;#F#(AFO7Xot1OSfMaj6sjbw<nD9PF@;j{gQ2nLRt?0sU_chZ3WbS(GFi;6_c1pdpFzloK=(jY3WPNkseh2LU49 KA9u%{eEM%BlV&CW literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..ea93f1ae370ac37d9d55018c9ad05bb35e5f3b5e GIT binary patch literal 2596 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 qK(Ejn?4Ir4?;25S?V*du+`n{n5 literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_camera.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_camera.png new file mode 100644 index 0000000000000000000000000000000000000000..cda7d4b7dec94d4b7e0b0055369701d6fb0b1ef3 GIT binary patch literal 2885 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 literal 0 HcmV?d00001 diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml index 09923a7f7435d..0421910c541b3 100644 --- a/packages/SystemUI/res/layout/navigation_bar.xml +++ b/packages/SystemUI/res/layout/navigation_bar.xml @@ -145,15 +145,30 @@ /> - + + + + + + + +