Commit d51d3420 authored by Aldo Culquicondor's avatar Aldo Culquicondor Committed by Commit Bot

VR: Adding move support for the platform UI

This enables touch interaction with the web contents, effectively
enabling long press, drag, selection, etc.

Context menu and selection handles are disabled for VR in this CL.

Bug: 842916, 733656, 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;luci.chromium.try:linux_vr
Change-Id: If50401ddbc130abde697b57d580bc492de2c4dda
Reviewed-on: https://chromium-review.googlesource.com/1091281
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567745}
parent 307e8978
......@@ -150,6 +150,7 @@ include_rules = [
"+third_party/blink/public/platform/web_input_event.h",
"+third_party/blink/public/platform/web_mouse_event.h",
"+third_party/blink/public/platform/web_mouse_wheel_event.h",
"+third_party/blink/public/platform/web_touch_event.h",
"+third_party/blink/public/platform/web_referrer_policy.h",
"+third_party/blink/public/platform/web_security_style.h",
"+third_party/blink/public/platform/web_speech_synthesis_constants.h",
......
......@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/web_gesture_event.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_touch_event.h"
using base::android::JavaParamRef;
using base::android::JavaRef;
......@@ -32,9 +33,12 @@ AndroidUiGestureTarget::~AndroidUiGestureTarget() = default;
void AndroidUiGestureTarget::DispatchWebInputEvent(
std::unique_ptr<blink::WebInputEvent> event) {
blink::WebMouseEvent* mouse;
blink::WebTouchEvent* touch;
blink::WebGestureEvent* gesture;
if (blink::WebInputEvent::IsMouseEventType(event->GetType())) {
mouse = static_cast<blink::WebMouseEvent*>(event.get());
} else if (blink::WebInputEvent::IsTouchEventType(event->GetType())) {
touch = static_cast<blink::WebTouchEvent*>(event.get());
} else {
gesture = static_cast<blink::WebGestureEvent*>(event.get());
}
......@@ -94,22 +98,28 @@ void AndroidUiGestureTarget::DispatchWebInputEvent(
break;
case blink::WebMouseEvent::kMouseMove:
case blink::WebMouseEvent::kMouseLeave:
// We don't need to inject MOTION_EVENT_ACTION_HOVER_EXIT as the platform
// will generate it for us if the pointer is out of bounds.
// The platform ignores HOVER_EXIT, so we instead send a fixed
// out-of-bounds point (http://crbug.com/715114).
SetPointer(mouse->PositionInWidget().x, mouse->PositionInWidget().y);
Inject(content::MOTION_EVENT_ACTION_HOVER_MOVE, event_time_ms);
break;
case blink::WebMouseEvent::kMouseDown:
case blink::WebTouchEvent::kTouchStart:
// Mouse down events are translated into touch events on Android anyways,
// so we can just send touch events.
// We intentionally don't support long press or drags/swipes with mouse
// input as this could trigger long press and open 2D popups.
SetPointer(mouse->PositionInWidget().x, mouse->PositionInWidget().y);
SetPointer(touch->touches[0].PositionInWidget().x,
touch->touches[0].PositionInWidget().y);
Inject(content::MOTION_EVENT_ACTION_START, event_time_ms);
break;
case blink::WebTouchEvent::kTouchEnd:
SetPointer(touch->touches[0].PositionInWidget().x,
touch->touches[0].PositionInWidget().y);
Inject(content::MOTION_EVENT_ACTION_END, event_time_ms);
break;
case blink::WebMouseEvent::kMouseUp:
// No need to do anything for mouseUp as mouseDown already handled up.
case blink::WebTouchEvent::kTouchMove:
DCHECK_EQ(touch->touches_length, 1u);
SetPointer(touch->touches[0].PositionInWidget().x,
touch->touches[0].PositionInWidget().y);
Inject(content::MOTION_EVENT_ACTION_MOVE, event_time_ms);
break;
default:
NOTREACHED() << "Unsupported event type sent to Android UI.";
......
......@@ -871,6 +871,7 @@ void VrShellGl::EnableAlertDialog(PlatformInputHandler* input_handler,
showing_vr_dialog_ = true;
vr_dialog_input_delegate_.reset(new PlatformUiInputDelegate(input_handler));
vr_dialog_input_delegate_->SetSize(width, height);
vr_dialog_input_delegate_->SetPlatformController(controller_.get());
ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(),
width / content_tex_buffer_size_.width(),
height / content_tex_buffer_size_.width());
......
......@@ -15,6 +15,7 @@
#include "chrome/browser/android/download/download_controller_base.h"
#include "chrome/browser/image_decoder.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/vr/vr_tab_helper.h"
#include "chrome/common/chrome_render_frame.mojom.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "content/public/browser/render_frame_host.h"
......@@ -107,6 +108,12 @@ ContextMenuHelper::~ContextMenuHelper() {
void ContextMenuHelper::ShowContextMenu(
content::RenderFrameHost* render_frame_host,
const content::ContextMenuParams& params) {
// TODO(crbug.com/851495): support context menu in VR.
if (vr::VrTabHelper::IsUiSuppressedInVr(
web_contents_, vr::UiSuppressedElement::kContextMenu)) {
web_contents_->NotifyContextMenuClosed(params.custom_context);
return;
}
JNIEnv* env = base::android::AttachCurrentThread();
context_menu_params_ = params;
render_frame_id_ = render_frame_host->GetRoutingID();
......
......@@ -146,44 +146,4 @@ void ContentInputDelegate::OnWebInputTextChanged(const base::string16& text) {
base::ResetAndReturn(&update_state_callback).Run(pending_text_input_info_);
}
std::unique_ptr<blink::WebMouseEvent> ContentInputDelegate::MakeMouseEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) {
if (!controller_)
return nullptr;
gfx::Point location(size().width() * normalized_web_content_location.x(),
size().height() * normalized_web_content_location.y());
blink::WebInputEvent::Modifiers modifiers =
controller_->IsButtonDown(PlatformController::kButtonSelect)
? blink::WebInputEvent::kLeftButtonDown
: blink::WebInputEvent::kNoModifiers;
base::TimeTicks timestamp;
switch (type) {
case blink::WebInputEvent::kMouseUp:
case blink::WebInputEvent::kMouseDown:
timestamp = controller_->GetLastButtonTimestamp();
break;
case blink::WebInputEvent::kMouseMove:
case blink::WebInputEvent::kMouseEnter:
case blink::WebInputEvent::kMouseLeave:
timestamp = controller_->GetLastOrientationTimestamp();
break;
default:
NOTREACHED();
}
auto mouse_event =
std::make_unique<blink::WebMouseEvent>(type, modifiers, timestamp);
mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse;
mouse_event->button = blink::WebPointerProperties::Button::kLeft;
mouse_event->SetPositionInWidget(location.x(), location.y());
// TODO(mthiesse): Should we support double-clicks for input? What should the
// timeout be?
mouse_event->click_count = 1;
return mouse_event;
}
} // namespace vr
......@@ -20,7 +20,6 @@
namespace vr {
class PlatformController;
class PlatformInputHandler;
// This class is responsible for processing all events and gestures for
......@@ -48,10 +47,6 @@ class VR_EXPORT ContentInputDelegate : public PlatformUiInputDelegate {
int compositon_end,
base::OnceCallback<void(const TextInputInfo&)> callback);
void OnPlatformControllerInitialized(PlatformController* controller) {
controller_ = controller;
}
void OnWebInputTextChangedForTest(const base::string16& text) {
OnWebInputTextChanged(text);
}
......@@ -61,9 +56,6 @@ class VR_EXPORT ContentInputDelegate : public PlatformUiInputDelegate {
protected:
void SendGestureToTarget(
std::unique_ptr<blink::WebInputEvent> event) override;
std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) override;
private:
enum TextRequestState {
......@@ -77,8 +69,6 @@ class VR_EXPORT ContentInputDelegate : public PlatformUiInputDelegate {
int content_id_ = 0;
int locked_content_id_ = 0;
PlatformController* controller_ = nullptr;
EditedText last_keyboard_edit_;
TextRequestState pending_text_request_state_ = kNoPendingRequest;
TextInputInfo pending_text_input_info_;
......
......@@ -51,6 +51,11 @@ void PlatformUiElement::OnButtonUp(const gfx::PointF& position) {
delegate_->OnButtonUp(position);
}
void PlatformUiElement::OnTouchMove(const gfx::PointF& position) {
if (delegate_)
delegate_->OnTouchMove(position);
}
void PlatformUiElement::OnFlingCancel(
std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& position) {
......
......@@ -27,6 +27,7 @@ class PlatformUiElement : public UiElement {
void OnHoverMove(const gfx::PointF& position) override;
void OnButtonDown(const gfx::PointF& position) override;
void OnButtonUp(const gfx::PointF& position) override;
void OnTouchMove(const gfx::PointF& position) override;
void OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& position) override;
void OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
......
......@@ -10,6 +10,7 @@
#include "chrome/browser/vr/platform_input_handler.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
#include "third_party/blink/public/platform/web_mouse_event.h"
#include "third_party/blink/public/platform/web_touch_event.h"
namespace vr {
......@@ -52,13 +53,19 @@ void PlatformUiInputDelegate::OnHoverMove(
void PlatformUiInputDelegate::OnButtonDown(
const gfx::PointF& normalized_hit_point) {
SendGestureToTarget(
MakeMouseEvent(blink::WebInputEvent::kMouseDown, normalized_hit_point));
MakeTouchEvent(blink::WebInputEvent::kTouchStart, normalized_hit_point));
}
void PlatformUiInputDelegate::OnButtonUp(
const gfx::PointF& normalized_hit_point) {
SendGestureToTarget(
MakeMouseEvent(blink::WebInputEvent::kMouseUp, normalized_hit_point));
MakeTouchEvent(blink::WebInputEvent::kTouchEnd, normalized_hit_point));
}
void PlatformUiInputDelegate::OnTouchMove(
const gfx::PointF& normalized_hit_point) {
SendGestureToTarget(
MakeTouchEvent(blink::WebInputEvent::kTouchMove, normalized_hit_point));
}
void PlatformUiInputDelegate::OnFlingCancel(
......@@ -106,14 +113,30 @@ void PlatformUiInputDelegate::SendGestureToTarget(
std::unique_ptr<blink::WebMouseEvent> PlatformUiInputDelegate::MakeMouseEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) {
gfx::Point location(size_.width() * normalized_web_content_location.x(),
size_.height() * normalized_web_content_location.y());
blink::WebInputEvent::Modifiers modifiers =
blink::WebInputEvent::kNoModifiers;
const gfx::PointF& normalized_web_content_location) const {
// TODO(acondor): Remove dependency on platform controller.
if (!controller_)
return nullptr;
auto mouse_event = std::make_unique<blink::WebMouseEvent>(
type, modifiers, base::TimeTicks::Now());
gfx::Point location = CalculateLocation(normalized_web_content_location);
blink::WebInputEvent::Modifiers modifiers =
controller_->IsButtonDown(PlatformController::kButtonSelect)
? blink::WebInputEvent::kLeftButtonDown
: blink::WebInputEvent::kNoModifiers;
base::TimeTicks timestamp;
switch (type) {
case blink::WebInputEvent::kMouseMove:
case blink::WebInputEvent::kMouseEnter:
case blink::WebInputEvent::kMouseLeave:
timestamp = controller_->GetLastOrientationTimestamp();
break;
default:
NOTREACHED();
}
auto mouse_event =
std::make_unique<blink::WebMouseEvent>(type, modifiers, timestamp);
mouse_event->pointer_type = blink::WebPointerProperties::PointerType::kMouse;
mouse_event->button = blink::WebPointerProperties::Button::kLeft;
mouse_event->SetPositionInWidget(location.x(), location.y());
......@@ -121,4 +144,49 @@ std::unique_ptr<blink::WebMouseEvent> PlatformUiInputDelegate::MakeMouseEvent(
return mouse_event;
}
std::unique_ptr<blink::WebTouchEvent> PlatformUiInputDelegate::MakeTouchEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) const {
// TODO(acondor): Remove dependency on platform controller.
if (!controller_)
return nullptr;
gfx::Point location = CalculateLocation(normalized_web_content_location);
blink::WebInputEvent::Modifiers modifiers =
blink::WebInputEvent::kNoModifiers;
base::TimeTicks timestamp;
blink::WebTouchPoint::State touch_state =
blink::WebTouchPoint::kStateUndefined;
switch (type) {
case blink::WebInputEvent::kTouchStart:
touch_state = blink::WebTouchPoint::kStatePressed;
timestamp = controller_->GetLastButtonTimestamp();
break;
case blink::WebInputEvent::kTouchEnd:
touch_state = blink::WebTouchPoint::kStateReleased;
timestamp = controller_->GetLastButtonTimestamp();
break;
case blink::WebInputEvent::kTouchMove:
touch_state = blink::WebTouchPoint::kStateMoved;
timestamp = controller_->GetLastOrientationTimestamp();
break;
default:
NOTREACHED();
}
auto touch_event =
std::make_unique<blink::WebTouchEvent>(type, modifiers, timestamp);
touch_event->touches_length = 1;
touch_event->touches[0].state = touch_state;
touch_event->touches[0].SetPositionInWidget(location.x(), location.y());
return touch_event;
}
gfx::Point PlatformUiInputDelegate::CalculateLocation(
const gfx::PointF& normalized_web_content_location) const {
return gfx::Point(size_.width() * normalized_web_content_location.x(),
size_.height() * normalized_web_content_location.y());
}
} // namespace vr
......@@ -21,6 +21,7 @@
namespace blink {
class WebGestureEvent;
class WebMouseEvent;
class WebTouchEvent;
} // namespace blink
namespace gfx {
......@@ -29,6 +30,7 @@ class PointF;
namespace vr {
class PlatformController;
class PlatformInputHandler;
// This class is responsible for processing all events and gestures for
......@@ -48,6 +50,7 @@ class VR_EXPORT PlatformUiInputDelegate {
VIRTUAL_FOR_MOCKS void OnHoverMove(const gfx::PointF& normalized_hit_point);
VIRTUAL_FOR_MOCKS void OnButtonDown(const gfx::PointF& normalized_hit_point);
VIRTUAL_FOR_MOCKS void OnButtonUp(const gfx::PointF& normalized_hit_point);
VIRTUAL_FOR_MOCKS void OnTouchMove(const gfx::PointF& normalized_hit_point);
VIRTUAL_FOR_MOCKS void OnFlingCancel(
std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& normalized_hit_point);
......@@ -61,6 +64,10 @@ class VR_EXPORT PlatformUiInputDelegate {
std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& normalized_hit_point);
void SetPlatformController(PlatformController* controller) {
controller_ = controller;
}
void SetSize(int width, int height) { size_ = {width, height}; }
void SetPlatformInputHandlerForTest(PlatformInputHandler* input_handler) {
input_handler_ = input_handler;
......@@ -68,18 +75,27 @@ class VR_EXPORT PlatformUiInputDelegate {
protected:
virtual void SendGestureToTarget(std::unique_ptr<blink::WebInputEvent> event);
virtual std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location);
PlatformInputHandler* input_handler() const { return input_handler_; }
private:
void UpdateGesture(const gfx::PointF& normalized_content_hit_point,
blink::WebGestureEvent& gesture);
std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) const;
std::unique_ptr<blink::WebTouchEvent> MakeTouchEvent(
blink::WebInputEvent::Type type,
const gfx::PointF& normalized_web_content_location) const;
gfx::Point CalculateLocation(
const gfx::PointF& normalized_web_content_location) const;
gfx::Size size_;
PlatformInputHandler* input_handler_ = nullptr;
// TODO(acondor): Remove dependency on platform controller.
PlatformController* controller_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(PlatformUiInputDelegate);
};
......
......@@ -438,7 +438,7 @@ void Ui::OnContentBoundsChanged(int width, int height) {
}
void Ui::OnPlatformControllerInitialized(PlatformController* controller) {
content_input_delegate_->OnPlatformControllerInitialized(controller);
content_input_delegate_->SetPlatformController(controller);
}
bool Ui::IsControllerVisible() const {
......
......@@ -25,6 +25,7 @@ enum class UiSuppressedElement : int {
kUsbChooser,
kSslClientCertificate,
kMediaRouterPresentationRequest,
kContextMenu,
// This must be last.
kCount,
......
......@@ -77,6 +77,7 @@ bool VrTabHelper::IsUiSuppressedInVr(content::WebContents* contents,
// and permission request dialog are supported in VR before we disable this
// suppression.
case UiSuppressedElement::kFileAccessPermission:
case UiSuppressedElement::kContextMenu:
suppress = true;
break;
// The following are not suppressed if kVrBrowsingNativeAndroidUi is
......
......@@ -506,11 +506,6 @@ void RenderWidgetHostViewAndroid::OnTextSelectionChanged(
RenderWidgetHostViewBase* updated_view) {
DCHECK_EQ(text_input_manager_, text_input_manager);
// TODO(asimjour): remove the flag and fix text selection popup for
// virtual reality mode.
if (is_in_vr_)
return;
if (!selection_popup_controller_)
return;
......@@ -1866,6 +1861,8 @@ void RenderWidgetHostViewAndroid::DismissTextHandles() {
void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(
bool hide_handles) {
// TODO(crbug.com/851054): support touch selection handles in VR.
DCHECK(hide_handles || !is_in_vr_);
if (!touch_selection_controller_ ||
handles_hidden_by_selection_ui_ == hide_handles)
return;
......@@ -1881,13 +1878,9 @@ base::Optional<SkColor> RenderWidgetHostViewAndroid::GetCachedBackgroundColor()
void RenderWidgetHostViewAndroid::SetIsInVR(bool is_in_vr) {
is_in_vr_ = is_in_vr;
// TODO(crbug.com/779126): support touch selection handles in VR.
if (is_in_vr) {
touch_selection_controller_.reset();
} else if (view_.parent()) {
touch_selection_controller_ = CreateSelectionController(
touch_selection_controller_client_manager_.get(), view_.parent());
}
// TODO(crbug.com/851054): support touch selection handles in VR.
SetTextHandlesTemporarilyHidden(is_in_vr);
}
bool RenderWidgetHostViewAndroid::IsInVR() const {
......
......@@ -47821,6 +47821,7 @@ Full version information for the fingerprint enum values:
<int value="12" label="SSL client certificate selector was suppressed in VR"/>
<int value="13"
label="Media router presentation request dialog was suppressed in VR"/>
<int value="14" label="Context menu was suppressed in VR"/>
</enum>
<enum name="VRUnsupportedMode">
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