internal override void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { #if UNITY_EDITOR StopSearchingForDevices(); base.SearchForDevices(appIntentProfile, onDevicesUpdated, autoReconnect, autoReconnectTimeout); if (onDevicesUpdated == null) { return; } USBAppIntentProfile usbProfile = MakeUSBProfile(appIntentProfile); unsafe { WearableUSBSetAppIntentProfile(&usbProfile); } WearableUSBRefreshDeviceList(); _performDeviceSearch = true; _nextDeviceSearchTime = Time.unscaledTime + WearableConstants.DeviceUSBConnectUpdateIntervalInSeconds; OnConnectionStatusChanged(autoReconnect ? ConnectionStatus.AutoReconnect : ConnectionStatus.Searching); #else Debug.LogError(WearableConstants.UnsupportedPlatformError); OnReceivedSearchDevices(WearableConstants.EmptyDeviceList); #endif // UNITY_EDITOR }
/// <summary> /// Check an arbitrary intent for validity against the configurable sensor and gesture availability. /// </summary> /// <param name="profile"></param> /// <returns></returns> private bool CheckIntentValidity(AppIntentProfile profile) { // Sensors for (int i = 0; i < WearableConstants.SensorIds.Length; i++) { SensorId id = WearableConstants.SensorIds[i]; if (profile.GetSensorInProfile(id) && !_virtualDevice.IsSensorAvailable(id)) { return(false); } } // Check gestures for (int i = 0; i < WearableConstants.GestureIds.Length; i++) { GestureId id = WearableConstants.GestureIds[i]; if (id == GestureId.None) { continue; } if (profile.GetGestureInProfile(id) && !_virtualDevice.IsGestureAvailable(id)) { return(false); } } // NB All intervals are supported by the debug provider, so this part of the intent profile is not validated. return(true); }
internal override void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { StopSearchingForDevices(); base.SearchForDevices(appIntentProfile, onDevicesUpdated, autoReconnect, autoReconnectTimeout); if (onDevicesUpdated == null) { return; } #if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR StartSearch(appIntentProfile, RSSIFilterThreshold); _performDeviceSearch = true; _nextDeviceSearchTime = Time.unscaledTime + WearableConstants.DEVICE_SEARCH_UPDATE_INTERVAL_IN_SECONDS; _performDeviceConnection = true; _nextDeviceConnectTime = Time.unscaledTime + WearableConstants.DEVICE_CONNECT_UPDATE_INTERVAL_IN_SECONDS; OnConnectionStatusChanged(autoReconnect ? ConnectionStatus.AutoReconnect : ConnectionStatus.Searching, null); #else OnReceivedSearchDevices(WearableConstants.EMPTY_DEVICE_LIST); #endif }
/// <summary> /// Triggers a request for validation of a given <see cref="AppIntentProfile"/>. This request will /// call the <see cref="callback"/> when the validation is complete. /// </summary> /// <param name="profile"></param> internal void RequestIntentProfileValidation(AppIntentProfile profile, Action <bool> callback) { if (!_connectedDevice.HasValue) { Debug.LogWarning(WearableConstants.DeviceIsNotCurrentlyConnected); _waitingForIntentValidation = false; return; } if (!_waitingForIntentValidation) { IntentValidationSubscribers += callback; _waitingForIntentValidation = true; RequestIntentProfileValidationInternal(profile); // Clear the dirty flag after the request has been sent out, so if any // change occurs after this point, we know that a re-validation would // be necessary. profile.IsDirty = false; } else { // If there is an outstanding request, generate an error and ignore this call. Debug.LogError(WearableConstants.TooManyValidationRequestsError); } }
internal override void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { #if UNITY_EDITOR StopSearchingForDevices(); base.SearchForDevices(appIntentProfile, onDevicesUpdated, autoReconnect, autoReconnectTimeout); USBAppIntentProfile usbProfile = MakeUSBProfile(appIntentProfile); unsafe { WearableUSBSetAppIntentProfile(&usbProfile); } WearableUSBRefreshDeviceList(); _performDeviceSearch = true; _nextDeviceSearchTime = Time.unscaledTime + WearableConstants.DEVICE_USB_CONNECT_UPDATE_INTERVAL_IN_SECONDS; OnConnectionStatusChanged(autoReconnect ? ConnectionStatus.AutoReconnect : ConnectionStatus.Searching); #else Debug.LogError(WearableConstants.UNSUPPORTED_PLATFORM_ERROR); OnReceivedSearchDevices(WearableConstants.EMPTY_DEVICE_LIST); #endif // UNITY_EDITOR }
/// <summary> /// Triggers a request for validation of a given <see cref="AppIntentProfile"/>. This request will /// call the <see cref="callback"/> when the validation is complete. /// </summary> /// <param name="profile"></param> /// <param name="callback"></param> internal void RequestIntentProfileValidation(AppIntentProfile profile, Action <bool> callback) { if (!_connectedDevice.HasValue) { Debug.LogWarning(WearableConstants.DEVICE_IS_NOT_CURRENTLY_CONNECTED); _waitingForIntentValidation = false; return; } if (!_waitingForIntentValidation) { IntentValidationSubscribers += callback; _waitingForIntentValidation = true; RequestIntentProfileValidationInternal(profile); // Clear the dirty flag after the request has been sent out, so if any // change occurs after this point, we know that a re-validation would // be necessary. profile.IsDirty = false; } else { // If there is an outstanding request, generate an error and ignore this call. Debug.LogError(WearableConstants.TOO_MANY_VALIDATION_REQUESTS_ERROR); } }
public void ReconnectToLastSuccessfulDeviceInternal(AppIntentProfile appIntentProfile) { int sensors = GetSensorsFromAppIntentProfile(appIntentProfile); int samplePeriods = GetSamplePeriodsFromAppIntentProfile(appIntentProfile); int gestures = GetGesturesFromAppIntentProfile(appIntentProfile); AndroidPlugin.ReconnectToLastSuccessfulDevice(sensors, samplePeriods, gestures); }
public void StartSearch(AppIntentProfile appIntentProfile, int rssiThreshold) { int sensors = GetSensorsFromAppIntentProfile(appIntentProfile); int samplePeriods = GetSamplePeriodsFromAppIntentProfile(appIntentProfile); int gestures = GetGesturesFromAppIntentProfile(appIntentProfile); AndroidPlugin.Scan(sensors, samplePeriods, gestures, rssiThreshold); }
public bool IsAppIntentProfileValid(AppIntentProfile appIntentProfile) { int sensors = GetSensorsFromAppIntentProfile(appIntentProfile); int samplePeriods = GetSamplePeriodsFromAppIntentProfile(appIntentProfile); int gestures = GetGesturesFromAppIntentProfile(appIntentProfile); return(AndroidPlugin.ValidateAppIntents(sensors, samplePeriods, gestures)); }
/// <summary> /// Searches for all Wearable devices that can be connected to. /// </summary> /// <param name="appIntentProfile"></param> /// <param name="onDevicesUpdated"></param> /// <param name="autoReconnect"></param> /// <param name="autoReconnectTimeout"></param> internal virtual void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { DeviceSearchCallback += onDevicesUpdated; _autoReconnect = autoReconnect; _autoReconnectTimeout = Time.unscaledTime + autoReconnectTimeout; }
protected override void RequestIntentProfileValidationInternal(AppIntentProfile appIntentProfile) { #if UNITY_EDITOR unsafe { USBAppIntentProfile usbProfile = MakeUSBProfile(appIntentProfile); bool valid = WearableUSBCheckAppIntentProfileForConnectedDevice(&usbProfile); OnReceivedIntentValidationResponse(valid); } #endif }
protected override void RequestIntentProfileValidationInternal(AppIntentProfile appIntentProfile) { if (_verbose) { Debug.Log(WearableConstants.DebugProviderIntentValidationRequested); } _waitingToSendIntentValidation = true; _sendIntentValidationTime = Time.unscaledTime + _simulatedDelayTime; _intentResponse = CheckIntentValidity(appIntentProfile); }
internal override void ReconnectToLastSuccessfulDevice(AppIntentProfile appIntentProfile) { base.ReconnectToLastSuccessfulDevice(appIntentProfile); #if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR _performDeviceConnection = true; _nextDeviceConnectTime = Time.unscaledTime + WearableConstants.DEVICE_SEARCH_UPDATE_INTERVAL_IN_SECONDS; OnConnectionStatusChanged(ConnectionStatus.Connecting, null); ReconnectToLastSuccessfulDeviceInternal(appIntentProfile); #endif }
private USBAppIntentProfile MakeUSBProfile(AppIntentProfile appIntentProfile) { USBAppIntentProfile usbProfile = new USBAppIntentProfile(); if (appIntentProfile != null) { // Sensors usbProfile.sensorBitmask = 0; for (int i = 0; i < WearableConstants.SensorIds.Length; i++) { SensorId sensor = WearableConstants.SensorIds[i]; // Does this profile require this sensor? if (appIntentProfile.GetSensorInProfile(sensor)) { SensorFlags sensorBit = WearableTools.GetSensorFlag(sensor); usbProfile.sensorBitmask |= (int)sensorBit; } } // Gestures usbProfile.gestureBitmask = 0; for (int i = 0; i < WearableConstants.GestureIds.Length; i++) { GestureId gesture = WearableConstants.GestureIds[i]; // Does this profile require this gesture? if (appIntentProfile.GetGestureInProfile(gesture)) { GestureFlags gestureBit = WearableTools.GetGestureFlag(gesture); usbProfile.gestureBitmask |= (int)gestureBit; } } usbProfile.updateIntervalBitmask = 0; for (int i = 0; i < WearableConstants.UpdateIntervals.Length; i++) { SensorUpdateInterval interval = WearableConstants.UpdateIntervals[i]; // Does this profile require this update interval? if (appIntentProfile.GetIntervalInProfile(interval)) { int intervalBit = WearableTools.SensorUpdateIntervalToBit(interval); usbProfile.updateIntervalBitmask |= intervalBit; } } } return(usbProfile); }
/// <summary> /// Searches for all Wearable devices that can be connected to. /// </summary> /// <param name="appIntentProfile"></param> /// <param name="onDevicesUpdated"></param> /// <param name="autoReconnect"></param> /// <param name="autoReconnectTimeout"></param> internal virtual void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { if (onDevicesUpdated != null) { DeviceSearchCallback += onDevicesUpdated; } _autoReconnect = autoReconnect; _autoReconnectTimeout = Mathf.Min(Time.unscaledTime + autoReconnectTimeout, float.MaxValue); _autoReconnectWithoutPrompts = false; }
private int GetSensorsFromAppIntentProfile(AppIntentProfile profile) { int sensors = 0; if (profile != null) { for (int i = 0; i < WearableConstants.SensorIds.Length; i++) { if (profile.GetSensorInProfile(WearableConstants.SensorIds[i])) { sensors |= (1 << i); } } } return(sensors); }
private int GetSamplePeriodsFromAppIntentProfile(AppIntentProfile profile) { int samplePeriods = 0; if (profile != null) { for (int i = 0; i < WearableConstants.UpdateIntervals.Length; i++) { if (profile.GetIntervalInProfile(WearableConstants.UpdateIntervals[i])) { samplePeriods |= (1 << i); } } } return(samplePeriods); }
/// <summary> /// Helper function to convert our AppIntentProfile to something more easily consumable /// by the bridge layer. /// </summary> private static BridgeAppIntentProfile CreateBridgeAppIntentProfile(AppIntentProfile appIntentProfile) { BridgeAppIntentProfile bridgeAppIntentProfile = new BridgeAppIntentProfile(); int sensors = 0; int samplePeriods = 0; int gestures = 0; if (appIntentProfile != null) { for (int i = 0; i < WearableConstants.SENSOR_IDS.Length; i++) { if (appIntentProfile.GetSensorInProfile(WearableConstants.SENSOR_IDS[i])) { sensors |= (1 << i); } } for (int i = 0; i < WearableConstants.UPDATE_INTERVALS.Length; i++) { if (appIntentProfile.GetIntervalInProfile(WearableConstants.UPDATE_INTERVALS[i])) { samplePeriods |= (1 << i); } } for (int i = 0; i < WearableConstants.GESTURE_IDS.Length; i++) { if (WearableConstants.GESTURE_IDS[i] == GestureId.None) { continue; } if (appIntentProfile.GetGestureInProfile(WearableConstants.GESTURE_IDS[i])) { gestures |= (1 << (i - 1)); } } } bridgeAppIntentProfile.sensors = sensors; bridgeAppIntentProfile.samplePeriods = samplePeriods; bridgeAppIntentProfile.gestures = gestures; return(bridgeAppIntentProfile); }
internal override void ReconnectToLastSuccessfulDevice(AppIntentProfile appIntentProfile) { // The WearableBluetoothProvider has a special implementation for this connection flow where devices are not // searched for; instead we continuously try to connect to the last successful UID we connected to. // Given that this is not possible in the USB Provider, we mimic the flow by using the autoReconnect // feature with an incredibly large timeout, and adding in appropriate failures during the process: // * When attempting to connect when there was no previously successful last connection. // Please Note: Since the USB Provider skips the firmware check step, a failed App Intent Validation would // automatically result in a failed connection. if (string.IsNullOrEmpty(LastConnectedDeviceUID)) { OnConnectionStatusChanged(ConnectionStatus.Failed); } else { SearchForDevices(appIntentProfile, null, true, float.MaxValue); base.ReconnectToLastSuccessfulDevice(appIntentProfile); } }
internal override void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { _connectionIntentProfile = appIntentProfile; StopSearchingForDevices(); base.SearchForDevices(appIntentProfile, onDevicesUpdated, autoReconnect, autoReconnectTimeout); if (_verbose) { Debug.Log(WearableConstants.DebugProviderSearchingForDevices); } OnConnectionStatusChanged(autoReconnect ? ConnectionStatus.AutoReconnect : ConnectionStatus.Searching); _searchingForDevice = true; _nextDeviceSearchUpdateTime = Time.unscaledTime; }
private int GetGesturesFromAppIntentProfile(AppIntentProfile profile) { int gestures = 0; if (profile != null) { for (int i = 0; i < WearableConstants.GestureIds.Length; i++) { if (WearableConstants.GestureIds[i] == GestureId.None) { continue; } if (profile.GetGestureInProfile(WearableConstants.GestureIds[i])) { gestures |= (1 << (i - 1)); } } } return(gestures); }
internal override void SearchForDevices( AppIntentProfile appIntentProfile, Action <Device[]> onDevicesUpdated, bool autoReconnect, float autoReconnectTimeout) { StopSearchingForDevices(); base.SearchForDevices(appIntentProfile, onDevicesUpdated, autoReconnect, autoReconnectTimeout); if (onDevicesUpdated == null) { return; } #if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR StartSearch(appIntentProfile, RSSIFilterThreshold); _performDeviceSearch = true; _nextDeviceSearchTime = Time.unscaledTime + WearableConstants.DeviceSearchUpdateIntervalInSeconds; OnConnectionStatusChanged(autoReconnect ? ConnectionStatus.AutoReconnect : ConnectionStatus.Searching); #else OnReceivedSearchDevices(WearableConstants.EmptyDeviceList); #endif }
public void StartSearch(AppIntentProfile appIntentProfile, int rssiThreshold) { BridgeAppIntentProfile bridgeAppIntentProfile = CreateBridgeAppIntentProfile(appIntentProfile); WearableStartDeviceSearch(bridgeAppIntentProfile, rssiThreshold); }
public bool IsAppIntentProfileValid(AppIntentProfile appIntentProfile) { return(true); }
public void StartSearch(AppIntentProfile appIntentProfile, int rssiThreshold) { }
public void ReconnectToLastSuccessfulDeviceInternal(AppIntentProfile appIntentProfile) { BridgeAppIntentProfile bridgeAppIntentProfile = CreateBridgeAppIntentProfile(appIntentProfile); WearableConnectToLastDevice(bridgeAppIntentProfile); }
protected override void RequestIntentProfileValidationInternal(AppIntentProfile appIntentProfile) { bool profileIsValid = IsAppIntentProfileValid(appIntentProfile); OnReceivedIntentValidationResponse(profileIsValid); }
public bool IsAppIntentProfileValid(AppIntentProfile appIntentProfile) { BridgeAppIntentProfile bridgeAppIntentProfile = CreateBridgeAppIntentProfile(appIntentProfile); return(WearableValidateAppIntents(bridgeAppIntentProfile)); }
/// <summary> /// Reconnects to the device last successfully connected. /// </summary> /// <param name="appIntentProfile"></param> internal virtual void ReconnectToLastSuccessfulDevice(AppIntentProfile appIntentProfile) { _autoReconnectWithoutPrompts = true; }
/// <summary> /// Makes the actual request to validate a device configuration. This request should call /// <see cref="OnReceivedIntentValidationResponse"/> on completion to trigger subscribed callbacks. /// </summary> /// <param name="appIntentProfile"></param> protected abstract void RequestIntentProfileValidationInternal(AppIntentProfile appIntentProfile);