/*
 * 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 android.view;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;

/**
 * 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 queuing 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 an 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 may 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 WindowManagerPolicyConstants#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 cancellation 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 WindowManagerPolicyConstants#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 get sent to the dispatcher should usually include the
 * {@link WindowManagerPolicyConstants#FLAG_PASS_TO_USER} flag.  Otherwise, they will be dropped!
 * </p><p>
 * It may be prudent to disable automatic key repeating for synthetic key events
 * by setting the {@link WindowManagerPolicyConstants#FLAG_DISABLE_KEY_REPEAT} policy flag.
 * </p>
 *
 * @hide
 */
public abstract class InputFilter extends IInputFilter.Stub {
    private static final int MSG_INSTALL = 1;
    private static final int MSG_UNINSTALL = 2;
    private static final int MSG_INPUT_EVENT = 3;

    // 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;

    private final H mH;

    private IInputFilterHost mHost;

    /**
     * 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.
     */
    public final void install(IInputFilterHost host) {
        mH.obtainMessage(MSG_INSTALL, host).sendToTarget();
    }

    /**
     * Called when the input filter is uninstalled.
     * This method is guaranteed to be non-reentrant.
     */
    public 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 public 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);
        }
        try {
            mHost.sendInputEvent(event, policyFlags);
        } catch (RemoteException re) {
            /* ignore */
        }
    }

    /**
     * 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 = (IInputFilterHost) 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;
                }
            }
        }
    }
}
