Web.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. // Copyright (c) 2024 Vuplex Inc. All rights reserved.
  2. //
  3. // Licensed under the Vuplex Commercial Software Library License, you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // https://vuplex.com/commercial-library-license
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. using System;
  15. using System.Threading.Tasks;
  16. using UnityEngine;
  17. using Vuplex.WebView.Internal;
  18. namespace Vuplex.WebView {
  19. /// <summary>
  20. /// The Web static class contains APIs that globally impact the behavior of all IWebView instances, such as configuration options
  21. /// and global actions. It also contains the CreateWebView() method for creating an IWebView directly.
  22. /// </summary>
  23. /// <remarks>
  24. /// The Web class's APIs cannot be used before Awake() is first called for the app. Attempting to use a Web API prior to Awake() will
  25. /// result in an InvalidOperationException.
  26. /// </remarks>
  27. /// <seealso cref="WebViewPrefab"/>
  28. /// <seealso cref="CanvasWebViewPrefab"/>
  29. /// <seealso cref="IWebView"/>
  30. public static class Web {
  31. /// <summary>
  32. /// Returns the ICookieManager for managing HTTP cookies, or `null` if ICookieManager
  33. /// isn't supported on the current platform.
  34. /// </summary>
  35. /// <remarks>
  36. /// ICookieManager is supported by all of the 3D WebView packages except for:
  37. /// - 3D WebView for Android with Gecko Engine
  38. /// - 2D WebView for WebGL
  39. /// </remarks>
  40. public static ICookieManager CookieManager {
  41. get => _pluginFactory.GetDefaultPlugin().CookieManager;
  42. }
  43. /// <summary>
  44. /// Gets the default 3D WebView plugin type among those
  45. /// installed for the current platform.
  46. /// </summary>
  47. public static WebPluginType DefaultPluginType {
  48. get => _pluginFactory.GetDefaultPlugin().Type;
  49. }
  50. /// <summary>
  51. /// Clears all data that persists between webview instances,
  52. /// including cookies, storage, and cached resources.
  53. /// </summary>
  54. /// <example>
  55. /// <code>
  56. /// void Awake() {
  57. /// Web.ClearAllData();
  58. /// }
  59. /// </code>
  60. /// </example>
  61. /// <remarks>
  62. /// Important notes:
  63. /// <list type="bullet">
  64. /// <item>On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().</item>
  65. /// <item>On Universal Windows Platform, this method is unable to clear cookies due to a UWP limitation.</item>
  66. /// </list>
  67. /// </remarks>
  68. /// <seealso cref="StandaloneWebView.DeleteAllCookies"/>
  69. public static void ClearAllData() {
  70. _pluginFactory.GetAllPlugins().ForEach(p => p.ClearAllData());
  71. }
  72. /// <summary>
  73. /// Creates a new webview in a platform-agnostic way. After a webview
  74. /// is created, it must be initialized by calling its Init() method.
  75. /// </summary>
  76. /// <remarks>
  77. /// Note that WebViewPrefab takes care of creating and managing
  78. /// an IWebView instance for you, so you only need to call this method directly
  79. /// if you need to create an IWebView instance outside of a prefab
  80. /// (for example, to connect it to your own custom GameObject).
  81. /// </remarks>
  82. /// <example>
  83. /// <code>
  84. /// var webView = Web.CreateWebView();
  85. /// // Initialize the webview to 600px x 300px.
  86. /// await webView.Init(600, 300);
  87. /// webView.LoadUrl("https://vuplex.com");
  88. /// // Set the Material attached to this GameObject to display the webview.
  89. /// GetComponent&lt;Renderer&gt;().material = webView.CreateMaterial();
  90. /// </code>
  91. /// </example>
  92. public static IWebView CreateWebView() {
  93. return _pluginFactory.GetDefaultPlugin().CreateWebView();
  94. }
  95. /// <summary>
  96. /// Like CreateWebView(), except an array of preferred plugin types can be
  97. /// provided to override which 3D WebView plugin is used in the case where
  98. /// multiple plugins are installed for the same build platform.
  99. /// </summary>
  100. /// <remarks>
  101. /// Currently, Android is the only platform that supports multiple 3D WebView
  102. /// plugins: WebPluginType.Android and WebPluginType.AndroidGecko. If both
  103. /// plugins are installed in the same project, WebPluginType.AndroidGecko will be used by default.
  104. /// However, you can override this to force WebPluginType.Android to be used instead by passing
  105. /// `new WebPluginType[] { WebPluginType.Android }`.
  106. /// </remarks>
  107. public static IWebView CreateWebView(WebPluginType[] preferredPlugins) {
  108. return _pluginFactory.GetDefaultPlugin(preferredPlugins).CreateWebView();
  109. }
  110. /// <summary>
  111. /// Enables [remote debugging](https://support.vuplex.com/articles/how-to-debug-web-content).
  112. /// </summary>
  113. /// <remarks>
  114. /// On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().
  115. /// </remarks>
  116. /// <example>
  117. /// <code>
  118. /// void Awake() {
  119. /// Web.EnableRemoteDebugging();
  120. /// }
  121. /// </code>
  122. /// </example>
  123. public static void EnableRemoteDebugging() {
  124. _pluginFactory.GetAllPlugins().ForEach(p => p.EnableRemoteDebugging());
  125. }
  126. /// <summary>
  127. /// By default, browsers block sites from autoplaying video with audio,
  128. /// but this method can be used to enable autoplay.
  129. /// </summary>
  130. /// <example>
  131. /// <code>
  132. /// void Awake() {
  133. /// Web.SetAutoplayEnabled(true);
  134. /// }
  135. /// </code>
  136. /// </example>
  137. /// <remarks>
  138. /// Important notes:
  139. /// <list type="bullet">
  140. /// <item>
  141. /// On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().
  142. /// </item>
  143. /// <item>
  144. /// This method works for every package except for 3D WebView for UWP,
  145. /// because the underlying UWP WebView control doesn't allow autoplaying
  146. /// video with audio.
  147. /// </item>
  148. /// </list>
  149. /// </remarks>
  150. public static void SetAutoplayEnabled(bool enabled) {
  151. _pluginFactory.GetAllPlugins().ForEach(p => p.SetAutoplayEnabled(enabled));
  152. }
  153. /// <summary>
  154. /// By default, web pages cannot access the device's
  155. /// camera or microphone via JavaScript, but this method can
  156. /// be used to grant **all web pages** access to the camera and microphone.
  157. /// This is useful, for example, to enable WebRTC support. Note that on
  158. /// macOS, Android, iOS, and UWP, [additional project configuration is needed in order to enable
  159. /// permission for the camera and microphone](https://support.vuplex.com/articles/webrtc).
  160. /// Camera and microphone permissions are enabled together with a single method because on some platforms (Windows, macOS, UWP),
  161. /// these permissions can only be enabled together and cannot be enabled separately.
  162. /// </summary>
  163. /// <remarks>
  164. /// Important notes:
  165. /// <list type="bullet">
  166. /// <item>
  167. /// On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().
  168. /// </item>
  169. /// <item>
  170. /// On iOS, enabling the camera and microphone is only supported in iOS 14.3 or newer
  171. /// and is only supported in Native 2D Mode.
  172. /// </item>
  173. /// </list>
  174. /// </remarks>
  175. /// <example>
  176. /// <code>
  177. /// void Awake() {
  178. /// Web.SetCameraAndMicrophoneEnabled(true);
  179. /// }
  180. /// </code>
  181. /// </example>
  182. public static void SetCameraAndMicrophoneEnabled(bool enabled) {
  183. _pluginFactory.GetAllPlugins().ForEach(p => p.SetCameraAndMicrophoneEnabled(enabled));
  184. }
  185. /// <summary>
  186. /// By default, browsers block https URLs with invalid SSL certificates
  187. /// from being loaded, but this method can be used to disable those
  188. /// certificate errors.
  189. /// </summary>
  190. /// <example>
  191. /// <code>
  192. /// void Awake() {
  193. /// Web.SetIgnoreCertificateErrors(true);
  194. /// }
  195. /// </code>
  196. /// </example>
  197. /// <remarks>
  198. /// Important notes:
  199. /// <list type="bullet">
  200. /// <item>
  201. /// On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().
  202. /// </item>
  203. /// <item>
  204. /// This method works for every package except for 3D WebView for UWP.
  205. /// For UWP, certificates must be [whitelisted in the Package.appxmanifest file](https://www.suchan.cz/2015/10/displaying-https-page-with-invalid-certificate-in-uwp-webview/).
  206. /// </item>
  207. /// </list>
  208. /// </remarks>
  209. public static void SetIgnoreCertificateErrors(bool ignore) {
  210. _pluginFactory.GetAllPlugins().ForEach(p => p.SetIgnoreCertificateErrors(ignore));
  211. }
  212. /// <summary>
  213. /// Controls whether data like cookies, localStorage, and cached resources
  214. /// is persisted between webview instances. The default is `true`, but this
  215. /// can be set to `false` to achieve an "incognito mode".
  216. /// </summary>
  217. /// <remarks>
  218. /// On Windows and macOS, this method cannot be executed while the Chromium browser process is running. So, you will likely need to call it from Awake() to ensure that it's executed before Chromium is started. Alternatively, you can manually terminate Chromium prior to calling this method using StandaloneWebView.TerminateBrowserProcess().
  219. /// </remarks>
  220. /// <example>
  221. /// <code>
  222. /// void Awake() {
  223. /// Web.SetStorageEnabled(false);
  224. /// }
  225. /// </code>
  226. /// </example>
  227. public static void SetStorageEnabled(bool enabled) {
  228. _pluginFactory.GetAllPlugins().ForEach(p => p.SetStorageEnabled(enabled));
  229. }
  230. /// <summary>
  231. /// Globally configures all webviews to use a mobile or desktop
  232. /// [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).
  233. /// By default, webviews use the browser engine's default User-Agent, but you
  234. /// can force them to use a mobile User-Agent by calling `Web.SetUserAgent(true)` or a
  235. /// desktop User-Agent with `Web.SetUserAgent(false)`.
  236. /// </summary>
  237. /// <example>
  238. /// <code>
  239. /// void Awake() {
  240. /// // Use a desktop User-Agent.
  241. /// Web.SetUserAgent(false);
  242. /// }
  243. /// </code>
  244. /// </example>
  245. /// <seealso cref="IWithSettableUserAgent"/>
  246. public static void SetUserAgent(bool mobile) {
  247. _pluginFactory.GetAllPlugins().ForEach(p => p.SetUserAgent(mobile));
  248. }
  249. /// <summary>
  250. /// Globally configures all webviews to use a custom
  251. /// [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent).
  252. /// </summary>
  253. /// <example>
  254. /// <code>
  255. /// void Awake() {
  256. /// // Use FireFox's User-Agent.
  257. /// Web.SetUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:91.0) Gecko/20100101 Firefox/91.0");
  258. /// }
  259. /// </code>
  260. /// </example>
  261. /// <seealso cref="IWithSettableUserAgent"/>
  262. public static void SetUserAgent(string userAgent) {
  263. _pluginFactory.GetAllPlugins().ForEach(p => p.SetUserAgent(userAgent));
  264. }
  265. static internal void SetPluginFactory(WebPluginFactory pluginFactory) => _pluginFactory = pluginFactory;
  266. static WebPluginFactory _pluginFactory = new WebPluginFactory();
  267. #region Obsolete APIs
  268. const string CreateMaterialMessage = "Web.CreateMaterial() is now deprecated in v4. Please use IWebView.CreateMaterial() instead: https://developer.vuplex.com/webview/IWebView#CreateMaterial";
  269. const string CreateTextureMessage = "Web.CreateTexture() has been removed in v4 because IWebView instances now automatically create their own textures. For more details, please see this article: https://support.vuplex.com/articles/v4-changes#init";
  270. // Added in v1.0, deprecated in v3.16.
  271. [Obsolete(CreateMaterialMessage)]
  272. public static Task<Material> CreateMaterial() {
  273. var taskSource = new TaskCompletionSource<Material>();
  274. _pluginFactory.GetDefaultPlugin().CreateMaterial(taskSource.SetResult);
  275. return taskSource.Task;
  276. }
  277. // Added in v3.8, deprecated in v4.0.
  278. [Obsolete(CreateMaterialMessage)]
  279. public static void CreateMaterial(Action<Material> callback) => _pluginFactory.GetDefaultPlugin().CreateMaterial(callback);
  280. // Added in v3.10, removed in v4.0.
  281. [Obsolete(CreateTextureMessage, true)]
  282. public static Task<Texture2D> CreateTexture(int width, int height) { return null; }
  283. // Added in v1.0, deprecated in v3.16, removed in v4.0.
  284. [Obsolete(CreateTextureMessage, true)]
  285. public static void CreateTexture(float width, float height, Action<Texture2D> callback) {}
  286. // Added in v1.0, removed in v4.0.
  287. [Obsolete("Web.CreateVideoMaterial() has been removed. Please use IWithFallbackVideo.CreateVideoMaterial() instead: https://developer.vuplex.com/webview/IWithFallbackVideo#CreateVideoMaterial", true)]
  288. public static void CreateVideoMaterial(Action<Material> callback) {}
  289. // Added in v3.10, deprecated in v3.14, removed in v4.0.
  290. [Obsolete("Web.SetTouchScreenKeyboardEnabled() has been removed. Please use the NativeOnScreenKeyboardEnabled property of WebViewPrefab / CanvasWebViewPrefab or the IWithNativeOnScreenKeyboard interface instead: https://developer.vuplex.com/webview/WebViewPrefab#NativeOnScreenKeyboardEnabled", true)]
  291. public static void SetTouchScreenKeyboardEnabled(bool enabled) {}
  292. #endregion
  293. }
  294. }