summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/res/res/layout-port/keyguard_host_view.xml10
-rwxr-xr-xcore/res/res/values/attrs.xml2
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java129
3 files changed, 125 insertions, 16 deletions
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 544447149eb..a3c81054537 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -36,7 +36,8 @@
<FrameLayout
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ androidprv:layout_childType="widgets">
<include layout="@layout/keyguard_widget_pager"
android:id="@+id/app_widget_container"
android:layout_width="match_parent"
@@ -51,12 +52,11 @@
<com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer
android:id="@+id/keyguard_security_container"
- android:layout_width="@dimen/keyguard_security_width"
+ android:layout_width="wrap_content"
android:layout_height="@dimen/keyguard_security_height"
androidprv:layout_childType="challenge"
- android:layout_marginLeft="@dimen/kg_edge_swipe_region_size"
- android:layout_marginRight="@dimen/kg_edge_swipe_region_size"
android:background="@drawable/kg_bouncer_bg_white"
+ android:padding="0dp"
android:gravity="bottom|center_horizontal">
<com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
@@ -64,9 +64,7 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:paddingLeft="@dimen/keyguard_security_view_margin"
android:paddingTop="@dimen/keyguard_security_view_margin"
- android:paddingRight="@dimen/keyguard_security_view_margin"
android:gravity="center">
</com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
</com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d186c4a85f6..627099c2fd2 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5798,6 +5798,8 @@
<!-- Scrim. This will block access to child views that
come before it in the child list in bouncer mode. -->
<enum name="scrim" value="4" />
+ <!-- The home for widgets. All widgets will be descendents of this. -->
+ <enum name="widgets" value="5" />
</attr>
<declare-styleable name="SlidingChallengeLayout">
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
index 74b05dde38a..7cf995c4f3f 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -16,11 +16,14 @@
package com.android.internal.policy.impl.keyguard;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -61,10 +64,12 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
private Drawable mHandleDrawable;
private Drawable mFrameDrawable;
private Drawable mDragIconDrawable;
+ private boolean mEdgeCaptured;
// Initialized during measurement from child layoutparams
private View mChallengeView;
private View mScrimView;
+ private View mWidgetsView;
// Range: 0 (fully hidden) to 1 (fully visible)
private float mChallengeOffset = 1.f;
@@ -110,9 +115,14 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
float mHandleAlpha;
float mFrameAlpha;
+ float mFrameAnimationTarget = Float.MIN_VALUE;
private ObjectAnimator mHandleAnimation;
private ObjectAnimator mFrameAnimation;
+ private final Rect mTempRect = new Rect();
+
+ private boolean mHasGlowpad;
+
static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
@Override
@@ -293,21 +303,43 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mHandleAnimation.start();
}
- void animateFrame(boolean visible, boolean full) {
+ void animateFrame(final boolean visible, final boolean full) {
if (mFrameDrawable == null) return;
- if (mFrameAnimation != null) {
+ final float targetAlpha = visible ? (full ? 1.f : 0.5f) : 0.f;
+ if (mFrameAnimation != null && targetAlpha != mFrameAnimationTarget) {
mFrameAnimation.cancel();
- mFrameAnimation = null;
+ mFrameAnimationTarget = Float.MIN_VALUE;
}
- final float targetAlpha = visible ? (full ? 1.f : 0.5f) : 0.f;
- if (targetAlpha == mFrameAlpha) {
+ if (targetAlpha == mFrameAlpha || targetAlpha == mFrameAnimationTarget) {
return;
}
+ mFrameAnimationTarget = targetAlpha;
mFrameAnimation = ObjectAnimator.ofFloat(this, FRAME_ALPHA, targetAlpha);
mFrameAnimation.setInterpolator(sHandleFadeInterpolator);
mFrameAnimation.setDuration(HANDLE_ANIMATE_DURATION);
+ mFrameAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mFrameAnimationTarget = Float.MIN_VALUE;
+
+ if (!visible && full && mChallengeView != null) {
+ // Mess with padding/margin to remove insets on the bouncer frame.
+ mChallengeView.setPadding(0, 0, 0, 0);
+ LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
+ lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
+ mChallengeView.setLayoutParams(lp);
+ }
+ mFrameAnimation = null;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mFrameAnimationTarget = Float.MIN_VALUE;
+ mFrameAnimation = null;
+ }
+ });
mFrameAnimation.start();
}
@@ -370,7 +402,9 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mScrollState = state;
animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
- animateFrame(false , false);
+ if (!mIsBouncing) {
+ animateFrame(false, false);
+ }
if (mScrollListener != null) {
mScrollListener.onScrollStateChanged(state);
}
@@ -380,6 +414,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
void completeChallengeScroll() {
setChallengeShowing(mChallengeOffset != 0);
setScrollState(SCROLL_STATE_IDLE);
+ mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
}
void setScrimView(View scrim) {
@@ -461,7 +496,22 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
if (mScrimView != null) {
mScrimView.setVisibility(VISIBLE);
}
+
+ // Mess with padding/margin to inset the bouncer frame.
+ // We have more space available to us otherwise.
+ if (mChallengeView != null) {
+ if (mFrameDrawable == null || !mFrameDrawable.getPadding(mTempRect)) {
+ mTempRect.set(0, 0, 0, 0);
+ }
+ mChallengeView.setPadding(mTempRect.left, mTempRect.top, mTempRect.right,
+ mTempRect.bottom);
+ final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
+ lp.leftMargin = lp.rightMargin = getChallengeMargin(false);
+ mChallengeView.setLayoutParams(lp);
+ }
+
animateFrame(true, true);
+
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(true);
}
@@ -470,17 +520,21 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
@Override
public void hideBouncer() {
if (!mIsBouncing) return;
- setChallengeShowing(false);
+ showChallenge(false);
mIsBouncing = false;
if (mScrimView != null) {
mScrimView.setVisibility(GONE);
}
- animateFrame(false, false);
+ animateFrame(false, true);
if (mBouncerListener != null) {
mBouncerListener.onBouncerStateChanged(false);
}
}
+ private int getChallengeMargin(boolean expanded) {
+ return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
+ }
+
@Override
public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
// We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
@@ -495,8 +549,6 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
mVelocityTracker.addMovement(ev);
- //Log.v(TAG, "onIntercept: " + ev);
-
final int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
@@ -525,6 +577,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mGestureStartY = y;
mGestureStartChallengeBottom = getChallengeBottom();
mDragging = true;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
} else if (isInChallengeView(x, y)) {
mBlockDrag = true;
}
@@ -601,6 +654,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
mActivePointerId = ev.getPointerId(i);
mGestureStartChallengeBottom = getChallengeBottom();
mDragging = true;
+ mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
break;
}
}
@@ -631,6 +685,52 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
/**
+ * The lifecycle of touch events is subtle and it's very easy to do something
+ * that will cause bugs that will be nasty to track when overriding this method.
+ * Normally one should always override onInterceptTouchEvent instead.
+ *
+ * To put it another way, don't try this at home.
+ */
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ final int action = ev.getActionMasked();
+ boolean handled = false;
+ if (action == MotionEvent.ACTION_DOWN) {
+ // Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
+ mEdgeCaptured = false;
+ }
+ if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
+ // Normally we would need to do a lot of extra stuff here.
+ // We can only get away with this because we haven't padded in
+ // the widget pager or otherwise transformed it during layout.
+ // We also don't support things like splitting MotionEvents.
+
+ // We set handled to captured even if dispatch is returning false here so that
+ // we don't send a different view a busted or incomplete event stream.
+ handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
+ }
+
+ if (!handled && !mEdgeCaptured) {
+ handled = super.dispatchTouchEvent(ev);
+ }
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mEdgeCaptured = false;
+ }
+
+ return handled;
+ }
+
+ private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
+ if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
+ return false;
+ }
+
+ final float x = ev.getX();
+ return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
+ }
+
+ /**
* We only want to add additional vertical space to the drag handle when the panel is fully
* closed.
*/
@@ -699,8 +799,16 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
}
// We're going to play silly games with the frame's background drawable later.
mFrameDrawable = mChallengeView.getBackground();
+
+ if (!mHasLayout) {
+ // Set up the margin correctly based on our content for the first run.
+ mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
+ lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
+ }
} else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
setScrimView(child);
+ } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
+ mWidgetsView = child;
}
if (child.getVisibility() == GONE) continue;
@@ -980,6 +1088,7 @@ public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout
public static final int CHILD_TYPE_NONE = 0;
public static final int CHILD_TYPE_CHALLENGE = 2;
public static final int CHILD_TYPE_SCRIM = 4;
+ public static final int CHILD_TYPE_WIDGETS = 5;
public LayoutParams() {
this(MATCH_PARENT, WRAP_CONTENT);