Merge changes from topic "dispatcher-policy-cleanup" into udc-dev
* changes: Clean up KeyEvent JNI APIs Clean up JNI methods of InputDispatcherPolicy Clean up InputDispatcherPolicyInterface
This commit is contained in:
committed by
Android (Google) Code Review
commit
c5d9123906
@@ -374,7 +374,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
|
||||
}
|
||||
inputEventObj =
|
||||
android_view_KeyEvent_fromNative(env,
|
||||
static_cast<KeyEvent*>(inputEvent));
|
||||
static_cast<KeyEvent&>(*inputEvent));
|
||||
break;
|
||||
|
||||
case InputEventType::MOTION: {
|
||||
|
||||
@@ -353,8 +353,7 @@ static jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jlong senderPtr,
|
||||
jint seq, jobject eventObj) {
|
||||
sp<NativeInputEventSender> sender =
|
||||
reinterpret_cast<NativeInputEventSender*>(senderPtr);
|
||||
KeyEvent event;
|
||||
android_view_KeyEvent_toNative(env, eventObj, &event);
|
||||
const KeyEvent event = android_view_KeyEvent_toNative(env, eventObj);
|
||||
status_t status = sender->sendKeyEvent(seq, &event);
|
||||
return !status;
|
||||
}
|
||||
|
||||
@@ -221,12 +221,7 @@ static jlong nativeSendKeyEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject e
|
||||
jboolean predispatch) {
|
||||
InputQueue* queue = reinterpret_cast<InputQueue*>(ptr);
|
||||
KeyEvent* event = queue->createKeyEvent();
|
||||
status_t status = android_view_KeyEvent_toNative(env, eventObj, event);
|
||||
if (status) {
|
||||
queue->recycleInputEvent(event);
|
||||
jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
|
||||
return -1;
|
||||
}
|
||||
*event = android_view_KeyEvent_toNative(env, eventObj);
|
||||
|
||||
if (predispatch) {
|
||||
event->setFlags(event->getFlags() | AKEY_EVENT_FLAG_PREDISPATCH);
|
||||
|
||||
@@ -217,7 +217,7 @@ static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
|
||||
result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
|
||||
if (result) {
|
||||
for (size_t i = 0; i < events.size(); i++) {
|
||||
jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
|
||||
jobject keyEventObj = android_view_KeyEvent_fromNative(env, events.itemAt(i));
|
||||
if (!keyEventObj) break; // threw OOM exception
|
||||
env->SetObjectArrayElement(result, jsize(i), keyEventObj);
|
||||
env->DeleteLocalRef(keyEventObj);
|
||||
|
||||
@@ -94,16 +94,16 @@ static struct {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) {
|
||||
ScopedLocalRef<jbyteArray> hmac = toJbyteArray(env, event->getHmac());
|
||||
jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event) {
|
||||
ScopedLocalRef<jbyteArray> hmac = toJbyteArray(env, event.getHmac());
|
||||
jobject eventObj =
|
||||
env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, gKeyEventClassInfo.obtain,
|
||||
event->getId(), event->getDownTime(), event->getEventTime(),
|
||||
event->getAction(), event->getKeyCode(),
|
||||
event->getRepeatCount(), event->getMetaState(),
|
||||
event->getDeviceId(), event->getScanCode(),
|
||||
event->getFlags(), event->getSource(),
|
||||
event->getDisplayId(), hmac.get(), nullptr);
|
||||
event.getId(), event.getDownTime(), event.getEventTime(),
|
||||
event.getAction(), event.getKeyCode(),
|
||||
event.getRepeatCount(), event.getMetaState(),
|
||||
event.getDeviceId(), event.getScanCode(), event.getFlags(),
|
||||
event.getSource(), event.getDisplayId(), hmac.get(),
|
||||
nullptr);
|
||||
if (env->ExceptionCheck()) {
|
||||
ALOGE("An exception occurred while obtaining a key event.");
|
||||
LOGE_EX(env);
|
||||
@@ -113,8 +113,7 @@ jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) {
|
||||
return eventObj;
|
||||
}
|
||||
|
||||
status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj,
|
||||
KeyEvent* event) {
|
||||
KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj) {
|
||||
jint id = env->GetIntField(eventObj, gKeyEventClassInfo.mId);
|
||||
jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId);
|
||||
jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource);
|
||||
@@ -133,9 +132,10 @@ status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj,
|
||||
jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime);
|
||||
jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime);
|
||||
|
||||
event->initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode,
|
||||
metaState, repeatCount, downTime, eventTime);
|
||||
return OK;
|
||||
KeyEvent event;
|
||||
event.initialize(id, deviceId, source, displayId, *hmac, action, flags, keyCode, scanCode,
|
||||
metaState, repeatCount, downTime, eventTime);
|
||||
return event;
|
||||
}
|
||||
|
||||
status_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) {
|
||||
|
||||
@@ -27,12 +27,11 @@ class KeyEvent;
|
||||
|
||||
/* Obtains an instance of a DVM KeyEvent object as a copy of a native KeyEvent instance.
|
||||
* Returns NULL on error. */
|
||||
extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event);
|
||||
extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent& event);
|
||||
|
||||
/* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance.
|
||||
* Returns non-zero on error. */
|
||||
extern status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj,
|
||||
KeyEvent* event);
|
||||
extern KeyEvent android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj);
|
||||
|
||||
/* Recycles a DVM KeyEvent object.
|
||||
* Key events should only be recycled if they are owned by the system since user
|
||||
|
||||
@@ -87,11 +87,8 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) {
|
||||
|
||||
const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) {
|
||||
std::unique_ptr<KeyEvent> event = std::make_unique<KeyEvent>();
|
||||
android::status_t ret = android::android_view_KeyEvent_toNative(env, keyEvent, event.get());
|
||||
if (ret == android::OK) {
|
||||
return event.release();
|
||||
}
|
||||
return nullptr;
|
||||
*event = android::android_view_KeyEvent_toNative(env, keyEvent);
|
||||
return event.release();
|
||||
}
|
||||
|
||||
int64_t AKeyEvent_getEventTime(const AInputEvent* key_event) {
|
||||
|
||||
@@ -342,15 +342,15 @@ public:
|
||||
void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
|
||||
InputDeviceSensorAccuracy accuracy) override;
|
||||
void notifyVibratorState(int32_t deviceId, bool isOn) override;
|
||||
bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override;
|
||||
void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override;
|
||||
void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) override;
|
||||
void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
|
||||
bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) override;
|
||||
InputDispatcherConfiguration getDispatcherConfiguration() override;
|
||||
void interceptKeyBeforeQueueing(const KeyEvent& keyEvent, uint32_t& policyFlags) override;
|
||||
void interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when,
|
||||
uint32_t& policyFlags) override;
|
||||
nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent* keyEvent,
|
||||
nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent& keyEvent,
|
||||
uint32_t policyFlags) override;
|
||||
bool dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent* keyEvent,
|
||||
uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) override;
|
||||
std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent& keyEvent,
|
||||
uint32_t policyFlags) override;
|
||||
void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) override;
|
||||
void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override;
|
||||
void setPointerCapture(const PointerCaptureRequest& request) override;
|
||||
@@ -450,7 +450,7 @@ NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& loo
|
||||
|
||||
mServiceObj = env->NewGlobalRef(serviceObj);
|
||||
|
||||
InputManager* im = new InputManager(this, this);
|
||||
InputManager* im = new InputManager(this, *this);
|
||||
mInputManager = im;
|
||||
defaultServiceManager()->addService(String16("inputflinger"), im);
|
||||
}
|
||||
@@ -1007,21 +1007,22 @@ void NativeInputManager::notifyVibratorState(int32_t deviceId, bool isOn) {
|
||||
checkAndClearExceptionFromCallback(env, "notifyVibratorState");
|
||||
}
|
||||
|
||||
void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
|
||||
InputDispatcherConfiguration NativeInputManager::getDispatcherConfiguration() {
|
||||
ATRACE_CALL();
|
||||
InputDispatcherConfiguration config;
|
||||
JNIEnv* env = jniEnv();
|
||||
|
||||
jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.getKeyRepeatTimeout);
|
||||
jint keyRepeatTimeout = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatTimeout);
|
||||
if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
|
||||
outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
|
||||
config.keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
|
||||
}
|
||||
|
||||
jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.getKeyRepeatDelay);
|
||||
jint keyRepeatDelay = env->CallIntMethod(mServiceObj, gServiceClassInfo.getKeyRepeatDelay);
|
||||
if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
|
||||
outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
|
||||
config.keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) {
|
||||
@@ -1294,110 +1295,112 @@ void NativeInputManager::notifyStylusGestureStarted(int32_t deviceId, nsecs_t ev
|
||||
checkAndClearExceptionFromCallback(env, "notifyStylusGestureStarted");
|
||||
}
|
||||
|
||||
bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
|
||||
bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) {
|
||||
ATRACE_CALL();
|
||||
jobject inputEventObj;
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
switch (inputEvent->getType()) {
|
||||
|
||||
ScopedLocalRef<jobject> inputEventObj(env);
|
||||
switch (inputEvent.getType()) {
|
||||
case InputEventType::KEY:
|
||||
inputEventObj =
|
||||
android_view_KeyEvent_fromNative(env, static_cast<const KeyEvent*>(inputEvent));
|
||||
inputEventObj.reset(
|
||||
android_view_KeyEvent_fromNative(env,
|
||||
static_cast<const KeyEvent&>(inputEvent)));
|
||||
break;
|
||||
case InputEventType::MOTION:
|
||||
inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
|
||||
static_cast<const MotionEvent&>(
|
||||
*inputEvent));
|
||||
inputEventObj.reset(
|
||||
android_view_MotionEvent_obtainAsCopy(env,
|
||||
static_cast<const MotionEvent&>(
|
||||
inputEvent)));
|
||||
break;
|
||||
default:
|
||||
return true; // dispatch the event normally
|
||||
}
|
||||
|
||||
if (!inputEventObj) {
|
||||
if (!inputEventObj.get()) {
|
||||
ALOGE("Failed to obtain input event object for filterInputEvent.");
|
||||
return true; // dispatch the event normally
|
||||
}
|
||||
|
||||
// The callee is responsible for recycling the event.
|
||||
jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
|
||||
inputEventObj, policyFlags);
|
||||
const jboolean continueEventDispatch =
|
||||
env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
|
||||
inputEventObj.get(), policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
|
||||
pass = true;
|
||||
return true; // dispatch the event normally
|
||||
}
|
||||
env->DeleteLocalRef(inputEventObj);
|
||||
return pass;
|
||||
return continueEventDispatch;
|
||||
}
|
||||
|
||||
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
|
||||
uint32_t& policyFlags) {
|
||||
void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent,
|
||||
uint32_t& policyFlags) {
|
||||
ATRACE_CALL();
|
||||
// Policy:
|
||||
// - Ignore untrusted events and pass them along.
|
||||
// - Ask the window manager what to do with normal events and trusted injected events.
|
||||
// - For normal events wake and brighten the screen if currently off or dim.
|
||||
bool interactive = mInteractive.load();
|
||||
const bool interactive = mInteractive.load();
|
||||
if (interactive) {
|
||||
policyFlags |= POLICY_FLAG_INTERACTIVE;
|
||||
}
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED)) {
|
||||
nsecs_t when = keyEvent->getEventTime();
|
||||
JNIEnv* env = jniEnv();
|
||||
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
|
||||
jint wmActions;
|
||||
if (keyEventObj) {
|
||||
wmActions = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.interceptKeyBeforeQueueing,
|
||||
keyEventObj, policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
|
||||
wmActions = 0;
|
||||
}
|
||||
android_view_KeyEvent_recycle(env, keyEventObj);
|
||||
env->DeleteLocalRef(keyEventObj);
|
||||
} else {
|
||||
ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
|
||||
wmActions = 0;
|
||||
}
|
||||
|
||||
handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
|
||||
} else {
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
|
||||
if (interactive) {
|
||||
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const nsecs_t when = keyEvent.getEventTime();
|
||||
JNIEnv* env = jniEnv();
|
||||
ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent));
|
||||
if (!keyEventObj.get()) {
|
||||
ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
|
||||
return;
|
||||
}
|
||||
|
||||
jint wmActions = env->CallIntMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeQueueing,
|
||||
keyEventObj.get(), policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
|
||||
wmActions = 0;
|
||||
}
|
||||
android_view_KeyEvent_recycle(env, keyEventObj.get());
|
||||
handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
|
||||
}
|
||||
|
||||
void NativeInputManager::interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
|
||||
uint32_t& policyFlags) {
|
||||
void NativeInputManager::interceptMotionBeforeQueueing(int32_t displayId, nsecs_t when,
|
||||
uint32_t& policyFlags) {
|
||||
ATRACE_CALL();
|
||||
// Policy:
|
||||
// - Ignore untrusted events and pass them along.
|
||||
// - No special filtering for injected events required at this time.
|
||||
// - Filter normal events based on screen state.
|
||||
// - For normal events brighten (but do not wake) the screen if currently dim.
|
||||
bool interactive = mInteractive.load();
|
||||
const bool interactive = mInteractive.load();
|
||||
if (interactive) {
|
||||
policyFlags |= POLICY_FLAG_INTERACTIVE;
|
||||
}
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
|
||||
if (policyFlags & POLICY_FLAG_INTERACTIVE) {
|
||||
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
||||
} else {
|
||||
JNIEnv* env = jniEnv();
|
||||
jint wmActions = env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
|
||||
displayId, when, policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env,
|
||||
"interceptMotionBeforeQueueingNonInteractive")) {
|
||||
wmActions = 0;
|
||||
}
|
||||
|
||||
handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
|
||||
}
|
||||
} else {
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED) == 0 || (policyFlags & POLICY_FLAG_INJECTED)) {
|
||||
if (interactive) {
|
||||
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (policyFlags & POLICY_FLAG_INTERACTIVE) {
|
||||
policyFlags |= POLICY_FLAG_PASS_TO_USER;
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
const jint wmActions =
|
||||
env->CallIntMethod(mServiceObj,
|
||||
gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
|
||||
displayId, when, policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env, "interceptMotionBeforeQueueingNonInteractive")) {
|
||||
return;
|
||||
}
|
||||
handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
|
||||
}
|
||||
|
||||
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
|
||||
@@ -1411,81 +1414,76 @@ void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
|
||||
}
|
||||
}
|
||||
|
||||
nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
|
||||
const sp<IBinder>& token,
|
||||
const KeyEvent* keyEvent, uint32_t policyFlags) {
|
||||
nsecs_t NativeInputManager::interceptKeyBeforeDispatching(const sp<IBinder>& token,
|
||||
const KeyEvent& keyEvent,
|
||||
uint32_t policyFlags) {
|
||||
ATRACE_CALL();
|
||||
// Policy:
|
||||
// - Ignore untrusted events and pass them along.
|
||||
// - Filter normal events and trusted injected events through the window manager policy to
|
||||
// handle the HOME key and the like.
|
||||
nsecs_t result = 0;
|
||||
if (policyFlags & POLICY_FLAG_TRUSTED) {
|
||||
JNIEnv* env = jniEnv();
|
||||
ScopedLocalFrame localFrame(env);
|
||||
|
||||
// Token may be null
|
||||
jobject tokenObj = javaObjectForIBinder(env, token);
|
||||
|
||||
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
|
||||
if (keyEventObj) {
|
||||
jlong delayMillis = env->CallLongMethod(mServiceObj,
|
||||
gServiceClassInfo.interceptKeyBeforeDispatching,
|
||||
tokenObj, keyEventObj, policyFlags);
|
||||
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
|
||||
android_view_KeyEvent_recycle(env, keyEventObj);
|
||||
env->DeleteLocalRef(keyEventObj);
|
||||
if (!error) {
|
||||
if (delayMillis < 0) {
|
||||
result = -1;
|
||||
} else if (delayMillis > 0) {
|
||||
result = milliseconds_to_nanoseconds(delayMillis);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
|
||||
}
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
ScopedLocalFrame localFrame(env);
|
||||
|
||||
// Token may be null
|
||||
ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
|
||||
ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent));
|
||||
if (!keyEventObj.get()) {
|
||||
ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const jlong delayMillis =
|
||||
env->CallLongMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeDispatching,
|
||||
tokenObj.get(), keyEventObj.get(), policyFlags);
|
||||
android_view_KeyEvent_recycle(env, keyEventObj.get());
|
||||
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching")) {
|
||||
return 0;
|
||||
}
|
||||
return delayMillis < 0 ? -1 : milliseconds_to_nanoseconds(delayMillis);
|
||||
}
|
||||
|
||||
bool NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
|
||||
const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
|
||||
std::optional<KeyEvent> NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
|
||||
const KeyEvent& keyEvent,
|
||||
uint32_t policyFlags) {
|
||||
ATRACE_CALL();
|
||||
// Policy:
|
||||
// - Ignore untrusted events and do not perform default handling.
|
||||
bool result = false;
|
||||
if (policyFlags & POLICY_FLAG_TRUSTED) {
|
||||
JNIEnv* env = jniEnv();
|
||||
ScopedLocalFrame localFrame(env);
|
||||
|
||||
// Note: tokenObj may be null.
|
||||
jobject tokenObj = javaObjectForIBinder(env, token);
|
||||
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
|
||||
if (keyEventObj) {
|
||||
jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
|
||||
gServiceClassInfo.dispatchUnhandledKey,
|
||||
tokenObj, keyEventObj, policyFlags);
|
||||
if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
|
||||
fallbackKeyEventObj = nullptr;
|
||||
}
|
||||
android_view_KeyEvent_recycle(env, keyEventObj);
|
||||
env->DeleteLocalRef(keyEventObj);
|
||||
|
||||
if (fallbackKeyEventObj) {
|
||||
// Note: outFallbackKeyEvent may be the same object as keyEvent.
|
||||
if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
|
||||
outFallbackKeyEvent)) {
|
||||
result = true;
|
||||
}
|
||||
android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
|
||||
env->DeleteLocalRef(fallbackKeyEventObj);
|
||||
}
|
||||
} else {
|
||||
ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
|
||||
}
|
||||
if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
|
||||
return {};
|
||||
}
|
||||
return result;
|
||||
|
||||
JNIEnv* env = jniEnv();
|
||||
ScopedLocalFrame localFrame(env);
|
||||
|
||||
// Note: tokenObj may be null.
|
||||
ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
|
||||
ScopedLocalRef<jobject> keyEventObj(env, android_view_KeyEvent_fromNative(env, keyEvent));
|
||||
if (!keyEventObj.get()) {
|
||||
ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
|
||||
return {};
|
||||
}
|
||||
|
||||
ScopedLocalRef<jobject>
|
||||
fallbackKeyEventObj(env,
|
||||
env->CallObjectMethod(mServiceObj,
|
||||
gServiceClassInfo.dispatchUnhandledKey,
|
||||
tokenObj.get(), keyEventObj.get(),
|
||||
policyFlags));
|
||||
|
||||
android_view_KeyEvent_recycle(env, keyEventObj.get());
|
||||
if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey") ||
|
||||
!fallbackKeyEventObj.get()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const KeyEvent fallbackEvent = android_view_KeyEvent_toNative(env, fallbackKeyEventObj.get());
|
||||
android_view_KeyEvent_recycle(env, fallbackKeyEventObj.get());
|
||||
return fallbackEvent;
|
||||
}
|
||||
|
||||
void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) {
|
||||
@@ -1876,13 +1874,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject i
|
||||
InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode);
|
||||
|
||||
if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
|
||||
KeyEvent keyEvent;
|
||||
status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
|
||||
if (status) {
|
||||
jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
|
||||
return static_cast<jint>(InputEventInjectionResult::FAILED);
|
||||
}
|
||||
|
||||
const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj);
|
||||
const InputEventInjectionResult result =
|
||||
im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode,
|
||||
std::chrono::milliseconds(
|
||||
@@ -1913,13 +1905,7 @@ static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobjec
|
||||
NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
|
||||
|
||||
if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
|
||||
KeyEvent keyEvent;
|
||||
status_t status = android_view_KeyEvent_toNative(env, inputEventObj, &keyEvent);
|
||||
if (status) {
|
||||
jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const KeyEvent keyEvent = android_view_KeyEvent_toNative(env, inputEventObj);
|
||||
std::unique_ptr<VerifiedInputEvent> verifiedEvent =
|
||||
im->getInputManager()->getDispatcher().verifyInputEvent(keyEvent);
|
||||
if (verifiedEvent == nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user