IndieGame/client/Packages/com.unity.inputsystem@1.7.0/InputSystem/Plugins/iOS/iOSStepCounter.cs

196 lines
6.0 KiB
C#
Raw Normal View History

2024-10-11 10:12:15 +08:00
#if UNITY_EDITOR || UNITY_IOS || PACKAGE_DOCS_GENERATION
using System.Runtime.InteropServices;
using AOT;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
namespace UnityEngine.InputSystem.iOS.LowLevel
{
/// <summary>
/// Describes the access for motion related features.
/// </summary>
/// <remarks>Enum values map values from CoreMotion.framework/Headers/CMAuthorization.h</remarks>
public enum MotionAuthorizationStatus
{
/// <summary>
/// The access status was not yet determined.
/// </summary>
NotDetermined = 0,
/// <summary>
/// Access was denied due system settings.
/// </summary>
Restricted,
/// <summary>
/// Access was denied by the user.
/// </summary>
Denied,
/// <summary>
/// Access was allowed by the user.
/// </summary>
Authorized
}
[StructLayout(LayoutKind.Sequential)]
internal struct iOSStepCounterState : IInputStateTypeInfo
{
public static FourCC kFormat = new FourCC('I', 'S', 'C', 'S');
public FourCC format => kFormat;
[InputControl(name = "stepCounter", layout = "Integer")]
public int stepCounter;
}
/// <summary>
/// Step Counter (also known as pedometer) sensor for iOS.
/// </summary>
/// <remarks>
/// You need to enable Motion Usage in Input System settings (see <see cref="InputSettings.iOSSettings.motionUsage"/>), to be allowed
/// to access the sensor on the user's device.
/// <example>
/// <code>
/// void Start()
/// {
/// InputSystem.EnableDevice(StepCounter.current);
/// }
///
/// void OnGUI()
/// {
/// GUILayout.Label(StepCounter.current.stepCounter.ReadValue().ToString());
/// }
/// </code>
/// </example>
/// </remarks>
/// <seealso cref="InputSettings.iOSSettings.motionUsage"/>
[InputControlLayout(stateType = typeof(iOSStepCounterState), variants = "StepCounter", hideInUI = true)]
public class iOSStepCounter : StepCounter
{
private const int kCommandFailure = -1;
private const int kCommandSuccess = 1;
internal delegate void OnDataReceivedDelegate(int deviceId, int numberOfSteps);
[StructLayout(LayoutKind.Sequential)]
private struct iOSStepCounterCallbacks
{
internal OnDataReceivedDelegate onData;
}
[DllImport("__Internal")]
private static extern int _iOSStepCounterEnable(int deviceId, ref iOSStepCounterCallbacks callbacks, int sizeOfCallbacks);
[DllImport("__Internal")]
private static extern int _iOSStepCounterDisable(int deviceId);
[DllImport("__Internal")]
private static extern int _iOSStepCounterIsEnabled(int deviceId);
[DllImport("__Internal")]
private static extern int _iOSStepCounterIsAvailable();
[DllImport("__Internal")]
private static extern int _iOSStepCounterGetAuthorizationStatus();
[MonoPInvokeCallback(typeof(OnDataReceivedDelegate))]
private static void OnDataReceived(int deviceId, int numberOfSteps)
{
var stepCounter = (iOSStepCounter)InputSystem.GetDeviceById(deviceId);
InputSystem.QueueStateEvent(stepCounter, new iOSStepCounterState {stepCounter = numberOfSteps});
}
#if UNITY_EDITOR
private bool m_Enabled = false;
#endif
protected override unsafe long ExecuteCommand(InputDeviceCommand* commandPtr)
{
var t = commandPtr->type;
if (t == QueryEnabledStateCommand.Type)
{
#if UNITY_EDITOR
((QueryEnabledStateCommand*)commandPtr)->isEnabled = m_Enabled;
#else
((QueryEnabledStateCommand*)commandPtr)->isEnabled = _iOSStepCounterIsEnabled(deviceId) != 0;
#endif
return kCommandSuccess;
}
if (t == EnableDeviceCommand.Type)
{
if (InputSystem.settings.iOS.motionUsage.enabled == false)
{
Debug.LogError("Please enable Motion Usage in Input Settings before using Step Counter.");
return kCommandFailure;
}
#if UNITY_EDITOR
m_Enabled = true;
return kCommandSuccess;
#else
var callbacks = new iOSStepCounterCallbacks();
callbacks.onData = OnDataReceived;
return _iOSStepCounterEnable(deviceId, ref callbacks, Marshal.SizeOf(callbacks));
#endif
}
if (t == DisableDeviceCommand.Type)
{
#if UNITY_EDITOR
m_Enabled = false;
return kCommandSuccess;
#else
return _iOSStepCounterDisable(deviceId);
#endif
}
if (t == QueryCanRunInBackground.Type)
{
((QueryCanRunInBackground*)commandPtr)->canRunInBackground = true;
return kCommandSuccess;
}
if (t == RequestResetCommand.Type)
{
#if UNITY_EDITOR
m_Enabled = false;
#else
_iOSStepCounterDisable(deviceId);
#endif
return kCommandSuccess;
}
return kCommandFailure;
}
/// <summary>
/// Does the phone support the pedometer?
/// </summary>
public static bool IsAvailable()
{
#if UNITY_EDITOR
return false;
#else
return _iOSStepCounterIsAvailable() != 0;
#endif
}
/// <summary>
/// Indicates whether the app is authorized to gather data for step counter sensor.
/// </summary>
public static MotionAuthorizationStatus AuthorizationStatus
{
get
{
#if UNITY_EDITOR
return MotionAuthorizationStatus.NotDetermined;
#else
return (MotionAuthorizationStatus)_iOSStepCounterGetAuthorizationStatus();
#endif
}
}
}
}
#endif