InputQueue.java revision c5ed5910c9ef066cec6a13bbb404ec57b1e92637
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.os.MessageQueue;
20import android.util.Slog;
21
22/**
23 * An input queue provides a mechanism for an application to receive incoming
24 * input events.  Currently only usable from native code.
25 */
26public final class InputQueue {
27    private static final String TAG = "InputQueue";
28
29    private static final boolean DEBUG = false;
30
31    public static interface Callback {
32        void onInputQueueCreated(InputQueue queue);
33        void onInputQueueDestroyed(InputQueue queue);
34    }
35
36    final InputChannel mChannel;
37
38    private static Object sLock = new Object();
39
40    private static native void nativeRegisterInputChannel(InputChannel inputChannel,
41            InputHandler inputHandler, MessageQueue messageQueue);
42    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
43    private static native void nativeFinished(long finishedToken);
44
45    /** @hide */
46    public InputQueue(InputChannel channel) {
47        mChannel = channel;
48    }
49
50    /** @hide */
51    public InputChannel getInputChannel() {
52        return mChannel;
53    }
54
55    /**
56     * Registers an input channel and handler.
57     * @param inputChannel The input channel to register.
58     * @param inputHandler The input handler to input events send to the target.
59     * @param messageQueue The message queue on whose thread the handler should be invoked.
60     * @hide
61     */
62    public static void registerInputChannel(InputChannel inputChannel, InputHandler inputHandler,
63            MessageQueue messageQueue) {
64        if (inputChannel == null) {
65            throw new IllegalArgumentException("inputChannel must not be null");
66        }
67        if (inputHandler == null) {
68            throw new IllegalArgumentException("inputHandler must not be null");
69        }
70        if (messageQueue == null) {
71            throw new IllegalArgumentException("messageQueue must not be null");
72        }
73
74        synchronized (sLock) {
75            if (DEBUG) {
76                Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
77            }
78
79            nativeRegisterInputChannel(inputChannel, inputHandler, messageQueue);
80        }
81    }
82
83    /**
84     * Unregisters an input channel.
85     * Does nothing if the channel is not currently registered.
86     * @param inputChannel The input channel to unregister.
87     * @hide
88     */
89    public static void unregisterInputChannel(InputChannel inputChannel) {
90        if (inputChannel == null) {
91            throw new IllegalArgumentException("inputChannel must not be null");
92        }
93
94        synchronized (sLock) {
95            if (DEBUG) {
96                Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
97            }
98
99            nativeUnregisterInputChannel(inputChannel);
100        }
101    }
102
103    @SuppressWarnings("unused")
104    private static void dispatchKeyEvent(InputHandler inputHandler,
105            KeyEvent event, long finishedToken) {
106        Runnable finishedCallback = new FinishedCallback(finishedToken);
107        inputHandler.handleKey(event, finishedCallback);
108    }
109
110    @SuppressWarnings("unused")
111    private static void dispatchMotionEvent(InputHandler inputHandler,
112            MotionEvent event, long finishedToken) {
113        Runnable finishedCallback = new FinishedCallback(finishedToken);
114        inputHandler.handleMotion(event, finishedCallback);
115    }
116
117    // TODO consider recycling finished callbacks when done
118    private static class FinishedCallback implements Runnable {
119        private long mFinishedToken;
120
121        public FinishedCallback(long finishedToken) {
122            mFinishedToken = finishedToken;
123        }
124
125        public void run() {
126            synchronized (sLock) {
127                nativeFinished(mFinishedToken);
128            }
129        }
130    }
131}
132