Skip to content

Commit e74fcc0

Browse files
adampAndroid (Google) Code Review
authored andcommitted
Merge "Fix keyguard bugs" into jb-mr1-lockscreen-dev
2 parents 3c416df + cdf8b48 commit e74fcc0

File tree

3 files changed

+125
-16
lines changed

3 files changed

+125
-16
lines changed

core/res/res/layout-port/keyguard_host_view.xml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636

3737
<FrameLayout
3838
android:layout_width="match_parent"
39-
android:layout_height="match_parent">
39+
android:layout_height="match_parent"
40+
androidprv:layout_childType="widgets">
4041
<include layout="@layout/keyguard_widget_pager"
4142
android:id="@+id/app_widget_container"
4243
android:layout_width="match_parent"
@@ -51,22 +52,19 @@
5152

5253
<com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
5354
android:id="@+id/keyguard_security_container"
54-
android:layout_width="@dimen/keyguard_security_width"
55+
android:layout_width="wrap_content"
5556
android:layout_height="@dimen/keyguard_security_height"
5657
androidprv:layout_childType="challenge"
57-
android:layout_marginLeft="@dimen/kg_edge_swipe_region_size"
58-
android:layout_marginRight="@dimen/kg_edge_swipe_region_size"
5958
android:background="@drawable/kg_bouncer_bg_white"
59+
android:padding="0dp"
6060
android:gravity="bottom|center_horizontal">
6161
<com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
6262
android:id="@+id/view_flipper"
6363
android:layout_width="match_parent"
6464
android:layout_height="match_parent"
6565
android:clipChildren="false"
6666
android:clipToPadding="false"
67-
android:paddingLeft="@dimen/keyguard_security_view_margin"
6867
android:paddingTop="@dimen/keyguard_security_view_margin"
69-
android:paddingRight="@dimen/keyguard_security_view_margin"
7068
android:gravity="center">
7169
</com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
7270
</com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>

core/res/res/values/attrs.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5798,6 +5798,8 @@
57985798
<!-- Scrim. This will block access to child views that
57995799
come before it in the child list in bouncer mode. -->
58005800
<enum name="scrim" value="4" />
5801+
<!-- The home for widgets. All widgets will be descendents of this. -->
5802+
<enum name="widgets" value="5" />
58015803
</attr>
58025804

58035805
<declare-styleable name="SlidingChallengeLayout">

policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java

Lines changed: 119 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616

1717
package com.android.internal.policy.impl.keyguard;
1818

19+
import android.animation.Animator;
20+
import android.animation.AnimatorListenerAdapter;
1921
import android.animation.ObjectAnimator;
2022
import android.content.Context;
2123
import android.content.res.TypedArray;
2224
import android.graphics.Canvas;
2325
import android.graphics.Paint;
26+
import android.graphics.Rect;
2427
import android.graphics.drawable.Drawable;
2528
import android.util.AttributeSet;
2629
import android.util.FloatProperty;
@@ -61,10 +64,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
6164
private Drawable mHandleDrawable;
6265
private Drawable mFrameDrawable;
6366
private Drawable mDragIconDrawable;
67+
private boolean mEdgeCaptured;
6468

6569
// Initialized during measurement from child layoutparams
6670
private View mChallengeView;
6771
private View mScrimView;
72+
private View mWidgetsView;
6873

6974
// Range: 0 (fully hidden) to 1 (fully visible)
7075
private float mChallengeOffset = 1.f;
@@ -110,9 +115,14 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
110115

111116
float mHandleAlpha;
112117
float mFrameAlpha;
118+
float mFrameAnimationTarget = Float.MIN_VALUE;
113119
private ObjectAnimator mHandleAnimation;
114120
private ObjectAnimator mFrameAnimation;
115121

122+
private final Rect mTempRect = new Rect();
123+
124+
private boolean mHasGlowpad;
125+
116126
static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
117127
new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
118128
@Override
@@ -293,21 +303,43 @@ void animateHandle(boolean visible) {
293303
mHandleAnimation.start();
294304
}
295305

