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.
5 #ifndef CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
6 #define CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
10 #include "base/observer_list.h"
11 #include "chrome/browser/guest_view/web_view/javascript_dialog_helper.h"
12 #include "chrome/browser/guest_view/web_view/web_view_find_helper.h"
13 #include "chrome/browser/guest_view/web_view/web_view_permission_helper.h"
14 #include "chrome/browser/guest_view/web_view/web_view_permission_types.h"
15 #include "chrome/browser/ui/zoom/zoom_observer.h"
16 #include "chrome/common/extensions/api/web_view_internal.h"
17 #include "content/public/browser/javascript_dialog_manager.h"
18 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h"
20 #include "extensions/browser/guest_view/guest_view.h"
21 #include "extensions/browser/script_executor.h"
22 #include "third_party/WebKit/public/web/WebFindOptions.h"
24 #if defined(OS_CHROMEOS)
25 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
28 class RenderViewContextMenu;
31 class SimpleMenuModel;
34 namespace extensions {
36 namespace webview_api = api::web_view_internal;
38 class WebViewInternalFindFunction;
40 // A WebViewGuest provides the browser-side implementation of the <webview> API
41 // and manages the dispatch of <webview> extension events. WebViewGuest is
42 // created on attachment. That is, when a guest WebContents is associated with
43 // a particular embedder WebContents. This happens on either initial navigation
44 // or through the use of the New Window API, when a new window is attached to
45 // a particular <webview>.
46 class WebViewGuest : public GuestView<WebViewGuest>,
47 public content::NotificationObserver,
50 static GuestViewBase* Create(content::BrowserContext* browser_context,
51 int guest_instance_id);
53 // For WebViewGuest, we create special guest processes, which host the
54 // tag content separately from the main application that embeds the tag.
55 // A <webview> can specify both the partition name and whether the storage
56 // for that partition should be persisted. Each tag gets a SiteInstance with
57 // a specially formatted URL, based on the application it is hosted by and
58 // the partition requested by it. The format for that URL is:
59 // chrome-guest://partition_domain/persist?partition_name
60 static bool GetGuestPartitionConfigForSite(const GURL& site,
61 std::string* partition_domain,
62 std::string* partition_name,
65 // Returns guestview::kInstanceIDNone if |contents| does not correspond to a
67 static int GetViewInstanceId(content::WebContents* contents);
69 static const char Type[];
71 // Request navigating the guest to the provided |src| URL.
72 void NavigateGuest(const std::string& src);
74 typedef std::vector<linked_ptr<webview_api::ContextMenuItem> > MenuItemVector;
75 // Shows the context menu for the guest.
76 // |items| acts as a filter. This restricts the current context's default
77 // menu items to contain only the items from |items|.
78 // |items| == NULL means no filtering will be applied.
79 void ShowContextMenu(int request_id, const MenuItemVector* items);
81 // Sets the frame name of the guest.
82 void SetName(const std::string& name);
84 // Set the zoom factor.
85 void SetZoom(double zoom_factor);
87 // GuestViewBase implementation.
88 virtual const char* GetAPINamespace() OVERRIDE;
89 virtual void CreateWebContents(
90 const std::string& embedder_extension_id,
91 int embedder_render_process_id,
92 const base::DictionaryValue& create_params,
93 const WebContentsCreatedCallback& callback) OVERRIDE;
94 virtual void DidAttachToEmbedder() OVERRIDE;
95 virtual void DidInitialize() OVERRIDE;
96 virtual void DidStopLoading() OVERRIDE;
97 virtual void EmbedderDestroyed() OVERRIDE;
98 virtual void GuestDestroyed() OVERRIDE;
99 virtual void GuestReady() OVERRIDE;
100 virtual void GuestSizeChangedDueToAutoSize(
101 const gfx::Size& old_size,
102 const gfx::Size& new_size) OVERRIDE;
103 virtual bool IsAutoSizeSupported() const OVERRIDE;
104 virtual bool IsDragAndDropEnabled() const OVERRIDE;
105 virtual void WillAttachToEmbedder() OVERRIDE;
106 virtual void WillDestroy() OVERRIDE;
108 // WebContentsDelegate implementation.
109 virtual bool AddMessageToConsole(content::WebContents* source,
111 const base::string16& message,
113 const base::string16& source_id) OVERRIDE;
114 virtual void LoadProgressChanged(content::WebContents* source,
115 double progress) OVERRIDE;
116 virtual void CloseContents(content::WebContents* source) OVERRIDE;
117 virtual void FindReply(content::WebContents* source,
119 int number_of_matches,
120 const gfx::Rect& selection_rect,
121 int active_match_ordinal,
122 bool final_update) OVERRIDE;
123 virtual bool HandleContextMenu(
124 const content::ContextMenuParams& params) OVERRIDE;
125 virtual void HandleKeyboardEvent(
126 content::WebContents* source,
127 const content::NativeWebKeyboardEvent& event) OVERRIDE;
128 virtual void RendererResponsive(content::WebContents* source) OVERRIDE;
129 virtual void RendererUnresponsive(content::WebContents* source) OVERRIDE;
130 virtual void RequestMediaAccessPermission(
131 content::WebContents* source,
132 const content::MediaStreamRequest& request,
133 const content::MediaResponseCallback& callback) OVERRIDE;
134 virtual void CanDownload(content::RenderViewHost* render_view_host,
136 const std::string& request_method,
137 const base::Callback<void(bool)>& callback) OVERRIDE;
138 virtual content::JavaScriptDialogManager*
139 GetJavaScriptDialogManager() OVERRIDE;
140 virtual content::ColorChooser* OpenColorChooser(
141 content::WebContents* web_contents,
143 const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
144 virtual void RunFileChooser(
145 content::WebContents* web_contents,
146 const content::FileChooserParams& params) OVERRIDE;
147 virtual void AddNewContents(content::WebContents* source,
148 content::WebContents* new_contents,
149 WindowOpenDisposition disposition,
150 const gfx::Rect& initial_pos,
152 bool* was_blocked) OVERRIDE;
153 virtual content::WebContents* OpenURLFromTab(
154 content::WebContents* source,
155 const content::OpenURLParams& params) OVERRIDE;
156 virtual void WebContentsCreated(content::WebContents* source_contents,
157 int opener_render_frame_id,
158 const base::string16& frame_name,
159 const GURL& target_url,
160 content::WebContents* new_contents) OVERRIDE;
162 // BrowserPluginGuestDelegate implementation.
163 virtual content::WebContents* CreateNewGuestWindow(
164 const content::WebContents::CreateParams& create_params) OVERRIDE;
165 virtual void RequestPointerLockPermission(
167 bool last_unlocked_by_target,
168 const base::Callback<void(bool)>& callback) OVERRIDE;
169 // NotificationObserver implementation.
170 virtual void Observe(int type,
171 const content::NotificationSource& source,
172 const content::NotificationDetails& details) OVERRIDE;
174 // Returns the current zoom factor.
177 // Begin or continue a find request.
179 const base::string16& search_text,
180 const blink::WebFindOptions& options,
181 scoped_refptr<WebViewInternalFindFunction> find_function);
183 // Conclude a find request to clear highlighting.
184 void StopFinding(content::StopFindAction);
186 // If possible, navigate the guest to |relative_index| entries away from the
187 // current navigation entry.
188 void Go(int relative_index);
193 typedef base::Callback<void(bool /* allow */,
194 const std::string& /* user_input */)>
195 PermissionResponseCallback;
196 int RequestPermission(
197 WebViewPermissionType permission_type,
198 const base::DictionaryValue& request_info,
199 const PermissionResponseCallback& callback,
200 bool allowed_by_default);
202 // Requests Geolocation Permission from the embedder.
203 void RequestGeolocationPermission(int bridge_id,
204 const GURL& requesting_frame,
206 const base::Callback<void(bool)>& callback);
207 void CancelGeolocationPermissionRequest(int bridge_id);
209 // Called when file system access is requested by the guest content using the
210 // HTML5 file system API in main thread, or a worker thread.
211 // The request is plumbed through the <webview> permission request API. The
213 // - Allowed if the embedder explicitly allowed it.
214 // - Denied if the embedder explicitly denied.
215 // - Determined by the guest's content settings if the embedder does not
216 // perform an explicit action.
217 void RequestFileSystemPermission(const GURL& url,
218 bool allowed_by_default,
219 const base::Callback<void(bool)>& callback);
221 // Overrides the user agent for this guest.
222 // This affects subsequent guest navigations.
223 void SetUserAgentOverride(const std::string& user_agent_override);
225 // Stop loading the guest.
228 // Kill the guest process.
231 // Clears data in the storage partition of this guest.
233 // Partition data that are newer than |removal_since| will be removed.
234 // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask.
235 bool ClearData(const base::Time remove_since,
237 const base::Closure& callback);
239 ScriptExecutor* script_executor() { return script_executor_.get(); }
242 friend class WebViewPermissionHelper;
243 WebViewGuest(content::BrowserContext* browser_context,
244 int guest_instance_id);
246 virtual ~WebViewGuest();
248 // Returns the top level items (ignoring submenus) as Value.
249 static scoped_ptr<base::ListValue> MenuModelToValue(
250 const ui::SimpleMenuModel& menu_model);
252 void AttachWebViewHelpers(content::WebContents* contents);
254 void OnWebViewNewWindowResponse(int new_window_instance_id,
256 const std::string& user_input);
258 // WebContentsObserver implementation.
259 virtual void DidCommitProvisionalLoadForFrame(
260 content::RenderFrameHost* render_frame_host,
262 content::PageTransition transition_type) OVERRIDE;
263 virtual void DidFailProvisionalLoad(
264 content::RenderFrameHost* render_frame_host,
265 const GURL& validated_url,
267 const base::string16& error_description) OVERRIDE;
268 virtual void DidStartProvisionalLoadForFrame(
269 content::RenderFrameHost* render_frame_host,
270 const GURL& validated_url,
272 bool is_iframe_srcdoc) OVERRIDE;
273 virtual void DocumentLoadedInFrame(
274 content::RenderFrameHost* render_frame_host) OVERRIDE;
275 virtual bool OnMessageReceived(
276 const IPC::Message& message,
277 content::RenderFrameHost* render_frame_host) OVERRIDE;
278 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
279 virtual void UserAgentOverrideSet(const std::string& user_agent) OVERRIDE;
281 // ZoomObserver implementation.
282 virtual void OnZoomChanged(
283 const ZoomController::ZoomChangedEventData& data) OVERRIDE;
285 // Informs the embedder of a frame name change.
286 void ReportFrameNameChange(const std::string& name);
288 // Called after the load handler is called in the guest's main frame.
289 void LoadHandlerCalled();
291 // Called when a redirect notification occurs.
292 void LoadRedirect(const GURL& old_url,
296 void PushWebViewStateToIOThread();
297 static void RemoveWebViewStateFromIOThread(
298 content::WebContents* web_contents);
300 #if defined(OS_CHROMEOS)
301 // Notification of a change in the state of an accessibility setting.
302 void OnAccessibilityStatusChanged(
303 const chromeos::AccessibilityStatusEventDetails& details);
306 void InjectChromeVoxIfNeeded(content::RenderViewHost* render_view_host);
308 void LoadURLWithParams(const GURL& url,
309 const content::Referrer& referrer,
310 content::PageTransition transition_type,
311 content::WebContents* web_contents);
313 void RequestNewWindowPermission(
314 WindowOpenDisposition disposition,
315 const gfx::Rect& initial_bounds,
317 content::WebContents* new_contents);
319 // Destroy unattached new windows that have been opened by this
321 void DestroyUnattachedWindows();
323 // Requests resolution of a potentially relative URL.
324 GURL ResolveURL(const std::string& src);
326 // Notification that a load in the guest resulted in abort. Note that |url|
328 void LoadAbort(bool is_top_level,
330 const std::string& error_type);
332 void OnUpdateFrameName(bool is_top_level, const std::string& name);
334 // Creates a new guest window owned by this WebViewGuest.
335 void CreateNewGuestWebViewWindow(const content::OpenURLParams& params);
337 void NewGuestWebViewCallback(const content::OpenURLParams& params,
338 content::WebContents* guest_web_contents);
340 bool HandleKeyboardShortcuts(const content::NativeWebKeyboardEvent& event);
342 void SetUpAutoSize();
344 ObserverList<ScriptExecutionObserver> script_observers_;
345 scoped_ptr<ScriptExecutor> script_executor_;
347 content::NotificationRegistrar notification_registrar_;
349 // A counter to generate a unique request id for a context menu request.
350 // We only need the ids to be unique for a given WebViewGuest.
351 int pending_context_menu_request_id_;
353 // True if the user agent is overridden.
354 bool is_overriding_user_agent_;
356 // Set to |true| if ChromeVox was already injected in main frame.
357 bool chromevox_injected_;
359 // Stores the current zoom factor.
360 double current_zoom_factor_;
362 // Stores the window name of the main frame of the guest.
365 // Handles find requests and replies for the webview find API.
366 WebViewFindHelper find_helper_;
368 // Handles the JavaScript dialog requests.
369 JavaScriptDialogHelper javascript_dialog_helper_;
371 // Handels permission requests.
372 scoped_ptr<WebViewPermissionHelper> web_view_permission_helper_;
374 friend void WebViewFindHelper::DispatchFindUpdateEvent(bool canceled,
377 // Holds the RenderViewContextMenu that has been built but yet to be
378 // shown. This is .Reset() after ShowContextMenu().
379 scoped_ptr<RenderViewContextMenu> pending_menu_;
381 #if defined(OS_CHROMEOS)
382 // Subscription to receive notifications on changes to a11y settings.
383 scoped_ptr<chromeos::AccessibilityStatusSubscription>
384 accessibility_subscription_;
387 // Tracks the name, and target URL of the new window. Once the first
388 // navigation commits, we no longer track this information.
389 struct NewWindowInfo {
393 NewWindowInfo(const GURL& url, const std::string& name) :
399 typedef std::map<WebViewGuest*, NewWindowInfo> PendingWindowMap;
400 PendingWindowMap pending_new_windows_;
402 DISALLOW_COPY_AND_ASSIGN(WebViewGuest);
405 } // namespace extensions
407 #endif // CHROME_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_