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 EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
6 #define EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_
10 #include "base/observer_list.h"
11 #include "components/guest_view/browser/guest_view.h"
12 #include "content/public/browser/javascript_dialog_manager.h"
13 #include "content/public/browser/notification_observer.h"
14 #include "content/public/browser/notification_registrar.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"
23 struct WebFindOptions
;
26 namespace extensions
{
28 class WebViewInternalFindFunction
;
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>.
36 class WebViewGuest
: public guest_view::GuestView
<WebViewGuest
>,
37 public content::NotificationObserver
{
39 static GuestViewBase
* Create(content::WebContents
* owner_web_contents
);
41 // For WebViewGuest, we create special guest processes, which host the
42 // tag content separately from the main application that embeds the tag.
43 // A <webview> can specify both the partition name and whether the storage
44 // for that partition should be persisted. Each tag gets a SiteInstance with
45 // a specially formatted URL, based on the application it is hosted by and
46 // the partition requested by it. The format for that URL is:
47 // chrome-guest://partition_domain/persist?partition_name
48 static bool GetGuestPartitionConfigForSite(const GURL
& site
,
49 std::string
* partition_domain
,
50 std::string
* partition_name
,
53 // Returns guest_view::kInstanceIDNone if |contents| does not correspond to a
55 static int GetViewInstanceId(content::WebContents
* contents
);
57 static const char Type
[];
59 // Returns the stored rules registry ID of the given webview. Will generate
60 // an ID for the first query.
61 static int GetOrGenerateRulesRegistryID(
62 int embedder_process_id
,
63 int web_view_instance_id
);
65 // Get the current zoom.
66 double GetZoom() const;
68 // Get the current zoom mode.
69 ui_zoom::ZoomController::ZoomMode
GetZoomMode();
71 // Request navigating the guest to the provided |src| URL.
72 void NavigateGuest(const std::string
& src
, bool force_navigation
);
74 // Shows the context menu for the guest.
75 // |items| acts as a filter. This restricts the current context's default
76 // menu items to contain only the items from |items|.
77 // |items| == NULL means no filtering will be applied.
80 const WebViewGuestDelegate::MenuItemVector
* items
);
82 // Sets the frame name of the guest.
83 void SetName(const std::string
& name
);
85 // Set the zoom factor.
86 void SetZoom(double zoom_factor
);
89 void SetZoomMode(ui_zoom::ZoomController::ZoomMode zoom_mode
);
91 void SetAllowScaling(bool allow
);
92 bool allow_scaling() const { return allow_scaling_
; }
94 // Sets the transparency of the guest.
95 void SetAllowTransparency(bool allow
);
96 bool allow_transparency() const { return allow_transparency_
; }
98 // Loads a data URL with a specified base URL and virtual URL.
99 bool LoadDataWithBaseURL(const std::string
& data_url
,
100 const std::string
& base_url
,
101 const std::string
& virtual_url
,
104 // GuestViewBase implementation.
105 bool CanRunInDetachedState() const override
;
106 void CreateWebContents(const base::DictionaryValue
& create_params
,
107 const WebContentsCreatedCallback
& callback
) override
;
108 void DidAttachToEmbedder() override
;
109 void DidDropLink(const GURL
& url
) override
;
110 void DidInitialize(const base::DictionaryValue
& create_params
) override
;
111 void GuestViewDidStopLoading() override
;
112 void EmbedderFullscreenToggled(bool entered_fullscreen
) override
;
113 void EmbedderWillBeDestroyed() override
;
114 const char* GetAPINamespace() const override
;
115 int GetTaskPrefix() const override
;
116 void GuestDestroyed() override
;
117 void GuestReady() override
;
118 void GuestSizeChangedDueToAutoSize(const gfx::Size
& old_size
,
119 const gfx::Size
& new_size
) override
;
120 void GuestZoomChanged(double old_zoom_level
, double new_zoom_level
) override
;
121 bool IsAutoSizeSupported() const override
;
122 bool IsDragAndDropEnabled() const override
;
123 void SignalWhenReady(const base::Closure
& callback
) override
;
124 void WillAttachToEmbedder() override
;
125 void WillDestroy() override
;
127 // WebContentsDelegate implementation.
128 bool AddMessageToConsole(content::WebContents
* source
,
130 const base::string16
& message
,
132 const base::string16
& source_id
) override
;
133 void LoadProgressChanged(content::WebContents
* source
,
134 double progress
) override
;
135 void CloseContents(content::WebContents
* source
) override
;
136 void FindReply(content::WebContents
* source
,
138 int number_of_matches
,
139 const gfx::Rect
& selection_rect
,
140 int active_match_ordinal
,
141 bool final_update
) override
;
142 bool HandleContextMenu(const content::ContextMenuParams
& params
) override
;
143 void HandleKeyboardEvent(
144 content::WebContents
* source
,
145 const content::NativeWebKeyboardEvent
& event
) override
;
146 bool PreHandleGestureEvent(content::WebContents
* source
,
147 const blink::WebGestureEvent
& event
) override
;
148 void RendererResponsive(content::WebContents
* source
) override
;
149 void RendererUnresponsive(content::WebContents
* source
) override
;
150 void RequestMediaAccessPermission(
151 content::WebContents
* source
,
152 const content::MediaStreamRequest
& request
,
153 const content::MediaResponseCallback
& callback
) override
;
154 void RequestPointerLockPermission(
156 bool last_unlocked_by_target
,
157 const base::Callback
<void(bool)>& callback
) override
;
158 bool CheckMediaAccessPermission(content::WebContents
* source
,
159 const GURL
& security_origin
,
160 content::MediaStreamType type
) override
;
161 void CanDownload(const GURL
& url
,
162 const std::string
& request_method
,
163 const base::Callback
<void(bool)>& callback
) override
;
164 content::JavaScriptDialogManager
* GetJavaScriptDialogManager(
165 content::WebContents
* source
) override
;
166 void AddNewContents(content::WebContents
* source
,
167 content::WebContents
* new_contents
,
168 WindowOpenDisposition disposition
,
169 const gfx::Rect
& initial_rect
,
171 bool* was_blocked
) override
;
172 content::WebContents
* OpenURLFromTab(
173 content::WebContents
* source
,
174 const content::OpenURLParams
& params
) override
;
175 void WebContentsCreated(content::WebContents
* source_contents
,
176 int opener_render_frame_id
,
177 const base::string16
& frame_name
,
178 const GURL
& target_url
,
179 content::WebContents
* new_contents
) override
;
180 void EnterFullscreenModeForTab(content::WebContents
* web_contents
,
181 const GURL
& origin
) override
;
182 void ExitFullscreenModeForTab(content::WebContents
* web_contents
) override
;
183 bool IsFullscreenForTabOrPending(
184 const content::WebContents
* web_contents
) const override
;
186 // NotificationObserver implementation.
187 void Observe(int type
,
188 const content::NotificationSource
& source
,
189 const content::NotificationDetails
& details
) override
;
191 // Begin or continue a find request.
192 void StartFindInternal(
193 const base::string16
& search_text
,
194 const blink::WebFindOptions
& options
,
195 scoped_refptr
<WebViewInternalFindFunction
> find_function
);
197 // Conclude a find request to clear highlighting.
198 void StopFindingInternal(content::StopFindAction
);
200 // If possible, navigate the guest to |relative_index| entries away from the
201 // current navigation entry. Returns true on success.
202 bool Go(int relative_index
);
207 using PermissionResponseCallback
=
208 base::Callback
<void(bool /* allow */,
209 const std::string
& /* user_input */)>;
210 int RequestPermission(
211 WebViewPermissionType permission_type
,
212 const base::DictionaryValue
& request_info
,
213 const PermissionResponseCallback
& callback
,
214 bool allowed_by_default
);
216 // Requests Geolocation Permission from the embedder.
217 void RequestGeolocationPermission(int bridge_id
,
218 const GURL
& requesting_frame
,
220 const base::Callback
<void(bool)>& callback
);
221 void CancelGeolocationPermissionRequest(int bridge_id
);
223 // Called when file system access is requested by the guest content using the
224 // HTML5 file system API in main thread, or a worker thread.
225 // The request is plumbed through the <webview> permission request API. The
227 // - Allowed if the embedder explicitly allowed it.
228 // - Denied if the embedder explicitly denied.
229 // - Determined by the guest's content settings if the embedder does not
230 // perform an explicit action.
231 void RequestFileSystemPermission(const GURL
& url
,
232 bool allowed_by_default
,
233 const base::Callback
<void(bool)>& callback
);
235 // Overrides the user agent for this guest.
236 // This affects subsequent guest navigations.
237 void SetUserAgentOverride(const std::string
& user_agent_override
);
239 // Stop loading the guest.
242 // Kill the guest process.
245 // Clears data in the storage partition of this guest.
247 // Partition data that are newer than |removal_since| will be removed.
248 // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask.
249 bool ClearData(const base::Time remove_since
,
251 const base::Closure
& callback
);
253 ScriptExecutor
* script_executor() { return script_executor_
.get(); }
255 scoped_ptr
<WebViewGuestDelegate
> SetDelegateForTesting(
256 scoped_ptr
<WebViewGuestDelegate
> delegate
) {
257 web_view_guest_delegate_
.swap(delegate
);
258 return delegate
.Pass();
262 friend class WebViewPermissionHelper
;
264 explicit WebViewGuest(content::WebContents
* owner_web_contents
);
266 ~WebViewGuest() override
;
268 void AttachWebViewHelpers(content::WebContents
* contents
);
270 void ClearDataInternal(const base::Time remove_since
,
272 const base::Closure
& callback
);
274 void OnWebViewNewWindowResponse(int new_window_instance_id
,
276 const std::string
& user_input
);
278 void OnFullscreenPermissionDecided(bool allowed
,
279 const std::string
& user_input
);
280 bool GuestMadeEmbedderFullscreen() const;
281 void SetFullscreenState(bool is_fullscreen
);
283 // WebContentsObserver implementation.
284 void DidCommitProvisionalLoadForFrame(
285 content::RenderFrameHost
* render_frame_host
,
287 ui::PageTransition transition_type
) override
;
288 void DidFailProvisionalLoad(content::RenderFrameHost
* render_frame_host
,
289 const GURL
& validated_url
,
291 const base::string16
& error_description
) override
;
292 void DidStartProvisionalLoadForFrame(
293 content::RenderFrameHost
* render_frame_host
,
294 const GURL
& validated_url
,
296 bool is_iframe_srcdoc
) override
;
297 void RenderProcessGone(base::TerminationStatus status
) override
;
298 void UserAgentOverrideSet(const std::string
& user_agent
) override
;
299 void FrameNameChanged(content::RenderFrameHost
* render_frame_host
,
300 const std::string
& name
) override
;
302 // Informs the embedder of a frame name change.
303 void ReportFrameNameChange(const std::string
& name
);
305 // Called after the load handler is called in the guest's main frame.
306 void LoadHandlerCalled();
308 // Called when a redirect notification occurs.
309 void LoadRedirect(const GURL
& old_url
,
313 void PushWebViewStateToIOThread();
314 static void RemoveWebViewStateFromIOThread(
315 content::WebContents
* web_contents
);
317 // Loads the |url| provided. |force_navigation| indicates whether to reload
318 // the content if the provided |url| matches the current page of the guest.
319 void LoadURLWithParams(const GURL
& url
,
320 const content::Referrer
& referrer
,
321 ui::PageTransition transition_type
,
322 bool force_navigation
);
324 void RequestNewWindowPermission(
325 WindowOpenDisposition disposition
,
326 const gfx::Rect
& initial_bounds
,
328 content::WebContents
* new_contents
);
330 // Requests resolution of a potentially relative URL.
331 GURL
ResolveURL(const std::string
& src
);
333 // Notification that a load in the guest resulted in abort. Note that |url|
335 void LoadAbort(bool is_top_level
,
338 const std::string
& error_type
);
340 // Creates a new guest window owned by this WebViewGuest.
341 void CreateNewGuestWebViewWindow(const content::OpenURLParams
& params
);
343 void NewGuestWebViewCallback(const content::OpenURLParams
& params
,
344 content::WebContents
* guest_web_contents
);
346 bool HandleKeyboardShortcuts(const content::NativeWebKeyboardEvent
& event
);
348 void ApplyAttributes(const base::DictionaryValue
& params
);
350 // Identifies the set of rules registries belonging to this guest.
351 int rules_registry_id_
;
353 // Handles find requests and replies for the webview find API.
354 WebViewFindHelper find_helper_
;
356 ObserverList
<ScriptExecutionObserver
> script_observers_
;
357 scoped_ptr
<ScriptExecutor
> script_executor_
;
359 content::NotificationRegistrar notification_registrar_
;
361 // True if the user agent is overridden.
362 bool is_overriding_user_agent_
;
364 // Stores the window name of the main frame of the guest.
367 // Stores whether the contents of the guest can be transparent.
368 bool allow_transparency_
;
370 // Stores the src URL of the WebView.
373 // Handles the JavaScript dialog requests.
374 JavaScriptDialogHelper javascript_dialog_helper_
;
376 // Handles permission requests.
377 scoped_ptr
<WebViewPermissionHelper
> web_view_permission_helper_
;
379 scoped_ptr
<WebViewGuestDelegate
> web_view_guest_delegate_
;
381 // Tracks the name, and target URL of the new window. Once the first
382 // navigation commits, we no longer track this information.
383 struct NewWindowInfo
{
387 NewWindowInfo(const GURL
& url
, const std::string
& name
) :
393 using PendingWindowMap
= std::map
<WebViewGuest
*, NewWindowInfo
>;
394 PendingWindowMap pending_new_windows_
;
396 // Determines if this guest accepts pinch-zoom gestures.
398 bool is_guest_fullscreen_
;
399 bool is_embedder_fullscreen_
;
400 bool last_fullscreen_permission_was_allowed_by_embedder_
;
402 // Tracks whether the webview has a pending zoom from before the first
403 // navigation. This will be equal to 0 when there is no pending zoom.
404 double pending_zoom_factor_
;
406 // This is used to ensure pending tasks will not fire after this object is
408 base::WeakPtrFactory
<WebViewGuest
> weak_ptr_factory_
;
410 DISALLOW_COPY_AND_ASSIGN(WebViewGuest
);
413 } // namespace extensions
415 #endif // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_