summaryrefslogtreecommitdiff
path: root/android/view/InputEventSender.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/view/InputEventSender.java')
-rw-r--r--android/view/InputEventSender.java143
1 files changed, 143 insertions, 0 deletions
diff --git a/android/view/InputEventSender.java b/android/view/InputEventSender.java
new file mode 100644
index 00000000..b25fb65b
--- /dev/null
+++ b/android/view/InputEventSender.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 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.Looper;
+import android.os.MessageQueue;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Provides a low-level mechanism for an application to send input events.
+ * @hide
+ */
+public abstract class InputEventSender {
+ private static final String TAG = "InputEventSender";
+
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+
+ private long mSenderPtr;
+
+ // We keep references to the input channel and message queue objects here so that
+ // they are not GC'd while the native peer of the receiver is using them.
+ private InputChannel mInputChannel;
+ private MessageQueue mMessageQueue;
+
+ private static native long nativeInit(WeakReference<InputEventSender> sender,
+ InputChannel inputChannel, MessageQueue messageQueue);
+ private static native void nativeDispose(long senderPtr);
+ private static native boolean nativeSendKeyEvent(long senderPtr, int seq, KeyEvent event);
+ private static native boolean nativeSendMotionEvent(long senderPtr, int seq, MotionEvent event);
+
+ /**
+ * Creates an input event sender bound to the specified input channel.
+ *
+ * @param inputChannel The input channel.
+ * @param looper The looper to use when invoking callbacks.
+ */
+ public InputEventSender(InputChannel inputChannel, Looper looper) {
+ if (inputChannel == null) {
+ throw new IllegalArgumentException("inputChannel must not be null");
+ }
+ if (looper == null) {
+ throw new IllegalArgumentException("looper must not be null");
+ }
+
+ mInputChannel = inputChannel;
+ mMessageQueue = looper.getQueue();
+ mSenderPtr = nativeInit(new WeakReference<InputEventSender>(this),
+ inputChannel, mMessageQueue);
+
+ mCloseGuard.open("dispose");
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ dispose(true);
+ } finally {
+ super.finalize();
+ }
+ }
+
+ /**
+ * Disposes the receiver.
+ */
+ public void dispose() {
+ dispose(false);
+ }
+
+ private void dispose(boolean finalized) {
+ if (mCloseGuard != null) {
+ if (finalized) {
+ mCloseGuard.warnIfOpen();
+ }
+ mCloseGuard.close();
+ }
+
+ if (mSenderPtr != 0) {
+ nativeDispose(mSenderPtr);
+ mSenderPtr = 0;
+ }
+ mInputChannel = null;
+ mMessageQueue = null;
+ }
+
+ /**
+ * Called when an input event is finished.
+ *
+ * @param seq The input event sequence number.
+ * @param handled True if the input event was handled.
+ */
+ public void onInputEventFinished(int seq, boolean handled) {
+ }
+
+ /**
+ * Sends an input event.
+ * Must be called on the same Looper thread to which the sender is attached.
+ *
+ * @param seq The input event sequence number.
+ * @param event The input event to send.
+ * @return True if the entire event was sent successfully. May return false
+ * if the input channel buffer filled before all samples were dispatched.
+ */
+ public final boolean sendInputEvent(int seq, InputEvent event) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+ if (mSenderPtr == 0) {
+ Log.w(TAG, "Attempted to send an input event but the input event "
+ + "sender has already been disposed.");
+ return false;
+ }
+
+ if (event instanceof KeyEvent) {
+ return nativeSendKeyEvent(mSenderPtr, seq, (KeyEvent)event);
+ } else {
+ return nativeSendMotionEvent(mSenderPtr, seq, (MotionEvent)event);
+ }
+ }
+
+ // Called from native code.
+ @SuppressWarnings("unused")
+ private void dispatchInputEventFinished(int seq, boolean handled) {
+ onInputEventFinished(seq, handled);
+ }
+}