296-
void animateFrame(boolean visible, boolean full) {
306+
void animateFrame(final boolean visible, final boolean full) {
297307
if (mFrameDrawable == null) return;
298308

299-
if (mFrameAnimation != null) {
309+
final float targetAlpha = visible ? (full ? 1.f : 0.5f) : 0.f;
310+
if (mFrameAnimation != null && targetAlpha != mFrameAnimationTarget) {
300311
mFrameAnimation.cancel();
301-
mFrameAnimation = null;
312+
mFrameAnimationTarget = Float.MIN_VALUE;
302313
}
303-
final float targetAlpha = visible ? (full ? 1.f : 0.5f) : 0.f;
304-
if (targetAlpha == mFrameAlpha) {
314+
if (targetAlpha == mFrameAlpha || targetAlpha == mFrameAnimationTarget) {
305315
return;
306316
}
317+
mFrameAnimationTarget = targetAlpha;
307318

308319
mFrameAnimation = ObjectAnimator.ofFloat(this, FRAME_ALPHA, targetAlpha);
309320
mFrameAnimation.setInterpolator(sHandleFadeInterpolator);
310321
mFrameAnimation.setDuration(HANDLE_ANIMATE_DURATION);
322+
mFrameAnimation.addListener(new AnimatorListenerAdapter() {
323+
@Override
324+
public void onAnimationEnd(Animator animation) {
325+
mFrameAnimationTarget = Float.MIN_VALUE;
326+
327+
if (!visible && full && mChallengeView != null) {
328+
// Mess with padding/margin to remove insets on the bouncer frame.
329+
mChallengeView.setPadding(0, 0, 0, 0);
330+
LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
331+
lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
332+
mChallengeView.setLayoutParams(lp);
333+
}
334+
mFrameAnimation = null;
335+
}
336+
337+
@Override
338+
public void onAnimationCancel(Animator animation) {
339+
mFrameAnimationTarget = Float.MIN_VALUE;
340+
mFrameAnimation = null;
341+
}
342+
});
311343
mFrameAnimation.start();
312344
}
313345

@@ -370,7 +402,9 @@ void setScrollState(int state) {
370402
mScrollState = state;
371403

372404
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
373-
animateFrame(false , false);
405+
if (!mIsBouncing) {
406+
animateFrame(false, false);
407+
}
374408
if (mScrollListener != null) {
375409
mScrollListener.onScrollStateChanged(state);
376410
}
@@ -380,6 +414,7 @@ void setScrollState(int state) {
380414
void completeChallengeScroll() {
381415
setChallengeShowing(mChallengeOffset != 0);
382416
setScrollState(SCROLL_STATE_IDLE);
417+
mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
383418
}
384419

385420
void setScrimView(View scrim) {
@@ -461,7 +496,22 @@ public void showBouncer() {
461496
if (mScrimView != null) {
462497
mScrimView.setVisibility(VISIBLE);
463498
}
499+
500+
// Mess with padding/margin to inset the bouncer frame.
501+
// We have more space available to us otherwise.
502+
if (mChallengeView != null) {
503+
if (mFrameDrawable == null || !mFrameDrawable.getPadding(mTempRect)) {
504+
mTempRect.set(0, 0, 0, 0);
505+
}
506+
mChallengeView.setPadding(mTempRect.left, mTempRect.top, mTempRect.right,
507+
mTempRect.bottom);
508+
final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
509+
lp.leftMargin = lp.rightMargin = getChallengeMargin(false);
510+
mChallengeView.setLayoutParams(lp);
511+
}
512+
464513
animateFrame(true, true);
514+
465515
if (mBouncerListener != null) {
466516
mBouncerListener.onBouncerStateChanged(true);
467517
}
@@ -470,17 +520,21 @@ public void showBouncer() {
470520
@Override
471521
public void hideBouncer() {
472522
if (!mIsBouncing) return;
473-
setChallengeShowing(false);
523+
showChallenge(false);
474524
mIsBouncing = false;
475525
if (mScrimView != null) {
476526
mScrimView.setVisibility(GONE);
477527
}
478-
animateFrame(false, false);
528+
animateFrame(false, true);
479529
if (mBouncerListener != null) {
480530
mBouncerListener.onBouncerStateChanged(false);
481531
}
482532
}
483533

534+
private int getChallengeMargin(boolean expanded) {
535+
return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
536+
}
537+
484538
@Override
485539
public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
486540
// We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
@@ -495,8 +549,6 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
495549
}
496550
mVelocityTracker.addMovement(ev);
497551

498-
//Log.v(TAG, "onIntercept: " + ev);
499-
500552
final int action = ev.getActionMasked();
501553
switch (action) {
502554
case MotionEvent.ACTION_DOWN:
@@ -525,6 +577,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
525577
mGestureStartY = y;
526578
mGestureStartChallengeBottom = getChallengeBottom();
527579
mDragging = true;
580+
mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
528581
} else if (isInChallengeView(x, y)) {
529582
mBlockDrag = true;
530583
}
@@ -601,6 +654,7 @@ && isInDragHandle(mGestureStartX, mGestureStartY)
601654
mActivePointerId = ev.getPointerId(i);
602655
mGestureStartChallengeBottom = getChallengeBottom();
603656
mDragging = true;
657+
mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
604658
break;
605659
}
606660
}
@@ -630,6 +684,52 @@ && isInDragHandle(mGestureStartX, mGestureStartY)
630684
return true;
631685
}
632686

687+
/**
688+
* The lifecycle of touch events is subtle and it's very easy to do something
689+
* that will cause bugs that will be nasty to track when overriding this method.
690+
* Normally one should always override onInterceptTouchEvent instead.
691+
*
692+
* To put it another way, don't try this at home.
693+
*/
694+
@Override
695+
public boolean dispatchTouchEvent(MotionEvent ev) {
696+
final int action = ev.getActionMasked();
697+
boolean handled = false;
698+
if (action == MotionEvent.ACTION_DOWN) {
699+
// Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
700+
mEdgeCaptured = false;
701+
}
702+
if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
703+
// Normally we would need to do a lot of extra stuff here.
704+
// We can only get away with this because we haven't padded in
705+
// the widget pager or otherwise transformed it during layout.
706+
// We also don't support things like splitting MotionEvents.
707+
708+
// We set handled to captured even if dispatch is returning false here so that
709+
// we don't send a different view a busted or incomplete event stream.
710+
handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
711+
}
712+
713+
if (!handled && !mEdgeCaptured) {
714+
handled = super.dispatchTouchEvent(ev);
715+
}
716+
717+
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
718+
mEdgeCaptured = false;
719+
}
720+
721+
return handled;
722+
}
723+
724+
private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
725+
if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
726+
return false;
727+
}
728+
729+
final float x = ev.getX();
730+
return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
731+
}
732+
633733
/**
634734
* We only want to add additional vertical space to the drag handle when the panel is fully
635735
* closed.
@@ -699,8 +799,16 @@ protected void onMeasure(int widthSpec, int heightSpec) {
699799
}
700800
// We're going to play silly games with the frame's background drawable later.
701801
mFrameDrawable = mChallengeView.getBackground();
802+
803+
if (!mHasLayout) {
804+
// Set up the margin correctly based on our content for the first run.
805+
mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
806+
lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
807+
}
702808
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
703809
setScrimView(child);
810+
} else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
811+
mWidgetsView = child;
704812
}
705813

706814
if (child.getVisibility() == GONE) continue;
@@ -980,6 +1088,7 @@ public static class LayoutParams extends MarginLayoutParams {
9801088
public static final int CHILD_TYPE_NONE = 0;
9811089
public static final int CHILD_TYPE_CHALLENGE = 2;
9821090
public static final int CHILD_TYPE_SCRIM = 4;
1091+
public static final int CHILD_TYPE_WIDGETS = 5;
9831092

9841093
public LayoutParams() {
9851094
this(MATCH_PARENT, WRAP_CONTENT);

0 commit comments

Comments
 (0)