Keyguard bouncer notifications; focus moving and the bouncer; slops
Integrate changes from prototype app * Add callbacks for bouncer state changes * Dismiss the bouncer if focus leaves the challenge area * Increase edge swipe region, treat this as a slop for SlidingChallengeLayout's drag handle. (This allows edge swipes in the drag handle area to still page widgets instead.) Change-Id: I732de1a8d999a34c7cc8aa8ed99e24b597f3444c
This commit is contained in:
@@ -28,6 +28,5 @@
|
||||
android:paddingBottom="25dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
androidprv:pageSpacing="10dp"
|
||||
androidprv:edgeSwipeRegionSize="8dp">
|
||||
</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
|
||||
androidprv:pageSpacing="10dp">
|
||||
</com.android.internal.policy.impl.keyguard.KeyguardWidgetPager>
|
||||
|
||||
@@ -5766,7 +5766,6 @@
|
||||
<!-- The padding for the scroll indicator area -->
|
||||
<attr name="scrollIndicatorPaddingLeft" format="dimension" />
|
||||
<attr name="scrollIndicatorPaddingRight" format="dimension" />
|
||||
<attr name="edgeSwipeRegionSize" format="dimension" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="KeyguardGlowStripView">
|
||||
|
||||
@@ -323,4 +323,8 @@
|
||||
|
||||
<!-- Size of the text under the avator on the multiuser lockscreen. -->
|
||||
<dimen name="keyguard_avatar_name_size">10sp</dimen>
|
||||
|
||||
<!-- Size of the region along the edge of the screen that will accept
|
||||
swipes to scroll the widget area. -->
|
||||
<dimen name="kg_edge_swipe_region_size">16dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -1214,6 +1214,7 @@
|
||||
<java-symbol type="dimen" name="keyguard_avatar_size" />
|
||||
<java-symbol type="dimen" name="keyguard_avatar_frame_stroke_width" />
|
||||
<java-symbol type="dimen" name="keyguard_avatar_frame_shadow_radius" />
|
||||
<java-symbol type="dimen" name="kg_edge_swipe_region_size" />
|
||||
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
|
||||
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />
|
||||
<java-symbol type="drawable" name="ic_jog_dial_unlock" />
|
||||
|
||||
@@ -57,4 +57,36 @@ public interface ChallengeLayout {
|
||||
* potentially blocking access to other child views.
|
||||
*/
|
||||
boolean isBouncing();
|
||||
|
||||
/**
|
||||
* Set a listener that will respond to changes in bouncer state.
|
||||
*
|
||||
* @param listener listener to register
|
||||
*/
|
||||
void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener);
|
||||
|
||||
/**
|
||||
* Listener interface that reports changes in bouncer state.
|
||||
* The bouncer is
|
||||
*/
|
||||
public interface OnBouncerStateChangedListener {
|
||||
/**
|
||||
* Called when the bouncer state changes.
|
||||
* The bouncer is activated when the user must pass a security challenge
|
||||
* to proceed with the requested action.
|
||||
*
|
||||
* <p>This differs from simply showing or hiding the security challenge
|
||||
* as the bouncer will prevent interaction with other elements of the UI.
|
||||
* If the user attempts to escape from the bouncer, it will be dismissed,
|
||||
* this method will be called with false as the parameter, and the action
|
||||
* should be canceled. If the security component reports a successful
|
||||
* authentication and the containing code calls hideBouncer() as a result,
|
||||
* this method will also be called with a false parameter. It is up to the
|
||||
* caller of hideBouncer to be ready for this.</p>
|
||||
*
|
||||
* @param bouncerActive true if the bouncer is now active,
|
||||
* false if the bouncer was dismissed.
|
||||
*/
|
||||
public void onBouncerStateChanged(boolean bouncerActive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayo
|
||||
private View mChallengeView;
|
||||
private View mUserSwitcherView;
|
||||
private View mScrimView;
|
||||
private OnBouncerStateChangedListener mBouncerListener;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
|
||||
@@ -89,6 +90,9 @@ public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayo
|
||||
if (mScrimView != null) {
|
||||
mScrimView.setVisibility(GONE);
|
||||
}
|
||||
if (mBouncerListener != null) {
|
||||
mBouncerListener.onBouncerStateChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,6 +102,9 @@ public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayo
|
||||
if (mScrimView != null) {
|
||||
mScrimView.setVisibility(GONE);
|
||||
}
|
||||
if (mBouncerListener != null) {
|
||||
mBouncerListener.onBouncerStateChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,6 +112,21 @@ public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayo
|
||||
return mIsBouncing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
|
||||
mBouncerListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
if (mIsBouncing && child != mChallengeView) {
|
||||
// Clear out of the bouncer if the user tries to move focus outside of
|
||||
// the security challenge view.
|
||||
hideBouncer();
|
||||
}
|
||||
super.requestChildFocus(child, focused);
|
||||
}
|
||||
|
||||
void setScrimView(View scrim) {
|
||||
if (mScrimView != null) {
|
||||
mScrimView.setOnClickListener(null);
|
||||
|
||||
@@ -253,11 +253,12 @@ public class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeL
|
||||
mScrollIndicatorPaddingLeft =
|
||||
a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingLeft, 0);
|
||||
mScrollIndicatorPaddingRight =
|
||||
a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
|
||||
mEdgeSwipeRegionSize =
|
||||
a.getDimensionPixelSize(R.styleable.PagedView_edgeSwipeRegionSize, 0);
|
||||
a.getDimensionPixelSize(R.styleable.PagedView_scrollIndicatorPaddingRight, 0);
|
||||
a.recycle();
|
||||
|
||||
mEdgeSwipeRegionSize =
|
||||
getResources().getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
|
||||
|
||||
setHapticFeedbackEnabled(false);
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
|
||||
private final Scroller mScroller;
|
||||
private int mScrollState;
|
||||
private OnChallengeScrolledListener mListener;
|
||||
private OnChallengeScrolledListener mScrollListener;
|
||||
private OnBouncerStateChangedListener mBouncerListener;
|
||||
|
||||
public static final int SCROLL_STATE_IDLE = 0;
|
||||
public static final int SCROLL_STATE_DRAGGING = 1;
|
||||
@@ -77,6 +78,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
private int mMaxVelocity;
|
||||
private float mLastTouchY;
|
||||
private int mDragHandleSize;
|
||||
private int mDragHandleEdgeSlop;
|
||||
|
||||
private static final int DRAG_HANDLE_DEFAULT_SIZE = 32; // dp
|
||||
|
||||
@@ -172,6 +174,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
mMinVelocity = vc.getScaledMinimumFlingVelocity();
|
||||
mMaxVelocity = vc.getScaledMaximumFlingVelocity();
|
||||
|
||||
mDragHandleEdgeSlop = getResources().getDimensionPixelSize(
|
||||
R.dimen.kg_edge_swipe_region_size);
|
||||
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
@@ -187,20 +192,24 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
}
|
||||
|
||||
private void sendInitialListenerUpdates() {
|
||||
if (mListener != null) {
|
||||
if (mScrollListener != null) {
|
||||
int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
|
||||
mListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
|
||||
mListener.onScrollStateChanged(mScrollState);
|
||||
mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
|
||||
mScrollListener.onScrollStateChanged(mScrollState);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
|
||||
mListener = listener;
|
||||
mScrollListener = listener;
|
||||
if (mHasLayout) {
|
||||
sendInitialListenerUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
|
||||
mBouncerListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
@@ -216,6 +225,16 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
mHasLayout = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestChildFocus(View child, View focused) {
|
||||
if (mIsBouncing && child != mChallengeView) {
|
||||
// Clear out of the bouncer if the user tries to move focus outside of
|
||||
// the security challenge view.
|
||||
hideBouncer();
|
||||
}
|
||||
super.requestChildFocus(child, focused);
|
||||
}
|
||||
|
||||
// We want the duration of the page snap animation to be influenced by the distance that
|
||||
// the screen has to travel, however, we don't want this duration to be effected in a
|
||||
// purely linear fashion. Instead, we use this method to moderate the effect that the distance
|
||||
@@ -230,8 +249,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
if (mScrollState != state) {
|
||||
mScrollState = state;
|
||||
|
||||
if (mListener != null) {
|
||||
mListener.onScrollStateChanged(state);
|
||||
if (mScrollListener != null) {
|
||||
mScrollListener.onScrollStateChanged(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,6 +344,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
if (mScrimView != null) {
|
||||
mScrimView.setVisibility(GONE);
|
||||
}
|
||||
if (mBouncerListener != null) {
|
||||
mBouncerListener.onBouncerStateChanged(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -335,6 +357,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
if (mScrimView != null) {
|
||||
mScrimView.setVisibility(GONE);
|
||||
}
|
||||
if (mBouncerListener != null) {
|
||||
mBouncerListener.onBouncerStateChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -477,7 +502,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
private boolean isInDragHandle(float x, float y) {
|
||||
if (mChallengeView == null) return false;
|
||||
|
||||
return x >= 0 && y >= mChallengeView.getTop() && x < getWidth() &&
|
||||
return x >= mDragHandleEdgeSlop &&
|
||||
y >= mChallengeView.getTop() &&
|
||||
x < getWidth() - mDragHandleEdgeSlop &&
|
||||
y < mChallengeView.getTop() + mDragHandleSize;
|
||||
}
|
||||
|
||||
@@ -644,8 +671,8 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
|
||||
bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);
|
||||
|
||||
mChallengeView.setAlpha(offset);
|
||||
if (mListener != null) {
|
||||
mListener.onScrollPositionChanged(offset, mChallengeView.getTop());
|
||||
if (mScrollListener != null) {
|
||||
mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
|
||||
}
|
||||
postInvalidateOnAnimation();
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user