196 lines
6.0 KiB
C#
196 lines
6.0 KiB
C#
#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
|