/*
 * Copyright (C) 2015 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.server.accessibility;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.util.MathUtils;
import android.util.Slog;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import android.view.ScaleGestureDetector;
import android.view.ScaleGestureDetector.OnScaleGestureListener;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;

/**
 * This class handles magnification in response to touch events.
 *
 * The behavior is as follows:
 *
 * 1. Triple tap toggles permanent screen magnification which is magnifying
 *    the area around the location of the triple tap. One can think of the
 *    location of the triple tap as the center of the magnified viewport.
 *    For example, a triple tap when not magnified would magnify the screen
 *    and leave it in a magnified state. A triple tapping when magnified would
 *    clear magnification and leave the screen in a not magnified state.
 *
 * 2. Triple tap and hold would magnify the screen if not magnified and enable
 *    viewport dragging mode until the finger goes up. One can think of this
 *    mode as a way to move the magnified viewport since the area around the
 *    moving finger will be magnified to fit the screen. For example, if the
 *    screen was not magnified and the user triple taps and holds the screen
 *    would magnify and the viewport will follow the user's finger. When the
 *    finger goes up the screen will zoom out. If the same user interaction
 *    is performed when the screen is magnified, the viewport movement will
 *    be the same but when the finger goes up the screen will stay magnified.
 *    In other words, the initial magnified state is sticky.
 *
 * 3. Magnification can optionally be "triggered" by some external shortcut
 *    affordance. When this occurs via {@link #notifyShortcutTriggered()} a
 *    subsequent tap in a magnifiable region will engage permanent screen
 *    magnification as described in #1. Alternatively, a subsequent long-press
 *    or drag will engage magnification with viewport dragging as described in
 *    #2. Once magnified, all following behaviors apply whether magnification
 *    was engaged via a triple-tap or by a triggered shortcut.
 *
 * 4. Pinching with any number of additional fingers when viewport dragging
 *    is enabled, i.e. the user triple tapped and holds, would adjust the
 *    magnification scale which will become the current default magnification
 *    scale. The next time the user magnifies the same magnification scale
 *    would be used.
 *
 * 5. When in a permanent magnified state the user can use two or more fingers
 *    to pan the viewport. Note that in this mode the content is panned as
 *    opposed to the viewport dragging mode in which the viewport is moved.
 *
 * 6. When in a permanent magnified state the user can use two or more
 *    fingers to change the magnification scale which will become the current
 *    default magnification scale. The next time the user magnifies the same
 *    magnification scale would be used.
 *
 * 7. The magnification scale will be persisted in settings and in the cloud.
 */
class MagnificationGestureHandler implements EventStreamTransformation {
    private static final String LOG_TAG = "MagnificationEventHandler";

    private static final boolean DEBUG_STATE_TRANSITIONS = false;
    private static final boolean DEBUG_DETECTING = false;
    private static final boolean DEBUG_PANNING = false;

    private static final int STATE_DELEGATING = 1;
    private static final int STATE_DETECTING = 2;
    private static final int STATE_VIEWPORT_DRAGGING = 3;
    private static final int STATE_MAGNIFIED_INTERACTION = 4;

    private static final float MIN_SCALE = 2.0f;
    private static final float MAX_SCALE = 5.0f;

    private final MagnificationController mMagnificationController;
    private final DetectingStateHandler mDetectingStateHandler;
    private final MagnifiedContentInteractionStateHandler mMagnifiedContentInteractionStateHandler;
    private final StateViewportDraggingHandler mStateViewportDraggingHandler;

    private final ScreenStateReceiver mScreenStateReceiver;

    private final boolean mDetectTripleTap;
    private final boolean mTriggerable;

    private EventStreamTransformation mNext;

    private int mCurrentState;
    private int mPreviousState;

    private boolean mTranslationEnabledBeforePan;

    private boolean mShortcutTriggered;

    private PointerCoords[] mTempPointerCoords;
    private PointerProperties[] mTempPointerProperties;

    private long mDelegatingStateDownTime;

