deprecated="not deprecated"
visibility="public"
>
+<implements name="android.view.InputConsumer.Callback">
+</implements>
<implements name="android.view.SurfaceHolder.Callback">
</implements>
<constructor name="NativeActivity"
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"
</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"
<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"
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;
* 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;
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) {
ActivityInfo ai;
getWindow().takeSurface(this);
+ getWindow().takeInputChannel(this);
try {
ai = getPackageManager().getActivityInfo(
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());
+ }
}
/**
* 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 {
--- /dev/null
+/*
+ * 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;
+ }
+}
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.
}
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);
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;
}
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).
package com.android.internal.view;
+import android.view.InputConsumer;
import android.view.SurfaceHolder;
/** hahahah */
void setSurfaceType(int type);
void setSurfaceFormat(int format);
void setSurfaceKeepScreenOn(boolean keepOn);
+ InputConsumer.Callback willYouTakeTheInputConsumer();
}
#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>
dlhandle = _dlhandle;
createActivityFunc = _createFunc;
surface = NULL;
+ inputChannel = NULL;
+ nativeInputQueue = NULL;
}
~NativeCode() {
+ setSurface(NULL);
+ setInputChannel(NULL);
if (callbacks.onDestroy != NULL) {
callbacks.onDestroy(&activity);
}
}
}
+ 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;
android_activity_create_t* createActivityFunc;
jobject surface;
+ jobject inputChannel;
+ struct input_queue_t* nativeInputQueue;
};
static jint
}
}
+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 },
{ "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";
g_methods, NELEM(g_methods));
}
-}
+} // namespace android
#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);
*/
#define MAX_POINTERS 10
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct input_event_t { };
+
namespace android {
/*
/*
* Input events.
*/
-struct input_event_t { };
-
class InputEvent : public input_event_t {
public:
virtual ~InputEvent() { }
} // 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
}
} // 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);
-}
}
} // 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);
+}
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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);
+ }
+}
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
#include <jni.h>
+#include <android/input.h>
+
#ifdef __cplusplus
extern "C" {
#endif
* 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
import android.util.SparseArray;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
+import android.view.InputConsumer;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
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;
SurfaceHolder.Callback mTakeSurfaceCallback;
BaseSurfaceHolder mSurfaceHolder;
+ InputConsumer.Callback mTakeInputChannelCallback;
+
private boolean mIsFloating;
private LayoutInflater mLayoutInflater;
mTakeSurfaceCallback = callback;
}
+ public void takeInputChannel(InputConsumer.Callback callback) {
+ mTakeInputChannelCallback = callback;
+ }
+
@Override
public boolean isFloating() {
return mIsFloating;
return mFeatureId < 0 ? mTakeSurfaceCallback : null;
}
+ public InputConsumer.Callback willYouTakeTheInputConsumer() {
+ return mFeatureId < 0 ? mTakeInputChannelCallback : null;
+ }
+
public void setSurfaceType(int type) {
PhoneWindow.this.setType(type);
}