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 18struct RendererContentSettingRules; 19 20namespace 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. 29class 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 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> 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. 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. 85 virtual void DidInitialize() {} 86 87 // This method is called when the initial set of frames within the page have 88 // completed loading. 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. 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. 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. 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. 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. 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. 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 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 190 bool initialized() const { return initialized_; } 191 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. 198 base::DictionaryValue* attach_params() const { return attach_params_.get(); } 199 200 // Returns whether this guest has an associated embedder. 201 bool attached() const { return !!embedder_web_contents_; } 202 203 // Returns the instance ID of the <*view> element. 204 int view_instance_id() const { return view_instance_id_; } 205 206 // Returns the instance ID of this GuestViewBase. 207 int guest_instance_id() const { return guest_instance_id_; } 208 209 // Returns the extension ID of the embedder. 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. 215 bool in_extension() const { return !embedder_extension_id_.empty(); } 216 217 // Returns the user browser context of the embedder. 218 content::BrowserContext* browser_context() const { return browser_context_; } 219 220 // Returns the embedder's process ID. 221 int embedder_render_process_id() const { return embedder_render_process_id_; } 222 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