ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / extensions / browser / guest_view / guest_view_base.cc
blobb7bf687b7a249cc485d3a647f398889c1075f0de
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/browser/guest_view/guest_view_base.h"
7 #include "base/lazy_instance.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "components/ui/zoom/page_zoom.h"
10 #include "components/ui/zoom/zoom_controller.h"
11 #include "content/public/browser/navigation_details.h"
12 #include "content/public/browser/render_frame_host.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "content/public/common/page_zoom.h"
17 #include "content/public/common/url_constants.h"
18 #include "extensions/browser/api/extensions_api_client.h"
19 #include "extensions/browser/event_router.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "extensions/browser/guest_view/app_view/app_view_guest.h"
22 #include "extensions/browser/guest_view/extension_options/extension_options_guest.h"
23 #include "extensions/browser/guest_view/extension_view/extension_view_guest.h"
24 #include "extensions/browser/guest_view/guest_view_manager.h"
25 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
26 #include "extensions/browser/guest_view/surface_worker/surface_worker_guest.h"
27 #include "extensions/browser/guest_view/web_view/web_view_guest.h"
28 #include "extensions/browser/process_manager.h"
29 #include "extensions/browser/process_map.h"
30 #include "extensions/common/features/feature.h"
31 #include "extensions/common/features/feature_provider.h"
32 #include "extensions/common/guest_view/guest_view_constants.h"
33 #include "extensions/common/guest_view/guest_view_messages.h"
34 #include "third_party/WebKit/public/web/WebInputEvent.h"
36 using content::WebContents;
38 namespace content {
39 struct FrameNavigateParams;
42 namespace extensions {
44 namespace {
46 using GuestViewCreationMap =
47 std::map<std::string, GuestViewBase::GuestCreationCallback>;
48 static base::LazyInstance<GuestViewCreationMap> guest_view_registry =
49 LAZY_INSTANCE_INITIALIZER;
51 using WebContentsGuestViewMap = std::map<WebContents*, GuestViewBase*>;
52 static base::LazyInstance<WebContentsGuestViewMap> webcontents_guestview_map =
53 LAZY_INSTANCE_INITIALIZER;
55 } // namespace
57 SetSizeParams::SetSizeParams() {
59 SetSizeParams::~SetSizeParams() {
62 GuestViewBase::Event::Event(const std::string& name,
63 scoped_ptr<base::DictionaryValue> args)
64 : name_(name), args_(args.Pass()) {
67 GuestViewBase::Event::~Event() {
70 scoped_ptr<base::DictionaryValue> GuestViewBase::Event::GetArguments() {
71 return args_.Pass();
74 // This observer ensures that the GuestViewBase destroys itself when its
75 // embedder goes away.
76 class GuestViewBase::OwnerLifetimeObserver : public WebContentsObserver {
77 public:
78 OwnerLifetimeObserver(GuestViewBase* guest,
79 content::WebContents* embedder_web_contents)
80 : WebContentsObserver(embedder_web_contents),
81 destroyed_(false),
82 guest_(guest) {}
84 ~OwnerLifetimeObserver() override {}
86 // WebContentsObserver implementation.
87 void WebContentsDestroyed() override {
88 // If the embedder is destroyed then destroy the guest.
89 Destroy();
92 void DidNavigateMainFrame(
93 const content::LoadCommittedDetails& details,
94 const content::FrameNavigateParams& params) override {
95 // If the embedder navigates to a different page then destroy the guest.
96 if (details.is_navigation_to_different_page())
97 Destroy();
100 void RenderProcessGone(base::TerminationStatus status) override {
101 // If the embedder crashes, then destroy the guest.
102 Destroy();
105 private:
106 bool destroyed_;
107 GuestViewBase* guest_;
109 void Destroy() {
110 if (destroyed_)
111 return;
113 destroyed_ = true;
114 guest_->EmbedderWillBeDestroyed();
115 guest_->Destroy();
118 DISALLOW_COPY_AND_ASSIGN(OwnerLifetimeObserver);
121 // This observer ensures that the GuestViewBase destroys itself when its
122 // embedder goes away.
123 class GuestViewBase::OpenerLifetimeObserver : public WebContentsObserver {
124 public:
125 OpenerLifetimeObserver(GuestViewBase* guest)
126 : WebContentsObserver(guest->GetOpener()->web_contents()),
127 guest_(guest) {}
129 ~OpenerLifetimeObserver() override {}
131 // WebContentsObserver implementation.
132 void WebContentsDestroyed() override {
133 if (guest_->attached())
134 return;
136 // If the opener is destroyed then destroy the guest.
137 guest_->Destroy();
140 private:
141 GuestViewBase* guest_;
143 DISALLOW_COPY_AND_ASSIGN(OpenerLifetimeObserver);
146 GuestViewBase::GuestViewBase(content::WebContents* owner_web_contents)
147 : owner_web_contents_(owner_web_contents),
148 browser_context_(owner_web_contents->GetBrowserContext()),
149 guest_instance_id_(
150 GuestViewManager::FromBrowserContext(browser_context_)->
151 GetNextInstanceID()),
152 view_instance_id_(guestview::kInstanceIDNone),
153 element_instance_id_(guestview::kInstanceIDNone),
154 initialized_(false),
155 is_being_destroyed_(false),
156 guest_sizer_(nullptr),
157 auto_size_enabled_(false),
158 is_full_page_plugin_(false),
159 weak_ptr_factory_(this) {
162 void GuestViewBase::Init(const base::DictionaryValue& create_params,
163 const WebContentsCreatedCallback& callback) {
164 if (initialized_)
165 return;
166 initialized_ = true;
168 const Feature* feature = FeatureProvider::GetAPIFeature(GetAPINamespace());
169 CHECK(feature);
171 ProcessMap* process_map = ProcessMap::Get(browser_context());
172 CHECK(process_map);
174 const Extension* owner_extension =
175 ProcessManager::Get(owner_web_contents()->GetBrowserContext())->
176 GetExtensionForRenderViewHost(
177 owner_web_contents()->GetRenderViewHost());
178 owner_extension_id_ = owner_extension ? owner_extension->id() : std::string();
180 // Ok for |owner_extension| to be nullptr, the embedder might be WebUI.
181 Feature::Availability availability = feature->IsAvailableToContext(
182 owner_extension,
183 process_map->GetMostLikelyContextType(
184 owner_extension,
185 owner_web_contents()->GetRenderProcessHost()->GetID()),
186 GetOwnerSiteURL());
187 if (!availability.is_available()) {
188 // The derived class did not create a WebContents so this class serves no
189 // purpose. Let's self-destruct.
190 delete this;
191 callback.Run(nullptr);
192 return;
195 scoped_ptr<base::DictionaryValue> params(create_params.DeepCopy());
196 CreateWebContents(create_params,
197 base::Bind(&GuestViewBase::CompleteInit,
198 weak_ptr_factory_.GetWeakPtr(),
199 base::Passed(&params),
200 callback));
203 void GuestViewBase::InitWithWebContents(
204 const base::DictionaryValue& create_params,
205 content::WebContents* guest_web_contents) {
206 DCHECK(guest_web_contents);
208 // At this point, we have just created the guest WebContents, we need to add
209 // an observer to the owner WebContents. This observer will be responsible
210 // for destroying the guest WebContents if the owner goes away.
211 owner_lifetime_observer_.reset(
212 new OwnerLifetimeObserver(this, owner_web_contents_));
214 WebContentsObserver::Observe(guest_web_contents);
215 guest_web_contents->SetDelegate(this);
216 webcontents_guestview_map.Get().insert(
217 std::make_pair(guest_web_contents, this));
218 GuestViewManager::FromBrowserContext(browser_context_)->
219 AddGuest(guest_instance_id_, guest_web_contents);
221 // Create a ZoomController to allow the guest's contents to be zoomed.
222 ui_zoom::ZoomController::CreateForWebContents(guest_web_contents);
224 // Populate the view instance ID if we have it on creation.
225 create_params.GetInteger(guestview::kParameterInstanceId,
226 &view_instance_id_);
228 if (CanRunInDetachedState())
229 SetUpSizing(create_params);
231 // Give the derived class an opportunity to perform additional initialization.
232 DidInitialize(create_params);
235 void GuestViewBase::DispatchOnResizeEvent(const gfx::Size& old_size,
236 const gfx::Size& new_size) {
237 if (new_size == old_size)
238 return;
240 // Dispatch the onResize event.
241 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
242 args->SetInteger(guestview::kOldWidth, old_size.width());
243 args->SetInteger(guestview::kOldHeight, old_size.height());
244 args->SetInteger(guestview::kNewWidth, new_size.width());
245 args->SetInteger(guestview::kNewHeight, new_size.height());
246 DispatchEventToGuestProxy(new Event(guestview::kEventResize, args.Pass()));
249 void GuestViewBase::SetSize(const SetSizeParams& params) {
250 bool enable_auto_size =
251 params.enable_auto_size ? *params.enable_auto_size : auto_size_enabled_;
252 gfx::Size min_size = params.min_size ? *params.min_size : min_auto_size_;
253 gfx::Size max_size = params.max_size ? *params.max_size : max_auto_size_;
255 if (params.normal_size)
256 normal_size_ = *params.normal_size;
258 min_auto_size_ = min_size;
259 min_auto_size_.SetToMin(max_size);
260 max_auto_size_ = max_size;
261 max_auto_size_.SetToMax(min_size);
263 enable_auto_size &= !min_auto_size_.IsEmpty() && !max_auto_size_.IsEmpty() &&
264 IsAutoSizeSupported();
266 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
267 if (enable_auto_size) {
268 // Autosize is being enabled.
269 rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
270 normal_size_.SetSize(0, 0);
271 } else {
272 // Autosize is being disabled.
273 // Use default width/height if missing from partially defined normal size.
274 if (normal_size_.width() && !normal_size_.height())
275 normal_size_.set_height(guestview::kDefaultHeight);
276 if (!normal_size_.width() && normal_size_.height())
277 normal_size_.set_width(guestview::kDefaultWidth);
279 gfx::Size new_size;
280 if (!normal_size_.IsEmpty()) {
281 new_size = normal_size_;
282 } else if (!guest_size_.IsEmpty()) {
283 new_size = guest_size_;
284 } else {
285 new_size = gfx::Size(guestview::kDefaultWidth, guestview::kDefaultHeight);
288 if (auto_size_enabled_) {
289 // Autosize was previously enabled.
290 rvh->DisableAutoResize(new_size);
291 GuestSizeChangedDueToAutoSize(guest_size_, new_size);
292 } else {
293 // Autosize was already disabled.
294 guest_sizer_->SizeContents(new_size);
297 DispatchOnResizeEvent(guest_size_, new_size);
298 guest_size_ = new_size;
301 auto_size_enabled_ = enable_auto_size;
304 // static
305 void GuestViewBase::RegisterGuestViewType(
306 const std::string& view_type,
307 const GuestCreationCallback& callback) {
308 auto it = guest_view_registry.Get().find(view_type);
309 DCHECK(it == guest_view_registry.Get().end());
310 guest_view_registry.Get()[view_type] = callback;
313 // static
314 GuestViewBase* GuestViewBase::Create(
315 content::WebContents* owner_web_contents,
316 const std::string& view_type) {
317 if (guest_view_registry.Get().empty())
318 RegisterGuestViewTypes();
320 auto it = guest_view_registry.Get().find(view_type);
321 if (it == guest_view_registry.Get().end()) {
322 NOTREACHED();
323 return nullptr;
325 return it->second.Run(owner_web_contents);
328 // static
329 GuestViewBase* GuestViewBase::FromWebContents(WebContents* web_contents) {
330 WebContentsGuestViewMap* guest_map = webcontents_guestview_map.Pointer();
331 auto it = guest_map->find(web_contents);
332 return it == guest_map->end() ? nullptr : it->second;
335 // static
336 GuestViewBase* GuestViewBase::From(int owner_process_id,
337 int guest_instance_id) {
338 auto host = content::RenderProcessHost::FromID(owner_process_id);
339 if (!host)
340 return nullptr;
342 content::WebContents* guest_web_contents =
343 GuestViewManager::FromBrowserContext(host->GetBrowserContext())->
344 GetGuestByInstanceIDSafely(guest_instance_id, owner_process_id);
345 if (!guest_web_contents)
346 return nullptr;
348 return GuestViewBase::FromWebContents(guest_web_contents);
351 // static
352 bool GuestViewBase::IsGuest(WebContents* web_contents) {
353 return !!GuestViewBase::FromWebContents(web_contents);
356 bool GuestViewBase::IsAutoSizeSupported() const {
357 return false;
360 bool GuestViewBase::IsPreferredSizeModeEnabled() const {
361 return false;
364 bool GuestViewBase::IsDragAndDropEnabled() const {
365 return false;
368 bool GuestViewBase::ZoomPropagatesFromEmbedderToGuest() const {
369 return true;
372 content::WebContents* GuestViewBase::CreateNewGuestWindow(
373 const content::WebContents::CreateParams& create_params) {
374 auto guest_manager = GuestViewManager::FromBrowserContext(browser_context());
375 return guest_manager->CreateGuestWithWebContentsParams(
376 GetViewType(),
377 owner_web_contents(),
378 create_params);
381 void GuestViewBase::DidAttach(int guest_proxy_routing_id) {
382 opener_lifetime_observer_.reset();
384 SetUpSizing(*attach_params());
386 // Give the derived class an opportunity to perform some actions.
387 DidAttachToEmbedder();
389 // Inform the associated GuestViewContainer that the contentWindow is ready.
390 embedder_web_contents()->Send(new GuestViewMsg_GuestAttached(
391 element_instance_id_,
392 guest_proxy_routing_id));
394 SendQueuedEvents();
397 void GuestViewBase::DidDetach() {
398 GuestViewManager::FromBrowserContext(browser_context_)->DetachGuest(this);
399 StopTrackingEmbedderZoomLevel();
400 owner_web_contents()->Send(new GuestViewMsg_GuestDetached(
401 element_instance_id_));
402 element_instance_id_ = guestview::kInstanceIDNone;
405 WebContents* GuestViewBase::GetOwnerWebContents() const {
406 return owner_web_contents_;
409 void GuestViewBase::GuestSizeChanged(const gfx::Size& new_size) {
410 if (!auto_size_enabled_)
411 return;
412 GuestSizeChangedDueToAutoSize(guest_size_, new_size);
413 DispatchOnResizeEvent(guest_size_, new_size);
414 guest_size_ = new_size;
417 const GURL& GuestViewBase::GetOwnerSiteURL() const {
418 return owner_web_contents()->GetLastCommittedURL();
421 void GuestViewBase::Destroy() {
422 if (is_being_destroyed_)
423 return;
425 is_being_destroyed_ = true;
427 guest_sizer_ = nullptr;
429 // It is important to clear owner_web_contents_ after the call to
430 // StopTrackingEmbedderZoomLevel(), but before the rest of
431 // the statements in this function.
432 StopTrackingEmbedderZoomLevel();
433 owner_web_contents_ = nullptr;
435 DCHECK(web_contents());
437 // Give the derived class an opportunity to perform some cleanup.
438 WillDestroy();
440 // Invalidate weak pointers now so that bound callbacks cannot be called late
441 // into destruction. We must call this after WillDestroy because derived types
442 // may wish to access their openers.
443 weak_ptr_factory_.InvalidateWeakPtrs();
445 // Give the content module an opportunity to perform some cleanup.
446 if (!destruction_callback_.is_null())
447 destruction_callback_.Run();
449 webcontents_guestview_map.Get().erase(web_contents());
450 GuestViewManager::FromBrowserContext(browser_context_)->
451 RemoveGuest(guest_instance_id_);
452 pending_events_.clear();
454 delete web_contents();
457 void GuestViewBase::SetAttachParams(const base::DictionaryValue& params) {
458 attach_params_.reset(params.DeepCopy());
459 attach_params_->GetInteger(guestview::kParameterInstanceId,
460 &view_instance_id_);
463 void GuestViewBase::SetOpener(GuestViewBase* guest) {
464 if (guest && guest->IsViewType(GetViewType())) {
465 opener_ = guest->weak_ptr_factory_.GetWeakPtr();
466 if (!attached())
467 opener_lifetime_observer_.reset(new OpenerLifetimeObserver(this));
468 return;
470 opener_ = base::WeakPtr<GuestViewBase>();
471 opener_lifetime_observer_.reset();
474 void GuestViewBase::RegisterDestructionCallback(
475 const DestructionCallback& callback) {
476 destruction_callback_ = callback;
479 void GuestViewBase::SetGuestSizer(content::GuestSizer* guest_sizer) {
480 guest_sizer_ = guest_sizer;
483 void GuestViewBase::WillAttach(content::WebContents* embedder_web_contents,
484 int element_instance_id,
485 bool is_full_page_plugin) {
486 if (owner_web_contents_ != embedder_web_contents) {
487 DCHECK_EQ(owner_lifetime_observer_->web_contents(), owner_web_contents_);
488 // Stop tracking the old embedder's zoom level.
489 StopTrackingEmbedderZoomLevel();
490 owner_web_contents_ = embedder_web_contents;
491 owner_lifetime_observer_.reset(
492 new OwnerLifetimeObserver(this, embedder_web_contents));
495 // Start tracking the new embedder's zoom level.
496 StartTrackingEmbedderZoomLevel();
497 element_instance_id_ = element_instance_id;
498 is_full_page_plugin_ = is_full_page_plugin;
500 WillAttachToEmbedder();
503 int GuestViewBase::LogicalPixelsToPhysicalPixels(double logical_pixels) {
504 DCHECK(logical_pixels >= 0);
505 double zoom_factor = GetEmbedderZoomFactor();
506 return lround(logical_pixels * zoom_factor);
509 double GuestViewBase::PhysicalPixelsToLogicalPixels(int physical_pixels) {
510 DCHECK(physical_pixels >= 0);
511 double zoom_factor = GetEmbedderZoomFactor();
512 return physical_pixels / zoom_factor;
515 void GuestViewBase::DidStopLoading(content::RenderViewHost* render_view_host) {
516 if (IsPreferredSizeModeEnabled()) {
517 render_view_host->EnablePreferredSizeMode();
519 if (!IsDragAndDropEnabled()) {
520 const char script[] = "window.addEventListener('dragstart', function() { "
521 " window.event.preventDefault(); "
522 "});";
523 render_view_host->GetMainFrame()->ExecuteJavaScript(
524 base::ASCIIToUTF16(script));
526 DidStopLoading();
529 void GuestViewBase::RenderViewReady() {
530 GuestReady();
533 void GuestViewBase::WebContentsDestroyed() {
534 // Let the derived class know that its WebContents is in the process of
535 // being destroyed. web_contents() is still valid at this point.
536 // TODO(fsamuel): This allows for reentrant code into WebContents during
537 // destruction. This could potentially lead to bugs. Perhaps we should get rid
538 // of this?
539 GuestDestroyed();
541 // Self-destruct.
542 delete this;
545 void GuestViewBase::ActivateContents(WebContents* web_contents) {
546 if (!attached() || !embedder_web_contents()->GetDelegate())
547 return;
549 embedder_web_contents()->GetDelegate()->ActivateContents(
550 embedder_web_contents());
553 void GuestViewBase::DeactivateContents(WebContents* web_contents) {
554 if (!attached() || !embedder_web_contents()->GetDelegate())
555 return;
557 embedder_web_contents()->GetDelegate()->DeactivateContents(
558 embedder_web_contents());
561 void GuestViewBase::ContentsMouseEvent(content::WebContents* source,
562 const gfx::Point& location,
563 bool motion) {
564 if (!attached() || !embedder_web_contents()->GetDelegate())
565 return;
567 embedder_web_contents()->GetDelegate()->ContentsMouseEvent(
568 embedder_web_contents(), location, motion);
571 void GuestViewBase::ContentsZoomChange(bool zoom_in) {
572 ui_zoom::PageZoom::Zoom(
573 embedder_web_contents(),
574 zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT);
577 void GuestViewBase::HandleKeyboardEvent(
578 WebContents* source,
579 const content::NativeWebKeyboardEvent& event) {
580 if (!attached())
581 return;
583 // Send the keyboard events back to the embedder to reprocess them.
584 embedder_web_contents()->GetDelegate()->
585 HandleKeyboardEvent(embedder_web_contents(), event);
588 void GuestViewBase::LoadingStateChanged(content::WebContents* source,
589 bool to_different_document) {
590 if (!attached() || !embedder_web_contents()->GetDelegate())
591 return;
593 embedder_web_contents()->GetDelegate()->LoadingStateChanged(
594 embedder_web_contents(), to_different_document);
597 content::ColorChooser* GuestViewBase::OpenColorChooser(
598 WebContents* web_contents,
599 SkColor color,
600 const std::vector<content::ColorSuggestion>& suggestions) {
601 if (!attached() || !embedder_web_contents()->GetDelegate())
602 return nullptr;
604 return embedder_web_contents()->GetDelegate()->OpenColorChooser(
605 web_contents, color, suggestions);
608 void GuestViewBase::RunFileChooser(WebContents* web_contents,
609 const content::FileChooserParams& params) {
610 if (!attached() || !embedder_web_contents()->GetDelegate())
611 return;
613 embedder_web_contents()->GetDelegate()->RunFileChooser(web_contents, params);
616 bool GuestViewBase::ShouldFocusPageAfterCrash() {
617 // Focus is managed elsewhere.
618 return false;
621 bool GuestViewBase::PreHandleGestureEvent(content::WebContents* source,
622 const blink::WebGestureEvent& event) {
623 return event.type == blink::WebGestureEvent::GesturePinchBegin ||
624 event.type == blink::WebGestureEvent::GesturePinchUpdate ||
625 event.type == blink::WebGestureEvent::GesturePinchEnd;
628 void GuestViewBase::UpdatePreferredSize(
629 content::WebContents* target_web_contents,
630 const gfx::Size& pref_size) {
631 // In theory it's not necessary to check IsPreferredSizeModeEnabled() because
632 // there will only be events if it was enabled in the first place. However,
633 // something else may have turned on preferred size mode, so double check.
634 DCHECK_EQ(web_contents(), target_web_contents);
635 if (IsPreferredSizeModeEnabled()) {
636 OnPreferredSizeChanged(pref_size);
640 void GuestViewBase::UpdateTargetURL(content::WebContents* source,
641 const GURL& url) {
642 if (!attached() || !embedder_web_contents()->GetDelegate())
643 return;
645 embedder_web_contents()->GetDelegate()->UpdateTargetURL(
646 embedder_web_contents(), url);
649 GuestViewBase::~GuestViewBase() {
652 void GuestViewBase::OnZoomChanged(
653 const ui_zoom::ZoomController::ZoomChangedEventData& data) {
654 auto guest_zoom_controller =
655 ui_zoom::ZoomController::FromWebContents(web_contents());
656 if (content::ZoomValuesEqual(data.new_zoom_level,
657 guest_zoom_controller->GetZoomLevel())) {
658 return;
660 // When the embedder's zoom level doesn't match the guest's, then update the
661 // guest's zoom level to match.
662 guest_zoom_controller->SetZoomLevel(data.new_zoom_level);
665 void GuestViewBase::DispatchEventToGuestProxy(Event* event) {
666 DispatchEvent(event, guest_instance_id_);
669 void GuestViewBase::DispatchEventToView(Event* event) {
670 if (!attached() &&
671 (!CanRunInDetachedState() || !can_owner_receive_events())) {
672 pending_events_.push_back(linked_ptr<Event>(event));
673 return;
676 DispatchEvent(event, view_instance_id_);
679 void GuestViewBase::DispatchEvent(Event* event, int instance_id) {
680 scoped_ptr<Event> event_ptr(event);
682 EventFilteringInfo info;
683 info.SetInstanceID(instance_id);
684 scoped_ptr<base::ListValue> args(new base::ListValue());
685 args->Append(event->GetArguments().release());
687 EventRouter::DispatchEvent(
688 owner_web_contents_,
689 browser_context_,
690 owner_extension_id_,
691 event->name(),
692 args.Pass(),
693 EventRouter::USER_GESTURE_UNKNOWN,
694 info);
697 void GuestViewBase::SendQueuedEvents() {
698 if (!attached())
699 return;
700 while (!pending_events_.empty()) {
701 linked_ptr<Event> event_ptr = pending_events_.front();
702 pending_events_.pop_front();
703 DispatchEvent(event_ptr.release(), view_instance_id_);
707 void GuestViewBase::CompleteInit(
708 scoped_ptr<base::DictionaryValue> create_params,
709 const WebContentsCreatedCallback& callback,
710 content::WebContents* guest_web_contents) {
711 if (!guest_web_contents) {
712 // The derived class did not create a WebContents so this class serves no
713 // purpose. Let's self-destruct.
714 delete this;
715 callback.Run(nullptr);
716 return;
718 InitWithWebContents(*create_params, guest_web_contents);
719 callback.Run(guest_web_contents);
722 double GuestViewBase::GetEmbedderZoomFactor() {
723 if (!embedder_web_contents())
724 return 1.0;
726 auto zoom_controller =
727 ui_zoom::ZoomController::FromWebContents(embedder_web_contents());
728 if (!zoom_controller)
729 return 1.0;
731 double zoom_factor =
732 content::ZoomLevelToZoomFactor(zoom_controller->GetZoomLevel());
733 return zoom_factor;
736 void GuestViewBase::SetUpSizing(const base::DictionaryValue& params) {
737 // Read the autosize parameters passed in from the embedder.
738 bool auto_size_enabled = false;
739 params.GetBoolean(guestview::kAttributeAutoSize, &auto_size_enabled);
741 int max_height = 0;
742 int max_width = 0;
743 params.GetInteger(guestview::kAttributeMaxHeight, &max_height);
744 params.GetInteger(guestview::kAttributeMaxWidth, &max_width);
746 int min_height = 0;
747 int min_width = 0;
748 params.GetInteger(guestview::kAttributeMinHeight, &min_height);
749 params.GetInteger(guestview::kAttributeMinWidth, &min_width);
751 // Set the normal size to the element size so that the guestview will fit the
752 // element initially if autosize is disabled.
753 double element_height = 0.0;
754 double element_width = 0.0;
755 params.GetDouble(guestview::kElementHeight, &element_height);
756 params.GetDouble(guestview::kElementWidth, &element_width);
757 // Convert the element size from logical pixels to physical pixels.
758 int normal_height = LogicalPixelsToPhysicalPixels(element_height);
759 int normal_width = LogicalPixelsToPhysicalPixels(element_width);
761 SetSizeParams set_size_params;
762 set_size_params.enable_auto_size.reset(new bool(auto_size_enabled));
763 set_size_params.min_size.reset(new gfx::Size(min_width, min_height));
764 set_size_params.max_size.reset(new gfx::Size(max_width, max_height));
765 set_size_params.normal_size.reset(new gfx::Size(normal_width, normal_height));
767 // Call SetSize to apply all the appropriate validation and clipping of
768 // values.
769 SetSize(set_size_params);
772 void GuestViewBase::StartTrackingEmbedderZoomLevel() {
773 if (!ZoomPropagatesFromEmbedderToGuest())
774 return;
776 auto embedder_zoom_controller =
777 ui_zoom::ZoomController::FromWebContents(owner_web_contents());
778 // Chrome Apps do not have a ZoomController.
779 if (!embedder_zoom_controller)
780 return;
781 // Listen to the embedder's zoom changes.
782 embedder_zoom_controller->AddObserver(this);
783 // Set the guest's initial zoom level to be equal to the embedder's.
784 ui_zoom::ZoomController::FromWebContents(web_contents())
785 ->SetZoomLevel(embedder_zoom_controller->GetZoomLevel());
788 void GuestViewBase::StopTrackingEmbedderZoomLevel() {
789 if (!attached() || !ZoomPropagatesFromEmbedderToGuest())
790 return;
792 auto embedder_zoom_controller =
793 ui_zoom::ZoomController::FromWebContents(owner_web_contents());
794 // Chrome Apps do not have a ZoomController.
795 if (!embedder_zoom_controller)
796 return;
797 embedder_zoom_controller->RemoveObserver(this);
800 // static
801 void GuestViewBase::RegisterGuestViewTypes() {
802 AppViewGuest::Register();
803 ExtensionOptionsGuest::Register();
804 ExtensionViewGuest::Register();
805 MimeHandlerViewGuest::Register();
806 SurfaceWorkerGuest::Register();
807 WebViewGuest::Register();
810 } // namespace extensions