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 CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_
6#define CHROME_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/web_contents.h"
14#include "content/public/browser/web_contents_delegate.h"
15#include "content/public/browser/web_contents_observer.h"
16
17struct RendererContentSettingRules;
18
19// A GuestViewBase is the base class browser-side API implementation for a
20// <*view> tag. GuestViewBase maintains an association between a guest
21// WebContents and an embedder WebContents. It receives events issued from
22// the guest and relays them to the embedder.
23class GuestViewBase : public content::BrowserPluginGuestDelegate,
24                      public content::WebContentsDelegate,
25                      public content::WebContentsObserver {
26 public:
27  class Event {
28   public:
29    Event(const std::string& name, scoped_ptr<base::DictionaryValue> args);
30    ~Event();
31
32    const std::string& name() const { return name_; }
33
34    scoped_ptr<base::DictionaryValue> GetArguments();
35
36   private:
37    const std::string name_;
38    scoped_ptr<base::DictionaryValue> args_;
39  };
40
41  // Returns a *ViewGuest if this GuestView is of the given view type.
42  template <typename T>
43  T* As() {
44    if (IsViewType(T::Type))
45      return static_cast<T*>(this);
46
47    return NULL;
48  }
49
50  static GuestViewBase* Create(int guest_instance_id,
51                               content::WebContents* guest_web_contents,
52                               const std::string& embedder_extension_id,
53                               const std::string& view_type);
54
55  static GuestViewBase* FromWebContents(content::WebContents* web_contents);
56
57  static GuestViewBase* From(int embedder_process_id, int instance_id);
58
59  static bool IsGuest(content::WebContents* web_contents);
60
61  // By default, JavaScript and images are enabled in guest content.
62  static void GetDefaultContentSettingRules(RendererContentSettingRules* rules,
63                                            bool incognito);
64
65  virtual const char* GetViewType() const = 0;
66
67  // This method is called after the guest has been attached to an embedder and
68  // suspended resource loads have been resumed.
69  //
70  // This method can be overriden by subclasses. This gives the derived class
71  // an opportunity to perform setup actions after attachment.
72  virtual void DidAttachToEmbedder() {}
73
74  // This method can be overridden by subclasses. This method is called when
75  // the initial set of frames within the page have completed loading.
76  virtual void DidStopLoading() {}
77
78  // This method is called immediately before suspended resource loads have been
79  // resumed on attachment to an embedder.
80  //
81  // This method can be overriden by subclasses. This gives the derived class
82  // an opportunity to perform setup actions before attachment.
83  virtual void WillAttachToEmbedder() {}
84
85  // This method is called when the guest WebContents is about to be destroyed.
86  //
87  // This method can be overridden by subclasses. This gives the derived class
88  // an opportunity to perform some cleanup prior to destruction.
89  virtual void WillDestroy() {}
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 method can be overridden by subclasses. This gives the derived class
95  // an opportunity to perform some cleanup prior 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 method can be overridden by subclasses. This gives the derived class
102  // opportunity to perform some cleanup.
103  virtual void GuestDestroyed() {}
104
105  // This method queries whether drag-and-drop is enabled for this particular
106  // view. By default, drag-and-drop is disabled. Derived classes can override
107  // this behavior to enable drag-and-drop.
108  virtual bool IsDragAndDropEnabled() const;
109
110  // Once a guest WebContents is ready, this initiates the association of |this|
111  // GuestView with |guest_web_contents|.
112  void Init(content::WebContents* guest_web_contents,
113            const std::string& embedder_extension_id);
114
115  bool IsViewType(const char* const view_type) const {
116    return !strcmp(GetViewType(), view_type);
117  }
118
119  base::WeakPtr<GuestViewBase> AsWeakPtr();
120
121  content::WebContents* embedder_web_contents() const {
122    return embedder_web_contents_;
123  }
124
125  // Returns the guest WebContents.
126  content::WebContents* guest_web_contents() const {
127    return web_contents();
128  }
129
130  // Returns the extra parameters associated with this GuestView passed
131  // in from JavaScript.
132  base::DictionaryValue* extra_params() const {
133    return extra_params_.get();
134  }
135
136  // Returns whether this guest has an associated embedder.
137  bool attached() const { return !!embedder_web_contents_; }
138
139  // Returns the instance ID of the <*view> element.
140  int view_instance_id() const { return view_instance_id_; }
141
142  // Returns the instance ID of the guest WebContents.
143  int guest_instance_id() const { return guest_instance_id_; }
144
145  // Returns the extension ID of the embedder.
146  const std::string& embedder_extension_id() const {
147    return embedder_extension_id_;
148  }
149
150  // Returns whether this GuestView is embedded in an extension/app.
151  bool in_extension() const { return !embedder_extension_id_.empty(); }
152
153  // Returns the user browser context of the embedder.
154  content::BrowserContext* browser_context() const { return browser_context_; }
155
156  // Returns the embedder's process ID.
157  int embedder_render_process_id() const { return embedder_render_process_id_; }
158
159  GuestViewBase* GetOpener() const {
160    return opener_.get();
161  }
162
163  void SetOpener(GuestViewBase* opener);
164
165  // BrowserPluginGuestDelegate implementation.
166  virtual void Destroy() OVERRIDE FINAL;
167  virtual void DidAttach() OVERRIDE FINAL;
168  virtual void RegisterDestructionCallback(
169      const DestructionCallback& callback) OVERRIDE FINAL;
170  virtual void WillAttach(
171      content::WebContents* embedder_web_contents,
172      const base::DictionaryValue& extra_params) OVERRIDE FINAL;
173
174 protected:
175  explicit GuestViewBase(int guest_instance_id);
176
177  virtual ~GuestViewBase();
178
179  // Dispatches an event |event_name| to the embedder with the |event| fields.
180  void DispatchEvent(Event* event);
181
182 private:
183  class EmbedderWebContentsObserver;
184
185  void SendQueuedEvents();
186
187  // WebContentsObserver implementation.
188  virtual void DidStopLoading(
189      content::RenderViewHost* render_view_host) OVERRIDE FINAL;
190  virtual void WebContentsDestroyed() OVERRIDE FINAL;
191
192  // WebContentsDelegate implementation.
193  virtual bool ShouldFocusPageAfterCrash() OVERRIDE FINAL;
194  virtual bool PreHandleGestureEvent(
195      content::WebContents* source,
196      const blink::WebGestureEvent& event) OVERRIDE FINAL;
197
198  content::WebContents* embedder_web_contents_;
199  std::string embedder_extension_id_;
200  int embedder_render_process_id_;
201  content::BrowserContext* browser_context_;
202  // |guest_instance_id_| is a profile-wide unique identifier for a guest
203  // WebContents.
204  const int guest_instance_id_;
205  // |view_instance_id_| is an identifier that's unique within a particular
206  // embedder RenderViewHost for a particular <*view> instance.
207  int view_instance_id_;
208
209  bool initialized_;
210
211  // This is a queue of Events that are destined to be sent to the embedder once
212  // the guest is attached to a particular embedder.
213  std::deque<linked_ptr<Event> > pending_events_;
214
215  // The opener guest view.
216  base::WeakPtr<GuestViewBase> opener_;
217
218  DestructionCallback destruction_callback_;
219
220  // The extra parameters associated with this GuestView passed
221  // in from JavaScript. This will typically be the view instance ID,
222  // the API to use, and view-specific parameters. These parameters
223  // are passed along to new guests that are created from this guest.
224  scoped_ptr<base::DictionaryValue> extra_params_;
225
226  scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_;
227
228  // This is used to ensure pending tasks will not fire after this object is
229  // destroyed.
230  base::WeakPtrFactory<GuestViewBase> weak_ptr_factory_;
231
232  DISALLOW_COPY_AND_ASSIGN(GuestViewBase);
233};
234
235#endif  // CHROME_BROWSER_GUEST_VIEW_GUEST_VIEW_BASE_H_
236