    /**
     * @param context Context for resolving various magnification-related resources
     * @param ams AccessibilityManagerService used to obtain a {@link MagnificationController}
     * @param detectTripleTap {@code true} if this detector should detect and respond to triple-tap
     *                                    gestures for engaging and disengaging magnification,
     *                                    {@code false} if it should ignore such gestures
     * @param triggerable {@code true} if this detector should be "triggerable" by some external
     *                                shortcut invoking {@link #notifyShortcutTriggered}, {@code
     *                                false} if it should ignore such triggers.
     */
    public MagnificationGestureHandler(Context context, AccessibilityManagerService ams,
            boolean detectTripleTap, boolean triggerable) {
        mMagnificationController = ams.getMagnificationController();
        mDetectingStateHandler = new DetectingStateHandler(context);
        mStateViewportDraggingHandler = new StateViewportDraggingHandler();
        mMagnifiedContentInteractionStateHandler =
                new MagnifiedContentInteractionStateHandler(context);
        mDetectTripleTap = detectTripleTap;
        mTriggerable = triggerable;

        if (triggerable) {
            mScreenStateReceiver = new ScreenStateReceiver(context, this);
            mScreenStateReceiver.register();
        } else {
            mScreenStateReceiver = null;
        }

        transitionToState(STATE_DETECTING);
    }

