• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "content/public/browser/browser_plugin_guest_delegate.h"
13 #include "content/public/browser/render_process_host_observer.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_delegate.h"
16 #include "content/public/browser/web_contents_observer.h"
17 
18 struct RendererContentSettingRules;
19 
20 namespace extensions {
21 
22 // A GuestViewBase is the base class browser-side API implementation for a
23 // <*view> tag. GuestViewBase maintains an association between a guest
24 // WebContents and an embedder WebContents. It receives events issued from
25 // the guest and relays them to the embedder. GuestViewBase tracks the lifetime
26 // of its embedder render process until it is attached to a particular embedder
27 // WebContents. At that point, its lifetime is restricted in scope to the
28 // lifetime of its embedder WebContents.
29 class GuestViewBase : public content::BrowserPluginGuestDelegate,
30                       public content::RenderProcessHostObserver,
31                       public content::WebContentsDelegate,
32                       public content::WebContentsObserver {
33  public:
34   class Event {
35    public:
36     Event(const std::string& name, scoped_ptr<base::DictionaryValue> args);
37     ~Event();
38 
name()39     const std::string& name() const { return name_; }
40 
41     scoped_ptr<base::DictionaryValue> GetArguments();
42 
43    private:
44     const std::string name_;
45     scoped_ptr<base::DictionaryValue> args_;
46   };
47 
48   // Returns a *ViewGuest if this GuestView is of the given view type.
49   template <typename T>
As()50   T* As() {
51     if (IsViewType(T::Type))
52       return static_cast<T*>(this);
53 
54     return NULL;
55   }
56 
57   typedef base::Callback<GuestViewBase*(
58       content::BrowserContext*, int)> GuestCreationCallback;
59   static void RegisterGuestViewType(const std::string& view_type,
60                                     const GuestCreationCallback& callback);
61 
62   static GuestViewBase* Create(content::BrowserContext* browser_context,
63                                int guest_instance_id,
64                                const std::string& view_type);
65 
66   static GuestViewBase* FromWebContents(content::WebContents* web_contents);
67 
68   static GuestViewBase* From(int embedder_process_id, int instance_id);
69 
70   static bool IsGuest(content::WebContents* web_contents);
71 
72   virtual const char* GetViewType() const = 0;
73 
74   // This method is called after the guest has been attached to an embedder and
75   // suspended resource loads have been resumed.
76   //
77   // This method can be overriden by subclasses. This gives the derived class
78   // an opportunity to perform setup actions after attachment.
DidAttachToEmbedder()79   virtual void DidAttachToEmbedder() {}
80 
81   // This method is called after this GuestViewBase has been initiated.
82   //
83   // This gives the derived class an opportunity to perform additional
84   // initialization.
DidInitialize()85   virtual void DidInitialize() {}
86 
87   // This method is called when the initial set of frames within the page have
88   // completed loading.
DidStopLoading()89   virtual void DidStopLoading() {}
90 
91   // This method is called when the guest's embedder WebContents has been
92   // destroyed and the guest will be destroyed shortly.
93   //
94   // This gives the derived class an opportunity to perform some cleanup prior
95   // to destruction.
EmbedderDestroyed()96   virtual void EmbedderDestroyed() {}
97 
98   // This method is called when the guest WebContents has been destroyed. This
99   // object will be destroyed after this call returns.
100   //
101   // This gives the derived class an opportunity to perform some cleanup.
GuestDestroyed()102   virtual void GuestDestroyed() {}
103 
104   // This method is invoked when the guest RenderView is ready, e.g. because we
105   // recreated it after a crash.
106   //
107   // This gives the derived class an opportunity to perform some initialization
108   // work.
GuestReady()109   virtual void GuestReady() {}
110 
111   // This method is invoked when the contents auto-resized to give the container
112   // an opportunity to match it if it wishes.
113   //
114   // This gives the derived class an opportunity to inform its container element
115   // or perform other actions.
GuestSizeChangedDueToAutoSize(const gfx::Size & old_size,const gfx::Size & new_size)116   virtual void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
117                                              const gfx::Size& new_size) {}
118 
119   // This method queries whether autosize is supported for this particular view.
120   // By default, autosize is not supported. Derived classes can override this
121   // behavior to support autosize.
122   virtual bool IsAutoSizeSupported() const;
123 
124   // This method queries whether drag-and-drop is enabled for this particular
125   // view. By default, drag-and-drop is disabled. Derived classes can override
126   // this behavior to enable drag-and-drop.
127   virtual bool IsDragAndDropEnabled() const;
128 
129   // This method is called immediately before suspended resource loads have been
130   // resumed on attachment to an embedder.
131   //
132   // This method can be overriden by subclasses. This gives the derived class
133   // an opportunity to perform setup actions before attachment.
WillAttachToEmbedder()134   virtual void WillAttachToEmbedder() {}
135 
136   // This method is called when the guest WebContents is about to be destroyed.
137   //
138   // This gives the derived class an opportunity to perform some cleanup prior
139   // to destruction.
WillDestroy()140   virtual void WillDestroy() {}
141 
142   // This method is to be implemented by the derived class. Access to guest
143   // views are determined by the availability of the internal extension API
144   // used to implement the guest view.
145   //
146   // This should be the name of the API as it appears in the _api_features.json
147   // file.
148   virtual const char* GetAPINamespace() const = 0;
149 
150   // This method is to be implemented by the derived class. This method is the
151   // task prefix to show for a task produced by this GuestViewBase's derived
152   // type.
153   virtual int GetTaskPrefix() const = 0;
154 
155   // This method is to be implemented by the derived class. Given a set of
156   // initialization parameters, a concrete subclass of GuestViewBase can
157   // create a specialized WebContents that it returns back to GuestViewBase.
158   typedef base::Callback<void(content::WebContents*)>
159       WebContentsCreatedCallback;
160   virtual void CreateWebContents(
161       const std::string& embedder_extension_id,
162       int embedder_render_process_id,
163       const GURL& embedder_site_url,
164       const base::DictionaryValue& create_params,
165       const WebContentsCreatedCallback& callback) = 0;
166 
167   // This creates a WebContents and initializes |this| GuestViewBase to use the
168   // newly created WebContents.
169   void Init(const std::string& embedder_extension_id,
170             content::WebContents* embedder_web_contents,
171             const base::DictionaryValue& create_params,
172             const WebContentsCreatedCallback& callback);
173 
174   void InitWithWebContents(
175       const std::string& embedder_extension_id,
176       int embedder_render_process_id,
177       content::WebContents* guest_web_contents);
178 
IsViewType(const char * const view_type)179   bool IsViewType(const char* const view_type) const {
180     return !strcmp(GetViewType(), view_type);
181   }
182 
183   // Toggles autosize mode for this GuestView.
184   void SetAutoSize(bool enabled,
185                    const gfx::Size& min_size,
186                    const gfx::Size& max_size);
187 
188   base::WeakPtr<GuestViewBase> AsWeakPtr();
189 
initialized()190   bool initialized() const { return initialized_; }
191 
embedder_web_contents()192   content::WebContents* embedder_web_contents() const {
193     return embedder_web_contents_;
194   }
195 
196   // Returns the parameters associated with the element hosting this GuestView
197   // passed in from JavaScript.
attach_params()198   base::DictionaryValue* attach_params() const { return attach_params_.get(); }
199 
200   // Returns whether this guest has an associated embedder.
attached()201   bool attached() const { return !!embedder_web_contents_; }
202 
203   // Returns the instance ID of the <*view> element.
view_instance_id()204   int view_instance_id() const { return view_instance_id_; }
205 
206   // Returns the instance ID of this GuestViewBase.
guest_instance_id()207   int guest_instance_id() const { return guest_instance_id_; }
208 
209   // Returns the extension ID of the embedder.
embedder_extension_id()210   const std::string& embedder_extension_id() const {
211     return embedder_extension_id_;
212   }
213 
214   // Returns whether this GuestView is embedded in an extension/app.
in_extension()215   bool in_extension() const { return !embedder_extension_id_.empty(); }
216 
217   // Returns the user browser context of the embedder.
browser_context()218   content::BrowserContext* browser_context() const { return browser_context_; }
219 
220   // Returns the embedder's process ID.
embedder_render_process_id()221   int embedder_render_process_id() const { return embedder_render_process_id_; }
222 
GetOpener()223   GuestViewBase* GetOpener() const {
224     return opener_.get();
225   }
226 
227   // Sets some additional chrome/ initialization parameters.
228   void SetAttachParams(const base::DictionaryValue& params);
229   void SetOpener(GuestViewBase* opener);
230 
231   // RenderProcessHostObserver implementation
232   virtual void RenderProcessExited(content::RenderProcessHost* host,
233                                    base::ProcessHandle handle,
234                                    base::TerminationStatus status,
235                                    int exit_code) OVERRIDE;
236 
237   // BrowserPluginGuestDelegate implementation.
238   virtual void Destroy() OVERRIDE FINAL;
239   virtual void DidAttach(int guest_proxy_routing_id) OVERRIDE FINAL;
240   virtual void ElementSizeChanged(const gfx::Size& old_size,
241                                   const gfx::Size& new_size) OVERRIDE FINAL;
242   virtual void GuestSizeChanged(const gfx::Size& old_size,
243                                 const gfx::Size& new_size) OVERRIDE FINAL;
244   virtual void RegisterDestructionCallback(
245       const DestructionCallback& callback) OVERRIDE FINAL;
246   virtual void WillAttach(
247       content::WebContents* embedder_web_contents,
248       int browser_plugin_instance_id) OVERRIDE FINAL;
249 
250   // Dispatches an event |event_name| to the embedder with the |event| fields.
251   void DispatchEventToEmbedder(Event* event);
252 
253  protected:
254   GuestViewBase(content::BrowserContext* browser_context,
255                 int guest_instance_id);
256 
257   virtual ~GuestViewBase();
258 
259  private:
260   class EmbedderWebContentsObserver;
261 
262   void SendQueuedEvents();
263 
264   void CompleteInit(const std::string& embedder_extension_id,
265                     int embedder_render_process_id,
266                     const WebContentsCreatedCallback& callback,
267                     content::WebContents* guest_web_contents);
268 
269   static void RegisterGuestViewTypes();
270 
271   // WebContentsObserver implementation.
272   virtual void DidStopLoading(
273       content::RenderViewHost* render_view_host) OVERRIDE FINAL;
274   virtual void RenderViewReady() OVERRIDE FINAL;
275   virtual void WebContentsDestroyed() OVERRIDE FINAL;
276 
277   // WebContentsDelegate implementation.
278   virtual void ActivateContents(content::WebContents* contents) OVERRIDE FINAL;
279   virtual void DeactivateContents(
280       content::WebContents* contents) OVERRIDE FINAL;
281   virtual void RunFileChooser(
282       content::WebContents* web_contents,
283       const content::FileChooserParams& params) OVERRIDE;
284   virtual bool ShouldFocusPageAfterCrash() OVERRIDE FINAL;
285   virtual bool PreHandleGestureEvent(
286       content::WebContents* source,
287       const blink::WebGestureEvent& event) OVERRIDE FINAL;
288 
289   content::WebContents* embedder_web_contents_;
290   std::string embedder_extension_id_;
291   int embedder_render_process_id_;
292   content::BrowserContext* browser_context_;
293 
294   // |guest_instance_id_| is a profile-wide unique identifier for a guest
295   // WebContents.
296   const int guest_instance_id_;
297 
298   // |view_instance_id_| is an identifier that's unique within a particular
299   // embedder RenderViewHost for a particular <*view> instance.
300   int view_instance_id_;
301 
302   // |element_instance_id_| is an identififer that's unique to a particular
303   // GuestViewContainer element.
304   int element_instance_id_;
305 
306   bool initialized_;
307 
308   // This is a queue of Events that are destined to be sent to the embedder once
309   // the guest is attached to a particular embedder.
310   std::deque<linked_ptr<Event> > pending_events_;
311 
312   // The opener guest view.
313   base::WeakPtr<GuestViewBase> opener_;
314 
315   DestructionCallback destruction_callback_;
316 
317   // The parameters associated with the element hosting this GuestView that
318   // are passed in from JavaScript. This will typically be the view instance ID,
319   // and element-specific parameters. These parameters are passed along to new
320   // guests that are created from this guest.
321   scoped_ptr<base::DictionaryValue> attach_params_;
322 
323   scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_;
324 
325   // The size of the container element.
326   gfx::Size element_size_;
327 
328   // The size of the guest content. Note: In autosize mode, the container
329   // element may not match the size of the guest.
330   gfx::Size guest_size_;
331 
332   // Indicates whether autosize mode is enabled or not.
333   bool auto_size_enabled_;
334 
335   // The maximum size constraints of the container element in autosize mode.
336   gfx::Size max_auto_size_;
337 
338   // The minimum size constraints of the container element in autosize mode.
339   gfx::Size min_auto_size_;
340 
341   // This is used to ensure pending tasks will not fire after this object is
342   // destroyed.
343   base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_;
344 
345   DISALLOW_COPY_AND_ASSIGN(GuestViewBase);
346 };
347 
348 }  // namespace extensions
349 
350 #endif  // EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_
351