NRAndroidPermissionsManager.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /****************************************************************************
  2. * Copyright 2019 Nreal Techonology Limited. All rights reserved.
  3. *
  4. * This file is part of NRSDK.
  5. *
  6. * https://www.nreal.ai/
  7. *
  8. *****************************************************************************/
  9. namespace NRKernal
  10. {
  11. using System;
  12. using UnityEngine;
  13. /// <summary> Manages Android permissions for the Unity application. </summary>
  14. public class NRAndroidPermissionsManager : AndroidJavaProxy, IAndroidPermissionsCheck
  15. {
  16. /// <summary> The instance. </summary>
  17. private static NRAndroidPermissionsManager _instance;
  18. /// <summary> The activity. </summary>
  19. private static AndroidJavaObject _activity;
  20. /// <summary> The permission service. </summary>
  21. private static AndroidJavaObject _permissionService;
  22. /// <summary> The current request. </summary>
  23. private static AsyncTask<AndroidPermissionsRequestResult> _currentRequest = null;
  24. /// <summary> The action on permissions request finished. </summary>
  25. private static Action<AndroidPermissionsRequestResult> _onPermissionsRequestFinished;
  26. /// <summary> The current screen capture request. </summary>
  27. private static AsyncTask<AndroidJavaObject> _curScreenCaptureRequest = null;
  28. /// <summary> The action on screen capture request finished. </summary>
  29. private static Action<AndroidJavaObject> _onScreenCaptureRequestFinished;
  30. private static AndroidJavaObject _mediaProjection;
  31. /// <summary> Constructs a new AndroidPermissionsManager. </summary>
  32. public NRAndroidPermissionsManager() : base(
  33. "ai.nreal.sdk.UnityAndroidPermissions$IPermissionRequestResult")
  34. {
  35. }
  36. /// <summary> Checks if an Android permission is granted to the application. </summary>
  37. /// <param name="permissionName"> The full name of the Android permission to check (e.g.
  38. /// android.permission.CAMERA).</param>
  39. /// <returns>
  40. /// <c>true</c> if <c>permissionName</c> is granted to the application, otherwise
  41. /// <c>false</c>. </returns>
  42. public static bool IsPermissionGranted(string permissionName)
  43. {
  44. if (Application.platform != RuntimePlatform.Android)
  45. {
  46. return true;
  47. }
  48. return GetPermissionsService().Call<bool>(
  49. "IsPermissionGranted", GetUnityActivity(), permissionName);
  50. }
  51. /// <summary> Requests an Android permission from the user. </summary>
  52. /// <param name="permissionName"> The permission to be requested (e.g. android.permission.CAMERA).</param>
  53. /// <returns>
  54. /// An asynchronous task that completes when the user has accepted or rejected the requested
  55. /// permission and yields a <see cref="AndroidPermissionsRequestResult"/> that summarizes the
  56. /// result. If this method is called when another permissions request is pending, <c>null</c>
  57. /// will be returned instead. </returns>
  58. public static AsyncTask<AndroidPermissionsRequestResult> RequestPermission(
  59. string permissionName)
  60. {
  61. if (NRAndroidPermissionsManager.IsPermissionGranted(permissionName))
  62. {
  63. return new AsyncTask<AndroidPermissionsRequestResult>(
  64. new AndroidPermissionsRequestResult(
  65. new string[] { permissionName }, new bool[] { true }));
  66. }
  67. if (_currentRequest != null)
  68. {
  69. NRDebugger.Error("Attempted to make simultaneous Android permissions requests.");
  70. return null;
  71. }
  72. _currentRequest =
  73. new AsyncTask<AndroidPermissionsRequestResult>(out _onPermissionsRequestFinished);
  74. GetPermissionsService().Call("RequestPermissionAsync", GetUnityActivity(),
  75. new[] { permissionName }, GetInstance());
  76. return _currentRequest;
  77. }
  78. /// <summary> Requests an Android permission from the user. </summary>
  79. /// <param name="permissionName"> The permission to be requested (e.g. android.permission.CAMERA).</param>
  80. /// <returns>
  81. /// An asynchronous task that completes when the user has accepted or rejected the requested
  82. /// permission and yields a <see cref="AndroidPermissionsRequestResult"/> that summarizes the
  83. /// result. If this method is called when another permissions request is pending, <c>null</c>
  84. /// will be returned instead. </returns>
  85. public AsyncTask<AndroidPermissionsRequestResult> RequestAndroidPermission(
  86. string permissionName)
  87. {
  88. return RequestPermission(permissionName);
  89. }
  90. /// <summary> Callback fired when a permission is granted. </summary>
  91. /// <param name="permissionName"> The name of the permission that was granted.</param>
  92. public virtual void OnPermissionGranted(string permissionName)
  93. {
  94. OnPermissionResult(permissionName, true);
  95. }
  96. /// <summary> Callback fired when a permission is denied. </summary>
  97. /// <param name="permissionName"> The name of the permission that was denied.</param>
  98. public virtual void OnPermissionDenied(string permissionName)
  99. {
  100. OnPermissionResult(permissionName, false);
  101. }
  102. /// <summary> Gets the instance. </summary>
  103. /// <returns> The instance. </returns>
  104. public static NRAndroidPermissionsManager GetInstance()
  105. {
  106. if (_instance == null)
  107. {
  108. _instance = new NRAndroidPermissionsManager();
  109. }
  110. return _instance;
  111. }
  112. /// <summary> Gets unity activity. </summary>
  113. /// <returns> The unity activity. </returns>
  114. private static AndroidJavaObject GetUnityActivity()
  115. {
  116. if (_activity == null)
  117. {
  118. AndroidJavaClass unityPlayer =
  119. new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  120. _activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
  121. }
  122. return _activity;
  123. }
  124. /// <summary> Gets permissions service. </summary>
  125. /// <returns> The permissions service. </returns>
  126. private static AndroidJavaObject GetPermissionsService()
  127. {
  128. if (_permissionService == null)
  129. {
  130. _permissionService =
  131. new AndroidJavaObject("ai.nreal.sdk.UnityAndroidPermissions");
  132. }
  133. return _permissionService;
  134. }
  135. /// <summary> Callback fired on an Android permission result. </summary>
  136. /// <param name="permissionName"> The name of the permission.</param>
  137. /// <param name="granted"> If permission is granted or not.</param>
  138. private void OnPermissionResult(string permissionName, bool granted)
  139. {
  140. if (_onPermissionsRequestFinished == null)
  141. {
  142. Debug.LogErrorFormat(
  143. "AndroidPermissionsManager received an unexpected permissions result {0}",
  144. permissionName);
  145. return;
  146. }
  147. // Cache completion method and reset request state.
  148. var onRequestFinished = _onPermissionsRequestFinished;
  149. _currentRequest = null;
  150. _onPermissionsRequestFinished = null;
  151. onRequestFinished(new AndroidPermissionsRequestResult(new string[] { permissionName },
  152. new bool[] { granted }));
  153. }
  154. /// <summary> Requests Android screen capture from the user. </summary>
  155. /// <returns>
  156. /// An asynchronous task that completes when the user has approved or rejected the requested
  157. /// ScreenCapture and yields a <see cref="AndroidJavaObject"/> that store the Android MediaProjection
  158. /// result. If this method is called when another screen capture request is pending, <c>null</c>
  159. /// will be returned instead. </returns>
  160. public AsyncTask<AndroidJavaObject> RequestScreenCapture()
  161. {
  162. Debug.LogFormat("AndroidPermissionsManager RequestScreenCapture: cache={0}", _mediaProjection != null);
  163. if (_mediaProjection != null)
  164. {
  165. return new AsyncTask<AndroidJavaObject>(_mediaProjection);
  166. }
  167. if (_curScreenCaptureRequest != null)
  168. {
  169. NRDebugger.Error("Attempted to make simultaneous Android permissions requests.");
  170. return null;
  171. }
  172. _curScreenCaptureRequest =
  173. new AsyncTask<AndroidJavaObject>(out _onScreenCaptureRequestFinished);
  174. GetPermissionsService().Call("RequestScreenCaptureAsync", GetUnityActivity(), GetInstance());
  175. return _curScreenCaptureRequest;
  176. }
  177. /// <summary> Callback is fired when screen capture is granted. </summary>
  178. public virtual void OnScreenCaptureGranted(AndroidJavaObject mediaProjection)
  179. {
  180. OnScreenCaptureResult(true, mediaProjection);
  181. }
  182. /// <summary> Callback is fired when screen capture is denied. </summary>
  183. public virtual void OnScreenCaptureDenied()
  184. {
  185. OnScreenCaptureResult(false, null);
  186. }
  187. /// <summary> Callback fired on an Android screen capture result. </summary>
  188. /// <param name="granted"> If screen capture is granted or not.</param>
  189. /// <param name="mediaProjection"> The android MediaProjection object.</param>
  190. private void OnScreenCaptureResult(bool granted, AndroidJavaObject mediaProjection)
  191. {
  192. Debug.LogFormat("AndroidPermissionsManager OnScreenCaptureGranted: granted={0}, mediaProjection={1}", granted, mediaProjection!=null);
  193. if (_onScreenCaptureRequestFinished == null)
  194. {
  195. Debug.LogError("AndroidPermissionsManager received an unexpected screencapture result");
  196. return;
  197. }
  198. // Cache completion method and reset request state.
  199. var onRequestFinished = _onScreenCaptureRequestFinished;
  200. _curScreenCaptureRequest = null;
  201. _onScreenCaptureRequestFinished = null;
  202. if (granted)
  203. _mediaProjection = mediaProjection;
  204. onRequestFinished(mediaProjection);
  205. }
  206. }
  207. }