/*
 * Copyright (C) 2012 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.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatProperty;
import android.util.Log;
import android.util.Property;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.widget.Scroller;

/**
 * This layout handles interaction with the sliding security challenge views
 * that overlay/resize other keyguard contents.
 */
public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout {
    private static final String TAG = "SlidingChallengeLayout";
    private static final boolean DEBUG = false;

    // The drag handle is measured in dp above & below the top edge of the
    // challenge view; these parameters change based on whether the challenge
    // is open or closed.
    private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
    private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
    private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
    private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp

    private static final int HANDLE_ANIMATE_DURATION = 250; // ms

    // Drawn to show the drag handle in closed state; crossfades to the challenge view
    // when challenge is fully visible
    private boolean mEdgeCaptured;

    private DisplayMetrics mDisplayMetrics;

    // Initialized during measurement from child layoutparams
    private View mExpandChallengeView;
    private KeyguardSecurityContainer mChallengeView;
    private View mScrimView;
    private View mWidgetsView;

    // Range: 0 (fully hidden) to 1 (fully visible)
    private float mChallengeOffset = 1.f;
    private boolean mChallengeShowing = true;
    private boolean mChallengeShowingTargetState = true;
    private boolean mWasChallengeShowing = true;
    private boolean mIsBouncing = false;

    private final Scroller mScroller;
    private ObjectAnimator mFader;
    private int mScrollState;
    private OnChallengeScrolledListener mScrollListener;
    private OnBouncerStateChangedListener mBouncerListener;
    private boolean mEnableChallengeDragging;

    public static final int SCROLL_STATE_IDLE = 0;
    public static final int SCROLL_STATE_DRAGGING = 1;
    public static final int SCROLL_STATE_SETTLING = 2;
    public static final int SCROLL_STATE_FADING = 3;

    public static final int CHALLENGE_FADE_OUT_DURATION = 100;
    public static final int CHALLENGE_FADE_IN_DURATION = 160;

    private static final int MAX_SETTLE_DURATION = 600; // ms

    // ID of the pointer in charge of a current drag
    private int mActivePointerId = INVALID_POINTER;
    private static final int INVALID_POINTER = -1;

    // True if the user is currently dragging the slider
    private boolean mDragging;
    // True if the user may not drag until a new gesture begins
    private boolean mBlockDrag;

    private VelocityTracker mVelocityTracker;
    private int mMinVelocity;
    private int mMaxVelocity;
    private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
    private int mGestureStartChallengeBottom; // where was the challenge at that time?

    private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
    private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
    private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
    private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line

    private int mDragHandleEdgeSlop;
    private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
                                       // that should remain on-screen

    private int mTouchSlop;
    private int mTouchSlopSquare;

    float mHandleAlpha;
    float mFrameAlpha;
    float mFrameAnimationTarget = Float.MIN_VALUE;
    private ObjectAnimator mHandleAnimation;
    private ObjectAnimator mFrameAnimation;

    private boolean mHasGlowpad;
    private final Rect mInsets = new Rect();

    // We have an internal and external version, and we and them together.
    private boolean mChallengeInteractiveExternal = true;
    private boolean mChallengeInteractiveInternal = true;

    static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
            new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
        @Override
        public void setValue(SlidingChallengeLayout view, float value) {
            view.mHandleAlpha = value;
            view.invalidate();
        }

        @Override
        public Float get(SlidingChallengeLayout view) {
            return view.mHandleAlpha;
        }
    };

    // True if at least one layout pass has happened since the view was attached.
    private boolean mHasLayout;

    private static final Interpolator sMotionInterpolator = new Interpolator() {
        public float getInterpolation(float t) {
            t -= 1.0f;
            return t * t * t * t * t + 1.0f;
        }
    };

    private static final Interpolator sHandleFadeInterpolator = new Interpolator() {
        public float getInterpolation(float t) {
            return t * t;
        }
    };

    private final Runnable mEndScrollRunnable = new Runnable () {
        public void run() {
            completeChallengeScroll();
        }
    };

    private final OnClickListener mScrimClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            hideBouncer();
        }
    };

    private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!isChallengeShowing()) {
                showChallenge(true);
            }
        }
    };

    /**
     * Listener interface that reports changes in scroll state of the challenge area.
     */
    public interface OnChallengeScrolledListener {
        /**
         * The scroll state itself changed.
         *
         * <p>scrollState will be one of the following:</p>
         *
         * <ul>
         * <li><code>SCROLL_STATE_IDLE</code> - The challenge area is stationary.</li>
         * <li><code>SCROLL_STATE_DRAGGING</code> - The user is actively dragging
         * the challenge area.</li>
         * <li><code>SCROLL_STATE_SETTLING</code> - The challenge area is animating
         * into place.</li>
         * </ul>
         *
         * <p>Do not perform expensive operations (e.g. layout)
         * while the scroll state is not <code>SCROLL_STATE_IDLE</code>.</p>
         *
         * @param scrollState The new scroll state of the challenge area.
         */
        public void onScrollStateChanged(int scrollState);

        /**
         * The precise position of the challenge area has changed.
         *
         * <p>NOTE: It is NOT safe to modify layout or call any View methods that may
         * result in a requestLayout anywhere in your view hierarchy as a result of this call.
         * It may be called during drawing.</p>
         *
         * @param scrollPosition New relative position of the challenge area.
         *                       1.f = fully visible/ready to be interacted with.
         *                       0.f = fully invisible/inaccessible to the user.
         * @param challengeTop Position of the top edge of the challenge view in px in the
         *                     SlidingChallengeLayout's coordinate system.
         */
        public void onScrollPositionChanged(float scrollPosition, int challengeTop);
    }

    public SlidingChallengeLayout(Context context) {
        this(context, null);
    }

    public SlidingChallengeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mScroller = new Scroller(context, sMotionInterpolator);

        final ViewConfiguration vc = ViewConfiguration.get(context);
        mMinVelocity = vc.getScaledMinimumFlingVelocity();
        mMaxVelocity = vc.getScaledMaximumFlingVelocity();

        final Resources res = getResources();
        mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);

        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mTouchSlopSquare = mTouchSlop * mTouchSlop;

        mDisplayMetrics = res.getDisplayMetrics();
        final float density = mDisplayMetrics.density;

        // top half of the lock icon, plus another 25% to be sure
        mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
        mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
        mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
        mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);

        // how much space to account for in the handle when closed
        mChallengeBottomBound = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);

        setWillNotDraw(false);
        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    }

    public void setEnableChallengeDragging(boolean enabled) {
        mEnableChallengeDragging = enabled;
    }

    public void setInsets(Rect insets) {
        mInsets.set(insets);
    }

    public void setHandleAlpha(float alpha) {
        if (mExpandChallengeView != null) {
            mExpandChallengeView.setAlpha(alpha);
        }
    }

    public void setChallengeInteractive(boolean interactive) {
        mChallengeInteractiveExternal = interactive;
        if (mExpandChallengeView != null) {
            mExpandChallengeView.setEnabled(interactive);
        }
    }

    void animateHandle(boolean visible) {
        if (mHandleAnimation != null) {
            mHandleAnimation.cancel();
            mHandleAnimation = null;
        }
        final float targetAlpha = visible ? 1.f : 0.f;
        if (targetAlpha == mHandleAlpha) {
            return;
        }
        mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
        mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
        mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
        mHandleAnimation.start();
    }

    private void sendInitialListenerUpdates() {
        if (mScrollListener != null) {
            int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
            mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
            mScrollListener.onScrollStateChanged(mScrollState);
        }
    }

    public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
        mScrollListener = listener;
        if (mHasLayout) {
            sendInitialListenerUpdates();
        }
    }

    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
        mBouncerListener = listener;
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        mHasLayout = false;
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        removeCallbacks(mEndScrollRunnable);
        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
    // of travel has on the overall snap duration.
    float distanceInfluenceForSnapDuration(float f) {
        f -= 0.5f; // center the values about 0.
        f *= 0.3f * Math.PI / 2.0f;
        return (float) Math.sin(f);
    }

    void setScrollState(int state) {
        if (mScrollState != state) {
            mScrollState = state;

            animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
            if (mScrollListener != null) {
                mScrollListener.onScrollStateChanged(state);
            }
        }
    }

    void completeChallengeScroll() {
        setChallengeShowing(mChallengeShowingTargetState);
        mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
        setScrollState(SCROLL_STATE_IDLE);
        mChallengeInteractiveInternal = true;
        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
    }

    void setScrimView(View scrim) {
        if (mScrimView != null) {
            mScrimView.setOnClickListener(null);
        }
        mScrimView = scrim;
        if (mScrimView != null) {
            mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
            mScrimView.setFocusable(true);
            mScrimView.setOnClickListener(mScrimClickListener);
        }
    }

    /**
     * Animate the bottom edge of the challenge view to the given position.
     *
     * @param y desired final position for the bottom edge of the challenge view in px
     * @param velocity velocity in
     */
    void animateChallengeTo(int y, int velocity) {
        if (mChallengeView == null) {
            // Nothing to do.
            return;
        }

        cancelTransitionsInProgress();

        mChallengeInteractiveInternal = false;
        enableHardwareLayerForChallengeView();
        final int sy = mChallengeView.getBottom();
        final int dy = y - sy;
        if (dy == 0) {
            completeChallengeScroll();
            return;
        }

        setScrollState(SCROLL_STATE_SETTLING);

        final int childHeight = mChallengeView.getHeight();
        final int halfHeight = childHeight / 2;
        final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
        final float distance = halfHeight + halfHeight *
                distanceInfluenceForSnapDuration(distanceRatio);

        int duration = 0;
        velocity = Math.abs(velocity);
        if (velocity > 0) {
            duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
        } else {
            final float childDelta = (float) Math.abs(dy) / childHeight;
            duration = (int) ((childDelta + 1) * 100);
        }
        duration = Math.min(duration, MAX_SETTLE_DURATION);

        mScroller.startScroll(0, sy, 0, dy, duration);
        postInvalidateOnAnimation();
    }

    private void setChallengeShowing(boolean showChallenge) {
        if (mChallengeShowing == showChallenge) {
            return;
        }
        mChallengeShowing = showChallenge;

        if (mExpandChallengeView == null || mChallengeView == null) {
            // These might not be here yet if we haven't been through layout.
            // If we haven't, the first layout pass will set everything up correctly
            // based on mChallengeShowing as set above.
            return;
        }

        if (mChallengeShowing) {
            mExpandChallengeView.setVisibility(View.INVISIBLE);
            mChallengeView.setVisibility(View.VISIBLE);
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                mChallengeView.requestAccessibilityFocus();
                mChallengeView.announceForAccessibility(mContext.getString(
                        R.string.keyguard_accessibility_unlock_area_expanded));
            }
        } else {
            mExpandChallengeView.setVisibility(View.VISIBLE);
            mChallengeView.setVisibility(View.INVISIBLE);
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                mExpandChallengeView.requestAccessibilityFocus();
                mChallengeView.announceForAccessibility(mContext.getString(
                        R.string.keyguard_accessibility_unlock_area_collapsed));
            }
        }
    }

    /**
     * @return true if the challenge is at all visible.
     */
    public boolean isChallengeShowing() {
        return mChallengeShowing;
    }

    @Override
    public boolean isChallengeOverlapping() {
        return mChallengeShowing;
    }

    @Override
    public boolean isBouncing() {
        return mIsBouncing;
    }

    @Override
    public int getBouncerAnimationDuration() {
        return HANDLE_ANIMATE_DURATION;
    }

    @Override
    public void showBouncer() {
        if (mIsBouncing) return;
        setSystemUiVisibility(getSystemUiVisibility() | STATUS_BAR_DISABLE_SEARCH);
        mWasChallengeShowing = mChallengeShowing;
        mIsBouncing = true;
        showChallenge(true);
        if (mScrimView != null) {
            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
            anim.setDuration(HANDLE_ANIMATE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mScrimView.setVisibility(VISIBLE);
                }
            });
            anim.start();
        }
        if (mChallengeView != null) {
            mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
        }

        if (mBouncerListener != null) {
            mBouncerListener.onBouncerStateChanged(true);
        }
    }

    @Override
    public void hideBouncer() {
        if (!mIsBouncing) return;
        setSystemUiVisibility(getSystemUiVisibility() & ~STATUS_BAR_DISABLE_SEARCH);
        if (!mWasChallengeShowing) showChallenge(false);
        mIsBouncing = false;

        if (mScrimView != null) {
            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
            anim.setDuration(HANDLE_ANIMATE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mScrimView.setVisibility(GONE);
                }
            });
            anim.start();
        }
        if (mChallengeView != null) {
            mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
        }
        if (mBouncerListener != null) {
            mBouncerListener.onBouncerStateChanged(false);
        }
    }

    private int getChallengeMargin(boolean expanded) {
        return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
    }

    private float getChallengeAlpha() {
        float x = mChallengeOffset - 1;
        return x * x * x + 1.f;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
        // We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
        // If there are one or more pointers in the challenge view before we take over
        // touch events, onInterceptTouchEvent will set mBlockDrag.
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        final int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mGestureStartX = ev.getX();
                mGestureStartY = ev.getY();
                mBlockDrag = false;
                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                resetTouch();
                break;

            case MotionEvent.ACTION_MOVE:
                final int count = ev.getPointerCount();
                for (int i = 0; i < count; i++) {
                    final float x = ev.getX(i);
                    final float y = ev.getY(i);
                    if (!mIsBouncing && mActivePointerId == INVALID_POINTER
                                && (crossedDragHandle(x, y, mGestureStartY)
                                        && shouldEnableChallengeDragging()
                                        || (isInChallengeView(x, y) &&
                                        mScrollState == SCROLL_STATE_SETTLING))) {
                        mActivePointerId = ev.getPointerId(i);
                        mGestureStartX = x;
                        mGestureStartY = y;
                        mGestureStartChallengeBottom = getChallengeBottom();
                        mDragging = true;
                        enableHardwareLayerForChallengeView();
                    } else if (mChallengeShowing && isInChallengeView(x, y)
                            && shouldEnableChallengeDragging()) {
                        mBlockDrag = true;
                    }
                }
                break;
        }

        if (mBlockDrag || isChallengeInteractionBlocked()) {
            mActivePointerId = INVALID_POINTER;
            mDragging = false;
        }

        return mDragging;
    }

    private boolean shouldEnableChallengeDragging() {
        return mEnableChallengeDragging || !mChallengeShowing;
    }

    private boolean isChallengeInteractionBlocked() {
        return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
    }

    private void resetTouch() {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mActivePointerId = INVALID_POINTER;
        mDragging = mBlockDrag = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        final int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mBlockDrag = false;
                mGestureStartX = ev.getX();
                mGestureStartY = ev.getY();
                break;

            case MotionEvent.ACTION_CANCEL:
                if (mDragging && !isChallengeInteractionBlocked()) {
                    showChallenge(0);
                }
                resetTouch();
                break;

            case MotionEvent.ACTION_POINTER_UP:
                if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
                    break;
                }
            case MotionEvent.ACTION_UP:
                if (mDragging && !isChallengeInteractionBlocked()) {
                    mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
                    showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
                }
                resetTouch();
                break;

            case MotionEvent.ACTION_MOVE:
                if (!mDragging && !mBlockDrag && !mIsBouncing) {
                    final int count = ev.getPointerCount();
                    for (int i = 0; i < count; i++) {
                        final float x = ev.getX(i);
                        final float y = ev.getY(i);

                        if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
                                (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
                                && mActivePointerId == INVALID_POINTER
                                && !isChallengeInteractionBlocked()) {
                            mGestureStartX = x;
                            mGestureStartY = y;
                            mActivePointerId = ev.getPointerId(i);
                            mGestureStartChallengeBottom = getChallengeBottom();
                            mDragging = true;
                            enableHardwareLayerForChallengeView();
                            break;
                        }
                    }
                }
                // Not an else; this can be set above.
                if (mDragging) {
                    // No-op if already in this state, but set it here in case we arrived
                    // at this point from either intercept or the above.
                    setScrollState(SCROLL_STATE_DRAGGING);

                    final int index = ev.findPointerIndex(mActivePointerId);
                    if (index < 0) {
                        // Oops, bogus state. We lost some touch events somewhere.
                        // Just drop it with no velocity and let things settle.
                        resetTouch();
                        showChallenge(0);
                        return true;
                    }
                    final float y = ev.getY(index);
                    final float pos = Math.min(y - mGestureStartY,
                            getLayoutBottom() - mChallengeBottomBound);

                    moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
                }
                break;
        }
        return true;
    }

    /**
     * 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.
     */
    private int getDragHandleSizeAbove() {
        return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
    }
    private int getDragHandleSizeBelow() {
        return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
    }

    private boolean isInChallengeView(float x, float y) {
        return isPointInView(x, y, mChallengeView);
    }

    private boolean isInDragHandle(float x, float y) {
        return isPointInView(x, y, mExpandChallengeView);
    }

    private boolean isPointInView(float x, float y, View view) {
        if (view == null) {
            return false;
        }
        return x >= view.getLeft() && y >= view.getTop()
                && x < view.getRight() && y < view.getBottom();
    }

    private boolean crossedDragHandle(float x, float y, float initialY) {

        final int challengeTop = mChallengeView.getTop();
        final boolean horizOk = x >= 0 && x < getWidth();

        final boolean vertOk;
        if (mChallengeShowing) {
            vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
                    y > challengeTop + getDragHandleSizeBelow();
        } else {
            vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
                    y < challengeTop - getDragHandleSizeAbove();
        }
        return horizOk && vertOk;
    }

    private int makeChildMeasureSpec(int maxSize, int childDimen) {
        final int mode;
        final int size;
        switch (childDimen) {
            case LayoutParams.WRAP_CONTENT:
                mode = MeasureSpec.AT_MOST;
                size = maxSize;
                break;
            case LayoutParams.MATCH_PARENT:
                mode = MeasureSpec.EXACTLY;
                size = maxSize;
                break;
            default:
                mode = MeasureSpec.EXACTLY;
                size = Math.min(maxSize, childDimen);
                break;
        }
        return MeasureSpec.makeMeasureSpec(size, mode);
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
            throw new IllegalArgumentException(
                    "SlidingChallengeLayout must be measured with an exact size");
        }
        final int width = MeasureSpec.getSize(widthSpec);
        final int height = MeasureSpec.getSize(heightSpec);
        setMeasuredDimension(width, height);

        final int insetHeight = height - mInsets.top - mInsets.bottom;
        final int insetHeightSpec = MeasureSpec.makeMeasureSpec(insetHeight, MeasureSpec.EXACTLY);

        // Find one and only one challenge view.
        final View oldChallengeView = mChallengeView;
        final View oldExpandChallengeView = mChallengeView;
        mChallengeView = null;
        mExpandChallengeView = null;
        final int count = getChildCount();

        // First iteration through the children finds special children and sets any associated
        // state.
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
                if (mChallengeView != null) {
                    throw new IllegalStateException(
                            "There may only be one child with layout_isChallenge=\"true\"");
                }
                if (!(child instanceof KeyguardSecurityContainer)) {
                            throw new IllegalArgumentException(
                                    "Challenge must be a KeyguardSecurityContainer");
                }
                mChallengeView = (KeyguardSecurityContainer) child;
                if (mChallengeView != oldChallengeView) {
                    mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
                }
                // We're going to play silly games with the frame's background drawable later.
                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_EXPAND_CHALLENGE_HANDLE) {
                if (mExpandChallengeView != null) {
                    throw new IllegalStateException(
                            "There may only be one child with layout_childType"
                            + "=\"expandChallengeHandle\"");
                }
                mExpandChallengeView = child;
                if (mExpandChallengeView != oldExpandChallengeView) {
                    mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
                    mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
                }
            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                setScrimView(child);
            } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
                mWidgetsView = child;
            }
        }

        // We want to measure the challenge view first, since the KeyguardWidgetPager
        // needs to do things its measure pass that are dependent on the challenge view
        // having been measured.
        if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
            // This one's a little funny. If the IME is present - reported in the form
            // of insets on the root view - we only give the challenge the space it would
            // have had if the IME wasn't there in order to keep the rest of the layout stable.
            // We base this on the layout_maxHeight on the challenge view. If it comes out
            // negative or zero, either we didn't have a maxHeight or we're totally out of space,
            // so give up and measure as if this rule weren't there.
            int challengeHeightSpec = insetHeightSpec;
            final View root = getRootView();
            if (root != null) {
                final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
                final int windowHeight = mDisplayMetrics.heightPixels
                        - root.getPaddingTop() - mInsets.top;
                final int diff = windowHeight - insetHeight;
                final int maxChallengeHeight = lp.maxHeight - diff;
                if (maxChallengeHeight > 0) {
                    challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
                }
            }
            measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
        }

        // Measure the rest of the children
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            // Don't measure the challenge view twice!
            if (child == mChallengeView) continue;

            // Measure children. Widget frame measures special, so that we can ignore
            // insets for the IME.
            int parentWidthSpec = widthSpec, parentHeightSpec = insetHeightSpec;
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
                final View root = getRootView();
                if (root != null) {
                    // This calculation is super dodgy and relies on several assumptions.
                    // Specifically that the root of the window will be padded in for insets
                    // and that the window is LAYOUT_IN_SCREEN.
                    final int windowWidth = mDisplayMetrics.widthPixels;
                    final int windowHeight = mDisplayMetrics.heightPixels
                            - root.getPaddingTop() - mInsets.top;
                    parentWidthSpec = MeasureSpec.makeMeasureSpec(
                            windowWidth, MeasureSpec.EXACTLY);
                    parentHeightSpec = MeasureSpec.makeMeasureSpec(
                            windowHeight, MeasureSpec.EXACTLY);
                }
            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                // Allow scrim views to extend into the insets
                parentWidthSpec = widthSpec;
                parentHeightSpec = heightSpec;
            }
            measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        final int paddingRight = getPaddingRight();
        final int paddingBottom = getPaddingBottom();
        final int width = r - l;
        final int height = b - t;

        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);

            if (child.getVisibility() == GONE) continue;

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
                // Challenge views pin to the bottom, offset by a portion of their height,
                // and center horizontally.
                final int center = (paddingLeft + width - paddingRight) / 2;
                final int childWidth = child.getMeasuredWidth();
                final int childHeight = child.getMeasuredHeight();
                final int left = center - childWidth / 2;
                final int layoutBottom = height - paddingBottom - lp.bottomMargin - mInsets.bottom;
                // We use the top of the challenge view to position the handle, so
                // we never want less than the handle size showing at the bottom.
                final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
                        * (1 - mChallengeOffset));
                child.setAlpha(getChallengeAlpha());
                child.layout(left, bottom - childHeight, left + childWidth, bottom);
            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
                final int center = (paddingLeft + width - paddingRight) / 2;
                final int left = center - child.getMeasuredWidth() / 2;
                final int right = left + child.getMeasuredWidth();
                final int bottom = height - paddingBottom - lp.bottomMargin - mInsets.bottom;
                final int top = bottom - child.getMeasuredHeight();
                child.layout(left, top, right, bottom);
            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                // Scrim views use the entire area, including padding & insets
                child.layout(0, 0, getMeasuredWidth(), getMeasuredHeight());
            } else {
                // Non-challenge views lay out from the upper left, layered.
                child.layout(paddingLeft + lp.leftMargin,
                        paddingTop + lp.topMargin + mInsets.top,
                        paddingLeft + child.getMeasuredWidth(),
                        paddingTop + child.getMeasuredHeight() + mInsets.top);
            }
        }

        if (!mHasLayout) {
            mHasLayout = true;
        }
    }

    @Override
    public void draw(Canvas c) {
        super.draw(c);
        if (DEBUG) {
            final Paint debugPaint = new Paint();
            debugPaint.setColor(0x40FF00CC);
            // show the isInDragHandle() rect
            c.drawRect(mDragHandleEdgeSlop,
                    mChallengeView.getTop() - getDragHandleSizeAbove(),
                    getWidth() - mDragHandleEdgeSlop,
                    mChallengeView.getTop() + getDragHandleSizeBelow(),
                    debugPaint);
        }
    }

    public void computeScroll() {
        super.computeScroll();

        if (!mScroller.isFinished()) {
            if (mChallengeView == null) {
                // Can't scroll if the view is missing.
                Log.e(TAG, "Challenge view missing in computeScroll");
                mScroller.abortAnimation();
                return;
            }

            mScroller.computeScrollOffset();
            moveChallengeTo(mScroller.getCurrY());

            if (mScroller.isFinished()) {
                post(mEndScrollRunnable);
            }
        }
    }

    private void cancelTransitionsInProgress() {
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
            completeChallengeScroll();
        }
        if (mFader != null) {
            mFader.cancel();
        }
    }

    public void fadeInChallenge() {
        fadeChallenge(true);
    }

    public void fadeOutChallenge() {
        fadeChallenge(false);
    }

    public void fadeChallenge(final boolean show) {
        if (mChallengeView != null) {

            cancelTransitionsInProgress();
            float alpha = show ? 1f : 0f;
            int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
            mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
            mFader.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    onFadeStart(show);
                }
                @Override
                public void onAnimationEnd(Animator animation) {
                    onFadeEnd(show);
                }
            });
            mFader.setDuration(duration);
            mFader.start();
        }
    }

    private int getMaxChallengeBottom() {
        if (mChallengeView == null) return 0;
        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getMeasuredHeight();

        return (layoutBottom + challengeHeight - mChallengeBottomBound);
    }

    private int getMinChallengeBottom() {
        return getLayoutBottom();
    }


    private void onFadeStart(boolean show) {
        mChallengeInteractiveInternal = false;
        enableHardwareLayerForChallengeView();

        if (show) {
            moveChallengeTo(getMinChallengeBottom());
        }

        setScrollState(SCROLL_STATE_FADING);
    }

    private void enableHardwareLayerForChallengeView() {
        if (mChallengeView.isHardwareAccelerated()) {
            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
        }
    }

    private void onFadeEnd(boolean show) {
        mChallengeInteractiveInternal = true;
        setChallengeShowing(show);

        if (!show) {
            moveChallengeTo(getMaxChallengeBottom());
        }

        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
        mFader = null;
        setScrollState(SCROLL_STATE_IDLE);
    }

    public int getMaxChallengeTop() {
        if (mChallengeView == null) return 0;

        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getMeasuredHeight();
        return layoutBottom - challengeHeight - mInsets.top;
    }

    /**
     * Move the bottom edge of mChallengeView to a new position and notify the listener
     * if it represents a change in position. Changes made through this method will
     * be stable across layout passes. If this method is called before first layout of
     * this SlidingChallengeLayout it will have no effect.
     *
     * @param bottom New bottom edge in px in this SlidingChallengeLayout's coordinate system.
     * @return true if the challenge view was moved
     */
    private boolean moveChallengeTo(int bottom) {
        if (mChallengeView == null || !mHasLayout) {
            return false;
        }

        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getHeight();

        bottom = Math.max(getMinChallengeBottom(),
                Math.min(bottom, getMaxChallengeBottom()));

        float offset = 1.f - (float) (bottom - layoutBottom) /
                (challengeHeight - mChallengeBottomBound);
        mChallengeOffset = offset;
        if (offset > 0 && !mChallengeShowing) {
            setChallengeShowing(true);
        }

        mChallengeView.layout(mChallengeView.getLeft(),
                bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);

        mChallengeView.setAlpha(getChallengeAlpha());
        if (mScrollListener != null) {
            mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
        }
        postInvalidateOnAnimation();
        return true;
    }

    /**
     * The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
     * the bottom edge of mChallengeView when the challenge is fully opened.
     */
    private int getLayoutBottom() {
        final int bottomMargin = (mChallengeView == null)
                ? 0
                : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
        final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin
                - mInsets.bottom;
        return layoutBottom;
    }

    /**
     * The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
     */
    private int getChallengeBottom() {
        if (mChallengeView == null) return 0;

        return mChallengeView.getBottom();
    }

    /**
     * Show or hide the challenge view, animating it if necessary.
     * @param show true to show, false to hide
     */
    public void showChallenge(boolean show) {
        showChallenge(show, 0);
        if (!show) {
            // Block any drags in progress so that callers can use this to disable dragging
            // for other touch interactions.
            mBlockDrag = true;
        }
    }

    private void showChallenge(int velocity) {
        boolean show = false;
        if (Math.abs(velocity) > mMinVelocity) {
            show = velocity < 0;
        } else {
            show = mChallengeOffset >= 0.5f;
        }
        showChallenge(show, velocity);
    }

    private void showChallenge(boolean show, int velocity) {
        if (mChallengeView == null) {
            setChallengeShowing(false);
            return;
        }

        if (mHasLayout) {
            mChallengeShowingTargetState = show;
            final int layoutBottom = getLayoutBottom();
            animateChallengeTo(show ? layoutBottom :
                    layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
        }
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
                new LayoutParams(p);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams();
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

    public static class LayoutParams extends MarginLayoutParams {
        public int childType = CHILD_TYPE_NONE;
        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 static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;

        public int maxHeight;

        public LayoutParams() {
            this(MATCH_PARENT, WRAP_CONTENT);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
            super(source);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(LayoutParams source) {
            super(source);

            childType = source.childType;
        }

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);

            final TypedArray a = c.obtainStyledAttributes(attrs,
                    R.styleable.SlidingChallengeLayout_Layout);
            childType = a.getInt(R.styleable.SlidingChallengeLayout_Layout_layout_childType,
                    CHILD_TYPE_NONE);
            maxHeight = a.getDimensionPixelSize(
                    R.styleable.SlidingChallengeLayout_Layout_layout_maxHeight, 0);
            a.recycle();
        }
    }
}
