using System;
using System.Collections.Generic;
using UnityEngine.XR.MagicLeap.Native;
namespace UnityEngine.XR.MagicLeap
{
[Obsolete("MLPermissions is deprecated. Use MagicLeap.Android.Permissions instead.")]
public sealed partial class MLPermissions : MLAutoAPISingleton<MLPermissions>
{
public delegate void OnPermissionGrantedDelegate(string permission);
public delegate void OnPermissionDeniedDelegate(string permission);
public delegate void OnPermissionDeniedAndDontAskAgainDelegate(string permission);
public class Callbacks
{
public event OnPermissionGrantedDelegate OnPermissionGranted = delegate { };
public event OnPermissionDeniedDelegate OnPermissionDenied = delegate { };
public event OnPermissionDeniedAndDontAskAgainDelegate OnPermissionDeniedAndDontAskAgain = delegate { };
internal void TriggerGranted(string permission)
{
OnPermissionGranted(permission);
}
internal void TriggerDenied(string permission)
{
OnPermissionDenied(permission);
}
internal void TriggerDeniedAndDontAskAgain(string permission)
{
OnPermissionDeniedAndDontAskAgain(permission);
}
}
private readonly Queue<string> permissionRequests = new Queue<string>();
private readonly Dictionary<string, List<Callbacks>> requestData = new Dictionary<string, List<Callbacks>>();
private readonly HashSet<string> deniedPermissions = new HashSet<string>();
private readonly HashSet<string> dontAskAgainPermissions = new HashSet<string>();
private bool currentlyRequestingPermission = false;
public static MLResult CheckPermission(string permission) => MLResult.Create(Instance.CheckPermissionInternal(permission));
public static MLResult RequestPermission(string permission, Callbacks callbacks) => MLResult.Create(Instance.RequestPermissionInternal(permission, callbacks));
private static bool NativeCallSuccess(MLResult.Code resultCode)
{
switch (resultCode)
{
case MLResult.Code.Ok:
case MLResult.Code.Pending:
return true;
default:
return false;
}
}
protected override MLResult.Code StartAPI() => MLResult.Code.Ok;
protected override MLResult.Code StopAPI() => MLResult.Code.Ok;
protected override void Update()
{
base.Update();
ProcessRequestQueue();
}
private void ProcessRequestQueue()
{
if (permissionRequests.Count > 0)
{
if (Application.isEditor)
return;
if (currentlyRequestingPermission)
{
return;
}
var permissionName = permissionRequests.Dequeue();
if (Android.Permission.HasUserAuthorizedPermission(permissionName) || dontAskAgainPermissions.Contains(permissionName))
{
return;
}
currentlyRequestingPermission = true;
var callbacks = new Android.PermissionCallbacks();
callbacks.PermissionGranted += OnPermissionGranted;
callbacks.PermissionDenied += OnPermissionDenied;
callbacks.PermissionDeniedAndDontAskAgain += OnPermissionDeniedDontAskAgain;
Android.Permission.RequestUserPermission(permissionName, callbacks);
}
}
private MLResult.Code CheckPermissionInternal(string permission)
{
if (string.IsNullOrEmpty(permission))
{
return MLResult.Code.InvalidParam;
}
MLResult.Code result = MLResult.Code.Ok;
if (Application.isEditor)
return result;
nativeMLPermissionsCheckPermissionPerfMarker.Begin();
if (Android.Permission.HasUserAuthorizedPermission(permission))
{
result = MLResult.Code.Ok;
}
else
{
if (dontAskAgainPermissions.Contains(permission))
{
result = MLResult.Code.PermissionDenied;
}
else if (!deniedPermissions.Contains(permission))
{
result = MLResult.Code.Pending;
}
else
{
result = MLResult.Code.PermissionDenied;
}
}
MLResult.DidNativeCallSucceed(result, nameof(Android.Permission.HasUserAuthorizedPermission), NativeCallSuccess);
nativeMLPermissionsCheckPermissionPerfMarker.End();
return result;
}
private MLResult.Code RequestPermissionInternal(string permission, Callbacks callbacks)
{
if (Application.isEditor)
return MLResult.Code.Ok;
if (string.IsNullOrEmpty(permission))
{
Debug.LogError($"MLPermissions: requested permission name is blank");
return MLResult.Code.InvalidParam;
}
nativeMLPermissionsRequestPermissionPerfMarker.Begin();
MLResult.Code result = MLResult.Code.Ok;
if (!requestData.ContainsKey(permission))
{
requestData.Add(permission, new List<Callbacks>());
}
if (callbacks != null)
{
requestData[permission].Add(callbacks);
}
if (MLResult.IsOK(CheckPermissionInternal(permission)))
{
foreach (Callbacks cb in requestData[permission])
{
cb.TriggerGranted(permission);
}
requestData[permission].Clear();
}
else
{
result = MLResult.Code.Pending;
if (!permissionRequests.Contains(permission))
{
permissionRequests.Enqueue(permission);
}
}
nativeMLPermissionsRequestPermissionPerfMarker.End();
return result;
}
private void OnPermissionDeniedDontAskAgain(string permission)
{
dontAskAgainPermissions.Add(permission);
deniedPermissions.Add(permission);
MLPluginLog.Debug($"MLPermissions: User denied {permission}, DON'T ASK AGAIN.");
MLThreadDispatch.ScheduleMain(() =>
{
foreach (Callbacks cb in requestData[permission])
{
cb.TriggerDeniedAndDontAskAgain(permission);
}
requestData[permission].Clear();
});
currentlyRequestingPermission = false;
}
private void OnPermissionDenied(string permission)
{
deniedPermissions.Add(permission);
MLPluginLog.Debug($"MLPermissions: User denied {permission}");
MLThreadDispatch.ScheduleMain(() =>
{
foreach (Callbacks cb in requestData[permission])
{
cb.TriggerDenied(permission);
}
requestData[permission].Clear();
});
currentlyRequestingPermission = false;
}
private void OnPermissionGranted(string permission)
{
MLPluginLog.Debug($"MLPermissions: User granted {permission}");
MLThreadDispatch.ScheduleMain(() =>
{
foreach (Callbacks cb in requestData[permission])
{
cb.TriggerGranted(permission);
}
requestData[permission].Clear();
});
currentlyRequestingPermission = false;
}
}
}