16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/services/native_viewport/native_viewport_impl.h"
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/bind.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/macros.h"
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/message_loop/message_loop.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/time/time.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/cpp/application/application_delegate.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/public/cpp/application/application_impl.h"
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/public/cpp/application/interface_factory.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/native_viewport/platform_viewport_headless.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/native_viewport/viewport_surface.h"
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/public/cpp/surfaces/surfaces_type_converters.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/events/event.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace mojo {
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace {
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool IsRateLimitedEventType(ui::Event* event) {
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return event->type() == ui::ET_MOUSE_MOVED ||
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         event->type() == ui::ET_MOUSE_DRAGGED ||
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)         event->type() == ui::ET_TOUCH_MOVED;
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciNativeViewportImpl::NativeViewportImpl(ApplicationImpl* app, bool is_headless)
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : is_headless_(is_headless),
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      widget_id_(0u),
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      waiting_for_event_ack_(false),
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  app->ConnectToService("mojo:mojo_surfaces_service", &surfaces_service_);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(jamesr): Should be mojo_gpu_service
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  app->ConnectToService("mojo:mojo_native_viewport_service", &gpu_service_);
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)NativeViewportImpl::~NativeViewportImpl() {
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Destroy the NativeViewport early on as it may call us back during
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // destruction and we want to be in a known state.
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  platform_viewport_.reset();
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid NativeViewportImpl::Create(SizePtr bounds) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (is_headless_)
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    platform_viewport_ = PlatformViewportHeadless::Create(this);
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  else
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    platform_viewport_ = PlatformViewport::Create(this);
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  gfx::Rect rect = gfx::Rect(bounds.To<gfx::Size>());
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  platform_viewport_->Init(rect);
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OnBoundsChanged(rect);
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::Show() {
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  platform_viewport_->Show();
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::Hide() {
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  platform_viewport_->Hide();
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::Close() {
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(platform_viewport_);
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  platform_viewport_->Close();
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid NativeViewportImpl::SetBounds(SizePtr bounds) {
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  platform_viewport_->SetBounds(gfx::Rect(bounds.To<gfx::Size>()));
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid NativeViewportImpl::SubmittedFrame(SurfaceIdPtr child_surface_id) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (child_surface_id_.is_null()) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // If this is the first indication that the client will use surfaces,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // initialize that system.
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(jamesr): When everything is converted to surfaces initialize this
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // eagerly.
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    viewport_surface_.reset(
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new ViewportSurface(surfaces_service_.get(),
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            gpu_service_.get(),
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            bounds_.size(),
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            child_surface_id.To<cc::SurfaceId>()));
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (widget_id_)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      viewport_surface_->SetWidgetId(widget_id_);
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  child_surface_id_ = child_surface_id.To<cc::SurfaceId>();
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (viewport_surface_)
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    viewport_surface_->SetChildId(child_surface_id_);
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::OnBoundsChanged(const gfx::Rect& bounds) {
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bounds_ = bounds;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnBoundsChanged(Size::From(bounds.size()));
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (viewport_surface_)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    viewport_surface_->SetSize(bounds.size());
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::OnAcceleratedWidgetAvailable(
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    gfx::AcceleratedWidget widget) {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  widget_id_ = static_cast<uint64_t>(bit_cast<uintptr_t>(widget));
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(jamesr): Remove once everything is converted to surfaces.
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client()->OnCreated(widget_id_);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (viewport_surface_)
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    viewport_surface_->SetWidgetId(widget_id_);
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool NativeViewportImpl::OnEvent(ui::Event* ui_event) {
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Must not return early before updating capture.
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  switch (ui_event->type()) {
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case ui::ET_MOUSE_PRESSED:
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case ui::ET_TOUCH_PRESSED:
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      platform_viewport_->SetCapture();
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case ui::ET_MOUSE_RELEASED:
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    case ui::ET_TOUCH_RELEASED:
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      platform_viewport_->ReleaseCapture();
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    default:
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      break;
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (waiting_for_event_ack_ && IsRateLimitedEventType(ui_event))
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return false;
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  client()->OnEvent(
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Event::From(*ui_event),
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&NativeViewportImpl::AckEvent, weak_factory_.GetWeakPtr()));
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  waiting_for_event_ack_ = true;
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return false;
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::OnDestroyed() {
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  client()->OnDestroyed();
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void NativeViewportImpl::AckEvent() {
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  waiting_for_event_ack_ = false;
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}  // namespace mojo
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
145