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_WEB_VIEW_WEB_VIEW_GUEST_H_
6#define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
7
8#include <vector>
9
10#include "base/observer_list.h"
11#include "content/public/browser/javascript_dialog_manager.h"
12#include "content/public/browser/notification_observer.h"
13#include "content/public/browser/notification_registrar.h"
14#include "extensions/browser/guest_view/guest_view.h"
15#include "extensions/browser/guest_view/web_view/javascript_dialog_helper.h"
16#include "extensions/browser/guest_view/web_view/web_view_find_helper.h"
17#include "extensions/browser/guest_view/web_view/web_view_guest_delegate.h"
18#include "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
19#include "extensions/browser/guest_view/web_view/web_view_permission_types.h"
20#include "extensions/browser/script_executor.h"
21
22namespace blink {
23struct WebFindOptions;
24}  // nanespace blink
25
26namespace extensions {
27
28class WebViewInternalFindFunction;
29
30// A WebViewGuest provides the browser-side implementation of the <webview> API
31// and manages the dispatch of <webview> extension events. WebViewGuest is
32// created on attachment. That is, when a guest WebContents is associated with
33// a particular embedder WebContents. This happens on either initial navigation
34// or through the use of the New Window API, when a new window is attached to
35// a particular <webview>.
36class WebViewGuest : public GuestView<WebViewGuest>,
37                     public content::NotificationObserver {
38 public:
39  static GuestViewBase* Create(content::BrowserContext* browser_context,
40                               int guest_instance_id);
41
42  // For WebViewGuest, we create special guest processes, which host the
43  // tag content separately from the main application that embeds the tag.
44  // A <webview> can specify both the partition name and whether the storage
45  // for that partition should be persisted. Each tag gets a SiteInstance with
46  // a specially formatted URL, based on the application it is hosted by and
47  // the partition requested by it. The format for that URL is:
48  // chrome-guest://partition_domain/persist?partition_name
49  static bool GetGuestPartitionConfigForSite(const GURL& site,
50                                             std::string* partition_domain,
51                                             std::string* partition_name,
52                                             bool* in_memory);
53
54  // Returns guestview::kInstanceIDNone if |contents| does not correspond to a
55  // WebViewGuest.
56  static int GetViewInstanceId(content::WebContents* contents);
57
58  static const char Type[];
59
60  // Request navigating the guest to the provided |src| URL.
61  void NavigateGuest(const std::string& src);
62
63  // Shows the context menu for the guest.
64  // |items| acts as a filter. This restricts the current context's default
65  // menu items to contain only the items from |items|.
66  // |items| == NULL means no filtering will be applied.
67  void ShowContextMenu(
68      int request_id,
69      const WebViewGuestDelegate::MenuItemVector* items);
70
71  // Sets the frame name of the guest.
72  void SetName(const std::string& name);
73
74  // Set the zoom factor.
75  void SetZoom(double zoom_factor);
76
77  // Sets the transparency of the guest.
78  void SetAllowTransparency(bool allow);
79
80  // GuestViewBase implementation.
81  virtual const char* GetAPINamespace() const OVERRIDE;
82  virtual int GetTaskPrefix() const OVERRIDE;
83  virtual void CreateWebContents(
84      const std::string& embedder_extension_id,
85      int embedder_render_process_id,
86      const GURL& embedder_site_url,
87      const base::DictionaryValue& create_params,
88      const WebContentsCreatedCallback& callback) OVERRIDE;
89  virtual void DidAttachToEmbedder() OVERRIDE;
90  virtual void DidInitialize() OVERRIDE;
91  virtual void DidStopLoading() OVERRIDE;
92  virtual void EmbedderDestroyed() OVERRIDE;
93  virtual void GuestDestroyed() OVERRIDE;
94  virtual void GuestReady() OVERRIDE;
95  virtual void GuestSizeChangedDueToAutoSize(
96      const gfx::Size& old_size,
97      const gfx::Size& new_size) OVERRIDE;
98  virtual bool IsAutoSizeSupported() const OVERRIDE;
99  virtual bool IsDragAndDropEnabled() const OVERRIDE;
100  virtual void WillAttachToEmbedder() OVERRIDE;
101  virtual void WillDestroy() OVERRIDE;
102
103  // WebContentsDelegate implementation.
104  virtual bool AddMessageToConsole(content::WebContents* source,
105                                   int32 level,
106                                   const base::string16& message,
107                                   int32 line_no,
108                                   const base::string16& source_id) OVERRIDE;
109  virtual void LoadProgressChanged(content::WebContents* source,
110                                   double progress) OVERRIDE;
111  virtual void CloseContents(content::WebContents* source) OVERRIDE;
112  virtual void FindReply(content::WebContents* source,
113                         int request_id,
114                         int number_of_matches,
115                         const gfx::Rect& selection_rect,
116                         int active_match_ordinal,
117                         bool final_update) OVERRIDE;
118  virtual bool HandleContextMenu(
119      const content::ContextMenuParams& params) OVERRIDE;
120  virtual void HandleKeyboardEvent(
121      content::WebContents* source,
122      const content::NativeWebKeyboardEvent& event) OVERRIDE;
123  virtual void RendererResponsive(content::WebContents* source) OVERRIDE;
124  virtual void RendererUnresponsive(content::WebContents* source) OVERRIDE;
125  virtual void RequestMediaAccessPermission(
126      content::WebContents* source,
127      const content::MediaStreamRequest& request,
128      const content::MediaResponseCallback& callback) OVERRIDE;
129  virtual bool CheckMediaAccessPermission(
130      content::WebContents* source,
131      const GURL& security_origin,
132      content::MediaStreamType type) OVERRIDE;
133  virtual void CanDownload(content::RenderViewHost* render_view_host,
134                           const GURL& url,
135                           const std::string& request_method,
136                           const base::Callback<void(bool)>& callback) OVERRIDE;
137  virtual content::JavaScriptDialogManager*
138      GetJavaScriptDialogManager() OVERRIDE;
139  virtual content::ColorChooser* OpenColorChooser(
140      content::WebContents* web_contents,
141      SkColor color,
142      const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
143  virtual void AddNewContents(content::WebContents* source,
144                              content::WebContents* new_contents,
145                              WindowOpenDisposition disposition,
146                              const gfx::Rect& initial_pos,
147                              bool user_gesture,
148                              bool* was_blocked) OVERRIDE;
149  virtual content::WebContents* OpenURLFromTab(
150      content::WebContents* source,
151      const content::OpenURLParams& params) OVERRIDE;
152  virtual void WebContentsCreated(content::WebContents* source_contents,
153                                  int opener_render_frame_id,
154                                  const base::string16& frame_name,
155                                  const GURL& target_url,
156                                  content::WebContents* new_contents) OVERRIDE;
157
158  // BrowserPluginGuestDelegate implementation.
159  virtual content::WebContents* CreateNewGuestWindow(
160      const content::WebContents::CreateParams& create_params) OVERRIDE;
161  virtual void RequestPointerLockPermission(
162      bool user_gesture,
163      bool last_unlocked_by_target,
164      const base::Callback<void(bool)>& callback) OVERRIDE;
165  // NotificationObserver implementation.
166  virtual void Observe(int type,
167                       const content::NotificationSource& source,
168                       const content::NotificationDetails& details) OVERRIDE;
169
170  // Returns the current zoom factor.
171  double GetZoom();
172
173  // Begin or continue a find request.
174  void Find(const base::string16& search_text,
175            const blink::WebFindOptions& options,
176            scoped_refptr<WebViewInternalFindFunction> find_function);
177
178  // Conclude a find request to clear highlighting.
179  void StopFinding(content::StopFindAction);
180
181  // If possible, navigate the guest to |relative_index| entries away from the
182  // current navigation entry.
183  void Go(int relative_index);
184
185  // Reload the guest.
186  void Reload();
187
188  typedef base::Callback<void(bool /* allow */,
189                              const std::string& /* user_input */)>
190      PermissionResponseCallback;
191  int RequestPermission(
192      WebViewPermissionType permission_type,
193      const base::DictionaryValue& request_info,
194      const PermissionResponseCallback& callback,
195      bool allowed_by_default);
196
197  // Requests Geolocation Permission from the embedder.
198  void RequestGeolocationPermission(int bridge_id,
199                                    const GURL& requesting_frame,
200                                    bool user_gesture,
201                                    const base::Callback<void(bool)>& callback);
202  void CancelGeolocationPermissionRequest(int bridge_id);
203
204  // Called when file system access is requested by the guest content using the
205  // HTML5 file system API in main thread, or a worker thread.
206  // The request is plumbed through the <webview> permission request API. The
207  // request will be:
208  // - Allowed if the embedder explicitly allowed it.
209  // - Denied if the embedder explicitly denied.
210  // - Determined by the guest's content settings if the embedder does not
211  // perform an explicit action.
212  void RequestFileSystemPermission(const GURL& url,
213                                   bool allowed_by_default,
214                                   const base::Callback<void(bool)>& callback);
215
216  // Overrides the user agent for this guest.
217  // This affects subsequent guest navigations.
218  void SetUserAgentOverride(const std::string& user_agent_override);
219
220  // Stop loading the guest.
221  void Stop();
222
223  // Kill the guest process.
224  void Terminate();
225
226  // Clears data in the storage partition of this guest.
227  //
228  // Partition data that are newer than |removal_since| will be removed.
229  // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask.
230  bool ClearData(const base::Time remove_since,
231                 uint32 removal_mask,
232                 const base::Closure& callback);
233
234  ScriptExecutor* script_executor() { return script_executor_.get(); }
235
236 private:
237  friend class WebViewPermissionHelper;
238  WebViewGuest(content::BrowserContext* browser_context,
239               int guest_instance_id);
240
241  virtual ~WebViewGuest();
242
243  void AttachWebViewHelpers(content::WebContents* contents);
244
245  void OnWebViewNewWindowResponse(int new_window_instance_id,
246                                  bool allow,
247                                  const std::string& user_input);
248
249  // WebContentsObserver implementation.
250  virtual void DidCommitProvisionalLoadForFrame(
251      content::RenderFrameHost* render_frame_host,
252      const GURL& url,
253      ui::PageTransition transition_type) OVERRIDE;
254  virtual void DidFailProvisionalLoad(
255      content::RenderFrameHost* render_frame_host,
256      const GURL& validated_url,
257      int error_code,
258      const base::string16& error_description) OVERRIDE;
259  virtual void DidStartProvisionalLoadForFrame(
260      content::RenderFrameHost* render_frame_host,
261      const GURL& validated_url,
262      bool is_error_page,
263      bool is_iframe_srcdoc) OVERRIDE;
264  virtual void DocumentLoadedInFrame(
265      content::RenderFrameHost* render_frame_host) OVERRIDE;
266  virtual bool OnMessageReceived(
267      const IPC::Message& message,
268      content::RenderFrameHost* render_frame_host) OVERRIDE;
269  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
270  virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE;
271
272  // Informs the embedder of a frame name change.
273  void ReportFrameNameChange(const std::string& name);
274
275  // Called after the load handler is called in the guest's main frame.
276  void LoadHandlerCalled();
277
278  // Called when a redirect notification occurs.
279  void LoadRedirect(const GURL& old_url,
280                    const GURL& new_url,
281                    bool is_top_level);
282
283  void PushWebViewStateToIOThread();
284  static void RemoveWebViewStateFromIOThread(
285      content::WebContents* web_contents);
286
287  void LoadURLWithParams(const GURL& url,
288                         const content::Referrer& referrer,
289                         ui::PageTransition transition_type,
290                         content::WebContents* web_contents);
291
292  void RequestNewWindowPermission(
293      WindowOpenDisposition disposition,
294      const gfx::Rect& initial_bounds,
295      bool user_gesture,
296      content::WebContents* new_contents);
297
298  // Destroy unattached new windows that have been opened by this
299  // WebViewGuest.
300  void DestroyUnattachedWindows();
301
302  // Requests resolution of a potentially relative URL.
303  GURL ResolveURL(const std::string& src);
304
305  // Notification that a load in the guest resulted in abort. Note that |url|
306  // may be invalid.
307  void LoadAbort(bool is_top_level,
308                 const GURL& url,
309                 const std::string& error_type);
310
311  void OnFrameNameChanged(bool is_top_level, const std::string& name);
312
313  // Creates a new guest window owned by this WebViewGuest.
314  void CreateNewGuestWebViewWindow(const content::OpenURLParams& params);
315
316  void NewGuestWebViewCallback(const content::OpenURLParams& params,
317                               content::WebContents* guest_web_contents);
318
319  bool HandleKeyboardShortcuts(const content::NativeWebKeyboardEvent& event);
320
321  void SetUpAutoSize();
322
323  // Handles find requests and replies for the webview find API.
324  WebViewFindHelper find_helper_;
325
326  ObserverList<ScriptExecutionObserver> script_observers_;
327  scoped_ptr<ScriptExecutor> script_executor_;
328
329  content::NotificationRegistrar notification_registrar_;
330
331  // True if the user agent is overridden.
332  bool is_overriding_user_agent_;
333
334  // Stores the window name of the main frame of the guest.
335  std::string name_;
336
337  // Stores whether the contents of the guest can be transparent.
338  bool guest_opaque_;
339
340  // Handles the JavaScript dialog requests.
341  JavaScriptDialogHelper javascript_dialog_helper_;
342
343  // Handels permission requests.
344  scoped_ptr<WebViewPermissionHelper> web_view_permission_helper_;
345
346  scoped_ptr<WebViewGuestDelegate> web_view_guest_delegate_;
347
348  // Tracks the name, and target URL of the new window. Once the first
349  // navigation commits, we no longer track this information.
350  struct NewWindowInfo {
351    GURL url;
352    std::string name;
353    bool changed;
354    NewWindowInfo(const GURL& url, const std::string& name) :
355        url(url),
356        name(name),
357        changed(false) {}
358  };
359
360  typedef std::map<WebViewGuest*, NewWindowInfo> PendingWindowMap;
361  PendingWindowMap pending_new_windows_;
362
363  DISALLOW_COPY_AND_ASSIGN(WebViewGuest);
364};
365
366}  // namespace extensions
367
368#endif  // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
369