    @Override
    public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
        if (!event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)) {
            if (mNext != null) {
                mNext.onMotionEvent(event, rawEvent, policyFlags);
            }
            return;
        }
        if (!mDetectTripleTap && !mTriggerable) {
            if (mNext != null) {
                dispatchTransformedEvent(event, rawEvent, policyFlags);
            }
            return;
        }
        mMagnifiedContentInteractionStateHandler.onMotionEvent(event, rawEvent, policyFlags);
        switch (mCurrentState) {
            case STATE_DELEGATING: {
                handleMotionEventStateDelegating(event, rawEvent, policyFlags);
            }
            break;
            case STATE_DETECTING: {
                mDetectingStateHandler.onMotionEvent(event, rawEvent, policyFlags);
            }
            break;
            case STATE_VIEWPORT_DRAGGING: {
                mStateViewportDraggingHandler.onMotionEvent(event, rawEvent, policyFlags);
            }
            break;
            case STATE_MAGNIFIED_INTERACTION: {
                // mMagnifiedContentInteractionStateHandler handles events only
                // if this is the current state since it uses ScaleGestureDetector
                // and a GestureDetector which need well formed event stream.
            }
            break;
            default: {
                throw new IllegalStateException("Unknown state: " + mCurrentState);
            }
        }
    }

    @Override
    public void onKeyEvent(KeyEvent event, int policyFlags) {
        if (mNext != null) {
            mNext.onKeyEvent(event, policyFlags);
        }
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (mNext != null) {
            mNext.onAccessibilityEvent(event);
        }
    }

    @Override
    public void setNext(EventStreamTransformation next) {
        mNext = next;
    }

    @Override
    public void clearEvents(int inputSource) {
        if (inputSource == InputDevice.SOURCE_TOUCHSCREEN) {
            clear();
        }

        if (mNext != null) {
            mNext.clearEvents(inputSource);
        }
    }

    @Override
    public void onDestroy() {
        if (mScreenStateReceiver != null) {
            mScreenStateReceiver.unregister();
        }
        clear();
    }

    void notifyShortcutTriggered() {
        if (mTriggerable) {
            if (mMagnificationController.resetIfNeeded(true)) {
                clear();
            } else {
                setMagnificationShortcutTriggered(!mShortcutTriggered);
            }
        }
    }

    private void setMagnificationShortcutTriggered(boolean state) {
        if (mShortcutTriggered == state) {
            return;
        }

        mShortcutTriggered = state;
        mMagnificationController.setForceShowMagnifiableBounds(state);
    }

    private void clear() {
        mCurrentState = STATE_DETECTING;
        setMagnificationShortcutTriggered(false);
        mDetectingStateHandler.clear();
        mStateViewportDraggingHandler.clear();
        mMagnifiedContentInteractionStateHandler.clear();
    }

    private void handleMotionEventStateDelegating(MotionEvent event,
            MotionEvent rawEvent, int policyFlags) {
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                mDelegatingStateDownTime = event.getDownTime();
            }
            break;
            case MotionEvent.ACTION_UP: {
                if (mDetectingStateHandler.mDelayedEventQueue == null) {
                    transitionToState(STATE_DETECTING);
                }
            }
            break;
        }
        if (mNext != null) {
            // We cache some events to see if the user wants to trigger magnification.
            // If no magnification is triggered we inject these events with adjusted
            // time and down time to prevent subsequent transformations being confused
            // by stale events. After the cached events, which always have a down, are
            // injected we need to also update the down time of all subsequent non cached
            // events. All delegated events cached and non-cached are delivered here.
            event.setDownTime(mDelegatingStateDownTime);
            dispatchTransformedEvent(event, rawEvent, policyFlags);
        }
    }

    private void dispatchTransformedEvent(MotionEvent event, MotionEvent rawEvent,
            int policyFlags) {
        // If the event is within the magnified portion of the screen we have
        // to change its location to be where the user thinks he is poking the
        // UI which may have been magnified and panned.
        final float eventX = event.getX();
        final float eventY = event.getY();
        if (mMagnificationController.isMagnifying()
                && mMagnificationController.magnificationRegionContains(eventX, eventY)) {
            final float scale = mMagnificationController.getScale();
            final float scaledOffsetX = mMagnificationController.getOffsetX();
            final float scaledOffsetY = mMagnificationController.getOffsetY();
            final int pointerCount = event.getPointerCount();
            PointerCoords[] coords = getTempPointerCoordsWithMinSize(pointerCount);
            PointerProperties[] properties = getTempPointerPropertiesWithMinSize(
                    pointerCount);
            for (int i = 0; i < pointerCount; i++) {
                event.getPointerCoords(i, coords[i]);
                coords[i].x = (coords[i].x - scaledOffsetX) / scale;
                coords[i].y = (coords[i].y - scaledOffsetY) / scale;
                event.getPointerProperties(i, properties[i]);
            }
            event = MotionEvent.obtain(event.getDownTime(),
                    event.getEventTime(), event.getAction(), pointerCount, properties,
                    coords, 0, 0, 1.0f, 1.0f, event.getDeviceId(), 0, event.getSource(),
                    event.getFlags());
        }
        mNext.onMotionEvent(event, rawEvent, policyFlags);
    }

    private PointerCoords[] getTempPointerCoordsWithMinSize(int size) {
        final int oldSize = (mTempPointerCoords != null) ? mTempPointerCoords.length : 0;
        if (oldSize < size) {
            PointerCoords[] oldTempPointerCoords = mTempPointerCoords;
            mTempPointerCoords = new PointerCoords[size];
            if (oldTempPointerCoords != null) {
                System.arraycopy(oldTempPointerCoords, 0, mTempPointerCoords, 0, oldSize);
            }
        }
        for (int i = oldSize; i < size; i++) {
            mTempPointerCoords[i] = new PointerCoords();
        }
        return mTempPointerCoords;
    }

    private PointerProperties[] getTempPointerPropertiesWithMinSize(int size) {
        final int oldSize = (mTempPointerProperties != null) ? mTempPointerProperties.length
                : 0;
        if (oldSize < size) {
            PointerProperties[] oldTempPointerProperties = mTempPointerProperties;
            mTempPointerProperties = new PointerProperties[size];
            if (oldTempPointerProperties != null) {
                System.arraycopy(oldTempPointerProperties, 0, mTempPointerProperties, 0,
                        oldSize);
            }
        }
        for (int i = oldSize; i < size; i++) {
            mTempPointerProperties[i] = new PointerProperties();
        }
        return mTempPointerProperties;
    }

    private void transitionToState(int state) {
        if (DEBUG_STATE_TRANSITIONS) {
            switch (state) {
                case STATE_DELEGATING: {
                    Slog.i(LOG_TAG, "mCurrentState: STATE_DELEGATING");
                }
                break;
                case STATE_DETECTING: {
                    Slog.i(LOG_TAG, "mCurrentState: STATE_DETECTING");
                }
                break;
                case STATE_VIEWPORT_DRAGGING: {
                    Slog.i(LOG_TAG, "mCurrentState: STATE_VIEWPORT_DRAGGING");
                }
                break;
                case STATE_MAGNIFIED_INTERACTION: {
                    Slog.i(LOG_TAG, "mCurrentState: STATE_MAGNIFIED_INTERACTION");
                }
                break;
                default: {
                    throw new IllegalArgumentException("Unknown state: " + state);
                }
            }
        }
        mPreviousState = mCurrentState;
        mCurrentState = state;
    }

    private interface MotionEventHandler {

        void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags);

        void clear();
    }

    /**
     * This class determines if the user is performing a scale or pan gesture.
     */
    private final class MagnifiedContentInteractionStateHandler extends SimpleOnGestureListener
            implements OnScaleGestureListener, MotionEventHandler {

        private final ScaleGestureDetector mScaleGestureDetector;

        private final GestureDetector mGestureDetector;

        private final float mScalingThreshold;

        private float mInitialScaleFactor = -1;

        private boolean mScaling;

        public MagnifiedContentInteractionStateHandler(Context context) {
            final TypedValue scaleValue = new TypedValue();
            context.getResources().getValue(
                    com.android.internal.R.dimen.config_screen_magnification_scaling_threshold,
                    scaleValue, false);
            mScalingThreshold = scaleValue.getFloat();
            mScaleGestureDetector = new ScaleGestureDetector(context, this);
            mScaleGestureDetector.setQuickScaleEnabled(false);
            mGestureDetector = new GestureDetector(context, this);
        }

        @Override
        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
            mScaleGestureDetector.onTouchEvent(event);
            mGestureDetector.onTouchEvent(event);
            if (mCurrentState != STATE_MAGNIFIED_INTERACTION) {
                return;
            }
            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                clear();
                mMagnificationController.persistScale();
                if (mPreviousState == STATE_VIEWPORT_DRAGGING) {
                    transitionToState(STATE_VIEWPORT_DRAGGING);
                } else {
                    transitionToState(STATE_DETECTING);
                }
            }
        }

        @Override
        public boolean onScroll(MotionEvent first, MotionEvent second, float distanceX,
                float distanceY) {
            if (mCurrentState != STATE_MAGNIFIED_INTERACTION) {
                return true;
            }
            if (DEBUG_PANNING) {
                Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
                        + " scrollY: " + distanceY);
            }
            mMagnificationController.offsetMagnifiedRegion(distanceX, distanceY,
                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            if (!mScaling) {
                if (mInitialScaleFactor < 0) {
                    mInitialScaleFactor = detector.getScaleFactor();
                } else {
                    final float deltaScale = detector.getScaleFactor() - mInitialScaleFactor;
                    if (Math.abs(deltaScale) > mScalingThreshold) {
                        mScaling = true;
                        return true;
                    }
                }
                return false;
            }

            final float initialScale = mMagnificationController.getScale();
            final float targetScale = initialScale * detector.getScaleFactor();

            // Don't allow a gesture to move the user further outside the
            // desired bounds for gesture-controlled scaling.
            final float scale;
            if (targetScale > MAX_SCALE && targetScale > initialScale) {
                // The target scale is too big and getting bigger.
                scale = MAX_SCALE;
            } else if (targetScale < MIN_SCALE && targetScale < initialScale) {
                // The target scale is too small and getting smaller.
                scale = MIN_SCALE;
            } else {
                // The target scale may be outside our bounds, but at least
                // it's moving in the right direction. This avoids a "jump" if
                // we're at odds with some other service's desired bounds.
                scale = targetScale;
            }

            final float pivotX = detector.getFocusX();
            final float pivotY = detector.getFocusY();
            mMagnificationController.setScale(scale, pivotX, pivotY, false,
                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
            return true;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return (mCurrentState == STATE_MAGNIFIED_INTERACTION);
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            clear();
        }

        @Override
        public void clear() {
            mInitialScaleFactor = -1;
            mScaling = false;
        }
    }

    /**
     * This class handles motion events when the event dispatcher has
     * determined that the user is performing a single-finger drag of the
     * magnification viewport.
     */
    private final class StateViewportDraggingHandler implements MotionEventHandler {

        private boolean mLastMoveOutsideMagnifiedRegion;

        @Override
        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
            final int action = event.getActionMasked();
            switch (action) {
                case MotionEvent.ACTION_DOWN: {
                    throw new IllegalArgumentException("Unexpected event type: ACTION_DOWN");
                }
                case MotionEvent.ACTION_POINTER_DOWN: {
                    clear();
                    transitionToState(STATE_MAGNIFIED_INTERACTION);
                }
                break;
                case MotionEvent.ACTION_MOVE: {
                    if (event.getPointerCount() != 1) {
                        throw new IllegalStateException("Should have one pointer down.");
                    }
                    final float eventX = event.getX();
                    final float eventY = event.getY();
                    if (mMagnificationController.magnificationRegionContains(eventX, eventY)) {
                        if (mLastMoveOutsideMagnifiedRegion) {
                            mLastMoveOutsideMagnifiedRegion = false;
                            mMagnificationController.setCenter(eventX, eventY, true,
                                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                        } else {
                            mMagnificationController.setCenter(eventX, eventY, false,
                                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                        }
                    } else {
                        mLastMoveOutsideMagnifiedRegion = true;
                    }
                }
                break;
                case MotionEvent.ACTION_UP: {
                    if (!mTranslationEnabledBeforePan) {
                        mMagnificationController.reset(true);
                    }
                    clear();
                    transitionToState(STATE_DETECTING);
                }
                break;
                case MotionEvent.ACTION_POINTER_UP: {
                    throw new IllegalArgumentException(
                            "Unexpected event type: ACTION_POINTER_UP");
                }
            }
        }

        @Override
        public void clear() {
            mLastMoveOutsideMagnifiedRegion = false;
        }
    }

    /**
     * This class handles motion events when the event dispatch has not yet
     * determined what the user is doing. It watches for various tap events.
     */
    private final class DetectingStateHandler implements MotionEventHandler {

        private static final int MESSAGE_ON_ACTION_TAP_AND_HOLD = 1;

        private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2;

        private static final int ACTION_TAP_COUNT = 3;

        private final int mTapTimeSlop = ViewConfiguration.getJumpTapTimeout();

        private final int mMultiTapTimeSlop;

        private final int mTapDistanceSlop;

        private final int mMultiTapDistanceSlop;

        private MotionEventInfo mDelayedEventQueue;

        private MotionEvent mLastDownEvent;

        private MotionEvent mLastTapUpEvent;

        private int mTapCount;

        public DetectingStateHandler(Context context) {
            mMultiTapTimeSlop = ViewConfiguration.getDoubleTapTimeout()
                    + context.getResources().getInteger(
                    com.android.internal.R.integer.config_screen_magnification_multi_tap_adjustment);
            mTapDistanceSlop = ViewConfiguration.get(context).getScaledTouchSlop();
            mMultiTapDistanceSlop = ViewConfiguration.get(context).getScaledDoubleTapSlop();
        }

        private final Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                final int type = message.what;
                switch (type) {
                    case MESSAGE_ON_ACTION_TAP_AND_HOLD: {
                        MotionEvent event = (MotionEvent) message.obj;
                        final int policyFlags = message.arg1;
                        onActionTapAndHold(event, policyFlags);
                    }
                    break;
                    case MESSAGE_TRANSITION_TO_DELEGATING_STATE: {
                        transitionToState(STATE_DELEGATING);
                        sendDelayedMotionEvents();
                        clear();
                    }
                    break;
                    default: {
                        throw new IllegalArgumentException("Unknown message type: " + type);
                    }
                }
            }
        };

        @Override
        public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
            cacheDelayedMotionEvent(event, rawEvent, policyFlags);
            final int action = event.getActionMasked();
            switch (action) {
                case MotionEvent.ACTION_DOWN: {
                    mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
                    if (!mMagnificationController.magnificationRegionContains(
                            event.getX(), event.getY())) {
                        transitionToDelegatingState(!mShortcutTriggered);
                        return;
                    }
                    if (mShortcutTriggered) {
                        Message message = mHandler.obtainMessage(MESSAGE_ON_ACTION_TAP_AND_HOLD,
                                policyFlags, 0, event);
                        mHandler.sendMessageDelayed(message,
                                ViewConfiguration.getLongPressTimeout());
                        return;
                    }
                    if (mDetectTripleTap) {
                        if ((mTapCount == ACTION_TAP_COUNT - 1) && (mLastDownEvent != null)
                                && GestureUtils.isMultiTap(mLastDownEvent, event, mMultiTapTimeSlop,
                                        mMultiTapDistanceSlop, 0)) {
                            Message message = mHandler.obtainMessage(MESSAGE_ON_ACTION_TAP_AND_HOLD,
                                    policyFlags, 0, event);
                            mHandler.sendMessageDelayed(message,
                                    ViewConfiguration.getLongPressTimeout());
                        } else if (mTapCount < ACTION_TAP_COUNT) {
                            Message message = mHandler.obtainMessage(
                                    MESSAGE_TRANSITION_TO_DELEGATING_STATE);
                            mHandler.sendMessageDelayed(message, mMultiTapTimeSlop);
                        }
                        clearLastDownEvent();
                        mLastDownEvent = MotionEvent.obtain(event);
                    } else if (mMagnificationController.isMagnifying()) {
                        // If magnified, consume an ACTION_DOWN until mMultiTapTimeSlop or
                        // mTapDistanceSlop is reached to ensure MAGNIFIED_INTERACTION is reachable.
                        Message message = mHandler.obtainMessage(
                                MESSAGE_TRANSITION_TO_DELEGATING_STATE);
                        mHandler.sendMessageDelayed(message, mMultiTapTimeSlop);
                        return;
                    } else {
                        transitionToDelegatingState(true);
                        return;
                    }
                }
                break;
                case MotionEvent.ACTION_POINTER_DOWN: {
                    if (mMagnificationController.isMagnifying()) {
                        mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
                        transitionToState(STATE_MAGNIFIED_INTERACTION);
                        clear();
                    } else {
                        transitionToDelegatingState(true);
                    }
                }
                break;
                case MotionEvent.ACTION_MOVE: {
                    if (mLastDownEvent != null && mTapCount < ACTION_TAP_COUNT - 1) {
                        final double distance = GestureUtils.computeDistance(mLastDownEvent,
                                event, 0);
                        if (Math.abs(distance) > mTapDistanceSlop) {
                            transitionToDelegatingState(true);
                        }
                    }
                }
                break;
                case MotionEvent.ACTION_UP: {
                    if (!mMagnificationController.magnificationRegionContains(
                            event.getX(), event.getY())) {
                        transitionToDelegatingState(!mShortcutTriggered);
                        return;
                    }
                    if (mShortcutTriggered) {
                        clear();
                        onActionTap(event, policyFlags);
                        return;
                    }
                    if (mLastDownEvent == null) {
                        return;
                    }
                    mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
                    if (!GestureUtils.isTap(mLastDownEvent, event, mTapTimeSlop,
                            mTapDistanceSlop, 0)) {
                        transitionToDelegatingState(true);
                        return;
                    }
                    if (mLastTapUpEvent != null && !GestureUtils.isMultiTap(
                            mLastTapUpEvent, event, mMultiTapTimeSlop, mMultiTapDistanceSlop, 0)) {
                        transitionToDelegatingState(true);
                        return;
                    }
                    mTapCount++;
                    if (DEBUG_DETECTING) {
                        Slog.i(LOG_TAG, "Tap count:" + mTapCount);
                    }
                    if (mTapCount == ACTION_TAP_COUNT) {
                        clear();
                        onActionTap(event, policyFlags);
                        return;
                    }
                    clearLastTapUpEvent();
                    mLastTapUpEvent = MotionEvent.obtain(event);
                }
                break;
                case MotionEvent.ACTION_POINTER_UP: {
                    /* do nothing */
                }
                break;
            }
        }

        @Override
        public void clear() {
            setMagnificationShortcutTriggered(false);
            mHandler.removeMessages(MESSAGE_ON_ACTION_TAP_AND_HOLD);
            mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
            clearTapDetectionState();
            clearDelayedMotionEvents();
        }

        private void clearTapDetectionState() {
            mTapCount = 0;
            clearLastTapUpEvent();
            clearLastDownEvent();
        }

        private void clearLastTapUpEvent() {
            if (mLastTapUpEvent != null) {
                mLastTapUpEvent.recycle();
                mLastTapUpEvent = null;
            }
        }

        private void clearLastDownEvent() {
            if (mLastDownEvent != null) {
                mLastDownEvent.recycle();
                mLastDownEvent = null;
            }
        }

        private void cacheDelayedMotionEvent(MotionEvent event, MotionEvent rawEvent,
                int policyFlags) {
            MotionEventInfo info = MotionEventInfo.obtain(event, rawEvent,
                    policyFlags);
            if (mDelayedEventQueue == null) {
                mDelayedEventQueue = info;
            } else {
                MotionEventInfo tail = mDelayedEventQueue;
                while (tail.mNext != null) {
                    tail = tail.mNext;
                }
                tail.mNext = info;
            }
        }

        private void sendDelayedMotionEvents() {
            while (mDelayedEventQueue != null) {
                MotionEventInfo info = mDelayedEventQueue;
                mDelayedEventQueue = info.mNext;
                MagnificationGestureHandler.this.onMotionEvent(info.mEvent, info.mRawEvent,
                        info.mPolicyFlags);
                info.recycle();
            }
        }

        private void clearDelayedMotionEvents() {
            while (mDelayedEventQueue != null) {
                MotionEventInfo info = mDelayedEventQueue;
                mDelayedEventQueue = info.mNext;
                info.recycle();
            }
        }

        private void transitionToDelegatingState(boolean andClear) {
            transitionToState(STATE_DELEGATING);
            sendDelayedMotionEvents();
            if (andClear) {
                clear();
            }
        }

        private void onActionTap(MotionEvent up, int policyFlags) {
            if (DEBUG_DETECTING) {
                Slog.i(LOG_TAG, "onActionTap()");
            }

            if (!mMagnificationController.isMagnifying()) {
                final float targetScale = mMagnificationController.getPersistedScale();
                final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE);
                mMagnificationController.setScaleAndCenter(scale, up.getX(), up.getY(), true,
                        AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
            } else {
                mMagnificationController.reset(true);
            }
        }

        private void onActionTapAndHold(MotionEvent down, int policyFlags) {
            if (DEBUG_DETECTING) {
                Slog.i(LOG_TAG, "onActionTapAndHold()");
            }

            clear();
            mTranslationEnabledBeforePan = mMagnificationController.isMagnifying();

            final float targetScale = mMagnificationController.getPersistedScale();
            final float scale = MathUtils.constrain(targetScale, MIN_SCALE, MAX_SCALE);
            mMagnificationController.setScaleAndCenter(scale, down.getX(), down.getY(), true,
                    AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);

            transitionToState(STATE_VIEWPORT_DRAGGING);
        }
    }

    private static final class MotionEventInfo {

        private static final int MAX_POOL_SIZE = 10;

        private static final Object sLock = new Object();

        private static MotionEventInfo sPool;

        private static int sPoolSize;

        private MotionEventInfo mNext;

        private boolean mInPool;

        public MotionEvent mEvent;

        public MotionEvent mRawEvent;

        public int mPolicyFlags;

        public static MotionEventInfo obtain(MotionEvent event, MotionEvent rawEvent,
                int policyFlags) {
            synchronized (sLock) {
                MotionEventInfo info;
                if (sPoolSize > 0) {
                    sPoolSize--;
                    info = sPool;
                    sPool = info.mNext;
                    info.mNext = null;
                    info.mInPool = false;
                } else {
                    info = new MotionEventInfo();
                }
                info.initialize(event, rawEvent, policyFlags);
                return info;
            }
        }

        private void initialize(MotionEvent event, MotionEvent rawEvent,
                int policyFlags) {
            mEvent = MotionEvent.obtain(event);
            mRawEvent = MotionEvent.obtain(rawEvent);
            mPolicyFlags = policyFlags;
        }

        public void recycle() {
            synchronized (sLock) {
                if (mInPool) {
                    throw new IllegalStateException("Already recycled.");
                }
                clear();
                if (sPoolSize < MAX_POOL_SIZE) {
                    sPoolSize++;
                    mNext = sPool;
                    sPool = this;
                    mInPool = true;
                }
            }
        }

        private void clear() {
            mEvent.recycle();
            mEvent = null;
            mRawEvent.recycle();
            mRawEvent = null;
            mPolicyFlags = 0;
        }
    }

    /**
     * BroadcastReceiver used to cancel the magnification shortcut when the screen turns off
     */
    private static class ScreenStateReceiver extends BroadcastReceiver {
        private final Context mContext;
        private final MagnificationGestureHandler mGestureHandler;

        public ScreenStateReceiver(Context context, MagnificationGestureHandler gestureHandler) {
            mContext = context;
            mGestureHandler = gestureHandler;
        }

        public void register() {
            mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
        }

        public void unregister() {
            mContext.unregisterReceiver(this);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            mGestureHandler.setMagnificationShortcutTriggered(false);
        }
    }
}
