Fix keyboard focus in VR
Consider this VirtualDisplay (VD) scenario: HostActivity creates a VD which holds SettingsActivity. When EditText on SettingsActivity is tapped, it gains focus. On eventual taps, it loses focus i.e. the Window in VD loses focus and the host activity in primary display gets the focus instead. This happens because WM's TaskTapPointerEventListener.onPointerEvent() is called on the default display only. Root cause: 1. Tap detector isn't registered for non-default display. 2. Tap detector has no info on which displayId touch was received. 3. InputFlinger doesn't deliver InputMonitor events for non-default displays (fixed in a separate CL) Fixing above results in onPointerEvent(MotionEvent) to deliver the Touch events successfully to VD. We restrict these changes to physical multi-displays and VR VirtualDisplays (which uses virtual touch device). [VrManagerService calls WMInternal.setVr2dDisplayId(int)] In future, displayId should be part of InputEvent. Bug: 64258305 Bug: 62033391 Test: bit FrameworksServicesTests:com.android.server.wm.DisplayContentTests Change-Id: I3626f4de5aa9bcf905da9abd39f3ab1baefc4c48
This commit is contained in:
@@ -16,10 +16,6 @@
|
||||
|
||||
package android.inputmethodservice;
|
||||
|
||||
import com.android.internal.os.HandlerCaller;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.view.IInputMethodSession;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
@@ -34,9 +30,13 @@ import android.view.InputEventReceiver;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.CursorAnchorInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.InputMethodSession;
|
||||
import android.view.inputmethod.CursorAnchorInfo;
|
||||
|
||||
import com.android.internal.os.HandlerCaller;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.view.IInputMethodSession;
|
||||
|
||||
class IInputMethodSessionWrapper extends IInputMethodSession.Stub
|
||||
implements HandlerCaller.Callback {
|
||||
@@ -218,7 +218,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputEvent(InputEvent event) {
|
||||
public void onInputEvent(InputEvent event, int displayId) {
|
||||
if (mInputMethodSession == null) {
|
||||
// The session has been finished.
|
||||
finishInputEvent(event, false);
|
||||
|
||||
@@ -268,7 +268,7 @@ public abstract class WallpaperService extends Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputEvent(InputEvent event) {
|
||||
public void onInputEvent(InputEvent event, int displayId) {
|
||||
boolean handled = false;
|
||||
try {
|
||||
if (event instanceof MotionEvent
|
||||
|
||||
@@ -111,9 +111,10 @@ public abstract class InputEventReceiver {
|
||||
* to indicate whether the event was handled. No new input events will be received
|
||||
* until {@link #finishInputEvent} is called.
|
||||
*
|
||||
* @param displayId The display id on which input event triggered.
|
||||
* @param event The input event that was received.
|
||||
*/
|
||||
public void onInputEvent(InputEvent event) {
|
||||
public void onInputEvent(InputEvent event, int displayId) {
|
||||
finishInputEvent(event, false);
|
||||
}
|
||||
|
||||
@@ -180,9 +181,9 @@ public abstract class InputEventReceiver {
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
private void dispatchInputEvent(int seq, InputEvent event) {
|
||||
private void dispatchInputEvent(int seq, InputEvent event, int displayId) {
|
||||
mSeqMap.put(event.getSequenceNumber(), seq);
|
||||
onInputEvent(event);
|
||||
onInputEvent(event, displayId);
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
|
||||
@@ -6756,7 +6756,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputEvent(InputEvent event) {
|
||||
public void onInputEvent(InputEvent event, int displayId) {
|
||||
enqueueInputEvent(event, this, 0, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -347,4 +347,11 @@ public abstract class WindowManagerInternal {
|
||||
* Requests the window manager to recompute the windows for accessibility.
|
||||
*/
|
||||
public abstract void computeWindowsForAccessibility();
|
||||
|
||||
/**
|
||||
* Called after virtual display Id is updated by
|
||||
* {@link com.android.server.vr.Vr2dDisplay} with a specific
|
||||
* {@param vr2dDisplayId}.
|
||||
*/
|
||||
public abstract void setVr2dDisplayId(int vr2dDisplayId);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
|
||||
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
|
||||
@@ -616,7 +617,16 @@ public interface WindowManagerPolicy {
|
||||
* 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
|
||||
* copy() must be made and the copy must be recycled.
|
||||
**/
|
||||
public void onPointerEvent(MotionEvent motionEvent);
|
||||
void onPointerEvent(MotionEvent motionEvent);
|
||||
|
||||
/**
|
||||
* @see #onPointerEvent(MotionEvent)
|
||||
**/
|
||||
default void onPointerEvent(MotionEvent motionEvent, int displayId) {
|
||||
if (displayId == DEFAULT_DISPLAY) {
|
||||
onPointerEvent(motionEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Window has been added to the screen. */
|
||||
|
||||
Reference in New Issue
Block a user