Merge "First stab at attaching native event dispatching." into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
e24a60aa46
@ -26306,6 +26306,8 @@
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<implements name="android.view.InputConsumer.Callback">
|
||||
</implements>
|
||||
<implements name="android.view.SurfaceHolder.Callback">
|
||||
</implements>
|
||||
<constructor name="NativeActivity"
|
||||
@ -26316,6 +26318,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"
|
||||
@ -172813,6 +172841,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"
|
||||
@ -187266,6 +187337,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"
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
39
core/java/android/view/InputConsumer.java
Normal file
39
core/java/android/view/InputConsumer.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -154,7 +154,9 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|
||||
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.
|
||||
|
||||
@ -555,8 +557,17 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1736,7 +1747,12 @@ public final class ViewRoot extends Handler implements ViewParent,
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -480,6 +480,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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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() { }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
26
native/android/Android.mk
Normal file
26
native/android/Android.mk
Normal file
@ -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)
|
0
native/android/activity.cpp
Normal file
0
native/android/activity.cpp
Normal file
233
native/android/input.cpp
Normal file
233
native/android/input.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -56,6 +56,7 @@ import android.util.Log;
|
||||
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;
|
||||
@ -70,6 +71,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;
|
||||
@ -108,6 +110,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
|
||||
SurfaceHolder.Callback mTakeSurfaceCallback;
|
||||
BaseSurfaceHolder mSurfaceHolder;
|
||||
|
||||
InputConsumer.Callback mTakeInputChannelCallback;
|
||||
|
||||
private boolean mIsFloating;
|
||||
|
||||
private LayoutInflater mLayoutInflater;
|
||||
@ -251,6 +255,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;
|
||||
@ -2037,6 +2045,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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user