1 // Copyright 2013 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 IOS_WEB_PUBLIC_WEB_STATE_H_ 6 #define IOS_WEB_PUBLIC_WEB_STATE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 16 #include "base/callback_forward.h" 17 #include "base/callback_list.h" 18 #include "base/memory/weak_ptr.h" 19 #include "base/strings/string_piece.h" 20 #include "base/supports_user_data.h" 21 #include "ios/web/public/deprecated/url_verification_constants.h" 22 #include "ios/web/public/navigation/referrer.h" 23 #include "mojo/public/cpp/bindings/generic_pending_receiver.h" 24 #include "mojo/public/cpp/system/message_pipe.h" 25 #include "ui/base/page_transition_types.h" 26 #include "ui/base/window_open_disposition.h" 27 #include "url/gurl.h" 28 29 class GURL; 30 31 @class CRWJSInjectionReceiver; 32 @class CRWSessionStorage; 33 @protocol CRWScrollableContent; 34 @protocol CRWWebViewProxy; 35 typedef id<CRWWebViewProxy> CRWWebViewProxyType; 36 @class UIView; 37 typedef UIView<CRWScrollableContent> CRWContentView; 38 39 namespace base { 40 class DictionaryValue; 41 class Value; 42 } 43 44 namespace gfx { 45 class Image; 46 class RectF; 47 } 48 49 namespace web { 50 51 class BrowserState; 52 class NavigationManager; 53 class SessionCertificatePolicyCache; 54 class WebFrame; 55 class WebFramesManager; 56 class WebInterstitial; 57 class WebStateDelegate; 58 class WebStateObserver; 59 class WebStatePolicyDecider; 60 61 // Core interface for interaction with the web. 62 class WebState : public base::SupportsUserData { 63 public: 64 // Parameters for the Create() method. 65 struct CreateParams { 66 explicit CreateParams(web::BrowserState* browser_state); 67 ~CreateParams(); 68 69 // The corresponding BrowserState for the new WebState. 70 web::BrowserState* browser_state; 71 72 // Whether the WebState is created as the result of a window.open or by 73 // clicking a link with a blank target. Used to determine whether the 74 // WebState is allowed to be closed via window.close(). 75 bool created_with_opener; 76 }; 77 78 // Parameters for the OpenURL() method. 79 struct OpenURLParams { 80 OpenURLParams(const GURL& url, 81 const GURL& virtual_url, 82 const Referrer& referrer, 83 WindowOpenDisposition disposition, 84 ui::PageTransition transition, 85 bool is_renderer_initiated); 86 OpenURLParams(const GURL& url, 87 const Referrer& referrer, 88 WindowOpenDisposition disposition, 89 ui::PageTransition transition, 90 bool is_renderer_initiated); 91 OpenURLParams(const OpenURLParams& params); 92 ~OpenURLParams(); 93 94 // The URL/virtualURL/referrer to be opened. 95 GURL url; 96 GURL virtual_url; 97 Referrer referrer; 98 99 // The disposition requested by the navigation source. 100 WindowOpenDisposition disposition; 101 102 // The transition type of navigation. 103 ui::PageTransition transition; 104 105 // Whether this navigation is initiated by the renderer process. 106 bool is_renderer_initiated; 107 }; 108 109 // InterfaceBinder can be instantiated by subclasses of WebState and returned 110 // by GetInterfaceBinderForMainFrame(). 111 class InterfaceBinder { 112 public: 113 explicit InterfaceBinder(WebState* web_state); 114 ~InterfaceBinder(); 115 116 template <typename Interface> AddInterface(base::RepeatingCallback<void (mojo::PendingReceiver<Interface>)> callback)117 void AddInterface( 118 base::RepeatingCallback<void(mojo::PendingReceiver<Interface>)> 119 callback) { 120 AddInterface( 121 Interface::Name_, 122 base::BindRepeating(&WrapCallback<Interface>, std::move(callback))); 123 } 124 125 // Adds a callback to bind an interface receiver pipe carried by a 126 // GenericPendingReceiver. 127 using Callback = 128 base::RepeatingCallback<void(mojo::GenericPendingReceiver*)>; 129 void AddInterface(base::StringPiece interface_name, Callback callback); 130 131 // Attempts to bind |receiver| by matching its interface name against the 132 // callbacks registered on this InterfaceBinder. 133 void BindInterface(mojo::GenericPendingReceiver receiver); 134 135 private: 136 template <typename Interface> WrapCallback(base::RepeatingCallback<void (mojo::PendingReceiver<Interface>)> callback,mojo::GenericPendingReceiver * receiver)137 static void WrapCallback( 138 base::RepeatingCallback<void(mojo::PendingReceiver<Interface>)> 139 callback, 140 mojo::GenericPendingReceiver* receiver) { 141 if (auto typed_receiver = receiver->As<Interface>()) 142 callback.Run(std::move(typed_receiver)); 143 } 144 145 WebState* const web_state_; 146 std::map<std::string, Callback> callbacks_; 147 148 DISALLOW_COPY_AND_ASSIGN(InterfaceBinder); 149 }; 150 151 // Creates a new WebState. 152 static std::unique_ptr<WebState> Create(const CreateParams& params); 153 154 // Creates a new WebState from a serialized representation of the session. 155 // |session_storage| must not be nil. 156 static std::unique_ptr<WebState> CreateWithStorageSession( 157 const CreateParams& params, 158 CRWSessionStorage* session_storage); 159 ~WebState()160 ~WebState() override {} 161 162 // A callback that returns a pointer to a WebState. The callback can always be 163 // used, but it may return nullptr if the info used to instantiate the 164 // callback can no longer be used to return a WebState. 165 using Getter = base::RepeatingCallback<WebState*(void)>; 166 // Use this variant for instances that will only run the callback a single 167 // time. 168 using OnceGetter = base::OnceCallback<WebState*(void)>; 169 170 // Creates default WebState getters that return this WebState, or nullptr if 171 // the WebState has been deallocated. 172 virtual Getter CreateDefaultGetter() = 0; 173 virtual OnceGetter CreateDefaultOnceGetter() = 0; 174 175 // Gets/Sets the delegate. 176 virtual WebStateDelegate* GetDelegate() = 0; 177 virtual void SetDelegate(WebStateDelegate* delegate) = 0; 178 179 // Whether or not a web view is allowed to exist in this WebState. Defaults 180 // to false; this should be enabled before attempting to access the view. 181 virtual bool IsWebUsageEnabled() const = 0; 182 virtual void SetWebUsageEnabled(bool enabled) = 0; 183 184 // The view containing the contents of the current web page. If the view has 185 // been purged due to low memory, this will recreate it. It is up to the 186 // caller to size the view. 187 virtual UIView* GetView() = 0; 188 189 // Notifies the WebState that the WebContent is covered. Triggers 190 // visibilitychange event. 191 virtual void DidCoverWebContent() = 0; 192 // Notifies the WebState that the WebContent is no longer covered. Triggers 193 // visibilitychange event. 194 virtual void DidRevealWebContent() = 0; 195 196 // Must be called when the WebState becomes shown/hidden. 197 virtual void WasShown() = 0; 198 virtual void WasHidden() = 0; 199 200 // When |true|, attempt to prevent the WebProcess from suspending. Embedder 201 // must override WebClient::GetWindowedContainer to maintain this 202 // functionality. 203 virtual void SetKeepRenderProcessAlive(bool keep_alive) = 0; 204 205 // Gets the BrowserState associated with this WebState. Can never return null. 206 virtual BrowserState* GetBrowserState() const = 0; 207 208 // Opens a URL with the given disposition. The transition specifies how this 209 // navigation should be recorded in the history system (for example, typed). 210 virtual void OpenURL(const OpenURLParams& params) = 0; 211 212 // Stops any pending navigation. 213 virtual void Stop() = 0; 214 215 // Gets the NavigationManager associated with this WebState. Can never return 216 // null. 217 virtual const NavigationManager* GetNavigationManager() const = 0; 218 virtual NavigationManager* GetNavigationManager() = 0; 219 220 // Gets the WebFramesManager associated with this WebState. Can never return 221 // null. 222 virtual const WebFramesManager* GetWebFramesManager() const = 0; 223 virtual WebFramesManager* GetWebFramesManager() = 0; 224 225 // Gets the SessionCertificatePolicyCache for this WebState. Can never return 226 // null. 227 virtual const SessionCertificatePolicyCache* 228 GetSessionCertificatePolicyCache() const = 0; 229 virtual SessionCertificatePolicyCache* GetSessionCertificatePolicyCache() = 0; 230 231 // Creates a serializable representation of the session. The returned value 232 // is autoreleased. 233 virtual CRWSessionStorage* BuildSessionStorage() = 0; 234 235 // Gets the CRWJSInjectionReceiver associated with this WebState. 236 virtual CRWJSInjectionReceiver* GetJSInjectionReceiver() const = 0; 237 238 // Loads |data| of type |mime_type| and replaces last committed URL with the 239 // given |url|. 240 virtual void LoadData(NSData* data, NSString* mime_type, const GURL& url) = 0; 241 242 // DISCOURAGED. Prefer using |WebFrame CallJavaScriptFunction| instead because 243 // it restricts JavaScript execution to functions within __gCrWeb and can also 244 // call those functions on any frame in the page. ExecuteJavaScript here can 245 // execute arbitrary JavaScript code, which is not as safe and is restricted 246 // to executing only on the main frame. 247 // Runs JavaScript in the main frame's context. If a callback is provided, it 248 // will be used to return the result, when the result is available or script 249 // execution has failed due to an error. 250 // NOTE: Integer values will be returned as Type::DOUBLE because of underlying 251 // library limitation. 252 typedef base::OnceCallback<void(const base::Value*)> JavaScriptResultCallback; 253 virtual void ExecuteJavaScript(const base::string16& javascript) = 0; 254 virtual void ExecuteJavaScript(const base::string16& javascript, 255 JavaScriptResultCallback callback) = 0; 256 257 // Asynchronously executes |javaScript| in the main frame's context, 258 // registering user interaction. 259 virtual void ExecuteUserJavaScript(NSString* javaScript) = 0; 260 261 // Gets the contents MIME type. 262 virtual const std::string& GetContentsMimeType() const = 0; 263 264 // Returns true if the current page is a web view with HTML. 265 virtual bool ContentIsHTML() const = 0; 266 267 // Returns the current navigation title. This could be the title of the page 268 // if it is available or the URL. 269 virtual const base::string16& GetTitle() const = 0; 270 271 // Returns true if the current page is loading. 272 virtual bool IsLoading() const = 0; 273 274 // The fraction of the page load that has completed as a number between 0.0 275 // (nothing loaded) and 1.0 (fully loaded). 276 virtual double GetLoadingProgress() const = 0; 277 278 // Whether the WebState is visible. Returns true after WasShown() call and 279 // false after WasHidden() call. 280 virtual bool IsVisible() const = 0; 281 282 // Returns true if the web process backing this WebState is believed to 283 // currently be crashed. 284 virtual bool IsCrashed() const = 0; 285 286 // Returns true if the web process backing this WebState is believed to 287 // currently be crashed or was evicted (by calling SetWebUsageEnabled 288 // with false). 289 // TODO(crbug.com/619971): Remove once all code has been ported to use 290 // IsCrashed() instead of IsEvicted(). 291 virtual bool IsEvicted() const = 0; 292 293 // Whether this instance is in the process of being destroyed. 294 virtual bool IsBeingDestroyed() const = 0; 295 296 // Gets the URL currently being displayed in the URL bar, if there is one. 297 // This URL might be a pending navigation that hasn't committed yet, so it is 298 // not guaranteed to match the current page in this WebState. A typical 299 // example of this is interstitials, which show the URL of the new/loading 300 // page (active) but the security context is of the old page (last committed). 301 virtual const GURL& GetVisibleURL() const = 0; 302 303 // Gets the last committed URL. It represents the current page that is 304 // displayed in this WebState. It represents the current security context. 305 virtual const GURL& GetLastCommittedURL() const = 0; 306 307 // Returns the WebState view of the current URL. Moreover, this method 308 // will set the trustLevel enum to the appropriate level from a security point 309 // of view. The caller has to handle the case where |trust_level| is not 310 // appropriate. Passing |null| will skip the trust check. 311 // TODO(crbug.com/457679): Figure out a clean API for this. 312 virtual GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const = 0; 313 314 // Returns true if a WebInterstitial is currently displayed. 315 virtual bool IsShowingWebInterstitial() const = 0; 316 317 // Returns the currently visible WebInterstitial if one is shown. 318 virtual WebInterstitial* GetWebInterstitial() const = 0; 319 320 // Callback used to handle script commands. |message| is the JS message sent 321 // from the |sender_frame| in the page, |page_url| is the URL of page's main 322 // frame, |user_is_interacting| indicates if the user is interacting with the 323 // page. 324 // TODO(crbug.com/881813): remove |page_url|. 325 using ScriptCommandCallbackSignature = 326 void(const base::DictionaryValue& message, 327 const GURL& page_url, 328 bool user_is_interacting, 329 web::WebFrame* sender_frame); 330 using ScriptCommandCallback = 331 base::RepeatingCallback<ScriptCommandCallbackSignature>; 332 using ScriptCommandSubscription = 333 base::RepeatingCallbackList<ScriptCommandCallbackSignature>::Subscription; 334 // Registers |callback| for JS message whose 'command' matches 335 // |command_prefix|. The returned ScriptCommandSubscription should be stored 336 // by the caller. When the description object is destroyed, it will unregister 337 // |callback| if this WebState is still alive, and do nothing if this WebState 338 // is already destroyed. Therefore if the caller want to stop receiving JS 339 // messages it can just destroy the subscription object. 340 virtual std::unique_ptr<ScriptCommandSubscription> AddScriptCommandCallback( 341 const ScriptCommandCallback& callback, 342 const std::string& command_prefix) WARN_UNUSED_RESULT = 0; 343 344 // Returns the current CRWWebViewProxy object. 345 virtual CRWWebViewProxyType GetWebViewProxy() const = 0; 346 347 // Typically an embedder will: 348 // - Implement this method to receive notification of changes to the page's 349 // |VisibleSecurityState|, updating security UI (e.g. a lock icon) to 350 // reflect the current security state of the page. 351 // ...and optionally: 352 // - Invoke this method upon detection of an event that will change 353 // the security state (e.g. a non-secure form element is edited). 354 virtual void DidChangeVisibleSecurityState() = 0; 355 356 virtual InterfaceBinder* GetInterfaceBinderForMainFrame(); 357 358 // Whether this WebState was created with an opener. 359 // See CreateParams::created_with_opener for more details. 360 virtual bool HasOpener() const = 0; 361 virtual void SetHasOpener(bool has_opener) = 0; 362 363 // Callback used to handle snapshots. The parameter is the snapshot image. 364 typedef base::RepeatingCallback<void(const gfx::Image&)> SnapshotCallback; 365 366 // Returns whether TakeSnapshot() can be executed. The API may be disabled if 367 // the WKWebView IPC mechanism is blocked due to an outstanding JavaScript 368 // dialog. 369 virtual bool CanTakeSnapshot() const = 0; 370 371 // Takes a snapshot of this WebState with |rect|. |rect| should be specified 372 // in the coordinate system of the view returned by GetView(). |callback| is 373 // asynchronously invoked after performing the snapshot. Prior to iOS 11, the 374 // callback is invoked with a nil snapshot. 375 virtual void TakeSnapshot(const gfx::RectF& rect, 376 SnapshotCallback callback) = 0; 377 378 // Creates PDF representation of the web page and invokes the |callback| with 379 // the NSData of the PDF or nil if a PDF couldn't be generated. 380 virtual void CreateFullPagePdf( 381 base::OnceCallback<void(NSData*)> callback) = 0; 382 383 // Adds and removes observers for page navigation notifications. The order in 384 // which notifications are sent to observers is undefined. Clients must be 385 // sure to remove the observer before they go away. 386 virtual void AddObserver(WebStateObserver* observer) = 0; 387 virtual void RemoveObserver(WebStateObserver* observer) = 0; 388 389 // Instructs the delegate to close this web state. Called when the page calls 390 // wants to close self by calling window.close() JavaScript API. 391 virtual void CloseWebState() = 0; 392 393 protected: 394 friend class WebStatePolicyDecider; 395 396 // Adds and removes policy deciders for navigation actions. The order in which 397 // deciders are called is undefined, and will stop on the first decider that 398 // refuses a navigation. Clients must be sure to remove the deciders before 399 // they go away. 400 virtual void AddPolicyDecider(WebStatePolicyDecider* decider) = 0; 401 virtual void RemovePolicyDecider(WebStatePolicyDecider* decider) = 0; 402 WebState()403 WebState() {} 404 405 private: 406 DISALLOW_COPY_AND_ASSIGN(WebState); 407 }; 408 409 } // namespace web 410 411 #endif // IOS_WEB_PUBLIC_WEB_STATE_H_ 412