1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/native_viewport/native_viewport_impl.h"
7 #include "base/auto_reset.h"
9 #include "base/macros.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/time/time.h"
12 #include "components/gles2/gpu_state.h"
13 #include "components/native_viewport/platform_viewport_headless.h"
14 #include "mojo/converters/geometry/geometry_type_converters.h"
15 #include "third_party/mojo/src/mojo/public/cpp/application/interface_factory.h"
16 #include "ui/events/event.h"
18 namespace native_viewport
{
20 NativeViewportImpl::NativeViewportImpl(
22 const scoped_refptr
<gles2::GpuState
>& gpu_state
,
23 mojo::InterfaceRequest
<mojo::NativeViewport
> request
)
24 : is_headless_(is_headless
),
25 context_provider_(gpu_state
),
27 metrics_(mojo::ViewportMetrics::New()),
28 binding_(this, request
.Pass()),
30 binding_
.set_error_handler(this);
33 NativeViewportImpl::~NativeViewportImpl() {
34 // Destroy the NativeViewport early on as it may call us back during
35 // destruction and we want to be in a known state.
36 platform_viewport_
.reset();
39 void NativeViewportImpl::Create(mojo::SizePtr size
,
40 const CreateCallback
& callback
) {
41 create_callback_
= callback
;
42 metrics_
->size
= size
.Clone();
44 platform_viewport_
= PlatformViewportHeadless::Create(this);
46 platform_viewport_
= PlatformViewport::Create(this);
47 platform_viewport_
->Init(gfx::Rect(size
.To
<gfx::Size
>()));
50 void NativeViewportImpl::RequestMetrics(
51 const RequestMetricsCallback
& callback
) {
53 callback
.Run(metrics_
.Clone());
57 metrics_callback_
= callback
;
60 void NativeViewportImpl::Show() {
61 platform_viewport_
->Show();
64 void NativeViewportImpl::Hide() {
65 platform_viewport_
->Hide();
68 void NativeViewportImpl::Close() {
69 DCHECK(platform_viewport_
);
70 platform_viewport_
->Close();
73 void NativeViewportImpl::SetSize(mojo::SizePtr size
) {
74 platform_viewport_
->SetBounds(gfx::Rect(size
.To
<gfx::Size
>()));
77 void NativeViewportImpl::GetContextProvider(
78 mojo::InterfaceRequest
<mojo::ContextProvider
> request
) {
79 context_provider_
.Bind(request
.Pass());
82 void NativeViewportImpl::SetEventDispatcher(
83 mojo::NativeViewportEventDispatcherPtr dispatcher
) {
84 event_dispatcher_
= dispatcher
.Pass();
87 void NativeViewportImpl::OnMetricsChanged(mojo::ViewportMetricsPtr metrics
) {
88 if (metrics_
->Equals(*metrics
))
91 metrics_
= metrics
.Pass();
92 sent_metrics_
= false;
94 if (!metrics_callback_
.is_null()) {
95 metrics_callback_
.Run(metrics_
.Clone());
96 metrics_callback_
.reset();
101 void NativeViewportImpl::OnAcceleratedWidgetAvailable(
102 gfx::AcceleratedWidget widget
) {
103 context_provider_
.SetAcceleratedWidget(widget
);
104 // TODO: The metrics here might not match the actual window size on android
105 // where we don't know the actual size until the first OnMetricsChanged call.
106 create_callback_
.Run(metrics_
.Clone());
107 sent_metrics_
= true;
108 create_callback_
.reset();
111 void NativeViewportImpl::OnAcceleratedWidgetDestroyed() {
112 context_provider_
.SetAcceleratedWidget(gfx::kNullAcceleratedWidget
);
115 bool NativeViewportImpl::OnEvent(mojo::EventPtr event
) {
116 if (event
.is_null() || !event_dispatcher_
.get())
119 mojo::NativeViewportEventDispatcher::OnEventCallback callback
;
120 switch (event
->action
) {
121 case mojo::EVENT_TYPE_POINTER_MOVE
: {
122 // TODO(sky): add logic to remember last event location and not send if
124 if (pointers_waiting_on_ack_
.count(event
->pointer_data
->pointer_id
))
127 pointers_waiting_on_ack_
.insert(event
->pointer_data
->pointer_id
);
129 base::Bind(&NativeViewportImpl::AckEvent
, weak_factory_
.GetWeakPtr(),
130 event
->pointer_data
->pointer_id
);
134 case mojo::EVENT_TYPE_POINTER_CANCEL
:
135 pointers_waiting_on_ack_
.clear();
138 case mojo::EVENT_TYPE_POINTER_UP
:
139 pointers_waiting_on_ack_
.erase(event
->pointer_data
->pointer_id
);
146 event_dispatcher_
->OnEvent(event
.Pass(), callback
);
150 void NativeViewportImpl::OnDestroyed() {
151 // This will signal a connection error and cause us to delete |this|.
155 void NativeViewportImpl::OnConnectionError() {
156 binding_
.set_error_handler(nullptr);
160 void NativeViewportImpl::AckEvent(int32 pointer_id
) {
161 pointers_waiting_on_ack_
.erase(pointer_id
);
164 } // namespace native_viewport