Commit 0d7abffc authored by Aldo Culquicondor's avatar Aldo Culquicondor Committed by Commit Bot

VR: Ensuring consistency of events when transitioning to 2D UI

Also, making sure the source of motion events is set, in order
to avoid warnings from InputEventConsistencyVerifier.

BUG=848740

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_vr
Change-Id: Id1ee62b2d9eb63a6a3058b7a0914914823cf81d9
Reviewed-on: https://chromium-review.googlesource.com/1089856
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarJinsuk Kim <jinsukkim@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565437}
parent 0181723e
......@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.vr_shell;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
......@@ -27,7 +28,8 @@ public class AndroidUiGestureTarget {
@CalledByNative
private void inject(int action, long timeInMs) {
mMotionEventSynthesizer.inject(action, 1 /* pointerCount */, timeInMs);
mMotionEventSynthesizer.inject(
action, 1 /* pointerCount */, timeInMs, InputDevice.SOURCE_CLASS_POINTER);
}
@CalledByNative
......
......@@ -592,13 +592,19 @@ public class VrShellImpl
@Override
public void onWindowFocusChanged(boolean focused) {
// This handles the case where we open 2D popups in 2D-in-VR. We lose window focus, but stay
// resumed, so we have to listen for focus gain to know when the popup was closed.
// This also handles the case where we're launched via intent and turn VR mode on with
// a popup open. We'll lose window focus when the popup 'gets shown' and know to turn VR
// mode off.
// resumed, so we have to listen for focus gain to know when the popup was closed. However,
// we pause VrShellImpl so that we don't react to input from the controller nor do any
// rendering. This also handles the case where we're launched via intent and turn VR mode on
// with a popup open. We'll lose window focus when the popup 'gets shown' and know to turn
// VR mode off.
// TODO(asimjour): Focus is a bad signal. We should listen for windows being created and
// destroyed if possible.
if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) {
if (focused) {
resume();
} else {
pause();
}
VrShellDelegate.setVrModeEnabled(mActivity, focused);
setVisibility(focused ? View.VISIBLE : View.INVISIBLE);
}
......
......@@ -55,6 +55,12 @@ public class VrViewContainer extends FrameLayout {
return false;
}
// We also avoid propagation of hover events from the android root view to the java views.
@Override
public boolean dispatchHoverEvent(MotionEvent event) {
return false;
}
@SuppressLint("MissingSuperCall")
@Override
public void draw(Canvas canvas) {
......
......@@ -2029,6 +2029,7 @@ void VrShellGl::OnPause() {
paused_ = true;
vsync_helper_.CancelVSyncRequest();
controller_->OnPause();
ui_->input_manager()->OnPause();
gvr_api_->PauseTracking();
webvr_frame_timeout_.Cancel();
webvr_spinner_timeout_.Cancel();
......
......@@ -129,6 +129,15 @@ void UiInputManager::HandleInput(base::TimeTicks current_time,
previous_button_state_ = controller_model.touchpad_button_state;
}
void UiInputManager::OnPause() {
if (hover_target_id_) {
UiElement* prev_hovered = scene_->GetUiElementById(hover_target_id_);
if (prev_hovered)
prev_hovered->OnHoverLeave();
hover_target_id_ = 0;
}
}
void UiInputManager::SendFlingCancel(GestureList* gesture_list,
const gfx::PointF& target_point) {
if (!fling_target_id_) {
......
......@@ -57,6 +57,8 @@ class VR_EXPORT UiInputManager {
ReticleModel* reticle_model,
GestureList* gesture_list);
void OnPause();
// Text input related.
void RequestFocus(int element_id);
void RequestUnfocus(int element_id);
......
......@@ -4,7 +4,6 @@
package org.chromium.content.browser;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
......@@ -91,16 +90,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
* @param action Type of the action to inject.
* @param pointerCount The number of points associated with the event.
* @param timeInMs Timestamp for the event.
* @param source Source of the event.
*/
@Override
public void inject(int action, int pointerCount, long timeInMs) {
public void inject(int action, int pointerCount, long timeInMs, int source) {
switch (action) {
case MotionEventAction.START: {
mDownTimeInMs = timeInMs;
MotionEvent event = MotionEvent.obtain(
mDownTimeInMs, timeInMs, MotionEvent.ACTION_DOWN, 1,
mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, 0, 0);
MotionEvent event =
MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_DOWN, 1,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
......@@ -111,7 +110,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_POINTER_DOWN | pointerIndex, pointerCount,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
}
......@@ -119,18 +118,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
}
case MotionEventAction.MOVE: {
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_MOVE,
pointerCount, mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, 0, 0);
MotionEvent.ACTION_MOVE, pointerCount, mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
break;
}
case MotionEventAction.CANCEL: {
MotionEvent event = MotionEvent.obtain(
mDownTimeInMs, timeInMs, MotionEvent.ACTION_CANCEL, 1,
mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, 0, 0);
MotionEvent event =
MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_CANCEL, 1,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
break;
......@@ -143,15 +140,14 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_POINTER_UP | pointerIndex, pointerCount,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
}
MotionEvent event = MotionEvent.obtain(
mDownTimeInMs, timeInMs, MotionEvent.ACTION_UP, 1,
mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, 0, 0);
MotionEvent event =
MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_UP, 1,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchTouchEvent(event);
event.recycle();
break;
......@@ -160,7 +156,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
assert pointerCount == 1;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_SCROLL, pointerCount, mPointerProperties, mPointerCoords,
0, 0, 1, 1, 0, 0, InputDevice.SOURCE_CLASS_POINTER, 0);
0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchGenericMotionEvent(event);
event.recycle();
break;
......@@ -168,7 +164,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
case MotionEventAction.HOVER_ENTER:
case MotionEventAction.HOVER_EXIT:
case MotionEventAction.HOVER_MOVE: {
injectHover(action, pointerCount, timeInMs);
injectHover(action, pointerCount, timeInMs, source);
break;
}
default: {
......@@ -178,14 +174,13 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
}
}
private void injectHover(int action, int pointerCount, long timeInMs) {
private void injectHover(int action, int pointerCount, long timeInMs, int source) {
assert pointerCount == 1;
int androidAction = MotionEvent.ACTION_HOVER_ENTER;
if (MotionEventAction.HOVER_EXIT == action) androidAction = MotionEvent.ACTION_HOVER_EXIT;
if (MotionEventAction.HOVER_MOVE == action) androidAction = MotionEvent.ACTION_HOVER_MOVE;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, androidAction, pointerCount,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0,
InputDevice.SOURCE_CLASS_POINTER, 0);
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
mTarget.dispatchGenericMotionEvent(event);
event.recycle();
}
......
......@@ -27,7 +27,7 @@ public class SyntheticGestureTarget {
@CalledByNative
private void inject(int action, int pointerCount, long timeInMs) {
mMotionEventSynthesizer.inject(action, pointerCount, timeInMs);
mMotionEventSynthesizer.inject(action, pointerCount, timeInMs, 0 /* source */);
}
@CalledByNative
......
......@@ -33,6 +33,7 @@ public interface MotionEventSynthesizer {
* @param action Type of the action to inject.
* @param pointerCount The number of points associated with the event.
* @param timeInMs Timestamp for the event.
* @param source Source of the event.
*/
void inject(int action, int pointerCount, long timeInMs);
void inject(int action, int pointerCount, long timeInMs, int source);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment