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

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.InputEvent;
import android.view.InputEventConsistencyVerifier;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.WindowManagerPolicy;

/**
 * Filters input events before they are dispatched to the system.
 * <p>
 * At most one input filter can be installed by calling
 * {@link WindowManagerService#setInputFilter}.  When an input filter is installed, the
 * system's behavior changes as follows:
 * <ul>
 * <li>Input events are first delivered to the {@link WindowManagerPolicy}
 * interception methods before queueing as usual.  This critical step takes care of managing
 * the power state of the device and handling wake keys.</li>
 * <li>Input events are then asynchronously delivered to the input filter's
 * {@link #onInputEvent(InputEvent)} method instead of being enqueued for dispatch to
 * applications as usual.  The input filter only receives input events that were
 * generated by input device; the input filter will not receive input events that were
 * injected into the system by other means, such as by instrumentation.</li>
 * <li>The input filter processes and optionally transforms the stream of events.  For example,
 * it may transform a sequence of motion events representing an accessibility gesture into
 * a different sequence of motion events, key presses or other system-level interactions.
 * The input filter can send events to be dispatched by calling
 * {@link #sendInputEvent(InputEvent)} and passing appropriate policy flags for the
 * input event.</li>
 * </ul>
 * </p>
 * <h3>The importance of input event consistency</h3>
 * <p>
 * The input filter mechanism is very low-level.  At a minimum, it needs to ensure that it
 * sends an internally consistent stream of input events to the dispatcher.  There are
 * very important invariants to be maintained.
 * </p><p>
 * For example, if a key down is sent, a corresponding key up should also be sent eventually.
 * Likewise, for touch events, each pointer must individually go down with
 * {@link MotionEvent#ACTION_DOWN} or {@link MotionEvent#ACTION_POINTER_DOWN} and then
 * individually go up with {@link MotionEvent#ACTION_POINTER_UP} or {@link MotionEvent#ACTION_UP}
 * and the sequence of pointer ids used must be consistent throughout the gesture.
 * </p><p>
 * Sometimes a filter may wish to cancel a previously dispatched key or motion.  It should
 * use {@link KeyEvent#FLAG_CANCELED} or {@link MotionEvent#ACTION_CANCEL} accordingly.
 * </p><p>
 * The input filter must take into account the fact that the input events coming from different
 * devices or even different sources all consist of distinct streams of input.
 * Use {@link InputEvent#getDeviceId()} and {@link InputEvent#getSource()} to identify
 * the source of the event and its semantics.  There are be multiple sources of keys,
 * touches and other input: they must be kept separate.
 * </p>
 * <h3>Policy flags</h3>
 * <p>
 * Input events received from the dispatcher and sent to the dispatcher have policy flags
 * associated with them.  Policy flags control some functions of the dispatcher.
 * </p><p>
 * The early policy interception decides whether an input event should be delivered
 * to applications or dropped.  The policy indicates its decision by setting the
 * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} policy flag.  The input filter may
 * sometimes receive events that do not have this flag set.  It should take note of
 * the fact that the policy intends to drop the event, clean up its state, and
 * then send appropriate cancelation events to the dispatcher if needed.
 * </p><p>
 * For example, suppose the input filter is processing a gesture and one of the touch events
 * it receives does not have the {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag set.
 * The input filter should clear its internal state about the gesture and then send key or
 * motion events to the dispatcher to cancel any keys or pointers that are down.
 * </p><p>
 * Corollary: Events that set sent to the dispatcher should usually include the
 * {@link WindowManagerPolicy#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
 * </p><p>
 * It may be prudent to disable automatic key repeating for synthetically generated
 * keys by setting the {@link WindowManagerPolicy#FLAG_DISABLE_KEY_REPEAT} policy flag.
 * </p>
 */
public abstract class InputFilter {
    private static final int MSG_INSTALL = 1;
    private static final int MSG_UNINSTALL = 2;
    private static final int MSG_INPUT_EVENT = 3;

    private final H mH;
    private Host mHost;

