Home | History | Annotate | Download | only in guest_view
      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 
     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