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 22 namespace blink { 23 struct WebFindOptions; 24 } // nanespace blink 25 26 namespace extensions { 27 28 class 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>. 36 class 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