    // Consistency verifiers for debugging purposes.
    private final InputEventConsistencyVerifier mInboundInputEventConsistencyVerifier =
            InputEventConsistencyVerifier.isInstrumentationEnabled() ?
                    new InputEventConsistencyVerifier(this,
                            InputEventConsistencyVerifier.FLAG_RAW_DEVICE_INPUT,
                            "InputFilter#InboundInputEventConsistencyVerifier") : null;
    private final InputEventConsistencyVerifier mOutboundInputEventConsistencyVerifier =
            InputEventConsistencyVerifier.isInstrumentationEnabled() ?
                    new InputEventConsistencyVerifier(this,
                            InputEventConsistencyVerifier.FLAG_RAW_DEVICE_INPUT,
                            "InputFilter#OutboundInputEventConsistencyVerifier") : null;

    /**
     * Creates the input filter.
     *
     * @param looper The looper to run callbacks on.
     */
    public InputFilter(Looper looper) {
        mH = new H(looper);
    }

    /**
     * Called when the input filter is installed.
     * This method is guaranteed to be non-reentrant.
     *
     * @param host The input filter host environment.
     */
    final void install(Host host) {
        mH.obtainMessage(MSG_INSTALL, host).sendToTarget();
    }

    /**
     * Called when the input filter is uninstalled.
     * This method is guaranteed to be non-reentrant.
     */
    final void uninstall() {
        mH.obtainMessage(MSG_UNINSTALL).sendToTarget();
    }

    /**
     * Called to enqueue the input event for filtering.
     * The event will be recycled after the input filter processes it.
     * This method is guaranteed to be non-reentrant.
     *
     * @param event The input event to enqueue.
     */
    final void filterInputEvent(InputEvent event, int policyFlags) {
        mH.obtainMessage(MSG_INPUT_EVENT, policyFlags, 0, event).sendToTarget();
    }

    /**
     * Sends an input event to the dispatcher.
     *
     * @param event The input event to publish.
     * @param policyFlags The input event policy flags.
     */
    public void sendInputEvent(InputEvent event, int policyFlags) {
        if (event == null) {
            throw new IllegalArgumentException("event must not be null");
        }
        if (mHost == null) {
            throw new IllegalStateException("Cannot send input event because the input filter " +
                    "is not installed.");
        }
        if (mOutboundInputEventConsistencyVerifier != null) {
            mOutboundInputEventConsistencyVerifier.onInputEvent(event, 0);
        }
        mHost.sendInputEvent(event, policyFlags);
    }

    /**
     * Called when an input event has been received from the dispatcher.
     * <p>
     * The default implementation sends the input event back to the dispatcher, unchanged.
     * </p><p>
     * The event will be recycled when this method returns.  If you want to keep it around,
     * make a copy!
     * </p>
     *
     * @param event The input event that was received.
     * @param policyFlags The input event policy flags.
     */
    public void onInputEvent(InputEvent event, int policyFlags) {
        sendInputEvent(event, policyFlags);
    }

    /**
     * Called when the filter is installed into the dispatch pipeline.
     * <p>
     * This method is called before the input filter receives any input events.
     * The input filter should take this opportunity to prepare itself.
     * </p>
     */
    public void onInstalled() {
    }

    /**
     * Called when the filter is uninstalled from the dispatch pipeline.
     * <p>
     * This method is called after the input filter receives its last input event.
     * The input filter should take this opportunity to clean up.
     * </p>
     */
    public void onUninstalled() {
    }

    private final class H extends Handler {
        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INSTALL:
                    mHost = (Host)msg.obj;
                    if (mInboundInputEventConsistencyVerifier != null) {
                        mInboundInputEventConsistencyVerifier.reset();
                    }
                    if (mOutboundInputEventConsistencyVerifier != null) {
                        mOutboundInputEventConsistencyVerifier.reset();
                    }
                    onInstalled();
                    break;

                case MSG_UNINSTALL:
                    try {
                        onUninstalled();
                    } finally {
                        mHost = null;
                    }
                    break;

                case MSG_INPUT_EVENT: {
                    final InputEvent event = (InputEvent)msg.obj;
                    try {
                        if (mInboundInputEventConsistencyVerifier != null) {
                            mInboundInputEventConsistencyVerifier.onInputEvent(event, 0);
                        }
                        onInputEvent(event, msg.arg1);
                    } finally {
                        event.recycle();
                    }
                    break;
                }
            }
        }
    }

    interface Host {
        public void sendInputEvent(InputEvent event, int policyFlags);
    }
}
