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
;
39 struct FrameNavigateParams
;
42 namespace extensions
{
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
;
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() {
74 // This observer ensures that the GuestViewBase destroys itself when its
75 // embedder goes away.
76 class GuestViewBase::OwnerLifetimeObserver
: public WebContentsObserver
{
78 OwnerLifetimeObserver(GuestViewBase
* guest
,
79 content::WebContents
* embedder_web_contents
)
80 : WebContentsObserver(embedder_web_contents
),
84 ~OwnerLifetimeObserver() override
{}
86 // WebContentsObserver implementation.
87 void WebContentsDestroyed() override
{
88 // If the embedder is destroyed then destroy the guest.
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())
100 void RenderProcessGone(base::TerminationStatus status
) override
{
101 // If the embedder crashes, then destroy the guest.
107 GuestViewBase
* guest_
;
114 guest_
->EmbedderWillBeDestroyed();
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
{
125 OpenerLifetimeObserver(GuestViewBase
* guest
)
126 : WebContentsObserver(guest
->GetOpener()->web_contents()),
129 ~OpenerLifetimeObserver() override
{}
131 // WebContentsObserver implementation.
132 void WebContentsDestroyed() override
{
133 if (guest_
->attached())
136 // If the opener is destroyed then destroy the guest.
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()),
150 GuestViewManager::FromBrowserContext(browser_context_
)->
151 GetNextInstanceID()),
152 view_instance_id_(guestview::kInstanceIDNone
),
153 element_instance_id_(guestview::kInstanceIDNone
),
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
) {
168 const Feature
* feature
= FeatureProvider::GetAPIFeature(GetAPINamespace());
171 ProcessMap
* process_map
= ProcessMap::Get(browser_context());
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(
183 process_map
->GetMostLikelyContextType(
185 owner_web_contents()->GetRenderProcessHost()->GetID()),
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.
191 callback
.Run(nullptr);
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(¶ms
),
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
,
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
)
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);
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
);
280 if (!normal_size_
.IsEmpty()) {
281 new_size
= normal_size_
;
282 } else if (!guest_size_
.IsEmpty()) {
283 new_size
= guest_size_
;
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
);
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
;
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
;
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()) {
325 return it
->second
.Run(owner_web_contents
);
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
;
336 GuestViewBase
* GuestViewBase::From(int owner_process_id
,
337 int guest_instance_id
) {
338 auto host
= content::RenderProcessHost::FromID(owner_process_id
);
342 content::WebContents
* guest_web_contents
=
343 GuestViewManager::FromBrowserContext(host
->GetBrowserContext())->
344 GetGuestByInstanceIDSafely(guest_instance_id
, owner_process_id
);
345 if (!guest_web_contents
)
348 return GuestViewBase::FromWebContents(guest_web_contents
);
352 bool GuestViewBase::IsGuest(WebContents
* web_contents
) {
353 return !!GuestViewBase::FromWebContents(web_contents
);
356 bool GuestViewBase::IsAutoSizeSupported() const {
360 bool GuestViewBase::IsPreferredSizeModeEnabled() const {
364 bool GuestViewBase::IsDragAndDropEnabled() const {
368 bool GuestViewBase::ZoomPropagatesFromEmbedderToGuest() const {
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(
377 owner_web_contents(),
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
));
397 void GuestViewBase::DidDetach() {
398 GuestViewManager::FromBrowserContext(browser_context_
)->DetachGuest(
399 this, element_instance_id_
);
400 StopTrackingEmbedderZoomLevel();
401 owner_web_contents()->Send(new GuestViewMsg_GuestDetached(
402 element_instance_id_
));
403 element_instance_id_
= guestview::kInstanceIDNone
;
406 void GuestViewBase::ElementSizeChanged(const gfx::Size
& size
) {
410 // Only resize if needed.
411 guest_sizer_
->SizeContents(size
);
412 DispatchOnResizeEvent(guest_size_
, size
);
416 WebContents
* GuestViewBase::GetOwnerWebContents() const {
417 return owner_web_contents_
;
420 void GuestViewBase::GuestSizeChanged(const gfx::Size
& new_size
) {
421 if (!auto_size_enabled_
)
423 GuestSizeChangedDueToAutoSize(guest_size_
, new_size
);
424 DispatchOnResizeEvent(guest_size_
, new_size
);
425 guest_size_
= new_size
;
428 const GURL
& GuestViewBase::GetOwnerSiteURL() const {
429 return owner_web_contents()->GetLastCommittedURL();
432 void GuestViewBase::Destroy() {
433 if (is_being_destroyed_
)
436 is_being_destroyed_
= true;
438 guest_sizer_
= nullptr;
440 // It is important to clear owner_web_contents_ after the call to
441 // StopTrackingEmbedderZoomLevel(), but before the rest of
442 // the statements in this function.
443 StopTrackingEmbedderZoomLevel();
444 owner_web_contents_
= nullptr;
446 DCHECK(web_contents());
448 // Give the derived class an opportunity to perform some cleanup.
451 // Invalidate weak pointers now so that bound callbacks cannot be called late
452 // into destruction. We must call this after WillDestroy because derived types
453 // may wish to access their openers.
454 weak_ptr_factory_
.InvalidateWeakPtrs();
456 // Give the content module an opportunity to perform some cleanup.
457 if (!destruction_callback_
.is_null())
458 destruction_callback_
.Run();
460 webcontents_guestview_map
.Get().erase(web_contents());
461 GuestViewManager::FromBrowserContext(browser_context_
)->
462 RemoveGuest(guest_instance_id_
);
463 pending_events_
.clear();
465 delete web_contents();
468 void GuestViewBase::SetAttachParams(const base::DictionaryValue
& params
) {
469 attach_params_
.reset(params
.DeepCopy());
470 attach_params_
->GetInteger(guestview::kParameterInstanceId
,
474 void GuestViewBase::SetOpener(GuestViewBase
* guest
) {
475 if (guest
&& guest
->IsViewType(GetViewType())) {
476 opener_
= guest
->weak_ptr_factory_
.GetWeakPtr();
478 opener_lifetime_observer_
.reset(new OpenerLifetimeObserver(this));
481 opener_
= base::WeakPtr
<GuestViewBase
>();
482 opener_lifetime_observer_
.reset();
485 void GuestViewBase::RegisterDestructionCallback(
486 const DestructionCallback
& callback
) {
487 destruction_callback_
= callback
;
490 void GuestViewBase::SetGuestSizer(content::GuestSizer
* guest_sizer
) {
491 guest_sizer_
= guest_sizer
;
494 void GuestViewBase::WillAttach(content::WebContents
* embedder_web_contents
,
495 int element_instance_id
,
496 bool is_full_page_plugin
) {
497 if (owner_web_contents_
!= embedder_web_contents
) {
498 DCHECK_EQ(owner_lifetime_observer_
->web_contents(), owner_web_contents_
);
499 // Stop tracking the old embedder's zoom level.
500 StopTrackingEmbedderZoomLevel();
501 owner_web_contents_
= embedder_web_contents
;
502 owner_lifetime_observer_
.reset(
503 new OwnerLifetimeObserver(this, embedder_web_contents
));
506 // Start tracking the new embedder's zoom level.
507 StartTrackingEmbedderZoomLevel();
508 element_instance_id_
= element_instance_id
;
509 is_full_page_plugin_
= is_full_page_plugin
;
511 WillAttachToEmbedder();
514 void GuestViewBase::DidStopLoading(content::RenderViewHost
* render_view_host
) {
515 if (IsPreferredSizeModeEnabled()) {
516 render_view_host
->EnablePreferredSizeMode();
518 if (!IsDragAndDropEnabled()) {
519 const char script
[] = "window.addEventListener('dragstart', function() { "
520 " window.event.preventDefault(); "
522 render_view_host
->GetMainFrame()->ExecuteJavaScript(
523 base::ASCIIToUTF16(script
));
528 void GuestViewBase::RenderViewReady() {
532 void GuestViewBase::WebContentsDestroyed() {
533 // Let the derived class know that its WebContents is in the process of
534 // being destroyed. web_contents() is still valid at this point.
535 // TODO(fsamuel): This allows for reentrant code into WebContents during
536 // destruction. This could potentially lead to bugs. Perhaps we should get rid
544 void GuestViewBase::ActivateContents(WebContents
* web_contents
) {
545 if (!attached() || !embedder_web_contents()->GetDelegate())
548 embedder_web_contents()->GetDelegate()->ActivateContents(
549 embedder_web_contents());
552 void GuestViewBase::DeactivateContents(WebContents
* web_contents
) {
553 if (!attached() || !embedder_web_contents()->GetDelegate())
556 embedder_web_contents()->GetDelegate()->DeactivateContents(
557 embedder_web_contents());
560 void GuestViewBase::ContentsMouseEvent(content::WebContents
* source
,
561 const gfx::Point
& location
,
563 if (!attached() || !embedder_web_contents()->GetDelegate())
566 embedder_web_contents()->GetDelegate()->ContentsMouseEvent(
567 embedder_web_contents(), location
, motion
);
570 void GuestViewBase::ContentsZoomChange(bool zoom_in
) {
571 ui_zoom::PageZoom::Zoom(
572 embedder_web_contents(),
573 zoom_in
? content::PAGE_ZOOM_IN
: content::PAGE_ZOOM_OUT
);
576 void GuestViewBase::HandleKeyboardEvent(
578 const content::NativeWebKeyboardEvent
& event
) {
582 // Send the keyboard events back to the embedder to reprocess them.
583 embedder_web_contents()->GetDelegate()->
584 HandleKeyboardEvent(embedder_web_contents(), event
);
587 void GuestViewBase::LoadingStateChanged(content::WebContents
* source
,
588 bool to_different_document
) {
589 if (!attached() || !embedder_web_contents()->GetDelegate())
592 embedder_web_contents()->GetDelegate()->LoadingStateChanged(
593 embedder_web_contents(), to_different_document
);
596 content::ColorChooser
* GuestViewBase::OpenColorChooser(
597 WebContents
* web_contents
,
599 const std::vector
<content::ColorSuggestion
>& suggestions
) {
600 if (!attached() || !embedder_web_contents()->GetDelegate())
603 return embedder_web_contents()->GetDelegate()->OpenColorChooser(
604 web_contents
, color
, suggestions
);
607 void GuestViewBase::RunFileChooser(WebContents
* web_contents
,
608 const content::FileChooserParams
& params
) {
609 if (!attached() || !embedder_web_contents()->GetDelegate())
612 embedder_web_contents()->GetDelegate()->RunFileChooser(web_contents
, params
);
615 bool GuestViewBase::ShouldFocusPageAfterCrash() {
616 // Focus is managed elsewhere.
620 bool GuestViewBase::PreHandleGestureEvent(content::WebContents
* source
,
621 const blink::WebGestureEvent
& event
) {
622 return event
.type
== blink::WebGestureEvent::GesturePinchBegin
||
623 event
.type
== blink::WebGestureEvent::GesturePinchUpdate
||
624 event
.type
== blink::WebGestureEvent::GesturePinchEnd
;
627 void GuestViewBase::UpdatePreferredSize(
628 content::WebContents
* target_web_contents
,
629 const gfx::Size
& pref_size
) {
630 // In theory it's not necessary to check IsPreferredSizeModeEnabled() because
631 // there will only be events if it was enabled in the first place. However,
632 // something else may have turned on preferred size mode, so double check.
633 DCHECK_EQ(web_contents(), target_web_contents
);
634 if (IsPreferredSizeModeEnabled()) {
635 OnPreferredSizeChanged(pref_size
);
639 void GuestViewBase::UpdateTargetURL(content::WebContents
* source
,
641 if (!attached() || !embedder_web_contents()->GetDelegate())
644 embedder_web_contents()->GetDelegate()->UpdateTargetURL(
645 embedder_web_contents(), url
);
648 GuestViewBase::~GuestViewBase() {
651 void GuestViewBase::OnZoomChanged(
652 const ui_zoom::ZoomController::ZoomChangedEventData
& data
) {
653 auto guest_zoom_controller
=
654 ui_zoom::ZoomController::FromWebContents(web_contents());
655 if (content::ZoomValuesEqual(data
.new_zoom_level
,
656 guest_zoom_controller
->GetZoomLevel())) {
659 // When the embedder's zoom level doesn't match the guest's, then update the
660 // guest's zoom level to match.
661 guest_zoom_controller
->SetZoomLevel(data
.new_zoom_level
);
664 void GuestViewBase::DispatchEventToGuestProxy(Event
* event
) {
665 DispatchEvent(event
, guest_instance_id_
);
668 void GuestViewBase::DispatchEventToView(Event
* event
) {
670 (!CanRunInDetachedState() || !can_owner_receive_events())) {
671 pending_events_
.push_back(linked_ptr
<Event
>(event
));
675 DispatchEvent(event
, view_instance_id_
);
678 void GuestViewBase::DispatchEvent(Event
* event
, int instance_id
) {
679 scoped_ptr
<Event
> event_ptr(event
);
681 EventFilteringInfo info
;
682 info
.SetInstanceID(instance_id
);
683 scoped_ptr
<base::ListValue
> args(new base::ListValue());
684 args
->Append(event
->GetArguments().release());
686 EventRouter::DispatchEvent(
692 EventRouter::USER_GESTURE_UNKNOWN
,
696 void GuestViewBase::SendQueuedEvents() {
699 while (!pending_events_
.empty()) {
700 linked_ptr
<Event
> event_ptr
= pending_events_
.front();
701 pending_events_
.pop_front();
702 DispatchEvent(event_ptr
.release(), view_instance_id_
);
706 void GuestViewBase::CompleteInit(
707 scoped_ptr
<base::DictionaryValue
> create_params
,
708 const WebContentsCreatedCallback
& callback
,
709 content::WebContents
* guest_web_contents
) {
710 if (!guest_web_contents
) {
711 // The derived class did not create a WebContents so this class serves no
712 // purpose. Let's self-destruct.
714 callback
.Run(nullptr);
717 InitWithWebContents(*create_params
, guest_web_contents
);
718 callback
.Run(guest_web_contents
);
721 void GuestViewBase::SetUpSizing(const base::DictionaryValue
& params
) {
722 // Read the autosize parameters passed in from the embedder.
723 bool auto_size_enabled
= false;
724 params
.GetBoolean(guestview::kAttributeAutoSize
, &auto_size_enabled
);
728 params
.GetInteger(guestview::kAttributeMaxHeight
, &max_height
);
729 params
.GetInteger(guestview::kAttributeMaxWidth
, &max_width
);
733 params
.GetInteger(guestview::kAttributeMinHeight
, &min_height
);
734 params
.GetInteger(guestview::kAttributeMinWidth
, &min_width
);
736 // Set the normal size to the element size so that the guestview will fit the
737 // element initially if autosize is disabled.
738 int normal_height
= 0;
739 int normal_width
= 0;
740 params
.GetInteger(guestview::kElementHeight
, &normal_height
);
741 params
.GetInteger(guestview::kElementWidth
, &normal_width
);
743 SetSizeParams set_size_params
;
744 set_size_params
.enable_auto_size
.reset(new bool(auto_size_enabled
));
745 set_size_params
.min_size
.reset(new gfx::Size(min_width
, min_height
));
746 set_size_params
.max_size
.reset(new gfx::Size(max_width
, max_height
));
747 set_size_params
.normal_size
.reset(new gfx::Size(normal_width
, normal_height
));
749 // Call SetSize to apply all the appropriate validation and clipping of
751 SetSize(set_size_params
);
754 void GuestViewBase::StartTrackingEmbedderZoomLevel() {
755 if (!ZoomPropagatesFromEmbedderToGuest())
758 auto embedder_zoom_controller
=
759 ui_zoom::ZoomController::FromWebContents(owner_web_contents());
760 // Chrome Apps do not have a ZoomController.
761 if (!embedder_zoom_controller
)
763 // Listen to the embedder's zoom changes.
764 embedder_zoom_controller
->AddObserver(this);
765 // Set the guest's initial zoom level to be equal to the embedder's.
766 ui_zoom::ZoomController::FromWebContents(web_contents())
767 ->SetZoomLevel(embedder_zoom_controller
->GetZoomLevel());
770 void GuestViewBase::StopTrackingEmbedderZoomLevel() {
771 if (!attached() || !ZoomPropagatesFromEmbedderToGuest())
774 auto embedder_zoom_controller
=
775 ui_zoom::ZoomController::FromWebContents(owner_web_contents());
776 // Chrome Apps do not have a ZoomController.
777 if (!embedder_zoom_controller
)
779 embedder_zoom_controller
->RemoveObserver(this);
783 void GuestViewBase::RegisterGuestViewTypes() {
784 AppViewGuest::Register();
785 ExtensionOptionsGuest::Register();
786 ExtensionViewGuest::Register();
787 MimeHandlerViewGuest::Register();
788 SurfaceWorkerGuest::Register();
789 WebViewGuest::Register();
792 } // namespace extensions