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
;
27 struct GlobalRequestID
;
28 } // namespace content
30 namespace extensions
{
32 class WebViewInternalFindFunction
;
34 // A WebViewGuest provides the browser-side implementation of the <webview> API
35 // and manages the dispatch of <webview> extension events. WebViewGuest is
36 // created on attachment. That is, when a guest WebContents is associated with
37 // a particular embedder WebContents. This happens on either initial navigation
38 // or through the use of the New Window API, when a new window is attached to
39 // a particular <webview>.
40 class WebViewGuest
: public guest_view::GuestView
<WebViewGuest
>,
41 public content::NotificationObserver
{
43 // Clean up state when this GuestView is being destroyed. See
44 // GuestViewBase::CleanUp().
45 static void CleanUp(content::BrowserContext
* browser_context
,
46 int embedder_process_id
,
47 int view_instance_id
);
49 static GuestViewBase
* Create(content::WebContents
* owner_web_contents
);
51 // For WebViewGuest, we create special guest processes, which host the
52 // tag content separately from the main application that embeds the tag.
53 // A <webview> can specify both the partition name and whether the storage
54 // for that partition should be persisted. Each tag gets a SiteInstance with
55 // a specially formatted URL, based on the application it is hosted by and
56 // the partition requested by it. The format for that URL is:
57 // chrome-guest://partition_domain/persist?partition_name
58 static bool GetGuestPartitionConfigForSite(const GURL
& site
,
59 std::string
* partition_domain
,
60 std::string
* partition_name
,
63 static const char Type
[];
65 // Returns the stored rules registry ID of the given webview. Will generate
66 // an ID for the first query.
67 static int GetOrGenerateRulesRegistryID(
68 int embedder_process_id
,
69 int web_view_instance_id
);
71 // Get the current zoom.
72 double GetZoom() const;
74 // Get the current zoom mode.
75 ui_zoom::ZoomController::ZoomMode
GetZoomMode();
77 // Request navigating the guest to the provided |src| URL.
78 void NavigateGuest(const std::string
& src
, bool force_navigation
);
80 // Shows the context menu for the guest.
81 // |items| acts as a filter. This restricts the current context's default
82 // menu items to contain only the items from |items|.
83 // |items| == NULL means no filtering will be applied.
86 const WebViewGuestDelegate::MenuItemVector
* items
);
88 // Sets the frame name of the guest.
89 void SetName(const std::string
& name
);
90 const std::string
& name() { return name_
; }
92 // Set the zoom factor.
93 void SetZoom(double zoom_factor
);
96 void SetZoomMode(ui_zoom::ZoomController::ZoomMode zoom_mode
);
98 void SetAllowScaling(bool allow
);
99 bool allow_scaling() const { return allow_scaling_
; }
101 // Sets the transparency of the guest.
102 void SetAllowTransparency(bool allow
);
103 bool allow_transparency() const { return allow_transparency_
; }
105 // Loads a data URL with a specified base URL and virtual URL.
106 bool LoadDataWithBaseURL(const std::string
& data_url
,
107 const std::string
& base_url
,
108 const std::string
& virtual_url
,
111 // GuestViewBase implementation.
112 bool CanRunInDetachedState() const override
;
113 void CreateWebContents(const base::DictionaryValue
& create_params
,
114 const WebContentsCreatedCallback
& callback
) override
;
115 void DidAttachToEmbedder() override
;
116 void DidDropLink(const GURL
& url
) override
;
117 void DidInitialize(const base::DictionaryValue
& create_params
) override
;
118 void GuestViewDidStopLoading() override
;
119 void EmbedderFullscreenToggled(bool entered_fullscreen
) override
;
120 const char* GetAPINamespace() const override
;
121 int GetTaskPrefix() const override
;
122 void GuestDestroyed() override
;
123 void GuestReady() override
;
124 void GuestSizeChangedDueToAutoSize(const gfx::Size
& old_size
,
125 const gfx::Size
& new_size
) override
;
126 void GuestZoomChanged(double old_zoom_level
, double new_zoom_level
) override
;
127 bool IsAutoSizeSupported() const override
;
128 void SignalWhenReady(const base::Closure
& callback
) override
;
129 void WillAttachToEmbedder() override
;
130 void WillDestroy() override
;
132 // WebContentsDelegate implementation.
133 bool AddMessageToConsole(content::WebContents
* source
,
135 const base::string16
& message
,
137 const base::string16
& source_id
) override
;
138 void LoadProgressChanged(content::WebContents
* source
,
139 double progress
) override
;
140 void CloseContents(content::WebContents
* source
) override
;
141 void FindReply(content::WebContents
* source
,
143 int number_of_matches
,
144 const gfx::Rect
& selection_rect
,
145 int active_match_ordinal
,
146 bool final_update
) override
;
147 bool HandleContextMenu(const content::ContextMenuParams
& params
) override
;
148 void HandleKeyboardEvent(
149 content::WebContents
* source
,
150 const content::NativeWebKeyboardEvent
& event
) override
;
151 bool PreHandleGestureEvent(content::WebContents
* source
,
152 const blink::WebGestureEvent
& event
) override
;
153 void RendererResponsive(content::WebContents
* source
) override
;
154 void RendererUnresponsive(content::WebContents
* source
) override
;
155 void RequestMediaAccessPermission(
156 content::WebContents
* source
,
157 const content::MediaStreamRequest
& request
,
158 const content::MediaResponseCallback
& callback
) override
;
159 void RequestPointerLockPermission(
161 bool last_unlocked_by_target
,
162 const base::Callback
<void(bool)>& callback
) override
;
163 bool CheckMediaAccessPermission(content::WebContents
* source
,
164 const GURL
& security_origin
,
165 content::MediaStreamType type
) override
;
166 void CanDownload(const GURL
& url
,
167 const std::string
& request_method
,
168 const base::Callback
<void(bool)>& callback
) override
;
169 content::JavaScriptDialogManager
* GetJavaScriptDialogManager(
170 content::WebContents
* source
) override
;
171 void AddNewContents(content::WebContents
* source
,
172 content::WebContents
* new_contents
,
173 WindowOpenDisposition disposition
,
174 const gfx::Rect
& initial_rect
,
176 bool* was_blocked
) override
;
177 content::WebContents
* OpenURLFromTab(
178 content::WebContents
* source
,
179 const content::OpenURLParams
& params
) override
;
180 void WebContentsCreated(content::WebContents
* source_contents
,
181 int opener_render_frame_id
,
182 const std::string
& frame_name
,
183 const GURL
& target_url
,
184 content::WebContents
* new_contents
) override
;
185 void EnterFullscreenModeForTab(content::WebContents
* web_contents
,
186 const GURL
& origin
) override
;
187 void ExitFullscreenModeForTab(content::WebContents
* web_contents
) override
;
188 bool IsFullscreenForTabOrPending(
189 const content::WebContents
* web_contents
) const override
;
191 // NotificationObserver implementation.
192 void Observe(int type
,
193 const content::NotificationSource
& source
,
194 const content::NotificationDetails
& details
) override
;
196 // Begin or continue a find request.
197 void StartFindInternal(
198 const base::string16
& search_text
,
199 const blink::WebFindOptions
& options
,
200 scoped_refptr
<WebViewInternalFindFunction
> find_function
);
202 // Conclude a find request to clear highlighting.
203 void StopFindingInternal(content::StopFindAction
);
205 // If possible, navigate the guest to |relative_index| entries away from the
206 // current navigation entry. Returns true on success.
207 bool Go(int relative_index
);
212 using PermissionResponseCallback
=
213 base::Callback
<void(bool /* allow */,
214 const std::string
& /* user_input */)>;
215 int RequestPermission(
216 WebViewPermissionType permission_type
,
217 const base::DictionaryValue
& request_info
,
218 const PermissionResponseCallback
& callback
,
219 bool allowed_by_default
);
221 // Requests Geolocation Permission from the embedder.
222 void RequestGeolocationPermission(int bridge_id
,
223 const GURL
& requesting_frame
,
225 const base::Callback
<void(bool)>& callback
);
226 void CancelGeolocationPermissionRequest(int bridge_id
);
228 // Called when file system access is requested by the guest content using the
229 // HTML5 file system API in main thread, or a worker thread.
230 // The request is plumbed through the <webview> permission request API. The
232 // - Allowed if the embedder explicitly allowed it.
233 // - Denied if the embedder explicitly denied.
234 // - Determined by the guest's content settings if the embedder does not
235 // perform an explicit action.
236 void RequestFileSystemPermission(const GURL
& url
,
237 bool allowed_by_default
,
238 const base::Callback
<void(bool)>& callback
);
240 // Overrides the user agent for this guest.
241 // This affects subsequent guest navigations.
242 void SetUserAgentOverride(const std::string
& user_agent_override
);
244 // Stop loading the guest.
247 // Kill the guest process.
250 // Clears data in the storage partition of this guest.
252 // Partition data that are newer than |removal_since| will be removed.
253 // |removal_mask| corresponds to bitmask in StoragePartition::RemoveDataMask.
254 bool ClearData(const base::Time remove_since
,
256 const base::Closure
& callback
);
258 ScriptExecutor
* script_executor() { return script_executor_
.get(); }
260 scoped_ptr
<WebViewGuestDelegate
> SetDelegateForTesting(
261 scoped_ptr
<WebViewGuestDelegate
> delegate
) {
262 web_view_guest_delegate_
.swap(delegate
);
263 return delegate
.Pass();
267 friend class WebViewPermissionHelper
;
269 explicit WebViewGuest(content::WebContents
* owner_web_contents
);
271 ~WebViewGuest() override
;
273 void ClearDataInternal(const base::Time remove_since
,
275 const base::Closure
& callback
);
277 void OnWebViewNewWindowResponse(int new_window_instance_id
,
279 const std::string
& user_input
);
281 void OnFullscreenPermissionDecided(bool allowed
,
282 const std::string
& user_input
);
283 bool GuestMadeEmbedderFullscreen() const;
284 void SetFullscreenState(bool is_fullscreen
);
286 // WebContentsObserver implementation.
287 void DidCommitProvisionalLoadForFrame(
288 content::RenderFrameHost
* render_frame_host
,
290 ui::PageTransition transition_type
) override
;
291 void DidFailProvisionalLoad(content::RenderFrameHost
* render_frame_host
,
292 const GURL
& validated_url
,
294 const base::string16
& error_description
,
295 bool was_ignored_by_handler
) override
;
296 void DidStartProvisionalLoadForFrame(
297 content::RenderFrameHost
* render_frame_host
,
298 const GURL
& validated_url
,
300 bool is_iframe_srcdoc
) override
;
301 void RenderProcessGone(base::TerminationStatus status
) override
;
302 void UserAgentOverrideSet(const std::string
& user_agent
) override
;
303 void FrameNameChanged(content::RenderFrameHost
* render_frame_host
,
304 const std::string
& name
) override
;
306 // Informs the embedder of a frame name change.
307 void ReportFrameNameChange(const std::string
& name
);
309 // Called after the load handler is called in the guest's main frame.
310 void LoadHandlerCalled();
312 // Called when a redirect notification occurs.
313 void LoadRedirect(const GURL
& old_url
,
317 void PushWebViewStateToIOThread();
318 static void RemoveWebViewStateFromIOThread(
319 content::WebContents
* web_contents
);
321 // Loads the |url| provided. |force_navigation| indicates whether to reload
322 // the content if the provided |url| matches the current page of the guest.
323 void LoadURLWithParams(
325 const content::Referrer
& referrer
,
326 ui::PageTransition transition_type
,
327 const content::GlobalRequestID
& transferred_global_request_id
,
328 bool force_navigation
);
330 void RequestNewWindowPermission(
331 WindowOpenDisposition disposition
,
332 const gfx::Rect
& initial_bounds
,
334 content::WebContents
* new_contents
);
336 // Requests resolution of a potentially relative URL.
337 GURL
ResolveURL(const std::string
& src
);
339 // Notification that a load in the guest resulted in abort. Note that |url|
341 void LoadAbort(bool is_top_level
,
344 const std::string
& error_type
);
346 // Creates a new guest window owned by this WebViewGuest.
347 void CreateNewGuestWebViewWindow(const content::OpenURLParams
& params
);
349 void NewGuestWebViewCallback(const content::OpenURLParams
& params
,
350 content::WebContents
* guest_web_contents
);
352 bool HandleKeyboardShortcuts(const content::NativeWebKeyboardEvent
& event
);
354 void ApplyAttributes(const base::DictionaryValue
& params
);
356 // Identifies the set of rules registries belonging to this guest.
357 int rules_registry_id_
;
359 // Handles find requests and replies for the webview find API.
360 WebViewFindHelper find_helper_
;
362 base::ObserverList
<ScriptExecutionObserver
> script_observers_
;
363 scoped_ptr
<ScriptExecutor
> script_executor_
;
365 content::NotificationRegistrar notification_registrar_
;
367 // True if the user agent is overridden.
368 bool is_overriding_user_agent_
;
370 // Stores the window name of the main frame of the guest.
373 // Stores whether the contents of the guest can be transparent.
374 bool allow_transparency_
;
376 // Stores the src URL of the WebView.
379 // Handles the JavaScript dialog requests.
380 JavaScriptDialogHelper javascript_dialog_helper_
;
382 // Handles permission requests.
383 scoped_ptr
<WebViewPermissionHelper
> web_view_permission_helper_
;
385 scoped_ptr
<WebViewGuestDelegate
> web_view_guest_delegate_
;
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 using PendingWindowMap
= std::map
<WebViewGuest
*, NewWindowInfo
>;
400 PendingWindowMap pending_new_windows_
;
402 // Determines if this guest accepts pinch-zoom gestures.
404 bool is_guest_fullscreen_
;
405 bool is_embedder_fullscreen_
;
406 bool last_fullscreen_permission_was_allowed_by_embedder_
;
408 // Tracks whether the webview has a pending zoom from before the first
409 // navigation. This will be equal to 0 when there is no pending zoom.
410 double pending_zoom_factor_
;
412 // This is used to ensure pending tasks will not fire after this object is
414 base::WeakPtrFactory
<WebViewGuest
> weak_ptr_factory_
;
416 DISALLOW_COPY_AND_ASSIGN(WebViewGuest
);
419 } // namespace extensions
421 #endif // EXTENSIONS_BROWSER_GUEST_VIEW_WEB_VIEW_WEB_VIEW_GUEST_H_