| 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 | |
| 348 void SetGuestZoomLevelToMatchEmbedder(); | |
| 349 | |
| 350 private: | |
| 351 class OwnerContentsObserver; | |
| 352 | |
| 353 class OpenerLifetimeObserver; | |
| 354 | |
| 355 void SendQueuedEvents(); | |
| 356 | |
| 357 void CompleteInit(scoped_ptr<base::DictionaryValue> create_params, | |
| 358 const WebContentsCreatedCallback& callback, | |
| 359 content::WebContents* guest_web_contents); | |
| 360 | |
| 361 // Dispatches the onResize event to the embedder. | |
| 362 void DispatchOnResizeEvent(const gfx::Size& old_size, | |
| 363 const gfx::Size& new_size); | |
| 364 | |
| 365 // Returns the default size of the guestview. | |
| 366 gfx::Size GetDefaultSize() const; | |
| 367 | |
| 368 // Get the zoom factor for the embedder's web contents. | |
| 369 double GetEmbedderZoomFactor() const; | |
| 370 | |
| 371 void SetUpSizing(const base::DictionaryValue& params); | |
| 372 | |
| 373 void StartTrackingEmbedderZoomLevel(); | |
| 374 void StopTrackingEmbedderZoomLevel(); | |
| 375 | |
| 376 // This guest tracks the lifetime of the WebContents specified by | |
| 377 // |owner_web_contents_|. If |owner_web_contents_| is destroyed then this | |
| 378 // guest will also self-destruct. | |
| 379 content::WebContents* owner_web_contents_; | |
| 380 std::string owner_host_; | |
| 381 content::BrowserContext* const browser_context_; | |
| 382 | |
| 383 // |guest_instance_id_| is a profile-wide unique identifier for a guest | |
| 384 // WebContents. | |
| 385 const int guest_instance_id_; | |
| 386 | |
| 387 // |view_instance_id_| is an identifier that's unique within a particular | |
| 388 // embedder RenderViewHost for a particular <*view> instance. | |
| 389 int view_instance_id_; | |
| 390 | |
| 391 // |element_instance_id_| is an identifer that's unique to a particular | |
| 392 // GuestViewContainer element. | |
| 393 int element_instance_id_; | |
| 394 | |
| 395 // |initialized_| indicates whether GuestViewBase::Init has been called for | |
| 396 // this object. | |
| 397 bool initialized_; | |
| 398 | |
| 399 // Indicates that this guest is in the process of being destroyed. | |
| 400 bool is_being_destroyed_; | |
| 401 | |
| 402 // This is a queue of Events that are destined to be sent to the embedder once | |
| 403 // the guest is attached to a particular embedder. | |
| 404 std::deque<linked_ptr<GuestViewEvent> > pending_events_; | |
| 405 | |
| 406 // The opener guest view. | |
| 407 base::WeakPtr<GuestViewBase> opener_; | |
| 408 | |
| 409 // The parameters associated with the element hosting this GuestView that | |
| 410 // are passed in from JavaScript. This will typically be the view instance ID, | |
| 411 // and element-specific parameters. These parameters are passed along to new | |
| 412 // guests that are created from this guest. | |
| 413 scoped_ptr<base::DictionaryValue> attach_params_; | |
| 414 | |
| 415 // This observer ensures that this guest self-destructs if the embedder goes | |
| 416 // away. | |
| 417 scoped_ptr<OwnerContentsObserver> owner_contents_observer_; | |
| 418 | |
| 419 // This observer ensures that if the guest is unattached and its opener goes | |
| 420 // away then this guest also self-destructs. | |
| 421 scoped_ptr<OpenerLifetimeObserver> opener_lifetime_observer_; | |
| 422 | |
| 423 // The size of the guest content. Note: In autosize mode, the container | |
| 424 // element may not match the size of the guest. | |
| 425 gfx::Size guest_size_; | |
| 426 | |
| 427 // A pointer to the guest_host. | |
| 428 content::GuestHost* guest_host_; | |
| 429 | |
| 430 // Indicates whether autosize mode is enabled or not. | |
| 431 bool auto_size_enabled_; | |
| 432 | |
| 433 // The maximum size constraints of the container element in autosize mode. | |
| 434 gfx::Size max_auto_size_; | |
| 435 | |
| 436 // The minimum size constraints of the container element in autosize mode. | |
| 437 gfx::Size min_auto_size_; | |
| 438 | |
| 439 // The size that will be used when autosize mode is disabled. | |
| 440 gfx::Size normal_size_; | |
| 441 | |
| 442 // Whether the guest view is inside a plugin document. | |
| 443 bool is_full_page_plugin_; | |
| 444 | |
| 445 // The routing ID of the proxy to the guest in the owner's renderer process. | |
| 446 int guest_proxy_routing_id_; | |
| 447 | |
| 448 // This is used to ensure pending tasks will not fire after this object is | |
| 449 // destroyed. | |
| 450 base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_; | |
| 451 | |
| 452 DISALLOW_COPY_AND_ASSIGN(GuestViewBase); | |
| 453 }; | |
| 454 | |
| 455 } // namespace extensions | |
| 456 | |
| 457 #endif // EXTENSIONS_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_ | |
| OLD | NEW |