OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ | |
6 #define EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ | |
7 | |
8 #include <queue> | |
9 | |
10 #include "base/memory/weak_ptr.h" | |
11 #include "base/values.h" | |
12 #include "components/ui/zoom/zoom_observer.h" | |
13 #include "content/public/browser/browser_plugin_guest_delegate.h" | |
14 #include "content/public/browser/guest_host.h" | |
15 #include "content/public/browser/render_process_host_observer.h" | |
16 #include "content/public/browser/web_contents.h" | |
17 #include "content/public/browser/web_contents_delegate.h" | |
18 #include "content/public/browser/web_contents_observer.h" | |
19 #include "extensions/common/guest_view/guest_view_constants.h" | |
20 | |
21 struct RendererContentSettingRules; | |
22 | |
23 namespace extensions { | |
24 | |
25 class GuestViewEvent; | |
26 | |
27 // A struct of parameters for SetSize(). The parameters are all declared as | |
28 // scoped pointers since they are all optional. Null pointers indicate that the | |
29 // parameter has not been provided, and the last used value should be used. Note | |
30 // that when |enable_auto_size| is true, providing |normal_size| is not | |
31 // meaningful. This is because the normal size of the guestview is overridden | |
32 // whenever autosizing occurs. | |
33 struct SetSizeParams { | |
34 SetSizeParams(); | |
35 ~SetSizeParams(); | |
36 | |
37 scoped_ptr<bool> enable_auto_size; | |
38 scoped_ptr<gfx::Size> min_size; | |
39 scoped_ptr<gfx::Size> max_size; | |
40 scoped_ptr<gfx::Size> normal_size; | |
41 }; | |
42 | |
43 // A GuestViewBase is the base class browser-side API implementation for a | |
44 // <*view> tag. GuestViewBase maintains an association between a guest | |
45 // WebContents and an owner WebContents. It receives events issued from | |
46 // the guest and relays them to the owner. GuestViewBase tracks the lifetime | |
47 // of its owner. A GuestViewBase's owner is referred to as an embedder if | |
48 // it is attached to a container within the owner's WebContents. | |
49 class GuestViewBase : public content::BrowserPluginGuestDelegate, | |
50 public content::WebContentsDelegate, | |
51 public content::WebContentsObserver, | |
52 public ui_zoom::ZoomObserver { | |
53 public: | |
54 // Returns a *ViewGuest if this GuestView is of the given view type. | |
55 template <typename T> | |
56 T* As() { | |
57 if (IsViewType(T::Type)) | |
58 return static_cast<T*>(this); | |
59 | |
60 return nullptr; | |
61 } | |
62 | |
63 static GuestViewBase* FromWebContents( | |
64 const content::WebContents* web_contents); | |
65 | |
66 static GuestViewBase* From(int owner_process_id, int instance_id); | |
67 | |
68 // Given a |web_contents|, returns the top level owner WebContents. If | |
69 // |web_contents| does not belong to a GuestView, it will be returned | |
70 // unchanged. | |
71 static content::WebContents* GetTopLevelWebContents( | |
72 content::WebContents* web_contents); | |
73 | |
74 static bool IsGuest(content::WebContents* web_contents); | |
75 | |
76 virtual const char* GetViewType() const = 0; | |
77 | |
78 // This method is called after the guest has been attached to an embedder and | |
79 // suspended resource loads have been resumed. | |
80 // | |
81 // This method can be overriden by subclasses. This gives the derived class | |
82 // an opportunity to perform setup actions after attachment. | |
83 virtual void DidAttachToEmbedder() {} | |
84 | |
85 // This method is called after this GuestViewBase has been initiated. | |
86 // | |
87 // This gives the derived class an opportunity to perform additional | |
88 // initialization. | |
89 virtual void DidInitialize(const base::DictionaryValue& create_params) {} | |
90 | |
91 // This method is called when the initial set of frames within the page have | |
92 // completed loading. | |
93 virtual void GuestViewDidStopLoading() {} | |
94 | |
95 // This method is called before the embedder is destroyed. | |
96 // |owner_web_contents_| should still be valid during this call. This | |
97 // allows the derived class to perform some cleanup related to the embedder | |
98 // web contents. | |
99 virtual void EmbedderWillBeDestroyed() {} | |
100 | |
101 // This method is called when the embedder's zoom changes. | |
102 virtual void EmbedderZoomChanged(double old_zoom_level, | |
103 double new_zoom_level) {} | |
104 | |
105 // This method is called when the guest WebContents has been destroyed. This | |
106 // object will be destroyed after this call returns. | |
107 // | |
108 // This gives the derived class an opportunity to perform some cleanup. | |
109 virtual void GuestDestroyed() {} | |
110 | |
111 // This method is invoked when the guest RenderView is ready, e.g. because we | |
112 // recreated it after a crash or after reattachment. | |
113 // | |
114 // This gives the derived class an opportunity to perform some initialization | |
115 // work. | |
116 virtual void GuestReady() {} | |
117 | |
118 // This method is called when the guest's zoom changes. | |
119 virtual void GuestZoomChanged(double old_zoom_level, double new_zoom_level) {} | |
120 | |
121 // This method is called when embedder WebContents's fullscreen is toggled. | |
122 // | |
123 // If the guest asked the embedder to enter fullscreen, the guest uses this | |
124 // signal to exit fullscreen state. | |
125 virtual void EmbedderFullscreenToggled(bool entered_fullscreen) {} | |
126 | |
127 // This method is invoked when the contents auto-resized to give the container | |
128 // an opportunity to match it if it wishes. | |
129 // | |
130 // This gives the derived class an opportunity to inform its container element | |
131 // or perform other actions. | |
132 virtual void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size, | |
133 const gfx::Size& new_size) {} | |
134 | |
135 // This method queries whether autosize is supported for this particular view. | |
136 // By default, autosize is not supported. Derived classes can override this | |
137 // behavior to support autosize. | |
138 virtual bool IsAutoSizeSupported() const; | |
139 | |
140 // This method is invoked when the contents preferred size changes. This will | |
141 // only ever fire if IsPreferredSizeSupported returns true. | |
142 virtual void OnPreferredSizeChanged(const gfx::Size& pref_size) {} | |
143 | |
144 // This method queries whether preferred size events are enabled for this | |
145 // view. By default, preferred size events are disabled, since they add a | |
146 // small amount of overhead. | |
147 virtual bool IsPreferredSizeModeEnabled() const; | |
148 | |
149 // This method queries whether drag-and-drop is enabled for this particular | |
150 // view. By default, drag-and-drop is disabled. Derived classes can override | |
151 // this behavior to enable drag-and-drop. | |
152 virtual bool IsDragAndDropEnabled() const; | |
153 | |
154 // This method is called immediately before suspended resource loads have been | |
155 // resumed on attachment to an embedder. | |
156 // | |
157 // This method can be overriden by subclasses. This gives the derived class | |
158 // an opportunity to perform setup actions before attachment. | |
159 virtual void WillAttachToEmbedder() {} | |
160 | |
161 // This method is called when the guest WebContents is about to be destroyed. | |
162 // | |
163 // This gives the derived class an opportunity to perform some cleanup prior | |
164 // to destruction. | |
165 virtual void WillDestroy() {} | |
166 | |
167 // This method is to be implemented by the derived class. This indicates | |
168 // whether zoom should propagate from the embedder to the guest content. | |
169 virtual bool ZoomPropagatesFromEmbedderToGuest() const; | |
170 | |
171 // This method is to be implemented by the derived class. Access to guest | |
172 // views are determined by the availability of the internal extension API | |
173 // used to implement the guest view. | |
174 // | |
175 // This should be the name of the API as it appears in the _api_features.json | |
176 // file. | |
177 virtual const char* GetAPINamespace() const = 0; | |
178 | |
179 // This method is to be implemented by the derived class. This method is the | |
180 // task prefix to show for a task produced by this GuestViewBase's derived | |
181 // type. | |
182 virtual int GetTaskPrefix() const = 0; | |
183 | |
184 // This method is to be implemented by the derived class. Given a set of | |
185 // initialization parameters, a concrete subclass of GuestViewBase can | |
186 // create a specialized WebContents that it returns back to GuestViewBase. | |
187 using WebContentsCreatedCallback = | |
188 base::Callback<void(content::WebContents*)>; | |
189 virtual void CreateWebContents( | |
190 const base::DictionaryValue& create_params, | |
191 const WebContentsCreatedCallback& callback) = 0; | |
192 | |
193 // This creates a WebContents and initializes |this| GuestViewBase to use the | |
194 // newly created WebContents. | |
195 void Init(const base::DictionaryValue& create_params, | |
196 const WebContentsCreatedCallback& callback); | |
197 | |
198 void InitWithWebContents(const base::DictionaryValue& create_params, | |
199 content::WebContents* guest_web_contents); | |
200 | |
201 void LoadURLWithParams( | |
202 const content::NavigationController::LoadURLParams& load_params); | |
203 | |
204 bool IsViewType(const char* const view_type) const { | |
205 return !strcmp(GetViewType(), view_type); | |
206 } | |
207 | |
208 // Used to toggle autosize mode for this GuestView, and set both the automatic | |
209 // and normal sizes. | |
210 void SetSize(const SetSizeParams& params); | |
211 | |
212 bool initialized() const { return initialized_; } | |
213 | |
214 content::WebContents* embedder_web_contents() const { | |
215 return attached() ? owner_web_contents_ : nullptr; | |
216 } | |
217 | |
218 content::WebContents* owner_web_contents() const { | |
219 return owner_web_contents_; | |
220 } | |
221 | |
222 content::GuestHost* host() const { | |
223 return guest_host_; | |
224 } | |
225 | |
226 // Returns the parameters associated with the element hosting this GuestView | |
227 // passed in from JavaScript. | |
228 base::DictionaryValue* attach_params() const { return attach_params_.get(); } | |
229 | |
230 // Returns whether this guest has an associated embedder. | |
231 bool attached() const { | |
232 return element_instance_id_ != guestview::kInstanceIDNone; | |
233 } | |
234 | |
235 // Returns the instance ID of the <*view> element. | |
236 int view_instance_id() const { return view_instance_id_; } | |
237 | |
238 // Returns the instance ID of this GuestViewBase. | |
239 int guest_instance_id() const { return guest_instance_id_; } | |
240 | |
241 // Returns the instance ID of the GuestViewBase's element. | |
242 int element_instance_id() const { return element_instance_id_; } | |
243 | |
244 bool can_owner_receive_events() const { return !!view_instance_id_; } | |
245 | |
246 // Returns the user browser context of the embedder. | |
247 content::BrowserContext* browser_context() const { return browser_context_; } | |
248 | |
249 GuestViewBase* GetOpener() const { | |
250 return opener_.get(); | |
251 } | |
252 | |
253 // Returns the URL of the owner WebContents. | |
254 const GURL& GetOwnerSiteURL() const; | |
255 | |
256 // Returns the host of the owner WebContents. For extensions, this is the | |
257 // extension ID. | |
258 std::string owner_host() const { return owner_host_; } | |
259 | |
260 // Whether the guest view is inside a plugin document. | |
261 bool is_full_page_plugin() const { return is_full_page_plugin_; } | |
262 | |
263 // Returns the routing ID of the guest proxy in the owner's renderer process. | |
264 // This value is only valid after attachment or first navigation. | |
265 int proxy_routing_id() const { return guest_proxy_routing_id_; } | |
266 | |
267 // Destroy this guest. | |
268 void Destroy(); | |
269 | |
270 // Saves the attach state of the custom element hosting this GuestView. | |
271 void SetAttachParams(const base::DictionaryValue& params); | |
272 void SetOpener(GuestViewBase* opener); | |
273 | |
274 // BrowserPluginGuestDelegate implementation. | |
275 content::WebContents* CreateNewGuestWindow( | |
276 const content::WebContents::CreateParams& create_params) final; | |
277 void DidAttach(int guest_proxy_routing_id) final; | |
278 void DidDetach() final; | |
279 content::WebContents* GetOwnerWebContents() const final; | |
280 void GuestSizeChanged(const gfx::Size& new_size) final; | |
281 void SetGuestHost(content::GuestHost* guest_host) final; | |
282 void WillAttach(content::WebContents* embedder_web_contents, | |
283 int browser_plugin_instance_id, | |
284 bool is_full_page_plugin) final; | |
285 | |
286 // ui_zoom::ZoomObserver implementation. | |
287 void OnZoomChanged( | |
288 const ui_zoom::ZoomController::ZoomChangedEventData& data) final; | |
289 | |
290 // Dispatches an event to the guest proxy. | |
291 void DispatchEventToGuestProxy(GuestViewEvent* event); | |
292 | |
293 // Dispatches an event to the view. | |
294 void DispatchEventToView(GuestViewEvent* event); | |
295 | |
296 protected: | |
297 explicit GuestViewBase(content::WebContents* owner_web_contents); | |
298 | |
299 ~GuestViewBase() override; | |
300 | |
301 // Convert sizes in pixels from logical to physical numbers of pixels. | |
302 // Note that a size can consist of a fractional number of logical pixels | |
303 // (hence |logical_pixels| is represented as a double), but will always | |
304 // consist of an integral number of physical pixels (hence the return value | |
305 // is represented as an int). | |
306 int LogicalPixelsToPhysicalPixels(double logical_pixels) const; | |
307 | |
308 // Convert sizes in pixels from physical to logical numbers of pixels. | |
309 // Note that a size can consist of a fractional number of logical pixels | |
310 // (hence the return value is represented as a double), but will always | |
311 // consist of an integral number of physical pixels (hence |physical_pixels| | |
312 // is represented as an int). | |
313 double PhysicalPixelsToLogicalPixels(int physical_pixels) const; | |
314 | |
315 // WebContentsObserver implementation. | |
316 void DidStopLoading() final; | |
317 void RenderViewReady() final; | |
318 void WebContentsDestroyed() final; | |
319 void DidNavigateMainFrame( | |
320 const content::LoadCommittedDetails& details, | |
321 const content::FrameNavigateParams& params) override; | |
322 | |
323 // WebContentsDelegate implementation. | |
324 void ActivateContents(content::WebContents* contents) final; | |
325 void DeactivateContents(content::WebContents* contents) final; | |
326 void ContentsMouseEvent(content::WebContents* source, | |
327 const gfx::Point& location, | |
328 bool motion) override; | |
329 void ContentsZoomChange(bool zoom_in) override; | |
330 void HandleKeyboardEvent( | |
331 content::WebContents* source, | |
332 const content::NativeWebKeyboardEvent& event) override; | |
333 void LoadingStateChanged(content::WebContents* source, | |
334 bool to_different_document) final; | |
335 content::ColorChooser* OpenColorChooser( | |
336 content::WebContents* web_contents, | |
337 SkColor color, | |
338 const std::vector<content::ColorSuggestion>& suggestions) override; | |
339 void RunFileChooser(content::WebContents* web_contents, | |
340 const content::FileChooserParams& params) override; | |
341 bool ShouldFocusPageAfterCrash() final; | |
342 bool PreHandleGestureEvent(content::WebContents* source, | |
343 const blink::WebGestureEvent& event) override; | |
344 void UpdatePreferredSize(content::WebContents* web_contents, | |
345 const gfx::Size& pref_size) final; | |
346 void UpdateTargetURL(content::WebContents* source, const GURL& url) override; | |
347 bool ShouldResumeRequestsForCreatedWindow() override; | |
348 | |
349 void SetGuestZoomLevelToMatchEmbedder(); | |
350 | |
351 private: | |
352 class OwnerContentsObserver; | |
353 | |
354 class OpenerLifetimeObserver; | |
355 | |
356 void SendQueuedEvents(); | |
357 | |
358 void CompleteInit(scoped_ptr<base::DictionaryValue> create_params, | |
359 const WebContentsCreatedCallback& callback, | |
360 content::WebContents* guest_web_contents); | |
361 | |
362 // Dispatches the onResize event to the embedder. | |
363 void DispatchOnResizeEvent(const gfx::Size& old_size, | |
364 const gfx::Size& new_size); | |
365 | |
366 // Returns the default size of the guestview. | |
367 gfx::Size GetDefaultSize() const; | |
368 | |
369 // Get the zoom factor for the embedder's web contents. | |
370 double GetEmbedderZoomFactor() const; | |
371 | |
372 void SetUpSizing(const base::DictionaryValue& params); | |
373 | |
374 void StartTrackingEmbedderZoomLevel(); | |
375 void StopTrackingEmbedderZoomLevel(); | |
376 | |
377 // This guest tracks the lifetime of the WebContents specified by | |
378 // |owner_web_contents_|. If |owner_web_contents_| is destroyed then this | |
379 // guest will also self-destruct. | |
380 content::WebContents* owner_web_contents_; | |
381 std::string owner_host_; | |
382 content::BrowserContext* const browser_context_; | |
383 | |
384 // |guest_instance_id_| is a profile-wide unique identifier for a guest | |
385 // WebContents. | |
386 const int guest_instance_id_; | |
387 | |
388 // |view_instance_id_| is an identifier that's unique within a particular | |
389 // embedder RenderViewHost for a particular <*view> instance. | |
390 int view_instance_id_; | |
391 | |
392 // |element_instance_id_| is an identifer that's unique to a particular | |
393 // GuestViewContainer element. | |
394 int element_instance_id_; | |
395 | |
396 // |initialized_| indicates whether GuestViewBase::Init has been called for | |
397 // this object. | |
398 bool initialized_; | |
399 | |
400 // Indicates that this guest is in the process of being destroyed. | |
401 bool is_being_destroyed_; | |
402 | |
403 // This is a queue of Events that are destined to be sent to the embedder once | |
404 // the guest is attached to a particular embedder. | |
405 std::deque<linked_ptr<GuestViewEvent> > pending_events_; | |
406 | |
407 // The opener guest view. | |
408 base::WeakPtr<GuestViewBase> opener_; | |
409 | |
410 // The parameters associated with the element hosting this GuestView that | |
411 // are passed in from JavaScript. This will typically be the view instance ID, | |
412 // and element-specific parameters. These parameters are passed along to new | |
413 // guests that are created from this guest. | |
414 scoped_ptr<base::DictionaryValue> attach_params_; | |
415 | |
416 // This observer ensures that this guest self-destructs if the embedder goes | |
417 // away. | |
418 scoped_ptr<OwnerContentsObserver> owner_contents_observer_; | |
419 | |
420 // This observer ensures that if the guest is unattached and its opener goes | |
421 // away then this guest also self-destructs. | |
422 scoped_ptr<OpenerLifetimeObserver> opener_lifetime_observer_; | |
423 | |
424 // The size of the guest content. Note: In autosize mode, the container | |
425 // element may not match the size of the guest. | |
426 gfx::Size guest_size_; | |
427 | |
428 // A pointer to the guest_host. | |
429 content::GuestHost* guest_host_; | |
430 | |
431 // Indicates whether autosize mode is enabled or not. | |
432 bool auto_size_enabled_; | |
433 | |
434 // The maximum size constraints of the container element in autosize mode. | |
435 gfx::Size max_auto_size_; | |
436 | |
437 // The minimum size constraints of the container element in autosize mode. | |
438 gfx::Size min_auto_size_; | |
439 | |
440 // The size that will be used when autosize mode is disabled. | |
441 gfx::Size normal_size_; | |
442 | |
443 // Whether the guest view is inside a plugin document. | |
444 bool is_full_page_plugin_; | |
445 | |
446 // The routing ID of the proxy to the guest in the owner's renderer process. | |
447 int guest_proxy_routing_id_; | |
448 | |
449 // This is used to ensure pending tasks will not fire after this object is | |
450 // destroyed. | |
451 base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_; | |
452 | |
453 DISALLOW_COPY_AND_ASSIGN(GuestViewBase); | |
454 }; | |
455 | |
456 } // namespace extensions | |
457 | |
458 #endif // EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ | |
OLD | NEW |