1 // Copyright (c) 2014 The Chromium Embedded Framework Authors.
2 // Portions copyright (c) 2012 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "libcef/browser/osr/render_widget_host_view_osr.h"
7
8 #include <stdint.h>
9
10 #include <utility>
11
12 #include "libcef/browser/alloy/alloy_browser_host_impl.h"
13 #include "libcef/browser/osr/osr_util.h"
14 #include "libcef/browser/osr/synthetic_gesture_target_osr.h"
15 #include "libcef/browser/osr/video_consumer_osr.h"
16 #include "libcef/browser/thread_util.h"
17
18 #include "base/callback_helpers.h"
19 #include "base/command_line.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "base/task/post_task.h"
23 #include "cc/base/switches.h"
24 #include "components/viz/common/features.h"
25 #include "components/viz/common/frame_sinks/begin_frame_args.h"
26 #include "components/viz/common/frame_sinks/copy_output_request.h"
27 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
28 #include "components/viz/common/surfaces/frame_sink_id_allocator.h"
29 #include "components/viz/common/switches.h"
30 #include "content/browser/bad_message.h"
31 #include "content/browser/gpu/gpu_data_manager_impl.h"
32 #include "content/browser/renderer_host/cursor_manager.h"
33 #include "content/browser/renderer_host/delegated_frame_host.h"
34 #include "content/browser/renderer_host/dip_util.h"
35 #include "content/browser/renderer_host/input/motion_event_web.h"
36 #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h"
37 #include "content/browser/renderer_host/render_widget_host_delegate.h"
38 #include "content/browser/renderer_host/render_widget_host_impl.h"
39 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
40 #include "content/common/content_switches_internal.h"
41 #include "content/public/browser/browser_task_traits.h"
42 #include "content/public/browser/browser_thread.h"
43 #include "content/public/browser/context_factory.h"
44 #include "content/public/browser/render_process_host.h"
45 #include "content/public/browser/render_view_host.h"
46 #include "content/public/common/content_switches.h"
47 #include "media/base/video_frame.h"
48 #include "media/capture/mojom/video_capture_buffer.mojom.h"
49 #include "ui/compositor/compositor.h"
50 #include "ui/events/blink/blink_event_util.h"
51 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
52 #include "ui/events/gesture_detection/motion_event.h"
53 #include "ui/gfx/geometry/dip_util.h"
54 #include "ui/gfx/geometry/size_conversions.h"
55
56 namespace {
57
58 // The maximum number of damage rects to cache for outstanding frame requests
59 // (for OnAcceleratedPaint).
60 const size_t kMaxDamageRects = 10;
61
62 const float kDefaultScaleFactor = 1.0;
63
ScreenInfoFrom(const CefScreenInfo & src)64 display::ScreenInfo ScreenInfoFrom(const CefScreenInfo& src) {
65 display::ScreenInfo screenInfo;
66 screenInfo.device_scale_factor = src.device_scale_factor;
67 screenInfo.depth = src.depth;
68 screenInfo.depth_per_component = src.depth_per_component;
69 screenInfo.is_monochrome = src.is_monochrome ? true : false;
70 screenInfo.rect =
71 gfx::Rect(src.rect.x, src.rect.y, src.rect.width, src.rect.height);
72 screenInfo.available_rect =
73 gfx::Rect(src.available_rect.x, src.available_rect.y,
74 src.available_rect.width, src.available_rect.height);
75
76 return screenInfo;
77 }
78
79 class CefDelegatedFrameHostClient : public content::DelegatedFrameHostClient {
80 public:
CefDelegatedFrameHostClient(CefRenderWidgetHostViewOSR * view)81 explicit CefDelegatedFrameHostClient(CefRenderWidgetHostViewOSR* view)
82 : view_(view) {}
83
84 CefDelegatedFrameHostClient(const CefDelegatedFrameHostClient&) = delete;
85 CefDelegatedFrameHostClient& operator=(const CefDelegatedFrameHostClient&) =
86 delete;
87
DelegatedFrameHostGetLayer() const88 ui::Layer* DelegatedFrameHostGetLayer() const override {
89 return view_->GetRootLayer();
90 }
91
DelegatedFrameHostIsVisible() const92 bool DelegatedFrameHostIsVisible() const override {
93 // Called indirectly from DelegatedFrameHost::WasShown.
94 return view_->IsShowing();
95 }
96
DelegatedFrameHostGetGutterColor() const97 SkColor DelegatedFrameHostGetGutterColor() const override {
98 // When making an element on the page fullscreen the element's background
99 // may not match the page's, so use black as the gutter color to avoid
100 // flashes of brighter colors during the transition.
101 if (view_->render_widget_host()->delegate() &&
102 view_->render_widget_host()->delegate()->IsFullscreen()) {
103 return SK_ColorBLACK;
104 }
105 return *view_->GetBackgroundColor();
106 }
107
OnFrameTokenChanged(uint32_t frame_token,base::TimeTicks activation_time)108 void OnFrameTokenChanged(uint32_t frame_token,
109 base::TimeTicks activation_time) override {
110 view_->render_widget_host()->DidProcessFrame(frame_token, activation_time);
111 }
112
GetDeviceScaleFactor() const113 float GetDeviceScaleFactor() const override {
114 return view_->GetDeviceScaleFactor();
115 }
116
CollectSurfaceIdsForEviction()117 std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
118 return view_->render_widget_host()->CollectSurfaceIdsForEviction();
119 }
120
InvalidateLocalSurfaceIdOnEviction()121 void InvalidateLocalSurfaceIdOnEviction() override {
122 view_->InvalidateLocalSurfaceId();
123 }
124
ShouldShowStaleContentOnEviction()125 bool ShouldShowStaleContentOnEviction() override { return false; }
126
127 private:
128 CefRenderWidgetHostViewOSR* const view_;
129 };
130
CreateGestureProviderConfig()131 ui::GestureProvider::Config CreateGestureProviderConfig() {
132 ui::GestureProvider::Config config = ui::GetGestureProviderConfig(
133 ui::GestureProviderConfigType::CURRENT_PLATFORM);
134 return config;
135 }
136
CreateLatencyInfo(const blink::WebInputEvent & event)137 ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) {
138 ui::LatencyInfo latency_info;
139 // The latency number should only be added if the timestamp is valid.
140 base::TimeTicks time = event.TimeStamp();
141 if (!time.is_null()) {
142 latency_info.AddLatencyNumberWithTimestamp(
143 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, time);
144 }
145 return latency_info;
146 }
147
GetViewBounds(AlloyBrowserHostImpl * browser)148 gfx::Rect GetViewBounds(AlloyBrowserHostImpl* browser) {
149 if (!browser)
150 return gfx::Rect();
151
152 CefRect rc;
153 CefRefPtr<CefRenderHandler> handler =
154 browser->GetClient()->GetRenderHandler();
155 CHECK(handler);
156
157 handler->GetViewRect(browser, rc);
158 CHECK_GT(rc.width, 0);
159 CHECK_GT(rc.height, 0);
160
161 return gfx::Rect(rc.x, rc.y, rc.width, rc.height);
162 }
163
GetImeUnderlineStyle(cef_composition_underline_style_t style)164 ui::ImeTextSpan::UnderlineStyle GetImeUnderlineStyle(
165 cef_composition_underline_style_t style) {
166 switch (style) {
167 case CEF_CUS_SOLID:
168 return ui::ImeTextSpan::UnderlineStyle::kSolid;
169 case CEF_CUS_DOT:
170 return ui::ImeTextSpan::UnderlineStyle::kDot;
171 case CEF_CUS_DASH:
172 return ui::ImeTextSpan::UnderlineStyle::kDash;
173 case CEF_CUS_NONE:
174 return ui::ImeTextSpan::UnderlineStyle::kNone;
175 }
176
177 NOTREACHED();
178 return ui::ImeTextSpan::UnderlineStyle::kSolid;
179 }
180
181 } // namespace
182
CefRenderWidgetHostViewOSR(SkColor background_color,bool use_shared_texture,bool use_external_begin_frame,content::RenderWidgetHost * widget,CefRenderWidgetHostViewOSR * parent_host_view)183 CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
184 SkColor background_color,
185 bool use_shared_texture,
186 bool use_external_begin_frame,
187 content::RenderWidgetHost* widget,
188 CefRenderWidgetHostViewOSR* parent_host_view)
189 : content::RenderWidgetHostViewBase(widget),
190 background_color_(background_color),
191 render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
192 has_parent_(parent_host_view != nullptr),
193 parent_host_view_(parent_host_view),
194 pinch_zoom_enabled_(content::IsPinchToZoomEnabled()),
195 mouse_wheel_phase_handler_(this),
196 gesture_provider_(CreateGestureProviderConfig(), this),
197 weak_ptr_factory_(this) {
198 DCHECK(render_widget_host_);
199 DCHECK(!render_widget_host_->GetView());
200
201 if (parent_host_view_) {
202 browser_impl_ = parent_host_view_->browser_impl();
203 DCHECK(browser_impl_);
204 } else if (content::RenderViewHost::From(render_widget_host_)) {
205 // AlloyBrowserHostImpl might not be created at this time for popups.
206 browser_impl_ = AlloyBrowserHostImpl::GetBrowserForHost(
207 content::RenderViewHost::From(render_widget_host_));
208 }
209
210 delegated_frame_host_client_.reset(new CefDelegatedFrameHostClient(this));
211
212 // Matching the attributes from BrowserCompositorMac.
213 delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
214 AllocateFrameSinkId(), delegated_frame_host_client_.get(),
215 false /* should_register_frame_sink_id */);
216
217 root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
218
219 bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
220 GetRootLayer()->SetFillsBoundsOpaquely(opaque);
221 GetRootLayer()->SetColor(background_color_);
222
223 external_begin_frame_enabled_ = use_external_begin_frame;
224
225 auto context_factory = content::GetContextFactory();
226
227 // Matching the attributes from RecyclableCompositorMac.
228 compositor_.reset(new ui::Compositor(
229 context_factory->AllocateFrameSinkId(), context_factory,
230 base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */,
231 use_external_begin_frame));
232 compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
233
234 compositor_->SetDelegate(this);
235 compositor_->SetRootLayer(root_layer_.get());
236 compositor_->AddChildFrameSink(GetFrameSinkId());
237
238 content::RenderWidgetHostImpl* render_widget_host_impl =
239 content::RenderWidgetHostImpl::From(render_widget_host_);
240 if (render_widget_host_impl)
241 render_widget_host_impl->SetCompositorForFlingScheduler(compositor_.get());
242
243 cursor_manager_.reset(new content::CursorManager(this));
244
245 // This may result in a call to GetFrameSinkId().
246 render_widget_host_->SetView(this);
247
248 if (GetTextInputManager())
249 GetTextInputManager()->AddObserver(this);
250
251 if (render_widget_host_->delegate() &&
252 render_widget_host_->delegate()->GetInputEventRouter()) {
253 render_widget_host_->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(
254 GetFrameSinkId(), this);
255 }
256
257 if (browser_impl_ && !parent_host_view_) {
258 // For child/popup views this will be called from the associated InitAs*()
259 // method.
260 SetRootLayerSize(false /* force */);
261 if (!render_widget_host_->is_hidden())
262 Show();
263 }
264 }
265
~CefRenderWidgetHostViewOSR()266 CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
267 ReleaseCompositor();
268 root_layer_.reset(nullptr);
269
270 DCHECK(!parent_host_view_);
271 DCHECK(!popup_host_view_);
272 DCHECK(!child_host_view_);
273 DCHECK(guest_host_views_.empty());
274
275 if (text_input_manager_)
276 text_input_manager_->RemoveObserver(this);
277 }
278
ReleaseCompositor()279 void CefRenderWidgetHostViewOSR::ReleaseCompositor() {
280 if (!compositor_) {
281 return; // already released
282 }
283
284 // Marking the DelegatedFrameHost as removed from the window hierarchy is
285 // necessary to remove all connections to its old ui::Compositor.
286 if (is_showing_) {
287 delegated_frame_host_->WasHidden(
288 content::DelegatedFrameHost::HiddenCause::kOther);
289 }
290 delegated_frame_host_->DetachFromCompositor();
291
292 delegated_frame_host_.reset(nullptr);
293 compositor_.reset(nullptr);
294 }
295
296 // Called for full-screen widgets.
InitAsChild(gfx::NativeView parent_view)297 void CefRenderWidgetHostViewOSR::InitAsChild(gfx::NativeView parent_view) {
298 DCHECK(parent_host_view_);
299 DCHECK(browser_impl_);
300
301 if (parent_host_view_->child_host_view_) {
302 // Cancel the previous popup widget.
303 parent_host_view_->child_host_view_->CancelWidget();
304 }
305
306 parent_host_view_->set_child_host_view(this);
307
308 // The parent view should not render while the full-screen view exists.
309 parent_host_view_->Hide();
310
311 SetRootLayerSize(false /* force */);
312 Show();
313 }
314
SetSize(const gfx::Size & size)315 void CefRenderWidgetHostViewOSR::SetSize(const gfx::Size& size) {}
316
SetBounds(const gfx::Rect & rect)317 void CefRenderWidgetHostViewOSR::SetBounds(const gfx::Rect& rect) {}
318
GetNativeView()319 gfx::NativeView CefRenderWidgetHostViewOSR::GetNativeView() {
320 return gfx::NativeView();
321 }
322
323 gfx::NativeViewAccessible
GetNativeViewAccessible()324 CefRenderWidgetHostViewOSR::GetNativeViewAccessible() {
325 return gfx::NativeViewAccessible();
326 }
327
Focus()328 void CefRenderWidgetHostViewOSR::Focus() {}
329
HasFocus()330 bool CefRenderWidgetHostViewOSR::HasFocus() {
331 return false;
332 }
333
IsSurfaceAvailableForCopy()334 bool CefRenderWidgetHostViewOSR::IsSurfaceAvailableForCopy() {
335 return delegated_frame_host_
336 ? delegated_frame_host_->CanCopyFromCompositingSurface()
337 : false;
338 }
339
ShowWithVisibility(content::PageVisibilityState)340 void CefRenderWidgetHostViewOSR::ShowWithVisibility(
341 content::PageVisibilityState) {
342 if (is_showing_)
343 return;
344
345 if (!content::GpuDataManagerImpl::GetInstance()->IsGpuCompositingDisabled() &&
346 !browser_impl_ &&
347 (!parent_host_view_ || !parent_host_view_->browser_impl_)) {
348 return;
349 }
350
351 is_showing_ = true;
352
353 // If the viz::LocalSurfaceId is invalid, we may have been evicted,
354 // and no other visual properties have since been changed. Allocate a new id
355 // and start synchronizing.
356 if (!GetLocalSurfaceId().is_valid()) {
357 AllocateLocalSurfaceId();
358 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
359 GetLocalSurfaceId());
360 }
361
362 if (render_widget_host_) {
363 render_widget_host_->WasShown(
364 /*record_tab_switch_time_request=*/{});
365
366 // Call OnRenderFrameMetadataChangedAfterActivation for every frame.
367 auto provider = content::RenderWidgetHostImpl::From(render_widget_host_)
368 ->render_frame_metadata_provider();
369 provider->AddObserver(this);
370 provider->ReportAllFrameSubmissionsForTesting(true);
371 }
372
373 if (delegated_frame_host_) {
374 delegated_frame_host_->AttachToCompositor(compositor_.get());
375 delegated_frame_host_->WasShown(GetLocalSurfaceId(), GetViewBounds().size(),
376 /*record_tab_switch_time_request=*/{});
377 }
378
379 if (!content::GpuDataManagerImpl::GetInstance()->IsGpuCompositingDisabled()) {
380 // Start generating frames when we're visible and at the correct size.
381 if (!video_consumer_) {
382 video_consumer_.reset(new CefVideoConsumerOSR(this));
383 UpdateFrameRate();
384 } else {
385 video_consumer_->SetActive(true);
386 }
387 }
388 }
389
Hide()390 void CefRenderWidgetHostViewOSR::Hide() {
391 if (!is_showing_)
392 return;
393
394 is_showing_ = false;
395
396 if (browser_impl_.get())
397 browser_impl_->CancelContextMenu();
398
399 if (video_consumer_) {
400 video_consumer_->SetActive(false);
401 }
402
403 if (render_widget_host_) {
404 render_widget_host_->WasHidden();
405
406 auto provider = content::RenderWidgetHostImpl::From(render_widget_host_)
407 ->render_frame_metadata_provider();
408 provider->RemoveObserver(this);
409 }
410
411 if (delegated_frame_host_) {
412 delegated_frame_host_->WasHidden(
413 content::DelegatedFrameHost::HiddenCause::kOther);
414 delegated_frame_host_->DetachFromCompositor();
415 }
416 }
417
IsShowing()418 bool CefRenderWidgetHostViewOSR::IsShowing() {
419 return is_showing_;
420 }
421
EnsureSurfaceSynchronizedForWebTest()422 void CefRenderWidgetHostViewOSR::EnsureSurfaceSynchronizedForWebTest() {
423 ++latest_capture_sequence_number_;
424 SynchronizeVisualProperties(cc::DeadlinePolicy::UseInfiniteDeadline(),
425 absl::nullopt);
426 }
427
GetViewBounds()428 gfx::Rect CefRenderWidgetHostViewOSR::GetViewBounds() {
429 if (IsPopupWidget())
430 return popup_position_;
431
432 return current_view_bounds_;
433 }
434
SetBackgroundColor(SkColor color)435 void CefRenderWidgetHostViewOSR::SetBackgroundColor(SkColor color) {
436 // The renderer will feed its color back to us with the first CompositorFrame.
437 // We short-cut here to show a sensible color before that happens.
438 UpdateBackgroundColorFromRenderer(color);
439
440 DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
441 SkColorGetA(color) == SK_AlphaTRANSPARENT);
442 content::RenderWidgetHostViewBase::SetBackgroundColor(color);
443 }
444
GetBackgroundColor()445 absl::optional<SkColor> CefRenderWidgetHostViewOSR::GetBackgroundColor() {
446 return background_color_;
447 }
448
UpdateBackgroundColor()449 void CefRenderWidgetHostViewOSR::UpdateBackgroundColor() {}
450
451 absl::optional<content::DisplayFeature>
GetDisplayFeature()452 CefRenderWidgetHostViewOSR::GetDisplayFeature() {
453 return absl::nullopt;
454 }
455
SetDisplayFeatureForTesting(const content::DisplayFeature * display_feature)456 void CefRenderWidgetHostViewOSR::SetDisplayFeatureForTesting(
457 const content::DisplayFeature* display_feature) {
458 NOTREACHED();
459 }
460
LockMouse(bool request_unadjusted_movement)461 blink::mojom::PointerLockResult CefRenderWidgetHostViewOSR::LockMouse(
462 bool request_unadjusted_movement) {
463 return blink::mojom::PointerLockResult::kPermissionDenied;
464 }
465
ChangeMouseLock(bool request_unadjusted_movement)466 blink::mojom::PointerLockResult CefRenderWidgetHostViewOSR::ChangeMouseLock(
467 bool request_unadjusted_movement) {
468 return blink::mojom::PointerLockResult::kPermissionDenied;
469 }
470
UnlockMouse()471 void CefRenderWidgetHostViewOSR::UnlockMouse() {}
472
TakeFallbackContentFrom(content::RenderWidgetHostView * view)473 void CefRenderWidgetHostViewOSR::TakeFallbackContentFrom(
474 content::RenderWidgetHostView* view) {
475 DCHECK(!static_cast<RenderWidgetHostViewBase*>(view)
476 ->IsRenderWidgetHostViewChildFrame());
477 CefRenderWidgetHostViewOSR* view_cef =
478 static_cast<CefRenderWidgetHostViewOSR*>(view);
479 SetBackgroundColor(view_cef->background_color_);
480 if (delegated_frame_host_ && view_cef->delegated_frame_host_) {
481 delegated_frame_host_->TakeFallbackContentFrom(
482 view_cef->delegated_frame_host_.get());
483 }
484 host()->GetContentRenderingTimeoutFrom(view_cef->host());
485 }
486
OnPresentCompositorFrame()487 void CefRenderWidgetHostViewOSR::OnPresentCompositorFrame() {}
488
OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata & metadata)489 void CefRenderWidgetHostViewOSR::OnDidUpdateVisualPropertiesComplete(
490 const cc::RenderFrameMetadata& metadata) {
491 if (host()->is_hidden()) {
492 // When an embedded child responds, we want to accept its changes to the
493 // viz::LocalSurfaceId. However we do not want to embed surfaces while
494 // hidden. Nor do we want to embed invalid ids when we are evicted. Becoming
495 // visible will generate a new id, if necessary, and begin embedding.
496 UpdateLocalSurfaceIdFromEmbeddedClient(metadata.local_surface_id);
497 } else {
498 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
499 metadata.local_surface_id);
500 }
501 }
502
AllocateLocalSurfaceId()503 void CefRenderWidgetHostViewOSR::AllocateLocalSurfaceId() {
504 if (!parent_local_surface_id_allocator_) {
505 parent_local_surface_id_allocator_ =
506 std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
507 }
508 parent_local_surface_id_allocator_->GenerateId();
509 }
510
511 const viz::LocalSurfaceId&
GetCurrentLocalSurfaceId() const512 CefRenderWidgetHostViewOSR::GetCurrentLocalSurfaceId() const {
513 return parent_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
514 }
515
UpdateLocalSurfaceIdFromEmbeddedClient(const absl::optional<viz::LocalSurfaceId> & embedded_client_local_surface_id)516 void CefRenderWidgetHostViewOSR::UpdateLocalSurfaceIdFromEmbeddedClient(
517 const absl::optional<viz::LocalSurfaceId>&
518 embedded_client_local_surface_id) {
519 if (embedded_client_local_surface_id) {
520 parent_local_surface_id_allocator_->UpdateFromChild(
521 *embedded_client_local_surface_id);
522 } else {
523 AllocateLocalSurfaceId();
524 }
525 }
526
527 const viz::LocalSurfaceId&
GetOrCreateLocalSurfaceId()528 CefRenderWidgetHostViewOSR::GetOrCreateLocalSurfaceId() {
529 if (!parent_local_surface_id_allocator_)
530 AllocateLocalSurfaceId();
531 return GetCurrentLocalSurfaceId();
532 }
533
InvalidateLocalSurfaceId()534 void CefRenderWidgetHostViewOSR::InvalidateLocalSurfaceId() {
535 if (!parent_local_surface_id_allocator_)
536 return;
537 parent_local_surface_id_allocator_->Invalidate();
538 }
539
AddDamageRect(uint32_t sequence,const gfx::Rect & rect)540 void CefRenderWidgetHostViewOSR::AddDamageRect(uint32_t sequence,
541 const gfx::Rect& rect) {
542 // Associate the given damage rect with the presentation token.
543 // For OnAcceleratedPaint we'll lookup the corresponding damage area based on
544 // the frame token which is passed back to OnPresentCompositorFrame.
545 base::AutoLock lock_scope(damage_rect_lock_);
546
547 // We assume our presentation_token is a counter. Since we're using an ordered
548 // map we can enforce a max size and remove oldest from the front. Worst case,
549 // if a damage rect isn't associated, we can simply pass the entire view size.
550 while (damage_rects_.size() >= kMaxDamageRects) {
551 damage_rects_.erase(damage_rects_.begin());
552 }
553 damage_rects_[sequence] = rect;
554 }
555
ResetFallbackToFirstNavigationSurface()556 void CefRenderWidgetHostViewOSR::ResetFallbackToFirstNavigationSurface() {
557 if (delegated_frame_host_) {
558 delegated_frame_host_->ResetFallbackToFirstNavigationSurface();
559 }
560 }
561
InitAsPopup(content::RenderWidgetHostView * parent_host_view,const gfx::Rect & bounds,const gfx::Rect & anchor_rect)562 void CefRenderWidgetHostViewOSR::InitAsPopup(
563 content::RenderWidgetHostView* parent_host_view,
564 const gfx::Rect& bounds,
565 const gfx::Rect& anchor_rect) {
566 DCHECK_EQ(parent_host_view_, parent_host_view);
567 DCHECK(browser_impl_);
568
569 if (parent_host_view_->popup_host_view_) {
570 // Cancel the previous popup widget.
571 parent_host_view_->popup_host_view_->CancelWidget();
572 }
573
574 parent_host_view_->set_popup_host_view(this);
575
576 CefRefPtr<CefRenderHandler> handler =
577 browser_impl_->GetClient()->GetRenderHandler();
578 CHECK(handler);
579
580 handler->OnPopupShow(browser_impl_.get(), true);
581
582 CefRect view_rect;
583 handler->GetViewRect(browser_impl_.get(), view_rect);
584 gfx::Rect client_pos(bounds.x() - view_rect.x, bounds.y() - view_rect.y,
585 bounds.width(), bounds.height());
586
587 popup_position_ = client_pos;
588
589 CefRect widget_pos(client_pos.x(), client_pos.y(), client_pos.width(),
590 client_pos.height());
591
592 if (handler.get())
593 handler->OnPopupSize(browser_impl_.get(), widget_pos);
594
595 // The size doesn't change for popups so we need to force the
596 // initialization.
597 SetRootLayerSize(true /* force */);
598 Show();
599 }
600
UpdateCursor(const content::WebCursor & cursor)601 void CefRenderWidgetHostViewOSR::UpdateCursor(
602 const content::WebCursor& cursor) {}
603
GetCursorManager()604 content::CursorManager* CefRenderWidgetHostViewOSR::GetCursorManager() {
605 return cursor_manager_.get();
606 }
607
SetIsLoading(bool is_loading)608 void CefRenderWidgetHostViewOSR::SetIsLoading(bool is_loading) {
609 if (!is_loading)
610 return;
611 // Make sure gesture detection is fresh.
612 gesture_provider_.ResetDetection();
613 forward_touch_to_popup_ = false;
614 }
615
RenderProcessGone()616 void CefRenderWidgetHostViewOSR::RenderProcessGone() {
617 Destroy();
618 }
619
Destroy()620 void CefRenderWidgetHostViewOSR::Destroy() {
621 if (!is_destroyed_) {
622 is_destroyed_ = true;
623
624 if (has_parent_) {
625 CancelWidget();
626 } else {
627 if (popup_host_view_)
628 popup_host_view_->CancelWidget();
629 if (child_host_view_)
630 child_host_view_->CancelWidget();
631 if (!guest_host_views_.empty()) {
632 // Guest RWHVs will be destroyed when the associated RWHVGuest is
633 // destroyed. This parent RWHV may be destroyed first, so disassociate
634 // the guest RWHVs here without destroying them.
635 for (auto guest_host_view : guest_host_views_)
636 guest_host_view->parent_host_view_ = nullptr;
637 guest_host_views_.clear();
638 }
639 Hide();
640 }
641 }
642
643 delete this;
644 }
645
UpdateTooltipUnderCursor(const std::u16string & tooltip_text)646 void CefRenderWidgetHostViewOSR::UpdateTooltipUnderCursor(
647 const std::u16string& tooltip_text) {
648 if (!browser_impl_.get())
649 return;
650
651 CefString tooltip(tooltip_text);
652 CefRefPtr<CefDisplayHandler> handler =
653 browser_impl_->GetClient()->GetDisplayHandler();
654 if (handler.get()) {
655 handler->OnTooltip(browser_impl_.get(), tooltip);
656 }
657 }
658
GetCompositorViewportPixelSize()659 gfx::Size CefRenderWidgetHostViewOSR::GetCompositorViewportPixelSize() {
660 return gfx::ScaleToCeiledSize(GetRequestedRendererSize(),
661 GetDeviceScaleFactor());
662 }
663
GetCaptureSequenceNumber() const664 uint32_t CefRenderWidgetHostViewOSR::GetCaptureSequenceNumber() const {
665 return latest_capture_sequence_number_;
666 }
667
CopyFromSurface(const gfx::Rect & src_rect,const gfx::Size & output_size,base::OnceCallback<void (const SkBitmap &)> callback)668 void CefRenderWidgetHostViewOSR::CopyFromSurface(
669 const gfx::Rect& src_rect,
670 const gfx::Size& output_size,
671 base::OnceCallback<void(const SkBitmap&)> callback) {
672 if (delegated_frame_host_) {
673 delegated_frame_host_->CopyFromCompositingSurface(src_rect, output_size,
674 std::move(callback));
675 }
676 }
677
GetNewScreenInfosForUpdate()678 display::ScreenInfos CefRenderWidgetHostViewOSR::GetNewScreenInfosForUpdate() {
679 display::ScreenInfo display_screen_info;
680
681 if (browser_impl_) {
682 CefScreenInfo screen_info(kDefaultScaleFactor, 0, 0, false, CefRect(),
683 CefRect());
684
685 CefRefPtr<CefRenderHandler> handler =
686 browser_impl_->client()->GetRenderHandler();
687 CHECK(handler);
688 if (!handler->GetScreenInfo(browser_impl_.get(), screen_info) ||
689 screen_info.rect.width == 0 || screen_info.rect.height == 0 ||
690 screen_info.available_rect.width == 0 ||
691 screen_info.available_rect.height == 0) {
692 // If a screen rectangle was not provided, try using the view rectangle
693 // instead. Otherwise, popup views may be drawn incorrectly, or not at
694 // all.
695 CefRect screenRect;
696 handler->GetViewRect(browser_impl_.get(), screenRect);
697 CHECK_GT(screenRect.width, 0);
698 CHECK_GT(screenRect.height, 0);
699
700 if (screen_info.rect.width == 0 || screen_info.rect.height == 0) {
701 screen_info.rect = screenRect;
702 }
703
704 if (screen_info.available_rect.width == 0 ||
705 screen_info.available_rect.height == 0) {
706 screen_info.available_rect = screenRect;
707 }
708 }
709
710 display_screen_info = ScreenInfoFrom(screen_info);
711 }
712
713 return display::ScreenInfos(display_screen_info);
714 }
715
TransformPointToRootSurface(gfx::PointF * point)716 void CefRenderWidgetHostViewOSR::TransformPointToRootSurface(
717 gfx::PointF* point) {}
718
GetBoundsInRootWindow()719 gfx::Rect CefRenderWidgetHostViewOSR::GetBoundsInRootWindow() {
720 if (!browser_impl_.get())
721 return gfx::Rect();
722
723 CefRect rc;
724 CefRefPtr<CefRenderHandler> handler =
725 browser_impl_->client()->GetRenderHandler();
726 CHECK(handler);
727 if (handler->GetRootScreenRect(browser_impl_.get(), rc))
728 return gfx::Rect(rc.x, rc.y, rc.width, rc.height);
729 return GetViewBounds();
730 }
731
732 #if !BUILDFLAG(IS_MAC)
733 viz::ScopedSurfaceIdAllocator
DidUpdateVisualProperties(const cc::RenderFrameMetadata & metadata)734 CefRenderWidgetHostViewOSR::DidUpdateVisualProperties(
735 const cc::RenderFrameMetadata& metadata) {
736 base::OnceCallback<void()> allocation_task = base::BindOnce(
737 &CefRenderWidgetHostViewOSR::OnDidUpdateVisualPropertiesComplete,
738 weak_ptr_factory_.GetWeakPtr(), metadata);
739 return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
740 }
741 #endif
742
GetCurrentSurfaceId() const743 viz::SurfaceId CefRenderWidgetHostViewOSR::GetCurrentSurfaceId() const {
744 return delegated_frame_host_ ? delegated_frame_host_->GetCurrentSurfaceId()
745 : viz::SurfaceId();
746 }
747
ImeSetComposition(const CefString & text,const std::vector<CefCompositionUnderline> & underlines,const CefRange & replacement_range,const CefRange & selection_range)748 void CefRenderWidgetHostViewOSR::ImeSetComposition(
749 const CefString& text,
750 const std::vector<CefCompositionUnderline>& underlines,
751 const CefRange& replacement_range,
752 const CefRange& selection_range) {
753 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::ImeSetComposition");
754 if (!render_widget_host_)
755 return;
756
757 std::vector<ui::ImeTextSpan> web_underlines;
758 web_underlines.reserve(underlines.size());
759 for (const CefCompositionUnderline& line : underlines) {
760 web_underlines.push_back(ui::ImeTextSpan(
761 ui::ImeTextSpan::Type::kComposition, line.range.from, line.range.to,
762 line.thick ? ui::ImeTextSpan::Thickness::kThick
763 : ui::ImeTextSpan::Thickness::kThin,
764 GetImeUnderlineStyle(line.style), line.background_color, line.color,
765 std::vector<std::string>()));
766 }
767 gfx::Range range(replacement_range.from, replacement_range.to);
768
769 // Start Monitoring for composition updates before we set.
770 RequestImeCompositionUpdate(true);
771
772 render_widget_host_->ImeSetComposition(
773 text, web_underlines, range, selection_range.from, selection_range.to);
774 }
775
ImeCommitText(const CefString & text,const CefRange & replacement_range,int relative_cursor_pos)776 void CefRenderWidgetHostViewOSR::ImeCommitText(
777 const CefString& text,
778 const CefRange& replacement_range,
779 int relative_cursor_pos) {
780 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::ImeCommitText");
781 if (!render_widget_host_)
782 return;
783
784 gfx::Range range(replacement_range.from, replacement_range.to);
785 render_widget_host_->ImeCommitText(text, std::vector<ui::ImeTextSpan>(),
786 range, relative_cursor_pos);
787
788 // Stop Monitoring for composition updates after we are done.
789 RequestImeCompositionUpdate(false);
790 }
791
ImeFinishComposingText(bool keep_selection)792 void CefRenderWidgetHostViewOSR::ImeFinishComposingText(bool keep_selection) {
793 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::ImeFinishComposingText");
794 if (!render_widget_host_)
795 return;
796
797 render_widget_host_->ImeFinishComposingText(keep_selection);
798
799 // Stop Monitoring for composition updates after we are done.
800 RequestImeCompositionUpdate(false);
801 }
802
ImeCancelComposition()803 void CefRenderWidgetHostViewOSR::ImeCancelComposition() {
804 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::ImeCancelComposition");
805 if (!render_widget_host_)
806 return;
807
808 render_widget_host_->ImeCancelComposition();
809
810 // Stop Monitoring for composition updates after we are done.
811 RequestImeCompositionUpdate(false);
812 }
813
SelectionChanged(const std::u16string & text,size_t offset,const gfx::Range & range)814 void CefRenderWidgetHostViewOSR::SelectionChanged(const std::u16string& text,
815 size_t offset,
816 const gfx::Range& range) {
817 RenderWidgetHostViewBase::SelectionChanged(text, offset, range);
818
819 if (!browser_impl_.get())
820 return;
821
822 CefString selected_text;
823 if (!range.is_empty() && !text.empty()) {
824 size_t pos = range.GetMin() - offset;
825 size_t n = range.length();
826 if (pos + n <= text.length())
827 selected_text = text.substr(pos, n);
828 }
829
830 CefRefPtr<CefRenderHandler> handler =
831 browser_impl_->GetClient()->GetRenderHandler();
832 CHECK(handler);
833
834 CefRange cef_range(range.start(), range.end());
835 handler->OnTextSelectionChanged(browser_impl_.get(), selected_text,
836 cef_range);
837 }
838
GetLocalSurfaceId() const839 const viz::LocalSurfaceId& CefRenderWidgetHostViewOSR::GetLocalSurfaceId()
840 const {
841 return const_cast<CefRenderWidgetHostViewOSR*>(this)
842 ->GetOrCreateLocalSurfaceId();
843 }
844
GetFrameSinkId() const845 const viz::FrameSinkId& CefRenderWidgetHostViewOSR::GetFrameSinkId() const {
846 return delegated_frame_host_
847 ? delegated_frame_host_->frame_sink_id()
848 : viz::FrameSinkIdAllocator::InvalidFrameSinkId();
849 }
850
GetRootFrameSinkId()851 viz::FrameSinkId CefRenderWidgetHostViewOSR::GetRootFrameSinkId() {
852 return compositor_ ? compositor_->frame_sink_id() : viz::FrameSinkId();
853 }
854
NotifyHostAndDelegateOnWasShown(blink::mojom::RecordContentToVisibleTimeRequestPtr visible_time_request)855 void CefRenderWidgetHostViewOSR::NotifyHostAndDelegateOnWasShown(
856 blink::mojom::RecordContentToVisibleTimeRequestPtr visible_time_request) {
857 // We don't call RenderWidgetHostViewBase::OnShowWithPageVisibility, so this
858 // method should not be called.
859 NOTREACHED();
860 }
861
RequestPresentationTimeFromHostOrDelegate(blink::mojom::RecordContentToVisibleTimeRequestPtr visible_time_request)862 void CefRenderWidgetHostViewOSR::RequestPresentationTimeFromHostOrDelegate(
863 blink::mojom::RecordContentToVisibleTimeRequestPtr visible_time_request) {
864 // We don't call RenderWidgetHostViewBase::OnShowWithPageVisibility, so this
865 // method should not be called.
866 NOTREACHED();
867 }
868
869 void CefRenderWidgetHostViewOSR::
CancelPresentationTimeRequestForHostAndDelegate()870 CancelPresentationTimeRequestForHostAndDelegate() {
871 // We don't call RenderWidgetHostViewBase::OnShowWithPageVisibility, so this
872 // method should not be called.
873 NOTREACHED();
874 }
875
876 std::unique_ptr<content::SyntheticGestureTarget>
CreateSyntheticGestureTarget()877 CefRenderWidgetHostViewOSR::CreateSyntheticGestureTarget() {
878 return std::make_unique<CefSyntheticGestureTargetOSR>(host());
879 }
880
TransformPointToCoordSpaceForView(const gfx::PointF & point,RenderWidgetHostViewBase * target_view,gfx::PointF * transformed_point)881 bool CefRenderWidgetHostViewOSR::TransformPointToCoordSpaceForView(
882 const gfx::PointF& point,
883 RenderWidgetHostViewBase* target_view,
884 gfx::PointF* transformed_point) {
885 if (target_view == this) {
886 *transformed_point = point;
887 return true;
888 }
889
890 return target_view->TransformPointToLocalCoordSpace(
891 point, GetCurrentSurfaceId(), transformed_point);
892 }
893
DidNavigate()894 void CefRenderWidgetHostViewOSR::DidNavigate() {
895 if (!IsShowing()) {
896 // Navigating while hidden should not allocate a new LocalSurfaceID. Once
897 // sizes are ready, or we begin to Show, we can then allocate the new
898 // LocalSurfaceId.
899 InvalidateLocalSurfaceId();
900 } else {
901 if (is_first_navigation_) {
902 // The first navigation does not need a new LocalSurfaceID. The renderer
903 // can use the ID that was already provided.
904 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
905 GetLocalSurfaceId());
906 } else {
907 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
908 absl::nullopt);
909 }
910 }
911 if (delegated_frame_host_)
912 delegated_frame_host_->DidNavigate();
913 is_first_navigation_ = false;
914 }
915
OnFrameComplete(const viz::BeginFrameAck & ack)916 void CefRenderWidgetHostViewOSR::OnFrameComplete(
917 const viz::BeginFrameAck& ack) {
918 DCHECK(begin_frame_pending_);
919 DCHECK_EQ(begin_frame_source_.source_id(), ack.frame_id.source_id);
920 DCHECK_EQ(begin_frame_number_, ack.frame_id.sequence_number);
921 begin_frame_pending_ = false;
922 }
923
OnRenderFrameMetadataChangedAfterActivation(base::TimeTicks activation_time)924 void CefRenderWidgetHostViewOSR::OnRenderFrameMetadataChangedAfterActivation(
925 base::TimeTicks activation_time) {
926 auto metadata =
927 host_->render_frame_metadata_provider()->LastRenderFrameMetadata();
928
929 if (video_consumer_) {
930 // Need to wait for the first frame of the new size before calling
931 // SizeChanged. Otherwise, the video frame will be letterboxed.
932 video_consumer_->SizeChanged(metadata.viewport_size_in_pixels);
933 }
934
935 gfx::PointF root_scroll_offset;
936 if (metadata.root_scroll_offset) {
937 root_scroll_offset = *metadata.root_scroll_offset;
938 }
939 if (root_scroll_offset != last_scroll_offset_) {
940 last_scroll_offset_ = root_scroll_offset;
941
942 if (!is_scroll_offset_changed_pending_) {
943 is_scroll_offset_changed_pending_ = true;
944
945 // Send the notification asynchronously.
946 CEF_POST_TASK(
947 CEF_UIT,
948 base::BindOnce(&CefRenderWidgetHostViewOSR::OnScrollOffsetChanged,
949 weak_ptr_factory_.GetWeakPtr()));
950 }
951 }
952 }
953
954 std::unique_ptr<viz::HostDisplayClient>
CreateHostDisplayClient()955 CefRenderWidgetHostViewOSR::CreateHostDisplayClient() {
956 host_display_client_ =
957 new CefHostDisplayClientOSR(this, gfx::kNullAcceleratedWidget);
958 host_display_client_->SetActive(true);
959 return base::WrapUnique(host_display_client_);
960 }
961
InstallTransparency()962 bool CefRenderWidgetHostViewOSR::InstallTransparency() {
963 if (background_color_ == SK_ColorTRANSPARENT) {
964 SetBackgroundColor(background_color_);
965 if (compositor_) {
966 compositor_->SetBackgroundColor(background_color_);
967 }
968 return true;
969 }
970 return false;
971 }
972
WasResized()973 void CefRenderWidgetHostViewOSR::WasResized() {
974 // Only one resize will be in-flight at a time.
975 if (hold_resize_) {
976 if (!pending_resize_)
977 pending_resize_ = true;
978 return;
979 }
980
981 SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
982 absl::nullopt);
983 }
984
SynchronizeVisualProperties(const cc::DeadlinePolicy & deadline_policy,const absl::optional<viz::LocalSurfaceId> & child_local_surface_id)985 void CefRenderWidgetHostViewOSR::SynchronizeVisualProperties(
986 const cc::DeadlinePolicy& deadline_policy,
987 const absl::optional<viz::LocalSurfaceId>& child_local_surface_id) {
988 SetFrameRate();
989
990 const bool resized = ResizeRootLayer();
991 bool surface_id_updated = false;
992
993 if (!resized && child_local_surface_id) {
994 // Update the current surface ID.
995 parent_local_surface_id_allocator_->UpdateFromChild(
996 *child_local_surface_id);
997 surface_id_updated = true;
998 }
999
1000 // Allocate a new surface ID if the surface has been resized or if the current
1001 // ID is invalid (meaning we may have been evicted).
1002 if (resized || !GetCurrentLocalSurfaceId().is_valid()) {
1003 AllocateLocalSurfaceId();
1004 surface_id_updated = true;
1005 }
1006
1007 if (surface_id_updated) {
1008 delegated_frame_host_->EmbedSurface(
1009 GetCurrentLocalSurfaceId(), GetViewBounds().size(), deadline_policy);
1010
1011 // |render_widget_host_| will retrieve resize parameters from the
1012 // DelegatedFrameHost and this view, so SynchronizeVisualProperties must be
1013 // called last.
1014 if (render_widget_host_) {
1015 render_widget_host_->SynchronizeVisualProperties();
1016 }
1017 }
1018 }
1019
OnScreenInfoChanged()1020 void CefRenderWidgetHostViewOSR::OnScreenInfoChanged() {
1021 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::OnScreenInfoChanged");
1022 if (!render_widget_host_)
1023 return;
1024
1025 SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
1026 absl::nullopt);
1027
1028 if (render_widget_host_->delegate())
1029 render_widget_host_->delegate()->SendScreenRects();
1030 else
1031 render_widget_host_->SendScreenRects();
1032
1033 render_widget_host_->NotifyScreenInfoChanged();
1034
1035 // We might want to change the cursor scale factor here as well - see the
1036 // cache for the current_cursor_, as passed by UpdateCursor from the
1037 // renderer in the rwhv_aura (current_cursor_.SetScaleFactor)
1038
1039 // Notify the guest hosts if any.
1040 for (auto guest_host_view : guest_host_views_)
1041 guest_host_view->OnScreenInfoChanged();
1042 }
1043
Invalidate(CefBrowserHost::PaintElementType type)1044 void CefRenderWidgetHostViewOSR::Invalidate(
1045 CefBrowserHost::PaintElementType type) {
1046 TRACE_EVENT1("cef", "CefRenderWidgetHostViewOSR::Invalidate", "type", type);
1047 if (!IsPopupWidget() && type == PET_POPUP) {
1048 if (popup_host_view_)
1049 popup_host_view_->Invalidate(type);
1050 return;
1051 }
1052 InvalidateInternal(gfx::Rect(SizeInPixels()));
1053 }
1054
SendExternalBeginFrame()1055 void CefRenderWidgetHostViewOSR::SendExternalBeginFrame() {
1056 DCHECK(external_begin_frame_enabled_);
1057
1058 if (begin_frame_pending_)
1059 return;
1060 begin_frame_pending_ = true;
1061
1062 base::TimeTicks frame_time = base::TimeTicks::Now();
1063 base::TimeTicks deadline = base::TimeTicks();
1064 base::TimeDelta interval = viz::BeginFrameArgs::DefaultInterval();
1065
1066 viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
1067 BEGINFRAME_FROM_HERE, begin_frame_source_.source_id(),
1068 ++begin_frame_number_, frame_time, deadline, interval,
1069 viz::BeginFrameArgs::NORMAL);
1070
1071 DCHECK(begin_frame_args.IsValid());
1072
1073 if (render_widget_host_)
1074 render_widget_host_->ProgressFlingIfNeeded(frame_time);
1075
1076 if (compositor_) {
1077 compositor_->IssueExternalBeginFrame(
1078 begin_frame_args, /* force= */ true,
1079 base::BindOnce(&CefRenderWidgetHostViewOSR::OnFrameComplete,
1080 weak_ptr_factory_.GetWeakPtr()));
1081 } else {
1082 begin_frame_pending_ = false;
1083 }
1084
1085 if (!IsPopupWidget() && popup_host_view_) {
1086 popup_host_view_->SendExternalBeginFrame();
1087 }
1088 }
1089
SendKeyEvent(const content::NativeWebKeyboardEvent & event)1090 void CefRenderWidgetHostViewOSR::SendKeyEvent(
1091 const content::NativeWebKeyboardEvent& event) {
1092 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendKeyEvent");
1093 content::RenderWidgetHostImpl* target_host = render_widget_host_;
1094
1095 // If there are multiple widgets on the page (such as when there are
1096 // out-of-process iframes), pick the one that should process this event.
1097 if (render_widget_host_ && render_widget_host_->delegate()) {
1098 target_host = render_widget_host_->delegate()->GetFocusedRenderWidgetHost(
1099 render_widget_host_);
1100 }
1101
1102 if (target_host && target_host->GetView()) {
1103 // Direct routing requires that events go directly to the View.
1104 target_host->ForwardKeyboardEventWithLatencyInfo(
1105 event,
1106 ui::LatencyInfo(event.GetType() == blink::WebInputEvent::Type::kChar ||
1107 event.GetType() ==
1108 blink::WebInputEvent::Type::kRawKeyDown
1109 ? ui::SourceEventType::KEY_PRESS
1110 : ui::SourceEventType::OTHER));
1111 }
1112 }
1113
SendMouseEvent(const blink::WebMouseEvent & event)1114 void CefRenderWidgetHostViewOSR::SendMouseEvent(
1115 const blink::WebMouseEvent& event) {
1116 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendMouseEvent");
1117 if (!IsPopupWidget()) {
1118 if (browser_impl_.get() &&
1119 event.GetType() == blink::WebMouseEvent::Type::kMouseDown) {
1120 browser_impl_->CancelContextMenu();
1121 }
1122
1123 if (popup_host_view_) {
1124 if (popup_host_view_->popup_position_.Contains(
1125 event.PositionInWidget().x(), event.PositionInWidget().y())) {
1126 blink::WebMouseEvent popup_event(event);
1127 popup_event.SetPositionInWidget(
1128 event.PositionInWidget().x() -
1129 popup_host_view_->popup_position_.x(),
1130 event.PositionInWidget().y() -
1131 popup_host_view_->popup_position_.y());
1132 popup_event.SetPositionInScreen(popup_event.PositionInWidget().x(),
1133 popup_event.PositionInWidget().y());
1134
1135 popup_host_view_->SendMouseEvent(popup_event);
1136 return;
1137 }
1138 } else if (!guest_host_views_.empty()) {
1139 for (auto guest_host_view : guest_host_views_) {
1140 if (!guest_host_view->render_widget_host_ ||
1141 !guest_host_view->render_widget_host_->GetView()) {
1142 continue;
1143 }
1144 const gfx::Rect& guest_bounds =
1145 guest_host_view->render_widget_host_->GetView()->GetViewBounds();
1146 if (guest_bounds.Contains(event.PositionInWidget().x(),
1147 event.PositionInWidget().y())) {
1148 blink::WebMouseEvent guest_event(event);
1149 guest_event.SetPositionInWidget(
1150 event.PositionInWidget().x() - guest_bounds.x(),
1151 event.PositionInWidget().y() - guest_bounds.y());
1152 guest_event.SetPositionInScreen(guest_event.PositionInWidget().x(),
1153 guest_event.PositionInWidget().y());
1154
1155 guest_host_view->SendMouseEvent(guest_event);
1156 return;
1157 }
1158 }
1159 }
1160 }
1161
1162 if (render_widget_host_ && render_widget_host_->GetView()) {
1163 if (ShouldRouteEvents()) {
1164 // RouteMouseEvent wants non-const pointer to WebMouseEvent, but it only
1165 // forwards it to RenderWidgetTargeter::FindTargetAndDispatch as a const
1166 // reference, so const_cast here is safe.
1167 render_widget_host_->delegate()->GetInputEventRouter()->RouteMouseEvent(
1168 this, const_cast<blink::WebMouseEvent*>(&event),
1169 ui::LatencyInfo(ui::SourceEventType::OTHER));
1170 } else {
1171 render_widget_host_->GetView()->ProcessMouseEvent(
1172 event, ui::LatencyInfo(ui::SourceEventType::OTHER));
1173 }
1174 }
1175 }
1176
SendMouseWheelEvent(const blink::WebMouseWheelEvent & event)1177 void CefRenderWidgetHostViewOSR::SendMouseWheelEvent(
1178 const blink::WebMouseWheelEvent& event) {
1179 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendMouseWheelEvent");
1180
1181 if (!IsPopupWidget()) {
1182 if (browser_impl_.get())
1183 browser_impl_->CancelContextMenu();
1184
1185 if (popup_host_view_) {
1186 if (popup_host_view_->popup_position_.Contains(
1187 event.PositionInWidget().x(), event.PositionInWidget().y())) {
1188 blink::WebMouseWheelEvent popup_mouse_wheel_event(event);
1189 popup_mouse_wheel_event.SetPositionInWidget(
1190 event.PositionInWidget().x() -
1191 popup_host_view_->popup_position_.x(),
1192 event.PositionInWidget().y() -
1193 popup_host_view_->popup_position_.y());
1194 popup_mouse_wheel_event.SetPositionInScreen(
1195 popup_mouse_wheel_event.PositionInWidget().x(),
1196 popup_mouse_wheel_event.PositionInWidget().y());
1197
1198 popup_host_view_->SendMouseWheelEvent(popup_mouse_wheel_event);
1199 return;
1200 } else {
1201 // Scrolling outside of the popup widget so destroy it.
1202 // Execute asynchronously to avoid deleting the widget from inside
1203 // some other callback.
1204 CEF_POST_TASK(
1205 CEF_UIT,
1206 base::BindOnce(&CefRenderWidgetHostViewOSR::CancelWidget,
1207 popup_host_view_->weak_ptr_factory_.GetWeakPtr()));
1208 }
1209 } else if (!guest_host_views_.empty()) {
1210 for (auto guest_host_view : guest_host_views_) {
1211 if (!guest_host_view->render_widget_host_ ||
1212 !guest_host_view->render_widget_host_->GetView()) {
1213 continue;
1214 }
1215 const gfx::Rect& guest_bounds =
1216 guest_host_view->render_widget_host_->GetView()->GetViewBounds();
1217 if (guest_bounds.Contains(event.PositionInWidget().x(),
1218 event.PositionInWidget().y())) {
1219 blink::WebMouseWheelEvent guest_mouse_wheel_event(event);
1220 guest_mouse_wheel_event.SetPositionInWidget(
1221 event.PositionInWidget().x() - guest_bounds.x(),
1222 event.PositionInWidget().y() - guest_bounds.y());
1223 guest_mouse_wheel_event.SetPositionInScreen(
1224 guest_mouse_wheel_event.PositionInWidget().x(),
1225 guest_mouse_wheel_event.PositionInWidget().y());
1226
1227 guest_host_view->SendMouseWheelEvent(guest_mouse_wheel_event);
1228 return;
1229 }
1230 }
1231 }
1232 }
1233
1234 if (render_widget_host_ && render_widget_host_->GetView()) {
1235 blink::WebMouseWheelEvent mouse_wheel_event(event);
1236
1237 mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(false);
1238 mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
1239 mouse_wheel_event, false);
1240
1241 if (ShouldRouteEvents()) {
1242 render_widget_host_->delegate()
1243 ->GetInputEventRouter()
1244 ->RouteMouseWheelEvent(
1245 this, const_cast<blink::WebMouseWheelEvent*>(&mouse_wheel_event),
1246 ui::LatencyInfo(ui::SourceEventType::WHEEL));
1247 } else {
1248 render_widget_host_->GetView()->ProcessMouseWheelEvent(
1249 mouse_wheel_event, ui::LatencyInfo(ui::SourceEventType::WHEEL));
1250 }
1251 }
1252 }
1253
SendTouchEvent(const CefTouchEvent & event)1254 void CefRenderWidgetHostViewOSR::SendTouchEvent(const CefTouchEvent& event) {
1255 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::SendTouchEvent");
1256
1257 if (!IsPopupWidget() && popup_host_view_) {
1258 if (!forward_touch_to_popup_ && event.type == CEF_TET_PRESSED &&
1259 pointer_state_.GetPointerCount() == 0) {
1260 forward_touch_to_popup_ =
1261 popup_host_view_->popup_position_.Contains(event.x, event.y);
1262 }
1263
1264 if (forward_touch_to_popup_) {
1265 CefTouchEvent popup_event(event);
1266 popup_event.x -= popup_host_view_->popup_position_.x();
1267 popup_event.y -= popup_host_view_->popup_position_.y();
1268 popup_host_view_->SendTouchEvent(popup_event);
1269 return;
1270 }
1271 }
1272
1273 // Update the touch event first.
1274 if (!pointer_state_.OnTouch(event))
1275 return;
1276
1277 ui::FilteredGestureProvider::TouchHandlingResult result =
1278 gesture_provider_.OnTouchEvent(pointer_state_);
1279
1280 blink::WebTouchEvent touch_event = ui::CreateWebTouchEventFromMotionEvent(
1281 pointer_state_, result.moved_beyond_slop_region, false);
1282
1283 pointer_state_.CleanupRemovedTouchPoints(event);
1284
1285 // Set unchanged touch point to StateStationary for touchmove and
1286 // touchcancel to make sure only send one ack per WebTouchEvent.
1287 if (!result.succeeded)
1288 pointer_state_.MarkUnchangedTouchPointsAsStationary(&touch_event, event);
1289
1290 if (!render_widget_host_)
1291 return;
1292
1293 ui::LatencyInfo latency_info = CreateLatencyInfo(touch_event);
1294 if (ShouldRouteEvents()) {
1295 render_widget_host_->delegate()->GetInputEventRouter()->RouteTouchEvent(
1296 this, &touch_event, latency_info);
1297 } else {
1298 render_widget_host_->ForwardTouchEventWithLatencyInfo(touch_event,
1299 latency_info);
1300 }
1301
1302 bool touch_end =
1303 touch_event.GetType() == blink::WebInputEvent::Type::kTouchEnd ||
1304 touch_event.GetType() == blink::WebInputEvent::Type::kTouchCancel;
1305
1306 if (touch_end && IsPopupWidget() && parent_host_view_ &&
1307 parent_host_view_->popup_host_view_ == this) {
1308 parent_host_view_->forward_touch_to_popup_ = false;
1309 }
1310 }
1311
ShouldRouteEvents() const1312 bool CefRenderWidgetHostViewOSR::ShouldRouteEvents() const {
1313 if (!render_widget_host_->delegate())
1314 return false;
1315
1316 // Do not route events that are currently targeted to page popups such as
1317 // <select> element drop-downs, since these cannot contain cross-process
1318 // frames.
1319 if (!render_widget_host_->delegate()->IsWidgetForPrimaryMainFrame(
1320 render_widget_host_)) {
1321 return false;
1322 }
1323
1324 return !!render_widget_host_->delegate()->GetInputEventRouter();
1325 }
1326
SetFocus(bool focus)1327 void CefRenderWidgetHostViewOSR::SetFocus(bool focus) {
1328 if (!render_widget_host_)
1329 return;
1330
1331 content::RenderWidgetHostImpl* widget =
1332 content::RenderWidgetHostImpl::From(render_widget_host_);
1333 if (focus) {
1334 widget->GotFocus();
1335 widget->SetActive(true);
1336 } else {
1337 if (browser_impl_.get())
1338 browser_impl_->CancelContextMenu();
1339
1340 widget->SetActive(false);
1341 widget->LostFocus();
1342 }
1343 }
1344
OnUpdateTextInputStateCalled(content::TextInputManager * text_input_manager,content::RenderWidgetHostViewBase * updated_view,bool did_update_state)1345 void CefRenderWidgetHostViewOSR::OnUpdateTextInputStateCalled(
1346 content::TextInputManager* text_input_manager,
1347 content::RenderWidgetHostViewBase* updated_view,
1348 bool did_update_state) {
1349 const auto state = text_input_manager->GetTextInputState();
1350 if (state && !state->show_ime_if_needed)
1351 return;
1352
1353 CefRenderHandler::TextInputMode mode = CEF_TEXT_INPUT_MODE_NONE;
1354 if (state && state->type != ui::TEXT_INPUT_TYPE_NONE) {
1355 static_assert(
1356 static_cast<int>(CEF_TEXT_INPUT_MODE_MAX) ==
1357 static_cast<int>(ui::TEXT_INPUT_MODE_MAX),
1358 "Enum values in cef_text_input_mode_t must match ui::TextInputMode");
1359 mode = static_cast<CefRenderHandler::TextInputMode>(state->mode);
1360 }
1361
1362 CefRefPtr<CefRenderHandler> handler =
1363 browser_impl_->GetClient()->GetRenderHandler();
1364 CHECK(handler);
1365
1366 handler->OnVirtualKeyboardRequested(browser_impl_->GetBrowser(), mode);
1367 }
1368
ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo & touch,blink::mojom::InputEventResultState ack_result)1369 void CefRenderWidgetHostViewOSR::ProcessAckedTouchEvent(
1370 const content::TouchEventWithLatencyInfo& touch,
1371 blink::mojom::InputEventResultState ack_result) {
1372 const bool event_consumed =
1373 ack_result == blink::mojom::InputEventResultState::kConsumed;
1374 gesture_provider_.OnTouchEventAck(touch.event.unique_touch_event_id,
1375 event_consumed, false);
1376 }
1377
OnGestureEvent(const ui::GestureEventData & gesture)1378 void CefRenderWidgetHostViewOSR::OnGestureEvent(
1379 const ui::GestureEventData& gesture) {
1380 if ((gesture.type() == ui::ET_GESTURE_PINCH_BEGIN ||
1381 gesture.type() == ui::ET_GESTURE_PINCH_UPDATE ||
1382 gesture.type() == ui::ET_GESTURE_PINCH_END) &&
1383 !pinch_zoom_enabled_) {
1384 return;
1385 }
1386
1387 blink::WebGestureEvent web_event =
1388 ui::CreateWebGestureEventFromGestureEventData(gesture);
1389
1390 // without this check, forwarding gestures does not work!
1391 if (web_event.GetType() == blink::WebInputEvent::Type::kUndefined)
1392 return;
1393
1394 ui::LatencyInfo latency_info = CreateLatencyInfo(web_event);
1395 if (ShouldRouteEvents()) {
1396 render_widget_host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
1397 this, &web_event, latency_info);
1398 } else {
1399 render_widget_host_->ForwardGestureEventWithLatencyInfo(web_event,
1400 latency_info);
1401 }
1402 }
1403
UpdateFrameRate()1404 void CefRenderWidgetHostViewOSR::UpdateFrameRate() {
1405 frame_rate_threshold_us_ = 0;
1406 SetFrameRate();
1407
1408 if (video_consumer_) {
1409 video_consumer_->SetFrameRate(base::Microseconds(frame_rate_threshold_us_));
1410 }
1411
1412 // Notify the guest hosts if any.
1413 for (auto guest_host_view : guest_host_views_)
1414 guest_host_view->UpdateFrameRate();
1415 }
1416
SizeInPixels()1417 gfx::Size CefRenderWidgetHostViewOSR::SizeInPixels() {
1418 return gfx::ScaleToCeiledSize(GetViewBounds().size(), GetDeviceScaleFactor());
1419 }
1420
1421 #if BUILDFLAG(IS_MAC)
SetActive(bool active)1422 void CefRenderWidgetHostViewOSR::SetActive(bool active) {}
1423
ShowDefinitionForSelection()1424 void CefRenderWidgetHostViewOSR::ShowDefinitionForSelection() {}
1425
SpeakSelection()1426 void CefRenderWidgetHostViewOSR::SpeakSelection() {}
1427
SetWindowFrameInScreen(const gfx::Rect & rect)1428 void CefRenderWidgetHostViewOSR::SetWindowFrameInScreen(const gfx::Rect& rect) {
1429 }
1430
ShowSharePicker(const std::string & title,const std::string & text,const std::string & url,const std::vector<std::string> & file_paths,blink::mojom::ShareService::ShareCallback callback)1431 void CefRenderWidgetHostViewOSR::ShowSharePicker(
1432 const std::string& title,
1433 const std::string& text,
1434 const std::string& url,
1435 const std::vector<std::string>& file_paths,
1436 blink::mojom::ShareService::ShareCallback callback) {
1437 std::move(callback).Run(blink::mojom::ShareError::INTERNAL_ERROR);
1438 }
1439 #endif // BUILDFLAG(IS_MAC)
1440
OnPaint(const gfx::Rect & damage_rect,const gfx::Size & pixel_size,const void * pixels)1441 void CefRenderWidgetHostViewOSR::OnPaint(const gfx::Rect& damage_rect,
1442 const gfx::Size& pixel_size,
1443 const void* pixels) {
1444 TRACE_EVENT0("cef", "CefRenderWidgetHostViewOSR::OnPaint");
1445
1446 // Workaround for https://bitbucket.org/chromiumembedded/cef/issues/2817
1447 if (!is_showing_) {
1448 return;
1449 }
1450
1451 if (!pixels) {
1452 return;
1453 }
1454
1455 CefRefPtr<CefRenderHandler> handler =
1456 browser_impl_->client()->GetRenderHandler();
1457 CHECK(handler);
1458
1459 gfx::Rect rect_in_pixels(0, 0, pixel_size.width(), pixel_size.height());
1460 rect_in_pixels.Intersect(damage_rect);
1461
1462 CefRenderHandler::RectList rcList;
1463 rcList.push_back(CefRect(rect_in_pixels.x(), rect_in_pixels.y(),
1464 rect_in_pixels.width(), rect_in_pixels.height()));
1465
1466 handler->OnPaint(browser_impl_.get(), IsPopupWidget() ? PET_POPUP : PET_VIEW,
1467 rcList, pixels, pixel_size.width(), pixel_size.height());
1468
1469 // Release the resize hold when we reach the desired size.
1470 if (hold_resize_) {
1471 DCHECK_GT(cached_scale_factor_, 0);
1472 gfx::Size expected_size =
1473 gfx::ScaleToCeiledSize(GetViewBounds().size(), cached_scale_factor_);
1474 if (pixel_size == expected_size)
1475 ReleaseResizeHold();
1476 }
1477 }
1478
GetRootLayer() const1479 ui::Layer* CefRenderWidgetHostViewOSR::GetRootLayer() const {
1480 return root_layer_.get();
1481 }
1482
SetFrameRate()1483 void CefRenderWidgetHostViewOSR::SetFrameRate() {
1484 CefRefPtr<AlloyBrowserHostImpl> browser;
1485 if (parent_host_view_) {
1486 // Use the same frame rate as the embedding browser.
1487 browser = parent_host_view_->browser_impl_;
1488 } else {
1489 browser = browser_impl_;
1490 }
1491 CHECK(browser);
1492
1493 // Only set the frame rate one time.
1494 if (frame_rate_threshold_us_ != 0)
1495 return;
1496
1497 int frame_rate =
1498 osr_util::ClampFrameRate(browser->settings().windowless_frame_rate);
1499
1500 frame_rate_threshold_us_ = 1000000 / frame_rate;
1501
1502 if (compositor_) {
1503 compositor_->SetDisplayVSyncParameters(
1504 base::TimeTicks::Now(), base::Microseconds(frame_rate_threshold_us_));
1505 }
1506
1507 if (video_consumer_) {
1508 video_consumer_->SetFrameRate(base::Microseconds(frame_rate_threshold_us_));
1509 }
1510 }
1511
SetScreenInfo()1512 bool CefRenderWidgetHostViewOSR::SetScreenInfo() {
1513 // This method should not be called while the resize hold is active.
1514 DCHECK(!hold_resize_);
1515
1516 display::ScreenInfo current_info = screen_infos_.current();
1517
1518 // This will result in a call to GetNewScreenInfosForUpdate().
1519 UpdateScreenInfo();
1520 if (screen_infos_.current() == current_info) {
1521 // Nothing changed.
1522 return false;
1523 }
1524
1525 // Notify the guest hosts if any.
1526 for (auto guest_host_view : guest_host_views_) {
1527 content::RenderWidgetHostImpl* rwhi = guest_host_view->render_widget_host();
1528 if (!rwhi)
1529 continue;
1530 auto guest_view_osr =
1531 static_cast<CefRenderWidgetHostViewOSR*>(rwhi->GetView());
1532 if (guest_view_osr) {
1533 guest_view_osr->SetScreenInfo();
1534 }
1535 }
1536
1537 return true;
1538 }
1539
SetViewBounds()1540 bool CefRenderWidgetHostViewOSR::SetViewBounds() {
1541 // This method should not be called while the resize hold is active.
1542 DCHECK(!hold_resize_);
1543
1544 // Popup bounds are set in InitAsPopup.
1545 if (IsPopupWidget())
1546 return false;
1547
1548 const gfx::Rect& new_bounds = ::GetViewBounds(browser_impl_.get());
1549 if (new_bounds == current_view_bounds_)
1550 return false;
1551
1552 current_view_bounds_ = new_bounds;
1553 return true;
1554 }
1555
SetRootLayerSize(bool force)1556 bool CefRenderWidgetHostViewOSR::SetRootLayerSize(bool force) {
1557 const bool screen_info_changed = SetScreenInfo();
1558 const bool view_bounds_changed = SetViewBounds();
1559 if (!force && !screen_info_changed && !view_bounds_changed)
1560 return false;
1561
1562 GetRootLayer()->SetBounds(gfx::Rect(GetViewBounds().size()));
1563
1564 if (compositor_) {
1565 compositor_local_surface_id_allocator_.GenerateId();
1566 compositor_->SetScaleAndSize(
1567 GetDeviceScaleFactor(), SizeInPixels(),
1568 compositor_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
1569 }
1570
1571 return (screen_info_changed || view_bounds_changed);
1572 }
1573
ResizeRootLayer()1574 bool CefRenderWidgetHostViewOSR::ResizeRootLayer() {
1575 if (!hold_resize_) {
1576 // The resize hold is not currently active.
1577 if (SetRootLayerSize(false /* force */)) {
1578 // The size has changed. Avoid resizing again until ReleaseResizeHold() is
1579 // called.
1580 hold_resize_ = true;
1581 cached_scale_factor_ = GetDeviceScaleFactor();
1582 return true;
1583 }
1584 } else if (!pending_resize_) {
1585 // The resize hold is currently active. Another resize will be triggered
1586 // from ReleaseResizeHold().
1587 pending_resize_ = true;
1588 }
1589 return false;
1590 }
1591
ReleaseResizeHold()1592 void CefRenderWidgetHostViewOSR::ReleaseResizeHold() {
1593 DCHECK(hold_resize_);
1594 hold_resize_ = false;
1595 cached_scale_factor_ = -1;
1596 if (pending_resize_) {
1597 pending_resize_ = false;
1598 CEF_POST_TASK(CEF_UIT,
1599 base::BindOnce(&CefRenderWidgetHostViewOSR::WasResized,
1600 weak_ptr_factory_.GetWeakPtr()));
1601 }
1602 }
1603
CancelWidget()1604 void CefRenderWidgetHostViewOSR::CancelWidget() {
1605 if (render_widget_host_)
1606 render_widget_host_->LostCapture();
1607
1608 Hide();
1609
1610 if (IsPopupWidget() && browser_impl_.get()) {
1611 CefRefPtr<CefRenderHandler> handler =
1612 browser_impl_->client()->GetRenderHandler();
1613 CHECK(handler);
1614 handler->OnPopupShow(browser_impl_.get(), false);
1615 browser_impl_ = nullptr;
1616 }
1617
1618 if (parent_host_view_) {
1619 if (parent_host_view_->popup_host_view_ == this) {
1620 parent_host_view_->set_popup_host_view(nullptr);
1621 } else if (parent_host_view_->child_host_view_ == this) {
1622 parent_host_view_->set_child_host_view(nullptr);
1623
1624 // Start rendering the parent view again.
1625 parent_host_view_->Show();
1626 } else {
1627 parent_host_view_->RemoveGuestHostView(this);
1628 }
1629 parent_host_view_ = nullptr;
1630 }
1631
1632 if (render_widget_host_ && !is_destroyed_) {
1633 is_destroyed_ = true;
1634
1635 // Don't delete the RWHI manually while owned by a std::unique_ptr in RVHI.
1636 // This matches a CHECK() in RenderWidgetHostImpl::Destroy().
1637 const bool also_delete = !render_widget_host_->owner_delegate();
1638
1639 // Results in a call to Destroy().
1640 render_widget_host_->ShutdownAndDestroyWidget(also_delete);
1641 }
1642 }
1643
OnScrollOffsetChanged()1644 void CefRenderWidgetHostViewOSR::OnScrollOffsetChanged() {
1645 if (browser_impl_.get()) {
1646 CefRefPtr<CefRenderHandler> handler =
1647 browser_impl_->client()->GetRenderHandler();
1648 CHECK(handler);
1649 handler->OnScrollOffsetChanged(browser_impl_.get(), last_scroll_offset_.x(),
1650 last_scroll_offset_.y());
1651 }
1652 is_scroll_offset_changed_pending_ = false;
1653 }
1654
AddGuestHostView(CefRenderWidgetHostViewOSR * guest_host)1655 void CefRenderWidgetHostViewOSR::AddGuestHostView(
1656 CefRenderWidgetHostViewOSR* guest_host) {
1657 guest_host_views_.insert(guest_host);
1658 }
1659
RemoveGuestHostView(CefRenderWidgetHostViewOSR * guest_host)1660 void CefRenderWidgetHostViewOSR::RemoveGuestHostView(
1661 CefRenderWidgetHostViewOSR* guest_host) {
1662 guest_host_views_.erase(guest_host);
1663 }
1664
InvalidateInternal(const gfx::Rect & bounds_in_pixels)1665 void CefRenderWidgetHostViewOSR::InvalidateInternal(
1666 const gfx::Rect& bounds_in_pixels) {
1667 if (video_consumer_) {
1668 video_consumer_->RequestRefreshFrame(bounds_in_pixels);
1669 } else if (host_display_client_) {
1670 OnPaint(bounds_in_pixels, host_display_client_->GetPixelSize(),
1671 host_display_client_->GetPixelMemory());
1672 }
1673 }
1674
RequestImeCompositionUpdate(bool start_monitoring)1675 void CefRenderWidgetHostViewOSR::RequestImeCompositionUpdate(
1676 bool start_monitoring) {
1677 if (!render_widget_host_)
1678 return;
1679 render_widget_host_->RequestCompositionUpdates(false, start_monitoring);
1680 }
1681
ImeCompositionRangeChanged(const gfx::Range & range,const std::vector<gfx::Rect> & character_bounds)1682 void CefRenderWidgetHostViewOSR::ImeCompositionRangeChanged(
1683 const gfx::Range& range,
1684 const std::vector<gfx::Rect>& character_bounds) {
1685 if (browser_impl_.get()) {
1686 CefRange cef_range(range.start(), range.end());
1687 CefRenderHandler::RectList rcList;
1688
1689 for (size_t i = 0; i < character_bounds.size(); ++i) {
1690 rcList.push_back(CefRect(character_bounds[i].x(), character_bounds[i].y(),
1691 character_bounds[i].width(),
1692 character_bounds[i].height()));
1693 }
1694
1695 CefRefPtr<CefRenderHandler> handler =
1696 browser_impl_->GetClient()->GetRenderHandler();
1697 CHECK(handler);
1698 handler->OnImeCompositionRangeChanged(browser_impl_->GetBrowser(),
1699 cef_range, rcList);
1700 }
1701 }
1702
AllocateFrameSinkId()1703 viz::FrameSinkId CefRenderWidgetHostViewOSR::AllocateFrameSinkId() {
1704 return render_widget_host_->GetFrameSinkId();
1705 }
1706
UpdateBackgroundColorFromRenderer(SkColor color)1707 void CefRenderWidgetHostViewOSR::UpdateBackgroundColorFromRenderer(
1708 SkColor color) {
1709 if (color == background_color_)
1710 return;
1711 background_color_ = color;
1712
1713 bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
1714 GetRootLayer()->SetFillsBoundsOpaquely(opaque);
1715 GetRootLayer()->SetColor(color);
1716 }
1717