summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml84
-rw-r--r--core/java/android/app/NativeActivity.java16
-rw-r--r--core/java/android/view/InputChannel.java5
-rw-r--r--core/java/android/view/InputConsumer.java39
-rw-r--r--core/java/android/view/ViewRoot.java24
-rw-r--r--core/java/android/view/Window.java7
-rw-r--r--core/java/com/android/internal/view/RootViewSurfaceTaker.java2
-rw-r--r--core/jni/android_app_NativeActivity.cpp69
-rw-r--r--core/jni/android_view_InputChannel.h4
-rw-r--r--include/ui/Input.h7
-rw-r--r--include/ui/InputTransport.h20
-rw-r--r--libs/ui/Input.cpp163
-rw-r--r--libs/ui/InputTransport.cpp19
-rw-r--r--native/android/Android.mk26
-rw-r--r--native/android/activity.cpp0
-rw-r--r--native/android/input.cpp233
-rw-r--r--native/include/android/input.h36
-rw-r--r--native/include/android/native_activity.h15
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java12
19 files changed, 606 insertions, 175 deletions
diff --git a/api/current.xml b/api/current.xml
index 9ba773b..c80c9ed 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -28293,6 +28293,8 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.view.InputConsumer.Callback">
+</implements>
<implements name="android.view.SurfaceHolder.Callback">
</implements>
<constructor name="NativeActivity"
@@ -28303,6 +28305,32 @@
visibility="public"
>
</constructor>
+<method name="onInputConsumerCreated"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="consumer" type="android.view.InputConsumer">
+</parameter>
+</method>
+<method name="onInputConsumerDestroyed"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="consumer" type="android.view.InputConsumer">
+</parameter>
+</method>
<method name="surfaceChanged"
return="void"
abstract="false"
@@ -176187,6 +176215,49 @@
</parameter>
</constructor>
</class>
+<class name="InputConsumer"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</class>
+<interface name="InputConsumer.Callback"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onInputConsumerCreated"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="consumer" type="android.view.InputConsumer">
+</parameter>
+</method>
+<method name="onInputConsumerDestroyed"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="consumer" type="android.view.InputConsumer">
+</parameter>
+</method>
+</interface>
<class name="KeyCharacterMap"
extends="java.lang.Object"
abstract="false"
@@ -190690,6 +190761,19 @@
<parameter name="event" type="android.view.MotionEvent">
</parameter>
</method>
+<method name="takeInputChannel"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="android.view.InputConsumer.Callback">
+</parameter>
+</method>
<method name="takeKeyEvents"
return="void"
abstract="true"
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index fd20b71..973ad60 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -6,6 +6,8 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
+import android.view.InputChannel;
+import android.view.InputConsumer;
import android.view.SurfaceHolder;
import java.io.File;
@@ -14,7 +16,8 @@ import java.io.File;
* Convenience for implementing an activity that will be implemented
* purely in native code. That is, a game (or game-like thing).
*/
-public class NativeActivity extends Activity implements SurfaceHolder.Callback {
+public class NativeActivity extends Activity implements SurfaceHolder.Callback,
+ InputConsumer.Callback {
public static final String META_DATA_LIB_NAME = "android.app.lib_name";
private int mNativeHandle;
@@ -33,6 +36,8 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
private native void onSurfaceChangedNative(int handle, SurfaceHolder holder,
int format, int width, int height);
private native void onSurfaceDestroyedNative(int handle, SurfaceHolder holder);
+ private native void onInputChannelCreatedNative(int handle, InputChannel channel);
+ private native void onInputChannelDestroyedNative(int handle, InputChannel channel);
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -40,6 +45,7 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
ActivityInfo ai;
getWindow().takeSurface(this);
+ getWindow().takeInputChannel(this);
try {
ai = getPackageManager().getActivityInfo(
@@ -138,4 +144,12 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback {
public void surfaceDestroyed(SurfaceHolder holder) {
onSurfaceDestroyedNative(mNativeHandle, holder);
}
+
+ public void onInputConsumerCreated(InputConsumer consumer) {
+ onInputChannelCreatedNative(mNativeHandle, consumer.getInputChannel());
+ }
+
+ public void onInputConsumerDestroyed(InputConsumer consumer) {
+ onInputChannelDestroyedNative(mNativeHandle, consumer.getInputChannel());
+ }
}
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index e5ebc69..e24c3c9 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -22,8 +22,9 @@ import android.util.Slog;
/**
* An input channel specifies the file descriptors used to send input events to
- * a window in another process. It is Parcelable so that it can be transmitted
- * to the ViewRoot through a Binder transaction as part of registering the Window.
+ * a window in another process. It is Parcelable so that it can be sent
+ * to the process that is to receive events. Only one thread should be reading
+ * from an InputChannel at a time.
* @hide
*/
public final class InputChannel implements Parcelable {
diff --git a/core/java/android/view/InputConsumer.java b/core/java/android/view/InputConsumer.java
new file mode 100644
index 0000000..63b26c6
--- /dev/null
+++ b/core/java/android/view/InputConsumer.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 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;
+
+/**
+ * Handle for consuming raw input events.
+ */
+public class InputConsumer {
+ public static interface Callback {
+ void onInputConsumerCreated(InputConsumer consumer);
+ void onInputConsumerDestroyed(InputConsumer consumer);
+ }
+
+ final InputChannel mChannel;
+
+ /** @hide */
+ public InputConsumer(InputChannel channel) {
+ mChannel = channel;
+ }
+
+ /** @hide */
+ public InputChannel getInputChannel() {
+ return mChannel;
+ }
+}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 0c12998..7f3a500 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -147,7 +147,9 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
final View.AttachInfo mAttachInfo;
InputChannel mInputChannel;
-
+ InputConsumer.Callback mInputConsumerCallback;
+ InputConsumer mInputConsumer;
+
final Rect mTempRect; // used in the transaction to not thrash the heap.
final Rect mVisRect; // used to retrieve visible rect of focused view.
@@ -439,8 +441,17 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
}
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
- InputQueue.registerInputChannel(mInputChannel, mInputHandler,
- Looper.myQueue());
+ if (view instanceof RootViewSurfaceTaker) {
+ mInputConsumerCallback =
+ ((RootViewSurfaceTaker)view).willYouTakeTheInputConsumer();
+ }
+ if (mInputConsumerCallback != null) {
+ mInputConsumer = new InputConsumer(mInputChannel);
+ mInputConsumerCallback.onInputConsumerCreated(mInputConsumer);
+ } else {
+ InputQueue.registerInputChannel(mInputChannel, mInputHandler,
+ Looper.myQueue());
+ }
}
view.assignParent(this);
@@ -1587,7 +1598,12 @@ public final class ViewRoot extends Handler implements ViewParent, View.AttachIn
if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
if (mInputChannel != null) {
- InputQueue.unregisterInputChannel(mInputChannel);
+ if (mInputConsumerCallback != null) {
+ mInputConsumerCallback.onInputConsumerDestroyed(mInputConsumer);
+ mInputConsumerCallback = null;
+ } else {
+ InputQueue.unregisterInputChannel(mInputChannel);
+ }
mInputChannel.dispose();
mInputChannel = null;
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 5e6c538..095e585 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -488,6 +488,13 @@ public abstract class Window {
public abstract void takeSurface(SurfaceHolder.Callback callback);
/**
+ * Take ownership of this window's InputChannel. The window will no
+ * longer read and dispatch input events from the channel; it is your
+ * responsibility to do so.
+ */
+ public abstract void takeInputChannel(InputConsumer.Callback callback);
+
+ /**
* Return whether this window is being displayed with a floating style
* (based on the {@link android.R.attr#windowIsFloating} attribute in
* the style/theme).
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
index fcb1645..991266a 100644
--- a/core/java/com/android/internal/view/RootViewSurfaceTaker.java
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -1,5 +1,6 @@
package com.android.internal.view;
+import android.view.InputConsumer;
import android.view.SurfaceHolder;
/** hahahah */
@@ -8,4 +9,5 @@ public interface RootViewSurfaceTaker {
void setSurfaceType(int type);
void setSurfaceFormat(int format);
void setSurfaceKeepScreenOn(boolean keepOn);
+ InputConsumer.Callback willYouTakeTheInputConsumer();
}
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index f2ab134..5e5e47e 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -18,8 +18,10 @@
#include <utils/Log.h>
#include "JNIHelp.h"
+#include "android_view_InputChannel.h"
#include <android_runtime/AndroidRuntime.h>
#include <android/native_activity.h>
+#include <ui/InputTransport.h>
#include <dlfcn.h>
@@ -33,9 +35,13 @@ struct NativeCode {
dlhandle = _dlhandle;
createActivityFunc = _createFunc;
surface = NULL;
+ inputChannel = NULL;
+ nativeInputQueue = NULL;
}
~NativeCode() {
+ setSurface(NULL);
+ setInputChannel(NULL);
if (callbacks.onDestroy != NULL) {
callbacks.onDestroy(&activity);
}
@@ -55,6 +61,31 @@ struct NativeCode {
}
}
+ status_t setInputChannel(jobject _channel) {
+ if (inputChannel != NULL) {
+ delete nativeInputQueue;
+ activity.env->DeleteGlobalRef(inputChannel);
+ }
+ inputChannel = NULL;
+ nativeInputQueue = NULL;
+ if (_channel != NULL) {
+ inputChannel = activity.env->NewGlobalRef(_channel);
+ sp<InputChannel> ic =
+ android_view_InputChannel_getInputChannel(activity.env, _channel);
+ if (ic != NULL) {
+ nativeInputQueue = new input_queue_t(ic);
+ if (nativeInputQueue->getConsumer().initialize() != android::OK) {
+ delete nativeInputQueue;
+ nativeInputQueue = NULL;
+ return UNKNOWN_ERROR;
+ }
+ } else {
+ return UNKNOWN_ERROR;
+ }
+ }
+ return OK;
+ }
+
android_activity_t activity;
android_activity_callbacks_t callbacks;
@@ -62,6 +93,8 @@ struct NativeCode {
android_activity_create_t* createActivityFunc;
jobject surface;
+ jobject inputChannel;
+ struct input_queue_t* nativeInputQueue;
};
static jint
@@ -217,6 +250,38 @@ onSurfaceDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject surfa
}
}
+static void
+onInputChannelCreated_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
+{
+ if (handle != 0) {
+ NativeCode* code = (NativeCode*)handle;
+ status_t err = code->setInputChannel(channel);
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Error setting input channel");
+ return;
+ }
+ if (code->callbacks.onInputQueueCreated != NULL) {
+ code->callbacks.onInputQueueCreated(&code->activity,
+ code->nativeInputQueue);
+ }
+ }
+}
+
+static void
+onInputChannelDestroyed_native(JNIEnv* env, jobject clazz, jint handle, jobject channel)
+{
+ if (handle != 0) {
+ NativeCode* code = (NativeCode*)handle;
+ if (code->nativeInputQueue != NULL
+ && code->callbacks.onInputQueueDestroyed != NULL) {
+ code->callbacks.onInputQueueDestroyed(&code->activity,
+ code->nativeInputQueue);
+ }
+ code->setInputChannel(NULL);
+ }
+}
+
static const JNINativeMethod g_methods[] = {
{ "loadNativeCode", "(Ljava/lang/String;)I", (void*)loadNativeCode_native },
{ "unloadNativeCode", "(I)V", (void*)unloadNativeCode_native },
@@ -230,6 +295,8 @@ static const JNINativeMethod g_methods[] = {
{ "onSurfaceCreatedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceCreated_native },
{ "onSurfaceChangedNative", "(ILandroid/view/SurfaceHolder;III)V", (void*)onSurfaceChanged_native },
{ "onSurfaceDestroyedNative", "(ILandroid/view/SurfaceHolder;)V", (void*)onSurfaceDestroyed_native },
+ { "onInputChannelCreatedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelCreated_native },
+ { "onInputChannelDestroyedNative", "(ILandroid/view/InputChannel;)V", (void*)onInputChannelDestroyed_native },
};
static const char* const kNativeActivityPathName = "android/app/NativeActivity";
@@ -248,4 +315,4 @@ int register_android_app_NativeActivity(JNIEnv* env)
g_methods, NELEM(g_methods));
}
-}
+} // namespace android
diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h
index ac1defb..fa2d282 100644
--- a/core/jni/android_view_InputChannel.h
+++ b/core/jni/android_view_InputChannel.h
@@ -19,9 +19,9 @@
#include "jni.h"
-namespace android {
+#include <ui/InputTransport.h>
-class InputChannel;
+namespace android {
typedef void (*InputChannelObjDisposeCallback)(JNIEnv* env, jobject inputChannelObj,
const sp<InputChannel>& inputChannel, void* data);
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 979d6e8..32f85b3 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -40,6 +40,11 @@ enum {
*/
#define MAX_POINTERS 10
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct input_event_t { };
+
namespace android {
/*
@@ -128,8 +133,6 @@ struct PointerCoords {
/*
* Input events.
*/
-struct input_event_t { };
-
class InputEvent : public input_event_t {
public:
virtual ~InputEvent() { }
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
index 7b182f3..d6bded6 100644
--- a/include/ui/InputTransport.h
+++ b/include/ui/InputTransport.h
@@ -330,4 +330,24 @@ private:
} // namespace android
+/*
+ * NDK input queue API.
+ */
+struct input_queue_t {
+public:
+ /* Creates a consumer associated with an input channel. */
+ explicit input_queue_t(const android::sp<android::InputChannel>& channel);
+
+ /* Destroys the consumer and releases its input channel. */
+ ~input_queue_t();
+
+ inline android::InputConsumer& getConsumer() { return mConsumer; }
+
+ android::status_t consume(android::InputEvent** event);
+
+private:
+ android::InputConsumer mConsumer;
+ android::PreallocatedInputEventFactory mInputEventFactory;
+};
+
#endif // _UI_INPUT_TRANSPORT_H
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0e6f2f5..4121b5a 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -88,166 +88,3 @@ void MotionEvent::offsetLocation(float xOffset, float yOffset) {
}
} // namespace android
-
-// NDK APIs
-
-using android::InputEvent;
-using android::KeyEvent;
-using android::MotionEvent;
-
-int32_t input_event_get_type(const input_event_t* event) {
- return reinterpret_cast<const InputEvent*>(event)->getType();
-}
-
-int32_t input_event_get_device_id(const input_event_t* event) {
- return reinterpret_cast<const InputEvent*>(event)->getDeviceId();
-}
-
-int32_t input_event_get_nature(const input_event_t* event) {
- return reinterpret_cast<const InputEvent*>(event)->getNature();
-}
-
-int32_t key_event_get_action(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getAction();
-}
-
-int32_t key_event_get_flags(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getFlags();
-}
-
-int32_t key_event_get_key_code(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getKeyCode();
-}
-
-int32_t key_event_get_scan_code(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getScanCode();
-}
-
-int32_t key_event_get_meta_state(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getMetaState();
-}
-int32_t key_event_get_repeat_count(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getRepeatCount();
-}
-
-int64_t key_event_get_down_time(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getDownTime();
-}
-
-int64_t key_event_get_event_time(const input_event_t* key_event) {
- return reinterpret_cast<const KeyEvent*>(key_event)->getEventTime();
-}
-
-int32_t motion_event_get_action(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getAction();
-}
-
-int32_t motion_event_get_meta_state(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getMetaState();
-}
-
-int32_t motion_event_get_edge_flags(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getEdgeFlags();
-}
-
-int64_t motion_event_get_down_time(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getDownTime();
-}
-
-int64_t motion_event_get_event_time(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getEventTime();
-}
-
-float motion_event_get_x_offset(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getXOffset();
-}
-
-float motion_event_get_y_offset(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getYOffset();
-}
-
-float motion_event_get_x_precision(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getXPrecision();
-}
-
-float motion_event_get_y_precision(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getYPrecision();
-}
-
-size_t motion_event_get_pointer_count(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getPointerCount();
-}
-
-int32_t motion_event_get_pointer_id(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getPointerId(pointer_index);
-}
-
-float motion_event_get_raw_x(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getRawX(pointer_index);
-}
-
-float motion_event_get_raw_y(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getRawY(pointer_index);
-}
-
-float motion_event_get_x(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getX(pointer_index);
-}
-
-float motion_event_get_y(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getY(pointer_index);
-}
-
-float motion_event_get_pressure(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getPressure(pointer_index);
-}
-
-float motion_event_get_size(const input_event_t* motion_event, size_t pointer_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getSize(pointer_index);
-}
-
-size_t motion_event_get_history_size(const input_event_t* motion_event) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistorySize();
-}
-
-int64_t motion_event_get_historical_event_time(input_event_t* motion_event,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalEventTime(
- history_index);
-}
-
-float motion_event_get_historical_raw_x(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalRawX(
- pointer_index, history_index);
-}
-
-float motion_event_get_historical_raw_y(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalRawY(
- pointer_index, history_index);
-}
-
-float motion_event_get_historical_x(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalX(
- pointer_index, history_index);
-}
-
-float motion_event_get_historical_y(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalY(
- pointer_index, history_index);
-}
-
-float motion_event_get_historical_pressure(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalPressure(
- pointer_index, history_index);
-}
-
-float motion_event_get_historical_size(input_event_t* motion_event, size_t pointer_index,
- size_t history_index) {
- return reinterpret_cast<const MotionEvent*>(motion_event)->getHistoricalSize(
- pointer_index, history_index);
-}
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 86bbd37..b2842d0 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -686,3 +686,22 @@ void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const {
}
} // namespace android
+
+// --- input_queue_t ---
+
+using android::InputEvent;
+using android::InputChannel;
+using android::InputConsumer;
+using android::sp;
+using android::status_t;
+
+input_queue_t::input_queue_t(const sp<InputChannel>& channel) :
+ mConsumer(channel) {
+}
+
+input_queue_t::~input_queue_t() {
+}
+
+status_t input_queue_t::consume(InputEvent** event) {
+ return mConsumer.consume(&mInputEventFactory, event);
+}
diff --git a/native/android/Android.mk b/native/android/Android.mk
new file mode 100644
index 0000000..8c621b6
--- /dev/null
+++ b/native/android/Android.mk
@@ -0,0 +1,26 @@
+BASE_PATH := $(call my-dir)
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# our source files
+#
+LOCAL_SRC_FILES:= \
+ activity.cpp \
+ input.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libandroid_runtime \
+ libcutils \
+ libutils \
+ libbinder \
+ libui
+
+LOCAL_C_INCLUDES += \
+ frameworks/base/native/include \
+ frameworks/base/core/jni/android \
+ dalvik/libnativehelper/include/nativehelper
+
+LOCAL_MODULE:= libandroid
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/native/android/activity.cpp b/native/android/activity.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/native/android/activity.cpp
diff --git a/native/android/input.cpp b/native/android/input.cpp
new file mode 100644
index 0000000..38d8567
--- /dev/null
+++ b/native/android/input.cpp
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+#define LOG_TAG "input"
+#include <utils/Log.h>
+
+#include <android/input.h>
+#include <ui/Input.h>
+#include <ui/InputTransport.h>
+
+#include <poll.h>
+
+using android::InputEvent;
+using android::KeyEvent;
+using android::MotionEvent;
+
+int32_t input_event_get_type(const input_event_t* event) {
+ return static_cast<const InputEvent*>(event)->getType();
+}
+
+int32_t input_event_get_device_id(const input_event_t* event) {
+ return static_cast<const InputEvent*>(event)->getDeviceId();
+}
+
+int32_t input_event_get_nature(const input_event_t* event) {
+ return static_cast<const InputEvent*>(event)->getNature();
+}
+
+int32_t key_event_get_action(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getAction();
+}
+
+int32_t key_event_get_flags(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getFlags();
+}
+
+int32_t key_event_get_key_code(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getKeyCode();
+}
+
+int32_t key_event_get_scan_code(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getScanCode();
+}
+
+int32_t key_event_get_meta_state(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getMetaState();
+}
+int32_t key_event_get_repeat_count(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getRepeatCount();
+}
+
+int64_t key_event_get_down_time(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getDownTime();
+}
+
+int64_t key_event_get_event_time(const input_event_t* key_event) {
+ return static_cast<const KeyEvent*>(key_event)->getEventTime();
+}
+
+int32_t motion_event_get_action(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getAction();
+}
+
+int32_t motion_event_get_meta_state(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getMetaState();
+}
+
+int32_t motion_event_get_edge_flags(const input_event_t* motion_event) {
+ return reinterpret_cast<const MotionEvent*>(motion_event)->getEdgeFlags();
+}
+
+int64_t motion_event_get_down_time(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getDownTime();
+}
+
+int64_t motion_event_get_event_time(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getEventTime();
+}
+
+float motion_event_get_x_offset(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getXOffset();
+}
+
+float motion_event_get_y_offset(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getYOffset();
+}
+
+float motion_event_get_x_precision(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getXPrecision();
+}
+
+float motion_event_get_y_precision(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getYPrecision();
+}
+
+size_t motion_event_get_pointer_count(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getPointerCount();
+}
+
+int32_t motion_event_get_pointer_id(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getPointerId(pointer_index);
+}
+
+float motion_event_get_raw_x(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getRawX(pointer_index);
+}
+
+float motion_event_get_raw_y(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getRawY(pointer_index);
+}
+
+float motion_event_get_x(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getX(pointer_index);
+}
+
+float motion_event_get_y(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getY(pointer_index);
+}
+
+float motion_event_get_pressure(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getPressure(pointer_index);
+}
+
+float motion_event_get_size(const input_event_t* motion_event, size_t pointer_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getSize(pointer_index);
+}
+
+size_t motion_event_get_history_size(const input_event_t* motion_event) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistorySize();
+}
+
+int64_t motion_event_get_historical_event_time(input_event_t* motion_event,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalEventTime(
+ history_index);
+}
+
+float motion_event_get_historical_raw_x(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalRawX(
+ pointer_index, history_index);
+}
+
+float motion_event_get_historical_raw_y(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalRawY(
+ pointer_index, history_index);
+}
+
+float motion_event_get_historical_x(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalX(
+ pointer_index, history_index);
+}
+
+float motion_event_get_historical_y(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalY(
+ pointer_index, history_index);
+}
+
+float motion_event_get_historical_pressure(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalPressure(
+ pointer_index, history_index);
+}
+
+float motion_event_get_historical_size(input_event_t* motion_event, size_t pointer_index,
+ size_t history_index) {
+ return static_cast<const MotionEvent*>(motion_event)->getHistoricalSize(
+ pointer_index, history_index);
+}
+
+int input_queue_get_fd(input_queue_t* queue) {
+ return queue->getConsumer().getChannel()->getReceivePipeFd();
+}
+
+int input_queue_has_events(input_queue_t* queue) {
+ struct pollfd pfd;
+
+ pfd.fd = queue->getConsumer().getChannel()->getReceivePipeFd();
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+
+ int nfd = poll(&pfd, 1, 0);
+ if (nfd <= 0) return nfd;
+ return pfd.revents == POLLIN ? 1 : -1;
+}
+
+int32_t input_queue_get_event(input_queue_t* queue, input_event_t** outEvent) {
+ *outEvent = NULL;
+
+ int32_t res = queue->getConsumer().receiveDispatchSignal();
+ if (res != android::OK) {
+ LOGE("channel '%s' ~ Failed to receive dispatch signal. status=%d",
+ queue->getConsumer().getChannel()->getName().string(), res);
+ return -1;
+ }
+
+ InputEvent* myEvent = NULL;
+ res = queue->consume(&myEvent);
+ if (res != android::OK) {
+ LOGW("channel '%s' ~ Failed to consume input event. status=%d",
+ queue->getConsumer().getChannel()->getName().string(), res);
+ queue->getConsumer().sendFinishedSignal();
+ return -1;
+ }
+
+ *outEvent = myEvent;
+ return 0;
+}
+
+void input_queue_finish_event(input_queue_t* queue, input_event_t* event,
+ int handled) {
+ int32_t res = queue->getConsumer().sendFinishedSignal();
+ if (res != android::OK) {
+ LOGW("Failed to send finished signal on channel '%s'. status=%d",
+ queue->getConsumer().getChannel()->getName().string(), res);
+ }
+}
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 193cbf3..2441af0 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -523,6 +523,42 @@ float motion_event_get_historical_pressure(input_event_t* motion_event, size_t p
float motion_event_get_historical_size(input_event_t* motion_event, size_t pointer_index,
size_t history_index);
+/*
+ * Input queue
+ *
+ * An input queue is the facility through which you retrieve input
+ * events.
+ */
+struct input_queue_t;
+typedef struct input_queue_t input_queue_t;
+
+/*
+ * Return a file descriptor for the queue, which you
+ * can use to determine if there are events available. This
+ * is typically used with select() or poll() to multiplex
+ * with other kinds of events.
+ */
+int input_queue_get_fd(input_queue_t* queue);
+
+/*
+ * Returns true if there are one or more events available in the
+ * input queue. Returns 1 if the queue has events; 0 if
+ * it does not have events; and a negative value if there is an error.
+ */
+int input_queue_has_events(input_queue_t* queue);
+
+/*
+ * Returns the next available event from the queue. Returns a negative
+ * value if no events are available or an error has occurred.
+ */
+int32_t input_queue_get_event(input_queue_t* queue, input_event_t** outEvent);
+
+/*
+ * Report that dispatching has finished with the given event.
+ * This must be called after receiving an event with input_queue_get_event().
+ */
+void input_queue_finish_event(input_queue_t* queue, input_event_t* event, int handled);
+
#ifdef __cplusplus
}
#endif
diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h
index 328a4b5..a58a7d2 100644
--- a/native/include/android/native_activity.h
+++ b/native/include/android/native_activity.h
@@ -23,6 +23,8 @@
#include <jni.h>
+#include <android/input.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -144,6 +146,19 @@ typedef struct android_activity_callbacks_t {
* returning from here.
*/
void (*onSurfaceDestroyed)(android_activity_t* activity, android_surface_t* surface);
+
+ /**
+ * The input queue for this native activity's window has been created.
+ * You can use the given input queue to start retrieving input events.
+ */
+ void (*onInputQueueCreated)(android_activity_t* activity, input_queue_t* queue);
+
+ /**
+ * The input queue for this native activity's window is being destroyed.
+ * You should no longer try to reference this object upon returning from this
+ * function.
+ */
+ void (*onInputQueueDestroyed)(android_activity_t* activity, input_queue_t* queue);
/**
* The system is running low on memory. Use this callback to release
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index eea855d..5e73b97 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -56,6 +56,7 @@ import android.util.SparseArray;
import android.view.ActionBarView;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
+import android.view.InputConsumer;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -69,6 +70,7 @@ import android.view.ViewManager;
import android.view.VolumePanel;
import android.view.Window;
import android.view.WindowManager;
+import android.view.InputConsumer.Callback;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
@@ -107,6 +109,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
SurfaceHolder.Callback mTakeSurfaceCallback;
BaseSurfaceHolder mSurfaceHolder;
+ InputConsumer.Callback mTakeInputChannelCallback;
+
private boolean mIsFloating;
private LayoutInflater mLayoutInflater;
@@ -252,6 +256,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mTakeSurfaceCallback = callback;
}
+ public void takeInputChannel(InputConsumer.Callback callback) {
+ mTakeInputChannelCallback = callback;
+ }
+
@Override
public boolean isFloating() {
return mIsFloating;
@@ -2066,6 +2074,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return mFeatureId < 0 ? mTakeSurfaceCallback : null;
}
+ public InputConsumer.Callback willYouTakeTheInputConsumer() {
+ return mFeatureId < 0 ? mTakeInputChannelCallback : null;
+ }
+
public void setSurfaceType(int type) {
PhoneWindow.this.setType(type);
}