Merge "Add camera affordance to navigation bar on phones" into klp-dev
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.internal.policy;
|
package com.android.internal.policy;
|
||||||
|
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.android.internal.policy.IKeyguardShowCallback;
|
import com.android.internal.policy.IKeyguardShowCallback;
|
||||||
import com.android.internal.policy.IKeyguardExitCallback;
|
import com.android.internal.policy.IKeyguardExitCallback;
|
||||||
|
|
||||||
@ -39,4 +41,5 @@ interface IKeyguardService {
|
|||||||
oneway void doKeyguardTimeout(in Bundle options);
|
oneway void doKeyguardTimeout(in Bundle options);
|
||||||
oneway void setCurrentUser(int userId);
|
oneway void setCurrentUser(int userId);
|
||||||
oneway void showAssistant();
|
oneway void showAssistant();
|
||||||
|
oneway void dispatch(in MotionEvent event);
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 591 B |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 621 B |
BIN
packages/Keyguard/res/drawable-xxhdpi/kg_widget_bg_padded.9.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
@ -1650,4 +1650,9 @@ public class KeyguardHostView extends KeyguardViewBase {
|
|||||||
mActivityLauncher.launchActivityWithAnimation(
|
mActivityLauncher.launchActivityWithAnimation(
|
||||||
intent, false, opts.toBundle(), null, null);
|
intent, false, opts.toBundle(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatch(MotionEvent event) {
|
||||||
|
mAppWidgetContainer.handleExternalCameraEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import android.os.Bundle;
|
|||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.android.internal.policy.IKeyguardService;
|
import com.android.internal.policy.IKeyguardService;
|
||||||
import com.android.internal.policy.IKeyguardExitCallback;
|
import com.android.internal.policy.IKeyguardExitCallback;
|
||||||
@ -132,6 +133,10 @@ public class KeyguardService extends Service {
|
|||||||
checkPermission();
|
checkPermission();
|
||||||
mKeyguardViewMediator.showAssistant();
|
mKeyguardViewMediator.showAssistant();
|
||||||
}
|
}
|
||||||
|
public void dispatch(MotionEvent event) {
|
||||||
|
checkPermission();
|
||||||
|
mKeyguardViewMediator.dispatch(event);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ import android.util.Slog;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewManager;
|
import android.view.ViewManager;
|
||||||
@ -425,4 +426,10 @@ public class KeyguardViewManager {
|
|||||||
mKeyguardView.showAssistant();
|
mKeyguardView.showAssistant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatch(MotionEvent event) {
|
||||||
|
if (mKeyguardView != null) {
|
||||||
|
mKeyguardView.dispatch(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import android.util.EventLog;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.WindowManagerPolicy;
|
import android.view.WindowManagerPolicy;
|
||||||
|
|
||||||
@ -120,6 +121,7 @@ public class KeyguardViewMediator {
|
|||||||
private static final int SET_HIDDEN = 12;
|
private static final int SET_HIDDEN = 12;
|
||||||
private static final int KEYGUARD_TIMEOUT = 13;
|
private static final int KEYGUARD_TIMEOUT = 13;
|
||||||
private static final int SHOW_ASSISTANT = 14;
|
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)
|
* The default amount of time we stay awake (used for all key input)
|
||||||
@ -1066,6 +1068,9 @@ public class KeyguardViewMediator {
|
|||||||
case SHOW_ASSISTANT:
|
case SHOW_ASSISTANT:
|
||||||
handleShowAssistant();
|
handleShowAssistant();
|
||||||
break;
|
break;
|
||||||
|
case DISPATCH_EVENT:
|
||||||
|
handleDispatchEvent((MotionEvent) msg.obj);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1102,6 +1107,10 @@ public class KeyguardViewMediator {
|
|||||||
sendUserPresentBroadcast();
|
sendUserPresentBroadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void handleDispatchEvent(MotionEvent event) {
|
||||||
|
mKeyguardViewManager.dispatch(event);
|
||||||
|
}
|
||||||
|
|
||||||
private void sendUserPresentBroadcast() {
|
private void sendUserPresentBroadcast() {
|
||||||
final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
|
final UserHandle currentUser = new UserHandle(mLockPatternUtils.getCurrentUser());
|
||||||
mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
|
mContext.sendBroadcastAsUser(USER_PRESENT_INTENT, currentUser);
|
||||||
@ -1327,4 +1336,9 @@ public class KeyguardViewMediator {
|
|||||||
public static MultiUserAvatarCache getAvatarCache() {
|
public static MultiUserAvatarCache getAvatarCache() {
|
||||||
return sMultiUserAvatarCache;
|
return sMultiUserAvatarCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatch(MotionEvent event) {
|
||||||
|
Message msg = mHandler.obtainMessage(DISPATCH_EVENT, event);
|
||||||
|
mHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ public class KeyguardViewStateManager implements
|
|||||||
SlidingChallengeLayout.OnChallengeScrolledListener,
|
SlidingChallengeLayout.OnChallengeScrolledListener,
|
||||||
ChallengeLayout.OnBouncerStateChangedListener {
|
ChallengeLayout.OnBouncerStateChangedListener {
|
||||||
|
|
||||||
|
private static final int WARP_FADE_DURATION = 250;
|
||||||
private KeyguardWidgetPager mKeyguardWidgetPager;
|
private KeyguardWidgetPager mKeyguardWidgetPager;
|
||||||
private ChallengeLayout mChallengeLayout;
|
private ChallengeLayout mChallengeLayout;
|
||||||
private KeyguardHostView mKeyguardHostView;
|
private KeyguardHostView mKeyguardHostView;
|
||||||
@ -32,6 +33,7 @@ public class KeyguardViewStateManager implements
|
|||||||
private KeyguardSecurityView mKeyguardSecurityContainer;
|
private KeyguardSecurityView mKeyguardSecurityContainer;
|
||||||
private static final int SCREEN_ON_HINT_DURATION = 1000;
|
private static final int SCREEN_ON_HINT_DURATION = 1000;
|
||||||
private static final int SCREEN_ON_RING_HINT_DELAY = 300;
|
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());
|
Handler mMainQueue = new Handler(Looper.myLooper());
|
||||||
|
|
||||||
int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
|
int mLastScrollState = SlidingChallengeLayout.SCROLL_STATE_IDLE;
|
||||||
@ -167,6 +169,16 @@ public class KeyguardViewStateManager implements
|
|||||||
mCurrentPage = newPageIndex;
|
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) {
|
private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
|
||||||
mTmpPoint[0] = 0;
|
mTmpPoint[0] = 0;
|
||||||
mTmpPoint[1] = top;
|
mTmpPoint[1] = top;
|
||||||
@ -296,7 +308,9 @@ public class KeyguardViewStateManager implements
|
|||||||
mKeyguardSecurityContainer.showUsabilityHint();
|
mKeyguardSecurityContainer.showUsabilityHint();
|
||||||
}
|
}
|
||||||
} , SCREEN_ON_RING_HINT_DELAY);
|
} , SCREEN_ON_RING_HINT_DELAY);
|
||||||
|
if (SHOW_INITIAL_PAGE_HINTS) {
|
||||||
mKeyguardWidgetPager.showInitialPageHints();
|
mKeyguardWidgetPager.showInitialPageHints();
|
||||||
|
}
|
||||||
if (mHideHintsRunnable != null) {
|
if (mHideHintsRunnable != null) {
|
||||||
mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
|
mMainQueue.postDelayed(mHideHintsRunnable, SCREEN_ON_HINT_DURATION);
|
||||||
}
|
}
|
||||||
|
@ -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
|
@Override
|
||||||
public void sendAccessibilityEvent(int eventType) {
|
public void sendAccessibilityEvent(int eventType) {
|
||||||
if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
|
if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
|
||||||
@ -923,4 +933,27 @@ public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwit
|
|||||||
|
|
||||||
return flags;
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ import java.util.ArrayList;
|
|||||||
public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
|
public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
|
||||||
private static final String TAG = "WidgetPagedView";
|
private static final String TAG = "WidgetPagedView";
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
private static final boolean DEBUG_WARP = false;
|
||||||
protected static final int INVALID_PAGE = -1;
|
protected static final int INVALID_PAGE = -1;
|
||||||
|
|
||||||
// the min drag distance for a fling to register, to prevent random page shifts
|
// 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 int TOUCH_STATE_REORDERING = 4;
|
||||||
|
|
||||||
protected final static float ALPHA_QUANTIZE_LEVEL = 0.0001f;
|
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 int mTouchState = TOUCH_STATE_REST;
|
||||||
protected boolean mForceScreenScrolled = false;
|
protected boolean mForceScreenScrolled = false;
|
||||||
@ -250,6 +252,10 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
// Bouncer
|
// Bouncer
|
||||||
private boolean mTopAlignPageWhenShrinkingForBouncer = false;
|
private boolean mTopAlignPageWhenShrinkingForBouncer = false;
|
||||||
|
|
||||||
|
// Page warping
|
||||||
|
private int mPageSwapIndex = -1;
|
||||||
|
private boolean mIsCameraEvent;
|
||||||
|
|
||||||
public interface PageSwitchListener {
|
public interface PageSwitchListener {
|
||||||
void onPageSwitching(View newPage, int newPageIndex);
|
void onPageSwitching(View newPage, int newPageIndex);
|
||||||
void onPageSwitched(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() {
|
protected void pageBeginMoving() {
|
||||||
|
if (DEBUG_WARP) Log.v(TAG, "pageBeginMoving(" + mIsPageMoving + ")");
|
||||||
if (!mIsPageMoving) {
|
if (!mIsPageMoving) {
|
||||||
mIsPageMoving = true;
|
mIsPageMoving = true;
|
||||||
|
if (mPageSwapIndex != -1) {
|
||||||
|
onPageBeginWarp();
|
||||||
|
swapPages(mPageSwapIndex, getPageCount() - 1);
|
||||||
|
}
|
||||||
onPageBeginMoving();
|
onPageBeginMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void pageEndMoving() {
|
protected void pageEndMoving() {
|
||||||
|
if (DEBUG_WARP) Log.v(TAG, "pageEndMoving(" + mIsPageMoving + ")");
|
||||||
if (mIsPageMoving) {
|
if (mIsPageMoving) {
|
||||||
mIsPageMoving = false;
|
mIsPageMoving = false;
|
||||||
|
if (mPageSwapIndex != -1) {
|
||||||
|
swapPages(mPageSwapIndex, getPageCount() - 1);
|
||||||
|
onPageEndWarp();
|
||||||
|
mPageSwapIndex = -1;
|
||||||
|
}
|
||||||
onPageEndMoving();
|
onPageEndMoving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -737,6 +754,11 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
setHorizontalScrollBarEnabled(true);
|
setHorizontalScrollBarEnabled(true);
|
||||||
mFirstLayout = false;
|
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) {
|
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.
|
* whether the user has moved far enough from his original down touch.
|
||||||
*/
|
*/
|
||||||
if (mActivePointerId != INVALID_POINTER) {
|
if (mActivePointerId != INVALID_POINTER) {
|
||||||
determineScrollingStart(ev);
|
if (mIsCameraEvent || determineScrollingStart(ev)) {
|
||||||
|
startScrolling(ev);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if mActivePointerId is INVALID_POINTER, then we must have missed an ACTION_DOWN
|
// 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: {
|
case MotionEvent.ACTION_DOWN: {
|
||||||
final float x = ev.getX();
|
// Remember where the motion event started
|
||||||
final float y = ev.getY();
|
saveDownState(ev);
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If being flinged and user touches the screen, initiate drag;
|
* 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 int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
|
||||||
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
|
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
|
||||||
if (finishedScrolling) {
|
if (finishedScrolling) {
|
||||||
mTouchState = TOUCH_STATE_REST;
|
setTouchState(TOUCH_STATE_REST);
|
||||||
mScroller.abortAnimation();
|
mScroller.abortAnimation();
|
||||||
} else {
|
} else {
|
||||||
if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
|
if (mIsCameraEvent || isTouchPointInViewportWithBuffer(
|
||||||
mTouchState = TOUCH_STATE_SCROLLING;
|
(int) mDownMotionX, (int) mDownMotionY)) {
|
||||||
|
setTouchState(TOUCH_STATE_SCROLLING);
|
||||||
} else {
|
} 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
|
// check if this can be the beginning of a tap on the side of the pages
|
||||||
// to scroll the current page
|
// to scroll the current page
|
||||||
if (!DISABLE_TOUCH_SIDE_PAGES) {
|
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) {
|
if (getChildCount() > 0) {
|
||||||
|
float x = ev.getX();
|
||||||
|
float y = ev.getY();
|
||||||
if (hitsPreviousPage(x, y)) {
|
if (hitsPreviousPage(x, y)) {
|
||||||
mTouchState = TOUCH_STATE_PREV_PAGE;
|
setTouchState(TOUCH_STATE_PREV_PAGE);
|
||||||
} else if (hitsNextPage(x, y)) {
|
} else if (hitsNextPage(x, y)) {
|
||||||
mTouchState = TOUCH_STATE_NEXT_PAGE;
|
setTouchState(TOUCH_STATE_NEXT_PAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1160,40 +1169,79 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
return mTouchState != TOUCH_STATE_REST;
|
return mTouchState != TOUCH_STATE_REST;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void determineScrollingStart(MotionEvent ev) {
|
private void setTouchState(int touchState) {
|
||||||
determineScrollingStart(ev, 1.0f);
|
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
|
* Determines if we should change the touch state to start scrolling after the
|
||||||
* user moves their touch point too far.
|
* 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
|
// Disallow scrolling if we don't have a valid pointer index
|
||||||
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
|
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
|
// Disallow scrolling if we started the gesture from outside the viewport
|
||||||
final float x = ev.getX(pointerIndex);
|
final float x = ev.getX(pointerIndex);
|
||||||
final float y = ev.getY(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
|
// If we're only allowing edge swipes, we break out early if the down event wasn't
|
||||||
// at the edge.
|
// at the edge.
|
||||||
if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return;
|
if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return false;
|
||||||
|
|
||||||
final int xDiff = (int) Math.abs(x - mLastMotionX);
|
final int xDiff = (int) Math.abs(x - mLastMotionX);
|
||||||
final int yDiff = (int) Math.abs(y - mLastMotionY);
|
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 xPaged = xDiff > mPagingTouchSlop;
|
||||||
boolean xMoved = xDiff > touchSlop;
|
boolean xMoved = xDiff > touchSlop;
|
||||||
boolean yMoved = yDiff > touchSlop;
|
boolean yMoved = yDiff > touchSlop;
|
||||||
|
|
||||||
if (xMoved || xPaged || yMoved) {
|
return (xMoved || xPaged || yMoved) && (mUsePagingTouchSlop ? xPaged : xMoved);
|
||||||
if (mUsePagingTouchSlop ? xPaged : xMoved) {
|
}
|
||||||
// Scroll if the user moved far enough along the X axis
|
|
||||||
mTouchState = TOUCH_STATE_SCROLLING;
|
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);
|
mTotalMotionX += Math.abs(mLastMotionX - x);
|
||||||
mLastMotionX = x;
|
mLastMotionX = x;
|
||||||
mLastMotionXRemainder = 0;
|
mLastMotionXRemainder = 0;
|
||||||
@ -1201,8 +1249,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
|
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
|
||||||
pageBeginMoving();
|
pageBeginMoving();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected float getMaxScrollProgress() {
|
protected float getMaxScrollProgress() {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
@ -1322,22 +1368,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remember where the motion event started
|
// Remember where the motion event started
|
||||||
mDownMotionX = mLastMotionX = ev.getX();
|
saveDownState(ev);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTouchState == TOUCH_STATE_SCROLLING) {
|
if (mTouchState == TOUCH_STATE_SCROLLING) {
|
||||||
pageBeginMoving();
|
pageBeginMoving();
|
||||||
@ -1479,8 +1510,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
removeCallbacks(mSidePageHoverRunnable);
|
removeCallbacks(mSidePageHoverRunnable);
|
||||||
mSidePageHoverIndex = -1;
|
mSidePageHoverIndex = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mIsCameraEvent || determineScrollingStart(ev)) {
|
||||||
determineScrollingStart(ev);
|
startScrolling(ev);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1604,7 +1635,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
private void resetTouchState() {
|
private void resetTouchState() {
|
||||||
releaseVelocityTracker();
|
releaseVelocityTracker();
|
||||||
endReordering();
|
endReordering();
|
||||||
mTouchState = TOUCH_STATE_REST;
|
setTouchState(TOUCH_STATE_REST);
|
||||||
mActivePointerId = INVALID_POINTER;
|
mActivePointerId = INVALID_POINTER;
|
||||||
mDownEventOnEdge = false;
|
mDownEventOnEdge = false;
|
||||||
}
|
}
|
||||||
@ -1821,8 +1852,17 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
|
|||||||
protected void snapToPage(int whichPage, int delta, int duration) {
|
protected void snapToPage(int whichPage, int delta, int duration) {
|
||||||
snapToPage(whichPage, delta, duration, false);
|
snapToPage(whichPage, delta, duration, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
|
protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
|
||||||
|
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;
|
mNextPage = whichPage;
|
||||||
|
}
|
||||||
|
|
||||||
notifyPageSwitching(whichPage);
|
notifyPageSwitching(whichPage);
|
||||||
View focusedChild = getFocusedChild();
|
View focusedChild = getFocusedChild();
|
||||||
if (focusedChild != null && whichPage != mCurrentPage &&
|
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.)
|
// Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
|
||||||
mTouchState = TOUCH_STATE_REORDERING;
|
setTouchState(TOUCH_STATE_REORDERING);
|
||||||
mIsReordering = true;
|
mIsReordering = true;
|
||||||
|
|
||||||
// Mark all the non-widget pages as invisible
|
// 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) {
|
public boolean onHoverEvent(android.view.MotionEvent event) {
|
||||||
return true;
|
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() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,9 @@
|
|||||||
<!-- Alarm clocks -->
|
<!-- Alarm clocks -->
|
||||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
||||||
|
|
||||||
|
<!-- Keyguard -->
|
||||||
|
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:persistent="true"
|
android:persistent="true"
|
||||||
android:allowClearUserData="false"
|
android:allowClearUserData="false"
|
||||||
|
BIN
packages/SystemUI/res/drawable-hdpi/ic_sysbar_camera.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
packages/SystemUI/res/drawable-mdpi/ic_sysbar_camera.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
packages/SystemUI/res/drawable-xhdpi/ic_sysbar_camera.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_camera.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
@ -145,16 +145,31 @@
|
|||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.android.systemui.statusbar.policy.KeyButtonView
|
<com.android.systemui.statusbar.policy.KeyButtonView
|
||||||
android:layout_width="80dp"
|
android:layout_width="80dp"
|
||||||
android:id="@+id/search_light"
|
android:id="@+id/search_light"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center"
|
||||||
android:src="@drawable/search_light"
|
android:src="@drawable/search_light"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<com.android.systemui.statusbar.policy.KeyButtonView
|
||||||
|
android:id="@+id/camera_button"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_gravity="center_vertical|right"
|
||||||
|
android:src="@drawable/ic_sysbar_camera"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<com.android.systemui.statusbar.policy.DeadZone
|
<com.android.systemui.statusbar.policy.DeadZone
|
||||||
android:id="@+id/deadzone"
|
android:id="@+id/deadzone"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -299,6 +314,8 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- No camera button in landscape mode -->
|
||||||
|
|
||||||
<com.android.systemui.statusbar.policy.DeadZone
|
<com.android.systemui.statusbar.policy.DeadZone
|
||||||
android:id="@+id/deadzone"
|
android:id="@+id/deadzone"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2013 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.statusbar.phone;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import com.android.internal.policy.IKeyguardExitCallback;
|
||||||
|
import com.android.internal.policy.IKeyguardShowCallback;
|
||||||
|
import com.android.internal.policy.IKeyguardService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Facilitates event communication between navigation bar and keyguard. Currently used to
|
||||||
|
* control WidgetPager in keyguard to expose the camera widget.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class KeyguardTouchDelegate {
|
||||||
|
// TODO: propagate changes to these to {@link KeyguardServiceDelegate}
|
||||||
|
static final String KEYGUARD_PACKAGE = "com.android.keyguard";
|
||||||
|
static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
|
||||||
|
|
||||||
|
IKeyguardService mService;
|
||||||
|
|
||||||
|
protected static final boolean DEBUG = false;
|
||||||
|
protected static final String TAG = "KeyguardTouchDelegate";
|
||||||
|
|
||||||
|
private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
Log.v(TAG, "Connected to keyguard");
|
||||||
|
mService = IKeyguardService.Stub.asInterface(service);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
Log.v(TAG, "Disconnected from keyguard");
|
||||||
|
mService = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
public KeyguardTouchDelegate(Context context) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
|
||||||
|
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
|
||||||
|
Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
|
||||||
|
if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
|
||||||
|
} else {
|
||||||
|
if (DEBUG) Log.v(TAG, "*** Keyguard started");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSecure() {
|
||||||
|
boolean secure = false;
|
||||||
|
if (mService != null) {
|
||||||
|
try {
|
||||||
|
secure = mService.isSecure();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "RemoteException calling keyguard.isSecure()!", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "isSecure(): NO SERVICE!");
|
||||||
|
}
|
||||||
|
return secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dispatch(MotionEvent event) {
|
||||||
|
if (mService != null) {
|
||||||
|
try {
|
||||||
|
mService.dispatch(event);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// What to do?
|
||||||
|
Log.e(TAG, "RemoteException sending event to keyguard!", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "dispatch(event): NO SERVICE!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -67,6 +67,7 @@ public final class NavigationBarTransitions extends BarTransitions {
|
|||||||
setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate);
|
setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate);
|
||||||
setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
|
setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
|
||||||
setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
|
setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
|
||||||
|
setKeyButtonViewQuiescentAlpha(mView.getCameraButton(), alpha, animate);
|
||||||
|
|
||||||
// apply to lights out
|
// apply to lights out
|
||||||
applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
|
applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
|
||||||
|
@ -17,14 +17,20 @@
|
|||||||
package com.android.systemui.statusbar.phone;
|
package com.android.systemui.statusbar.phone;
|
||||||
|
|
||||||
import android.animation.LayoutTransition;
|
import android.animation.LayoutTransition;
|
||||||
|
import android.app.ActivityManagerNative;
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
@ -77,6 +83,17 @@ public class NavigationBarView extends LinearLayout {
|
|||||||
final static boolean WORKAROUND_INVALID_LAYOUT = true;
|
final static boolean WORKAROUND_INVALID_LAYOUT = true;
|
||||||
final static int MSG_CHECK_INVALID_LAYOUT = 8686;
|
final static int MSG_CHECK_INVALID_LAYOUT = 8686;
|
||||||
|
|
||||||
|
// used to disable the camera icon in navbar when disabled by DPM
|
||||||
|
private boolean mCameraDisabledByDpm;
|
||||||
|
KeyguardTouchDelegate mTouchDelegate;
|
||||||
|
|
||||||
|
private final OnTouchListener mCameraTouchListener = new OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
return mTouchDelegate.dispatch(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private class H extends Handler {
|
private class H extends Handler {
|
||||||
public void handleMessage(Message m) {
|
public void handleMessage(Message m) {
|
||||||
switch (m.what) {
|
switch (m.what) {
|
||||||
@ -115,6 +132,26 @@ public class NavigationBarView extends LinearLayout {
|
|||||||
getIcons(res);
|
getIcons(res);
|
||||||
|
|
||||||
mBarTransitions = new NavigationBarTransitions(this);
|
mBarTransitions = new NavigationBarTransitions(this);
|
||||||
|
|
||||||
|
mTouchDelegate = new KeyguardTouchDelegate(mContext);
|
||||||
|
|
||||||
|
mCameraDisabledByDpm = isCameraDisabledByDpm();
|
||||||
|
watchForDevicePolicyChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void watchForDevicePolicyChanges() {
|
||||||
|
final IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
|
||||||
|
mContext.registerReceiver(new BroadcastReceiver() {
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mCameraDisabledByDpm = isCameraDisabledByDpm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BarTransitions getBarTransitions() {
|
public BarTransitions getBarTransitions() {
|
||||||
@ -173,6 +210,11 @@ public class NavigationBarView extends LinearLayout {
|
|||||||
return mCurrentView.findViewById(R.id.search_light);
|
return mCurrentView.findViewById(R.id.search_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shown when keyguard is visible and camera is available
|
||||||
|
public View getCameraButton() {
|
||||||
|
return mCurrentView.findViewById(R.id.camera_button);
|
||||||
|
}
|
||||||
|
|
||||||
private void getIcons(Resources res) {
|
private void getIcons(Resources res) {
|
||||||
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
|
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
|
||||||
mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
|
mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
|
||||||
@ -259,7 +301,31 @@ public class NavigationBarView extends LinearLayout {
|
|||||||
getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
|
getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
|
||||||
getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
|
getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
|
||||||
|
|
||||||
getSearchLight().setVisibility((disableHome && !disableSearch) ? View.VISIBLE : View.GONE);
|
final boolean shouldShowSearch = disableHome && !disableSearch;
|
||||||
|
getSearchLight().setVisibility(shouldShowSearch ? View.VISIBLE : View.GONE);
|
||||||
|
final View cameraButton = getCameraButton();
|
||||||
|
if (cameraButton != null) {
|
||||||
|
cameraButton.setVisibility(
|
||||||
|
shouldShowSearch && !mCameraDisabledByDpm ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCameraDisabledByDpm() {
|
||||||
|
final DevicePolicyManager dpm =
|
||||||
|
(DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||||
|
if (dpm != null) {
|
||||||
|
try {
|
||||||
|
final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
|
||||||
|
final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
|
||||||
|
final boolean disabledBecauseKeyguardSecure =
|
||||||
|
(disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
|
||||||
|
&& mTouchDelegate.isSecure();
|
||||||
|
return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Can't get userId", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSlippery(boolean newSlippery) {
|
public void setSlippery(boolean newSlippery) {
|
||||||
@ -302,6 +368,14 @@ public class NavigationBarView extends LinearLayout {
|
|||||||
: findViewById(R.id.rot270);
|
: findViewById(R.id.rot270);
|
||||||
|
|
||||||
mCurrentView = mRotatedViews[Surface.ROTATION_0];
|
mCurrentView = mRotatedViews[Surface.ROTATION_0];
|
||||||
|
|
||||||
|
// Add a touch handler for camera icon for all view orientations.
|
||||||
|
for (int i = 0; i < mRotatedViews.length; i++) {
|
||||||
|
View cameraButton = mRotatedViews[i].findViewById(R.id.camera_button);
|
||||||
|
if (cameraButton != null) {
|
||||||
|
cameraButton.setOnTouchListener(mCameraTouchListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVertical() {
|
public boolean isVertical() {
|
||||||
|
@ -29,8 +29,10 @@ import com.android.internal.widget.LockPatternUtils;
|
|||||||
* local or remote instances of keyguard.
|
* local or remote instances of keyguard.
|
||||||
*/
|
*/
|
||||||
public class KeyguardServiceDelegate {
|
public class KeyguardServiceDelegate {
|
||||||
private static final String KEYGUARD_PACKAGE = "com.android.keyguard";
|
// TODO: propagate changes to these to {@link KeyguardTouchDelegate}
|
||||||
private static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
|
public static final String KEYGUARD_PACKAGE = "com.android.keyguard";
|
||||||
|
public static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
|
||||||
|
|
||||||
private static final String TAG = "KeyguardServiceDelegate";
|
private static final String TAG = "KeyguardServiceDelegate";
|
||||||
private static final boolean DEBUG = true;
|
private static final boolean DEBUG = true;
|
||||||
protected KeyguardServiceWrapper mKeyguardService;
|
protected KeyguardServiceWrapper mKeyguardService;
|
||||||
|
@ -20,6 +20,7 @@ import android.os.Bundle;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import com.android.internal.policy.IKeyguardShowCallback;
|
import com.android.internal.policy.IKeyguardShowCallback;
|
||||||
import com.android.internal.policy.IKeyguardExitCallback;
|
import com.android.internal.policy.IKeyguardExitCallback;
|
||||||
@ -187,6 +188,10 @@ public class KeyguardServiceWrapper implements IKeyguardService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispatch(MotionEvent event) {
|
||||||
|
// Not used by PhoneWindowManager. See code in {@link NavigationBarView}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder asBinder() {
|
public IBinder asBinder() {
|
||||||
return mService.asBinder();
|
return mService.asBinder();
|
||||||
|