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 #ifndef EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_
6 #define EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_
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"
18 struct RendererContentSettingRules;
20 namespace extensions {
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::WebContentsDelegate,
31 public content::WebContentsObserver {
35 Event(const std::string& name, scoped_ptr<base::DictionaryValue> args);
38 const std::string& name() const { return name_; }
40 scoped_ptr<base::DictionaryValue> GetArguments();
43 const std::string name_;
44 scoped_ptr<base::DictionaryValue> args_;
47 // Returns a *ViewGuest if this GuestView is of the given view type.
50 if (IsViewType(T::Type))
51 return static_cast<T*>(this);
56 typedef base::Callback<GuestViewBase*(
57 content::BrowserContext*, int)> GuestCreationCallback;
58 static void RegisterGuestViewType(const std::string& view_type,
59 const GuestCreationCallback& callback);
61 static GuestViewBase* Create(content::BrowserContext* browser_context,
62 int guest_instance_id,
63 const std::string& view_type);
65 static GuestViewBase* FromWebContents(content::WebContents* web_contents);
67 static GuestViewBase* From(int embedder_process_id, int instance_id);
69 static bool IsGuest(content::WebContents* web_contents);
71 virtual const char* GetViewType() const = 0;
73 // This method is called after the guest has been attached to an embedder and
74 // suspended resource loads have been resumed.
76 // This method can be overriden by subclasses. This gives the derived class
77 // an opportunity to perform setup actions after attachment.
78 virtual void DidAttachToEmbedder() {}
80 // This method is called after this GuestViewBase has been initiated.
82 // This gives the derived class an opportunity to perform additional
84 virtual void DidInitialize() {}
86 // This method is called when the initial set of frames within the page have
88 virtual void DidStopLoading() {}
90 // This method is called before the embedder is destroyed.
91 // |embedder_web_contents_| should still be valid during this call. This
92 // allows the derived class to perform some cleanup related to the embedder
94 virtual void EmbedderWillBeDestroyed() {}
96 // This method is called when the guest WebContents has been destroyed. This
97 // object will be destroyed after this call returns.
99 // This gives the derived class an opportunity to perform some cleanup.
100 virtual void GuestDestroyed() {}
102 // This method is invoked when the guest RenderView is ready, e.g. because we
103 // recreated it after a crash or after reattachment.
105 // This gives the derived class an opportunity to perform some initialization
107 virtual void GuestReady() {}
109 // This method is invoked when the contents auto-resized to give the container
110 // an opportunity to match it if it wishes.
112 // This gives the derived class an opportunity to inform its container element
113 // or perform other actions.
114 virtual void GuestSizeChangedDueToAutoSize(const gfx::Size& old_size,
115 const gfx::Size& new_size) {}
117 // This method queries whether autosize is supported for this particular view.
118 // By default, autosize is not supported. Derived classes can override this
119 // behavior to support autosize.
120 virtual bool IsAutoSizeSupported() const;
122 // This method queries whether drag-and-drop is enabled for this particular
123 // view. By default, drag-and-drop is disabled. Derived classes can override
124 // this behavior to enable drag-and-drop.
125 virtual bool IsDragAndDropEnabled() const;
127 // This method is called immediately before suspended resource loads have been
128 // resumed on attachment to an embedder.
130 // This method can be overriden by subclasses. This gives the derived class
131 // an opportunity to perform setup actions before attachment.
132 virtual void WillAttachToEmbedder() {}
134 // This method is called when the guest WebContents is about to be destroyed.
136 // This gives the derived class an opportunity to perform some cleanup prior
138 virtual void WillDestroy() {}
140 // This method is to be implemented by the derived class. Access to guest
141 // views are determined by the availability of the internal extension API
142 // used to implement the guest view.
144 // This should be the name of the API as it appears in the _api_features.json
146 virtual const char* GetAPINamespace() const = 0;
148 // This method is to be implemented by the derived class. This method is the
149 // task prefix to show for a task produced by this GuestViewBase's derived
151 virtual int GetTaskPrefix() const = 0;
153 // This method is to be implemented by the derived class. Given a set of
154 // initialization parameters, a concrete subclass of GuestViewBase can
155 // create a specialized WebContents that it returns back to GuestViewBase.
156 typedef base::Callback<void(content::WebContents*)>
157 WebContentsCreatedCallback;
158 virtual void CreateWebContents(
159 const std::string& embedder_extension_id,
160 int embedder_render_process_id,
161 const GURL& embedder_site_url,
162 const base::DictionaryValue& create_params,
163 const WebContentsCreatedCallback& callback) = 0;
165 // This creates a WebContents and initializes |this| GuestViewBase to use the
166 // newly created WebContents.
167 void Init(const std::string& embedder_extension_id,
168 content::WebContents* embedder_web_contents,
169 const base::DictionaryValue& create_params,
170 const WebContentsCreatedCallback& callback);
172 void InitWithWebContents(const std::string& embedder_extension_id,
173 content::WebContents* embedder_web_contents,
174 content::WebContents* guest_web_contents);
176 bool IsViewType(const char* const view_type) const {
177 return !strcmp(GetViewType(), view_type);
180 // Toggles autosize mode for this GuestView.
181 void SetAutoSize(bool enabled,
182 const gfx::Size& min_size,
183 const gfx::Size& max_size);
185 bool initialized() const { return initialized_; }
187 content::WebContents* embedder_web_contents() const {
188 return embedder_web_contents_;
191 // Returns the parameters associated with the element hosting this GuestView
192 // passed in from JavaScript.
193 base::DictionaryValue* attach_params() const { return attach_params_.get(); }
195 // Returns whether this guest has an associated embedder.
196 bool attached() const { return !!embedder_web_contents_; }
198 // Returns the instance ID of the <*view> element.
199 int view_instance_id() const { return view_instance_id_; }
201 // Returns the instance ID of this GuestViewBase.
202 int guest_instance_id() const { return guest_instance_id_; }
204 // Returns the extension ID of the embedder.
205 const std::string& embedder_extension_id() const {
206 return embedder_extension_id_;
209 // Returns whether this GuestView is embedded in an extension/app.
210 bool in_extension() const { return !embedder_extension_id_.empty(); }
212 // Returns the user browser context of the embedder.
213 content::BrowserContext* browser_context() const { return browser_context_; }
215 // Returns the embedder's process ID.
216 int embedder_render_process_id() const { return embedder_render_process_id_; }
218 GuestViewBase* GetOpener() const {
219 return opener_.get();
222 // Destroy this guest.
225 // Saves the attach state of the custom element hosting this GuestView.
226 void SetAttachParams(const base::DictionaryValue& params);
227 void SetOpener(GuestViewBase* opener);
229 // BrowserPluginGuestDelegate implementation.
230 void DidAttach(int guest_proxy_routing_id) final;
231 void ElementSizeChanged(const gfx::Size& old_size,
232 const gfx::Size& new_size) final;
233 void GuestSizeChanged(const gfx::Size& old_size,
234 const gfx::Size& new_size) final;
235 void RegisterDestructionCallback(const DestructionCallback& callback) final;
236 void WillAttach(content::WebContents* embedder_web_contents,
237 int browser_plugin_instance_id) final;
239 // Dispatches an event |event_name| to the embedder with the |event| fields.
240 void DispatchEventToEmbedder(Event* event);
243 GuestViewBase(content::BrowserContext* browser_context,
244 int guest_instance_id);
246 ~GuestViewBase() override;
249 class EmbedderLifetimeObserver;
251 class OpenerLifetimeObserver;
253 void SendQueuedEvents();
255 void CompleteInit(const std::string& embedder_extension_id,
256 content::WebContents* embedder_web_contents,
257 const WebContentsCreatedCallback& callback,
258 content::WebContents* guest_web_contents);
260 static void RegisterGuestViewTypes();
262 // WebContentsObserver implementation.
263 void DidStopLoading(content::RenderViewHost* render_view_host) final;
264 void RenderViewReady() final;
265 void WebContentsDestroyed() final;
267 // WebContentsDelegate implementation.
268 void ActivateContents(content::WebContents* contents) final;
269 void DeactivateContents(content::WebContents* contents) final;
270 void RunFileChooser(content::WebContents* web_contents,
271 const content::FileChooserParams& params) override;
272 bool ShouldFocusPageAfterCrash() final;
273 bool PreHandleGestureEvent(content::WebContents* source,
274 const blink::WebGestureEvent& event) final;
276 content::WebContents* embedder_web_contents_;
277 std::string embedder_extension_id_;
278 int embedder_render_process_id_;
279 content::BrowserContext* browser_context_;
281 // |guest_instance_id_| is a profile-wide unique identifier for a guest
283 const int guest_instance_id_;
285 // |view_instance_id_| is an identifier that's unique within a particular
286 // embedder RenderViewHost for a particular <*view> instance.
287 int view_instance_id_;
289 // |element_instance_id_| is an identififer that's unique to a particular
290 // GuestViewContainer element.
291 int element_instance_id_;
295 // Indicates that this guest is in the process of being destroyed.
296 bool is_being_destroyed_;
298 // This is a queue of Events that are destined to be sent to the embedder once
299 // the guest is attached to a particular embedder.
300 std::deque<linked_ptr<Event> > pending_events_;
302 // The opener guest view.
303 base::WeakPtr<GuestViewBase> opener_;
305 DestructionCallback destruction_callback_;
307 // The parameters associated with the element hosting this GuestView that
308 // are passed in from JavaScript. This will typically be the view instance ID,
309 // and element-specific parameters. These parameters are passed along to new
310 // guests that are created from this guest.
311 scoped_ptr<base::DictionaryValue> attach_params_;
313 // This observer ensures that this guest self-destructs if the embedder goes
315 scoped_ptr<EmbedderLifetimeObserver> embedder_lifetime_observer_;
317 // This observer ensures that if the guest is unattached and its opener goes
318 // away then this guest also self-destructs.
319 scoped_ptr<OpenerLifetimeObserver> opener_lifetime_observer_;
321 // The size of the container element.
322 gfx::Size element_size_;
324 // The size of the guest content. Note: In autosize mode, the container
325 // element may not match the size of the guest.
326 gfx::Size guest_size_;
328 // Indicates whether autosize mode is enabled or not.
329 bool auto_size_enabled_;
331 // The maximum size constraints of the container element in autosize mode.
332 gfx::Size max_auto_size_;
334 // The minimum size constraints of the container element in autosize mode.
335 gfx::Size min_auto_size_;
337 // This is used to ensure pending tasks will not fire after this object is
339 base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_;
341 DISALLOW_COPY_AND_ASSIGN(GuestViewBase);
344 } // namespace extensions
346 #endif // EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_