diff options
-rw-r--r-- | api/current.xml | 84 | ||||
-rw-r--r-- | core/java/android/app/NativeActivity.java | 16 | ||||
-rw-r--r-- | core/java/android/view/InputChannel.java | 5 | ||||
-rw-r--r-- | core/java/android/view/InputConsumer.java | 39 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 24 | ||||
-rw-r--r-- | core/java/android/view/Window.java | 7 | ||||
-rw-r--r-- | core/java/com/android/internal/view/RootViewSurfaceTaker.java | 2 | ||||
-rw-r--r-- | core/jni/android_app_NativeActivity.cpp | 69 | ||||
-rw-r--r-- | core/jni/android_view_InputChannel.h | 4 | ||||
-rw-r--r-- | include/ui/Input.h | 7 | ||||
-rw-r--r-- | include/ui/InputTransport.h | 20 | ||||
-rw-r--r-- | libs/ui/Input.cpp | 163 | ||||
-rw-r--r-- | libs/ui/InputTransport.cpp | 19 | ||||
-rw-r--r-- | native/android/Android.mk | 26 | ||||
-rw-r--r-- | native/android/activity.cpp | 0 | ||||
-rw-r--r-- | native/android/input.cpp | 233 | ||||
-rw-r--r-- | native/include/android/input.h | 36 | ||||
-rw-r--r-- | native/include/android/native_activity.h | 15 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/PhoneWindow.java | 12 |
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); } |