Merge "Move focus dispatch to input (2/2)"

This commit is contained in:
TreeHugger Robot
2020-01-15 04:52:14 +00:00
committed by Android (Google) Code Review
5 changed files with 52 additions and 13 deletions

View File

@@ -127,6 +127,19 @@ public abstract class InputEventReceiver {
finishInputEvent(event, false);
}
/**
* Called when a focus event is received.
*
* @param hasFocus if true, the window associated with this input channel has just received
* focus
* if false, the window associated with this input channel has just lost focus
* @param inTouchMode if true, the device is in touch mode
* if false, the device is not in touch mode
*/
// Called from native code.
public void onFocusEvent(boolean hasFocus, boolean inTouchMode) {
}
/**
* Called when a batched input event is pending.
*
@@ -213,8 +226,13 @@ public abstract class InputEventReceiver {
onBatchedInputEventPending();
}
public static interface Factory {
public InputEventReceiver createInputEventReceiver(
InputChannel inputChannel, Looper looper);
/**
* Factory for InputEventReceiver
*/
public interface Factory {
/**
* Create a new InputReceiver for a given inputChannel
*/
InputEventReceiver createInputEventReceiver(InputChannel inputChannel, Looper looper);
}
}

View File

@@ -8043,6 +8043,11 @@ public final class ViewRootImpl implements ViewParent,
}
}
@Override
public void onFocusEvent(boolean hasFocus, boolean inTouchMode) {
windowFocusChanged(hasFocus, inTouchMode);
}
@Override
public void dispose() {
unscheduleConsumeBatchedInput();

View File

@@ -40,10 +40,15 @@ namespace android {
static const bool kDebugDispatchCycle = false;
static const char* toString(bool value) {
return value ? "true" : "false";
}
static struct {
jclass clazz;
jmethodID dispatchInputEvent;
jmethodID onFocusEvent;
jmethodID dispatchBatchedInputEventPending;
} gInputEventReceiverClassInfo;
@@ -219,8 +224,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%" PRId64,
getInputChannelName().c_str(),
consumeBatches ? "true" : "false", frameTime);
getInputChannelName().c_str(), toString(consumeBatches), frameTime);
}
if (consumeBatches) {
@@ -235,6 +239,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
for (;;) {
uint32_t seq;
InputEvent* inputEvent;
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent);
if (status) {
@@ -302,6 +307,19 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
break;
}
case AINPUT_EVENT_TYPE_FOCUS: {
FocusEvent* focusEvent = static_cast<FocusEvent*>(inputEvent);
if (kDebugDispatchCycle) {
ALOGD("channel '%s' ~ Received focus event: hasFocus=%s, inTouchMode=%s.",
getInputChannelName().c_str(), toString(focusEvent->getHasFocus()),
toString(focusEvent->getInTouchMode()));
}
env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.onFocusEvent,
jboolean(focusEvent->getHasFocus()),
jboolean(focusEvent->getInTouchMode()));
finishInputEvent(seq, true /* handled */);
return OK;
}
default:
assert(false); // InputConsumer should prevent this from ever happening
@@ -421,6 +439,8 @@ int register_android_view_InputEventReceiver(JNIEnv* env) {
gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
gInputEventReceiverClassInfo.clazz,
"dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
gInputEventReceiverClassInfo.onFocusEvent =
GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onFocusEvent", "(ZZ)V");
gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");

View File

@@ -4602,13 +4602,13 @@ public class WindowManagerService extends IWindowManager.Stub
if (newFocus != null) {
ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus);
newFocus.reportFocusChangedSerialized(true, mInTouchMode);
newFocus.reportFocusChangedSerialized(true);
notifyFocusChanged();
}
if (lastFocus != null) {
ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus);
lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
lastFocus.reportFocusChangedSerialized(false);
}
break;
}
@@ -4626,7 +4626,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (int i = 0; i < N; i++) {
ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing delayed focus: %s",
losers.get(i));
losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
losers.get(i).reportFocusChangedSerialized(false);
}
break;
}

View File

@@ -3339,11 +3339,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* Report a focus change. Must be called with no locks held, and consistently
* from the same serialized thread (such as dispatched from a handler).
*/
void reportFocusChangedSerialized(boolean focused, boolean inTouchMode) {
try {
mClient.windowFocusChanged(focused, inTouchMode);
} catch (RemoteException e) {
}
void reportFocusChangedSerialized(boolean focused) {
if (mFocusCallbacks != null) {
final int N = mFocusCallbacks.beginBroadcast();
for (int i=0; i<N; i++) {