You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

144 lines
6.0 KiB

  1. //
  2. // UniWebViewChannelMethodManager.cs
  3. // Created by Wang Wei(@onevcat) on 2023-04-21.
  4. //
  5. // This file is a part of UniWebView Project (https://uniwebview.com)
  6. // By purchasing the asset, you are allowed to use this code in as many as projects
  7. // you want, only if you publish the final products under the name of the same account
  8. // used for the purchase.
  9. //
  10. // This asset and all corresponding files (such as source code) are provided on an
  11. // “as is” basis, without warranty of any kind, express of implied, including but not
  12. // limited to the warranties of merchantability, fitness for a particular purpose, and
  13. // noninfringement. In no event shall the authors or copyright holders be liable for any
  14. // claim, damages or other liability, whether in action of contract, tort or otherwise,
  15. // arising from, out of or in connection with the software or the use of other dealing in the software.
  16. //
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Linq;
  20. using UnityEngine;
  21. enum UniWebViewChannelMethod {
  22. ShouldUniWebViewHandleRequest,
  23. RequestMediaCapturePermission
  24. }
  25. class UniWebViewChannelMethodManager {
  26. private static UniWebViewChannelMethodManager instance;
  27. private Dictionary<string, Dictionary<string, Func<object, object>>> channels =
  28. new Dictionary<string, Dictionary<string, Func<object, object>>>();
  29. internal static UniWebViewChannelMethodManager Instance {
  30. get {
  31. if (instance == null) {
  32. instance = new UniWebViewChannelMethodManager();
  33. }
  34. return instance;
  35. }
  36. }
  37. internal void RegisterChannelMethod(
  38. string webViewName,
  39. UniWebViewChannelMethod method,
  40. Func<object, object> handler)
  41. {
  42. if (!HasRegisteredChannel(webViewName)) {
  43. channels[webViewName] = new Dictionary<string, Func<object, object>>();
  44. }
  45. var methodName = method.ToString();
  46. channels[webViewName][methodName] = handler;
  47. UniWebViewLogger.Instance.Info("Channel method is registered for web view: " + webViewName + ", method: " +
  48. methodName);
  49. }
  50. internal void UnregisterChannel(string webViewName) {
  51. if (!HasRegisteredChannel(webViewName)) {
  52. return;
  53. }
  54. channels.Remove(webViewName);
  55. UniWebViewLogger.Instance.Debug("All channel methods are unregistered for web view: " + webViewName);
  56. }
  57. internal void UnregisterChannelMethod(string webViewName, UniWebViewChannelMethod method) {
  58. var methodName = method.ToString();
  59. if (!HasRegisteredChannel(webViewName)) {
  60. return;
  61. }
  62. channels[webViewName].Remove(methodName);
  63. UniWebViewLogger.Instance.Debug("Channel method is unregistered for web view: " + webViewName + ", method: " +
  64. methodName);
  65. }
  66. bool HasRegisteredChannel(string webViewName) {
  67. return channels.Keys.Contains(webViewName);
  68. }
  69. bool HasRegisteredMethod(string webViewName, string methodName) {
  70. if (!HasRegisteredChannel(webViewName)) {
  71. return false;
  72. }
  73. return channels[webViewName].Keys.Contains(methodName);
  74. }
  75. internal string InvokeMethod(string webViewName, string methodName, string parameters) {
  76. if (!HasRegisteredMethod(webViewName, methodName)) {
  77. UniWebViewLogger.Instance.Info("There is no handler for the channel method. Ignoring.");
  78. return null;
  79. }
  80. var func = channels[webViewName][methodName];
  81. if (!Enum.TryParse<UniWebViewChannelMethod>(methodName, out var method)) {
  82. UniWebViewLogger.Instance.Info("Unknown method name: " + methodName + ". Please check, ignoring.");
  83. return null;
  84. }
  85. UniWebViewLogger.Instance.Verbose("Channel method invoking received for web view: " + webViewName + ", method: " +
  86. methodName + ", parameters: " + parameters);
  87. string result;
  88. switch (method) {
  89. case UniWebViewChannelMethod.ShouldUniWebViewHandleRequest: {
  90. // (UniWebViewChannelMethodHandleRequest) -> bool
  91. var input = JsonUtility.FromJson<UniWebViewChannelMethodHandleRequest>(parameters);
  92. bool Func(UniWebViewChannelMethodHandleRequest i) => (bool)func(i);
  93. result = ResultJsonWith(Func(input));
  94. break;
  95. }
  96. case UniWebViewChannelMethod.RequestMediaCapturePermission: {
  97. // (UniWebViewChannelMethodMediaCapturePermission) -> UniWebViewMediaCapturePermissionDecision
  98. var input = JsonUtility.FromJson<UniWebViewChannelMethodMediaCapturePermission>(parameters);
  99. UniWebViewMediaCapturePermissionDecision Func(UniWebViewChannelMethodMediaCapturePermission i) => (UniWebViewMediaCapturePermissionDecision)func(i);
  100. result = ResultJsonWith(Func(input));
  101. break;
  102. }
  103. default:
  104. result = null;
  105. break;
  106. }
  107. UniWebViewLogger.Instance.Debug("Channel method handler responded. Result: " + result);
  108. return result;
  109. }
  110. string ResultJsonWith(bool value) {
  111. return value ? "{\"result\":true}" : "{\"result\":false}";
  112. }
  113. string ResultJsonWith(UniWebViewMediaCapturePermissionDecision decision) {
  114. switch (decision) {
  115. case UniWebViewMediaCapturePermissionDecision.Prompt:
  116. return "{\"result\":\"prompt\"}";
  117. case UniWebViewMediaCapturePermissionDecision.Grant:
  118. return "{\"result\":\"grant\"}";
  119. case UniWebViewMediaCapturePermissionDecision.Deny:
  120. return "{\"result\":\"deny\"}";
  121. default:
  122. UniWebViewLogger.Instance.Critical("Unknown decision: " + decision);
  123. break;
  124. }
  125. Debug.LogAssertion("Unrecognized UniWebViewMediaCapturePermissionDecision. Fallback to prompt.");
  126. return "{\"result\":\"prompt\"}";
  127. }
  128. }