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 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.vr_shell; package org.chromium.chrome.browser.vr_shell;
import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
...@@ -27,7 +28,8 @@ public class AndroidUiGestureTarget { ...@@ -27,7 +28,8 @@ public class AndroidUiGestureTarget {
@CalledByNative @CalledByNative
private void inject(int action, long timeInMs) { private void inject(int action, long timeInMs) {
mMotionEventSynthesizer.inject(action, 1 /* pointerCount */, timeInMs); mMotionEventSynthesizer.inject(
action, 1 /* pointerCount */, timeInMs, InputDevice.SOURCE_CLASS_POINTER);
} }
@CalledByNative @CalledByNative
......
...@@ -592,13 +592,19 @@ public class VrShellImpl ...@@ -592,13 +592,19 @@ public class VrShellImpl
@Override @Override
public void onWindowFocusChanged(boolean focused) { public void onWindowFocusChanged(boolean focused) {
// This handles the case where we open 2D popups in 2D-in-VR. We lose window focus, but stay // 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. // resumed, so we have to listen for focus gain to know when the popup was closed. However,
// This also handles the case where we're launched via intent and turn VR mode on with // we pause VrShellImpl so that we don't react to input from the controller nor do any
// a popup open. We'll lose window focus when the popup 'gets shown' and know to turn VR // rendering. This also handles the case where we're launched via intent and turn VR mode on
// mode off. // 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 // TODO(asimjour): Focus is a bad signal. We should listen for windows being created and
// destroyed if possible. // destroyed if possible.
if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) { if (VrShellDelegate.getVrClassesWrapper().bootsToVr()) {
if (focused) {
resume();
} else {
pause();
}
VrShellDelegate.setVrModeEnabled(mActivity, focused); VrShellDelegate.setVrModeEnabled(mActivity, focused);
setVisibility(focused ? View.VISIBLE : View.INVISIBLE); setVisibility(focused ? View.VISIBLE : View.INVISIBLE);
} }
......
...@@ -55,6 +55,12 @@ public class VrViewContainer extends FrameLayout { ...@@ -55,6 +55,12 @@ public class VrViewContainer extends FrameLayout {
return false; 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") @SuppressLint("MissingSuperCall")
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
......
...@@ -2029,6 +2029,7 @@ void VrShellGl::OnPause() { ...@@ -2029,6 +2029,7 @@ void VrShellGl::OnPause() {
paused_ = true; paused_ = true;
vsync_helper_.CancelVSyncRequest(); vsync_helper_.CancelVSyncRequest();
controller_->OnPause(); controller_->OnPause();
ui_->input_manager()->OnPause();
gvr_api_->PauseTracking(); gvr_api_->PauseTracking();
webvr_frame_timeout_.Cancel(); webvr_frame_timeout_.Cancel();
webvr_spinner_timeout_.Cancel(); webvr_spinner_timeout_.Cancel();
......
...@@ -129,6 +129,15 @@ void UiInputManager::HandleInput(base::TimeTicks current_time, ...@@ -129,6 +129,15 @@ void UiInputManager::HandleInput(base::TimeTicks current_time,
previous_button_state_ = controller_model.touchpad_button_state; 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, void UiInputManager::SendFlingCancel(GestureList* gesture_list,
const gfx::PointF& target_point) { const gfx::PointF& target_point) {
if (!fling_target_id_) { if (!fling_target_id_) {
......
...@@ -57,6 +57,8 @@ class VR_EXPORT UiInputManager { ...@@ -57,6 +57,8 @@ class VR_EXPORT UiInputManager {
ReticleModel* reticle_model, ReticleModel* reticle_model,
GestureList* gesture_list); GestureList* gesture_list);
void OnPause();
// Text input related. // Text input related.
void RequestFocus(int element_id); void RequestFocus(int element_id);
void RequestUnfocus(int element_id); void RequestUnfocus(int element_id);
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
package org.chromium.content.browser; package org.chromium.content.browser;
import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords; import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties; import android.view.MotionEvent.PointerProperties;
...@@ -91,16 +90,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -91,16 +90,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
* @param action Type of the action to inject. * @param action Type of the action to inject.
* @param pointerCount The number of points associated with the event. * @param pointerCount The number of points associated with the event.
* @param timeInMs Timestamp for the event. * @param timeInMs Timestamp for the event.
* @param source Source of the event.
*/ */
@Override @Override
public void inject(int action, int pointerCount, long timeInMs) { public void inject(int action, int pointerCount, long timeInMs, int source) {
switch (action) { switch (action) {
case MotionEventAction.START: { case MotionEventAction.START: {
mDownTimeInMs = timeInMs; mDownTimeInMs = timeInMs;
MotionEvent event = MotionEvent.obtain( MotionEvent event =
mDownTimeInMs, timeInMs, MotionEvent.ACTION_DOWN, 1, MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_DOWN, 1,
mPointerProperties, mPointerCoords, mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
0, 0, 1, 1, 0, 0, 0, 0);
mTarget.dispatchTouchEvent(event); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
...@@ -111,7 +110,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -111,7 +110,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT; int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
event = MotionEvent.obtain(mDownTimeInMs, timeInMs, event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_POINTER_DOWN | pointerIndex, pointerCount, 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); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
} }
...@@ -119,18 +118,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -119,18 +118,16 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
} }
case MotionEventAction.MOVE: { case MotionEventAction.MOVE: {
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_MOVE, MotionEvent.ACTION_MOVE, pointerCount, mPointerProperties, mPointerCoords,
pointerCount, mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
0, 0, 1, 1, 0, 0, 0, 0);
mTarget.dispatchTouchEvent(event); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
break; break;
} }
case MotionEventAction.CANCEL: { case MotionEventAction.CANCEL: {
MotionEvent event = MotionEvent.obtain( MotionEvent event =
mDownTimeInMs, timeInMs, MotionEvent.ACTION_CANCEL, 1, MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_CANCEL, 1,
mPointerProperties, mPointerCoords, mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
0, 0, 1, 1, 0, 0, 0, 0);
mTarget.dispatchTouchEvent(event); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
break; break;
...@@ -143,15 +140,14 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -143,15 +140,14 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT; int pointerIndex = 1 << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_POINTER_UP | pointerIndex, pointerCount, 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); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
} }
MotionEvent event = MotionEvent.obtain( MotionEvent event =
mDownTimeInMs, timeInMs, MotionEvent.ACTION_UP, 1, MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent.ACTION_UP, 1,
mPointerProperties, mPointerCoords, mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
0, 0, 1, 1, 0, 0, 0, 0);
mTarget.dispatchTouchEvent(event); mTarget.dispatchTouchEvent(event);
event.recycle(); event.recycle();
break; break;
...@@ -160,7 +156,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -160,7 +156,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
assert pointerCount == 1; assert pointerCount == 1;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs,
MotionEvent.ACTION_SCROLL, pointerCount, mPointerProperties, mPointerCoords, 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); mTarget.dispatchGenericMotionEvent(event);
event.recycle(); event.recycle();
break; break;
...@@ -168,7 +164,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -168,7 +164,7 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer {
case MotionEventAction.HOVER_ENTER: case MotionEventAction.HOVER_ENTER:
case MotionEventAction.HOVER_EXIT: case MotionEventAction.HOVER_EXIT:
case MotionEventAction.HOVER_MOVE: { case MotionEventAction.HOVER_MOVE: {
injectHover(action, pointerCount, timeInMs); injectHover(action, pointerCount, timeInMs, source);
break; break;
} }
default: { default: {
...@@ -178,14 +174,13 @@ public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { ...@@ -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; assert pointerCount == 1;
int androidAction = MotionEvent.ACTION_HOVER_ENTER; int androidAction = MotionEvent.ACTION_HOVER_ENTER;
if (MotionEventAction.HOVER_EXIT == action) androidAction = MotionEvent.ACTION_HOVER_EXIT; if (MotionEventAction.HOVER_EXIT == action) androidAction = MotionEvent.ACTION_HOVER_EXIT;
if (MotionEventAction.HOVER_MOVE == action) androidAction = MotionEvent.ACTION_HOVER_MOVE; if (MotionEventAction.HOVER_MOVE == action) androidAction = MotionEvent.ACTION_HOVER_MOVE;
MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, androidAction, pointerCount, MotionEvent event = MotionEvent.obtain(mDownTimeInMs, timeInMs, androidAction, pointerCount,
mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, mPointerProperties, mPointerCoords, 0, 0, 1, 1, 0, 0, source, 0);
InputDevice.SOURCE_CLASS_POINTER, 0);
mTarget.dispatchGenericMotionEvent(event); mTarget.dispatchGenericMotionEvent(event);
event.recycle(); event.recycle();
} }
......
...@@ -27,7 +27,7 @@ public class SyntheticGestureTarget { ...@@ -27,7 +27,7 @@ public class SyntheticGestureTarget {
@CalledByNative @CalledByNative
private void inject(int action, int pointerCount, long timeInMs) { private void inject(int action, int pointerCount, long timeInMs) {
mMotionEventSynthesizer.inject(action, pointerCount, timeInMs); mMotionEventSynthesizer.inject(action, pointerCount, timeInMs, 0 /* source */);
} }
@CalledByNative @CalledByNative
......
...@@ -33,6 +33,7 @@ public interface MotionEventSynthesizer { ...@@ -33,6 +33,7 @@ public interface MotionEventSynthesizer {
* @param action Type of the action to inject. * @param action Type of the action to inject.
* @param pointerCount The number of points associated with the event. * @param pointerCount The number of points associated with the event.
* @param timeInMs Timestamp for 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