AndroidWebPlugin.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /**
  2. * Copyright (c) 2021 Vuplex Inc. All rights reserved.
  3. *
  4. * Licensed under the Vuplex Commercial Software Library License, you may
  5. * not use this file except in compliance with the License. You may obtain
  6. * a copy of the License at
  7. *
  8. * https://vuplex.com/commercial-library-license
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #if UNITY_ANDROID && !UNITY_EDITOR
  17. #pragma warning disable CS0618
  18. using System;
  19. using UnityEngine;
  20. namespace Vuplex.WebView {
  21. class AndroidWebPlugin : MonoBehaviour,
  22. IWebPlugin,
  23. IPluginWithTouchScreenKeyboard {
  24. public static AndroidWebPlugin Instance {
  25. get {
  26. if (_instance == null) {
  27. _instance = (AndroidWebPlugin) new GameObject("AndroidWebPlugin").AddComponent<AndroidWebPlugin>();
  28. DontDestroyOnLoad(_instance.gameObject);
  29. // Native video rendering does not work on standalone VR headsets like
  30. // Oculus Go, Oculus Quest, or HTC Vive Focus,
  31. // so disable it in order to use fallback video rendering.
  32. var isStandaloneVrHeadset = XrUtils.XRSettings.enabled &&
  33. (XrUtils.SdkIsActive("oculus") ||
  34. XrUtils.SdkIsActive("MockHMD")); // HTC Vive Focus
  35. if (isStandaloneVrHeadset) {
  36. WebViewLogger.LogWarning("3D WebView for Android doesn't support native video and WebGL on standalone VR headsets, so a fallback video implementation will be used instead. For standalone VR headsets, it is recommended to instead use 3D WebView for Android with Gecko Engine: https://developer.vuplex.com/webview/android-comparison");
  37. AndroidWebView.SetNativeVideoRenderingEnabled(false);
  38. }
  39. #if UNITY_2017_2_OR_NEWER
  40. if (SystemInfo.deviceName == "Oculus Quest 2") {
  41. // The Quest 2's version of Chromium also has a bug where it often dispatches
  42. // pointer events at the wrong coordinates when using the default pointer
  43. // input system, so the alternative pointer input system must be used instead.
  44. AndroidWebView.SetAlternativePointerInputSystemEnabled(true);
  45. }
  46. #endif
  47. }
  48. return _instance;
  49. }
  50. }
  51. public WebPluginType Type {
  52. get {
  53. return WebPluginType.Android;
  54. }
  55. }
  56. public void ClearAllData() {
  57. AndroidWebView.ClearAllData();
  58. }
  59. public void CreateTexture(float width, float height, Action<Texture2D> callback) {
  60. AndroidTextureCreator.Instance.CreateTexture(width, height, callback);
  61. }
  62. public void CreateMaterial(Action<Material> callback) {
  63. CreateTexture(1, 1, texture => {
  64. Material material = null;
  65. if (XrUtils.SinglePassRenderingIsEnabled)
  66. {
  67. Shader shader = ResourceMgr.Instance.FindShader("Vuplex/Android Single Pass Stereo Viewport Shader", "Assets/Shaders/WebView/Android/AndroidSinglePassViewportShader");
  68. if (shader)
  69. {
  70. material = new Material(shader);
  71. material.mainTexture = texture;
  72. material.EnableKeyword("FLIP_Y");
  73. material.SetFloat("_FlipY", 1);
  74. material.renderQueue = 3000;
  75. }
  76. }
  77. else
  78. {
  79. Shader shader = ResourceMgr.Instance.FindShader("Vuplex/Android Viewport Shader", "Assets/Shaders/WebView/Android/AndroidViewportShader");
  80. if (shader)
  81. {
  82. material = new Material(shader);
  83. material.mainTexture = texture;
  84. material.SetTextureScale("_MainTex", new Vector2(-1, 1));
  85. material.EnableKeyword("FLIP_Y");
  86. material.SetFloat("_FlipY", 1);
  87. material.renderQueue = 3000;
  88. }
  89. }
  90. callback(material);
  91. });
  92. }
  93. public void CreateVideoMaterial(Action<Material> callback) {
  94. if (AndroidWebView.IsUsingNativeVideoRendering()) {
  95. // Video is rendered natively onto the web texture, so a separate video
  96. // texture isn't required.
  97. callback(null);
  98. return;
  99. }
  100. // Since native video rendering isn't supported in this Android version, fallback
  101. // to rendering video onto a separate texture.
  102. CreateTexture(1, 1, texture => {
  103. Material material = null;
  104. if (XrUtils.SinglePassRenderingIsEnabled)
  105. {
  106. Shader shader = ResourceMgr.Instance.FindShader("Vuplex/Android Single Pass Stereo Viewport Shader", "Assets/Shaders/WebView/Android/AndroidSinglePassViewportShader");
  107. if (shader)
  108. {
  109. material = new Material(shader);
  110. material.mainTexture = texture;
  111. material.EnableKeyword("FLIP_Y");
  112. material.SetFloat("_FlipY", 1);
  113. material.renderQueue = 2999;
  114. }
  115. }
  116. else
  117. {
  118. Shader shader = ResourceMgr.Instance.FindShader("Vuplex/Android Viewport Shader", "Assets/Shaders/WebView/Android/AndroidViewportShader");
  119. if (shader)
  120. {
  121. material = new Material(shader);
  122. material.mainTexture = texture;
  123. material.SetTextureScale("_MainTex", new Vector2(-1, 1));
  124. material.EnableKeyword("FLIP_Y");
  125. material.SetFloat("_FlipY", 1);
  126. material.renderQueue = 2999;
  127. }
  128. }
  129. callback(material);
  130. });
  131. }
  132. public virtual IWebView CreateWebView() {
  133. return AndroidWebView.Instantiate();
  134. }
  135. public void EnableRemoteDebugging() {
  136. WebViewLogger.Log("Remote debugging is enabled for Android. For instructions, please see https://support.vuplex.com/articles/how-to-debug-web-content#android.");
  137. }
  138. public void SetIgnoreCertificateErrors(bool ignore) {
  139. AndroidWebView.SetIgnoreCertificateErrors(ignore);
  140. }
  141. /// <see cref="IPluginWithTouchScreenKeyboard"/>
  142. public void SetTouchScreenKeyboardEnabled(bool enabled) {
  143. AndroidWebView.SetTouchScreenKeyboardEnabled(enabled);
  144. }
  145. public void SetStorageEnabled(bool enabled) {
  146. AndroidWebView.SetStorageEnabled(enabled);
  147. }
  148. public void SetUserAgent(bool mobile) {
  149. AndroidWebView.GloballySetUserAgent(mobile);
  150. }
  151. public void SetUserAgent(string userAgent) {
  152. AndroidWebView.GloballySetUserAgent(userAgent);
  153. }
  154. static AndroidWebPlugin _instance;
  155. string _getMaterialName() {
  156. return XrUtils.SinglePassRenderingIsEnabled ? "AndroidSinglePassViewportMaterial"
  157. : "AndroidViewportMaterial";
  158. }
  159. /// <summary>
  160. /// Automatically pause web processing and media playback
  161. /// when the app is paused and resume it when the app is resumed.
  162. /// </summary>
  163. void OnApplicationPause(bool isPaused) {
  164. if (isPaused) {
  165. AndroidWebView.PauseAll();
  166. } else {
  167. AndroidWebView.ResumeAll();
  168. }
  169. }
  170. }
  171. }
  172. #endif