• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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