InputQueue.java revision 46b9ac0ae2162309774a7478cd9d4e578747bfc2
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 sent over an input channel.  Signalling is implemented by MessageQueue.
25 * @hide
26 */
27public final class InputQueue {
28    private static final String TAG = "InputQueue";
29
30    // Describes the interpretation of an event.
31    // XXX This concept is tentative.  See comments in android/input.h.
32    public static final int INPUT_EVENT_NATURE_KEY = 1;
33    public static final int INPUT_EVENT_NATURE_TOUCH = 2;
34    public static final int INPUT_EVENT_NATURE_TRACKBALL = 3;
35
36    private static Object sLock = new Object();
37
38    private static native void nativeRegisterInputChannel(InputChannel inputChannel,
39            InputHandler inputHandler, MessageQueue messageQueue);
40    private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
41    private static native void nativeFinished(long finishedToken);
42
43    private InputQueue() {
44    }
45
46    /**
47     * Registers an input channel and handler.
48     * @param inputChannel The input channel to register.
49     * @param inputHandler The input handler to input events send to the target.
50     * @param messageQueue The message queue on whose thread the handler should be invoked.
51     */
52    public static void registerInputChannel(InputChannel inputChannel, InputHandler inputHandler,
53            MessageQueue messageQueue) {
54        if (inputChannel == null) {
55            throw new IllegalArgumentException("inputChannel must not be null");
56        }
57        if (inputHandler == null) {
58            throw new IllegalArgumentException("inputHandler must not be null");
59        }
60        if (messageQueue == null) {
61            throw new IllegalArgumentException("messageQueue must not be null");
62        }
63
64        synchronized (sLock) {
65            Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
66            nativeRegisterInputChannel(inputChannel, inputHandler, messageQueue);
67        }
68    }
69
70    /**
71     * Unregisters an input channel.
72     * Does nothing if the channel is not currently registered.
73     * @param inputChannel The input channel to unregister.
74     */
75    public static void unregisterInputChannel(InputChannel inputChannel) {
76        if (inputChannel == null) {
77            throw new IllegalArgumentException("inputChannel must not be null");
78        }
79
80        synchronized (sLock) {
81            Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
82            nativeUnregisterInputChannel(inputChannel);
83        }
84    }
85
86    @SuppressWarnings("unused")
87    private static void dispatchKeyEvent(InputHandler inputHandler,
88            KeyEvent event, int nature, long finishedToken) {
89        Runnable finishedCallback = new FinishedCallback(finishedToken);
90
91        if (nature == INPUT_EVENT_NATURE_KEY) {
92            inputHandler.handleKey(event, finishedCallback);
93        } else {
94            Slog.d(TAG, "Unsupported nature for key event: " + nature);
95        }
96    }
97
98    @SuppressWarnings("unused")
99    private static void dispatchMotionEvent(InputHandler inputHandler,
100            MotionEvent event, int nature, long finishedToken) {
101        Runnable finishedCallback = new FinishedCallback(finishedToken);
102
103        if (nature == INPUT_EVENT_NATURE_TOUCH) {
104            inputHandler.handleTouch(event, finishedCallback);
105        } else if (nature == INPUT_EVENT_NATURE_TRACKBALL) {
106            inputHandler.handleTrackball(event, finishedCallback);
107        } else {
108            Slog.d(TAG, "Unsupported nature for motion event: " + nature);
109        }
110    }
111
112    // TODO consider recycling finished callbacks when done
113    private static class FinishedCallback implements Runnable {
114        private long mFinishedToken;
115
116        public FinishedCallback(long finishedToken) {
117            mFinishedToken = finishedToken;
118        }
119
120        public void run() {
121            synchronized (sLock) {
122                nativeFinished(mFinishedToken);
123            }
124        }
125    }
126}
127