Example #1
0
        /// <summary>
        /// Handle the privilege states.
        /// </summary>
        private void UpdatePrivilege()
        {
            switch (_state)
            {
            /// Privilege API has been started successfully, ready to make requests.
            case PrivilegeState.Started:
            {
                RequestPrivileges();
                break;
            }

            /// Privilege requests have been made, wait until all privileges are granted before enabling the feature that requires privileges.
            case PrivilegeState.Requested:
            {
                foreach (MLPrivileges.Id priv in _privilegesToRequest)
                {
                    if (!_privilegesGranted.Contains(priv))
                    {
                        return;
                    }
                }

                _state = PrivilegeState.Succeeded;

                    #if PLATFORM_LUMIN
                OnPrivilegesDone(MLResult.Create(MLResult.Code.Ok));
                    #endif

                break;
            }

            /// Privileges have been denied, respond appropriately.
            case PrivilegeState.Failed:
            {
                    #if PLATFORM_LUMIN
                OnPrivilegesDone(MLResult.Create(MLResult.Code.PrivilegeDenied));
                    #endif

                enabled = false;
                break;
            }
            }
        }
            /// <summary>
            /// Having made a call to MLTokenAgentGetClientCredentialsAsync(), the user can call MLTokenAgentGetClientCredentialsWait()
            /// to detect whether the asynchronous call completed and if so, to retrieve the credentials in out_credentials.
            /// </summary>
            /// <param name="clientCredentials">Reference to the clientCredentials object.</param>
            /// <param name="credentials">Reference to the credentials struct of the clientCredentials object.</param>
            /// <param name="tokens">Reference to the tokens struct of the clientCredentials object.</param>
            /// <returns>
            /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the operation completed successfully before the timeout elapsed.
            /// MLResult.Result will be <c>MLResult.Code.Pending</c> if the timeout elapsed before the asynchronous call completed.
            /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the operation failed with an unspecified error.
            /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the future or out_credentials were 0 (null).
            /// MLResult.Result will be <c>MLResult.Code.AllocFailed</c> if the operation failed to allocate memory.
            /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if the caller does not have the ClientCredentialsRead privilege.
            /// MLResult.Result will be <c>MLResult.Code.TokenAgent*</c> if a token specific failure occurred during the operation.
            /// </returns>
            public static MLResult.Code ListenClientCredentialsResponse(MLTokenAgent.ClientCredentials clientCredentials, ref MLTokenAgent.Credentials credentials, ref MLTokenAgent.Tokens tokens)
            {
                try
                {
                    IntPtr clientCredentialsPtr       = clientCredentialsPtrMap.ContainsKey(clientCredentials) ? clientCredentialsPtrMap[clientCredentials] : IntPtr.Zero;
                    IntPtr clientCredentialsFuturePtr = clientCredentialsFuturePtrMap.ContainsKey(clientCredentials) ? clientCredentialsFuturePtrMap[clientCredentials] : IntPtr.Zero;

                    if (clientCredentialsFuturePtr == IntPtr.Zero)
                    {
                        MLPluginLog.Warning("MLTokenAgent.NativeBindings.ListenClientCredentialsResponse failed because a valid future pointer could not be found with the passed request.");
                        return(MLResult.Code.UnspecifiedFailure);
                    }

                    //// Attempt to get data if available, 0 is passed as a timeout to immediately return and never wait for results.
                    MLResult.Code resultCode = MLTokenAgent.NativeBindings.MLTokenAgentGetClientCredentialsWait(clientCredentialsFuturePtr, 0, ref clientCredentialsPtr);

                    // If it succeeded, copy any modifications made to the profile in unmanaged memory by the Identity API to managed memory.
                    if (MLResult.IsOK(resultCode))
                    {
                        clientCredentialsFuturePtrMap.Remove(clientCredentials);

                        clientCredentialsPtrMap.Remove(clientCredentials);
                        clientCredentialsPtrMap.Add(clientCredentials, clientCredentialsPtr);

                        MLTokenAgent.NativeBindings.ClientCredentialsNative clientCredentialsNative = (MLTokenAgent.NativeBindings.ClientCredentialsNative)Marshal.PtrToStructure(clientCredentialsPtr, typeof(MLTokenAgent.NativeBindings.ClientCredentialsNative));
                        credentials = clientCredentialsNative.Credentials;
                        tokens      = clientCredentials.Tokens;
                    }
                    else
                    {
                        credentials = new Credentials();
                        tokens      = new Tokens();
                    }

                    return(resultCode);
                }
                catch (EntryPointNotFoundException)
                {
                    MLPluginLog.Error("MLTokenAgent.NativeBindings.ListenClientCredentialsResponse failed. Reason: API symbols not found.");
                    return(MLResult.Code.UnspecifiedFailure);
                }
            }
            /// <summary>
            /// Handles when a request queries the attribute names.
            /// </summary>
            public void ProcessRequest()
            {
                if (this.request == null)
                {
                    return;
                }

                switch (this.request.RequestState)
                {
                case Request.State.REQUEST_ATTRIB_NAMES:
                    this.RequestAttributeNamesAsync();
                    break;

                case Request.State.LISTENING_ATTRIB_NAMES:
                    this.ListenAttributeNamesResponse();
                    break;

                case Request.State.REQUEST_ATTRIB_VALUES:
                    this.RequestAttributeValuesAsync();
                    break;

                case Request.State.LISTENING_ATTRIB_VALUES:
                    this.ListenAttributeValuesResponse();
                    break;

                case Request.State.DONE:
                    this.request?.Callback?.Invoke(MLResult.Create(this.request.ResultCode));

                    //// Removes the profile if something when wrong with the request.
                    if (!MLResult.IsOK(this.request.ResultCode))
                    {
                        this.request = null;
                        MLIdentity.RemoveProfile(this);
                    }

                    this.request = null;
                    break;

                default:
                    break;
                }
            }
        private MLResult InternalUpdateWatchHistory(MLScreensWatchHistoryEntry entry, Texture2D thumbnailImage)
        {
            if (!entry.IsValid)
            {
                return(MLResult.Create(MLResult.Code.InvalidParam, "Invalid entry parameter"));
            }

            if (!_watchHistory.ContainsKey(entry.Id))
            {
                return(MLResult.Create(MLResult.Code.InvalidParam, "Unknown entry Id"));
            }

            if (thumbnailImage != null && thumbnailImage.format != TextureFormat.RGB24)
            {
                return(MLResult.Create(MLResult.Code.InvalidParam, "Invalid thumbnail parameter format"));
            }

            MLScreensNativeBindings.MLScreensWatchHistoryEntryNative nativeEntry = MLScreensNativeBindings.MLScreensWatchHistoryEntryNative.Create();
            nativeEntry.Data = entry;

            MLImageNativeBindings.MLImageNative thumbnail =
                thumbnailImage == null ? _defaultGrayThumbnailImage : CreateThumbnailImage(thumbnailImage);
            MLResult.Code resultCode = MLScreensNativeBindings.MLScreensUpdateWatchHistoryEntry(ref nativeEntry, ref thumbnail);

            if (thumbnail.Image != IntPtr.Zero && thumbnail.Image != _defaultGrayThumbnailImage.Image)
            {
                Marshal.FreeHGlobal(thumbnail.Image);
            }

            Marshal.FreeHGlobal(nativeEntry.Title);
            Marshal.FreeHGlobal(nativeEntry.Subtitle);
            Marshal.FreeHGlobal(nativeEntry.CustomData);

            var result = MLResult.Create(resultCode);

            if (result.IsOk)
            {
                _watchHistory[entry.Id] = entry;
            }

            return(result);
        }
            /// <summary>
            /// Fetch the specified attributes and callback when result is known.
            /// </summary>
            /// <param name="callback">The callback to notify when the CurrentRequest is complete.</param>
            /// <returns>
            /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the operation completed successfully.
            /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an internal error.
            /// </returns>
            public MLResult Fetch(Request.RequestAttibutesDelegate callback)
            {
                if (this.CurrentRequest != null)
                {
                    MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "Already fetching attributes");
                    MLPluginLog.ErrorFormat("MLIdentity.Profile.Fetch failed. Reason: {0}", result);
                    return(result);
                }

                this.CurrentRequest = new Request
                {
                    Callback     = callback,
                    ResultCode   = MLResult.Code.Pending,
                    RequestState = Request.State.REQUEST_ATTRIB_NAMES,
                };

                MLIdentity.AddProfile(this);

                return(MLResult.Create(MLResult.Code.Ok));
            }
            /// <summary>
            /// Set the longer dimension of the image target.
            /// </summary>
            /// <param name="longerDimension"> Longer dimension in scene units. Default is meters.</param>
            /// <returns>
            /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful.
            /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter.
            /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error.
            /// </returns>
            public MLResult SetTargetLongerDimension(float longerDimension)
            {
                if (Mathf.Approximately(this.targetSettings.LongerDimension, longerDimension))
                {
                    return(MLResult.Create(MLResult.Code.Ok, "Longer dimension already set to value"));
                }

                float oldValue = this.targetSettings.LongerDimension;

                this.targetSettings.LongerDimension = longerDimension;
                MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateTargetSettings(this.trackerHandle, this.targetHandle, ref this.targetSettings);
                MLResult      result     = MLResult.Create(resultCode);

                if (!result.IsOk)
                {
                    this.targetSettings.LongerDimension = oldValue;
                }

                return(result);
            }
        /// <summary>
        /// <para>Attempts to cancel a previously requested selection process.</para>
        /// <para>If selection dialog has not yet been completed by the user, this request will
        /// dismiss the dialog and cancel the selection process.Otherwise this
        /// operation will return an error.</para>
        /// </summary>
        /// <returns>
        /// <para>MLResult.Result will be <c>MLResult.Code.Ok</c> if selection was successfully cancelled.</para>
        /// <para>MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if permissions haven't been granted to make this call.</para>
        /// <para>MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an unexpected failure.</para>
        /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsCancellationPending</c> if the selection request has been found and the system is attempting to cancel the process.</para>
        /// <para>MLResult.Result will be <c>MLResult.Code.ConnectionsInvalidHandle</c> if input handle is invalid.</para>
        /// </returns>
        public static MLResult CancelSelection()
        {
            if (MLConnections.IsValidInstance())
            {
                MLResult.Code resultCode = NativeBindings.MLConnectionsCancelSelection(_instance.selectionHandle);
                MLResult      result     = MLResult.Create(resultCode);

                if (!result.IsOk)
                {
                    MLPluginLog.ErrorFormat("MLConnections.CancelSelection failed to cancel the selection requested. Reason: {0}", result);
                }

                return(result);
            }
            else
            {
                MLPluginLog.ErrorFormat("MLConnections.CancelSelection failed. Reason: No Instance for MLConnections");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLConnections.CancelSelection failed. Reason: No Instance for MLConnections"));
            }
        }
Example #8
0
        /// <summary>
        /// Creates a new ray cast tracker.
        /// </summary>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful.
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to invalid input parameter.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error.
        /// </returns>
        protected override MLResult StartAPI()
        {
            _instance.trackerHandle = MagicLeapNativeBindings.InvalidHandle;

            MLResult.Code resultCode = NativeBindings.MLRaycastCreate(ref _instance.trackerHandle);
            if (resultCode != MLResult.Code.Ok)
            {
                MLResult result = MLResult.Create(resultCode);
                MLPluginLog.ErrorFormat("MLRaycast.StartAPI failed to create input tracker. Reason: {0}", result);
                return(result);
            }

            if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.trackerHandle))
            {
                MLPluginLog.Error("MLRaycast.StartAPI failed. Reason: Invalid handle returned when initializing an instance of MLRaycast");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure));
            }

            return(MLResult.Create(MLResult.Code.Ok));
        }
        /// <summary>
        /// Sets the offset position/rotation values from the current Perception root and can also set the PCF to be used as the new Perception root to which all MLSnapshotGetTransform will be relative to.
        /// </summary>
        /// <param name="offsetPosition">The offset to set from the root's position.</param>
        /// <param name="offsetRotation">The offset to set from the root's rotation.</param>
        /// <param name="pcf">The PCF to set the root to.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if operation completed successfully.
        /// MLResult.Result will be <c>MLResult.Code.MLPerceptionNotStarted</c> if unable to retrieve the Perception System.
        /// MLResult.Result will be <c>MLResult.Code.MLPerceptionInvalidPCFRoot</c> if the provided CFUID is not associated with a valid PCF.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the CFUID is not valid.
        /// </returns>
        public static MLResult SetPerceptionRoot(Vector3 offsetPosition, Quaternion offsetRotation, PCF pcf = null)
        {
            if (MLPersistentCoordinateFrames.IsValidInstance())
            {
                MLResult.Code resultCode = NativeBindings.SetPerceptionRoot(offsetPosition, offsetRotation, pcf);

                if (!MLResult.IsOK(resultCode))
                {
                    MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode));
                    return(MLResult.Create(MLResult.Code.UnspecifiedFailure, string.Format("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: {0}", MLResult.CodeToString(resultCode))));
                }

                return(MLResult.Create(resultCode));
            }
            else
            {
                MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames.");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.SetPerceptionRoot failed. Reason: No Instance for MLPersistentCoordinateFrames."));
            }
        }
Example #10
0
        /// <summary>
        /// Ends the collision matching the id and handle passed.
        /// </summary>
        /// <param name="collisionId">The id of the collider object.</param>
        /// <param name="collisionHandle">The handle for the collision session.</param>
        void EndCollision(CollisionType type, int collisionId, ulong collisionHandle)
        {
            MLResult result = MLMovement.EndCollision(sessionHandle, collisionHandle);

            if (type == CollisionType.Hard)
            {
                hardCollisionMap.Remove(collisionId);
            }
            else if (type == CollisionType.Soft)
            {
                softCollisionMap.Remove(collisionId);
            }

            if (!result.IsOk)
            {
                Debug.LogErrorFormat("MLMovementBehavior.EndCollision failed to end collision session, disabling script. Reason: {0}", result);
                enabled = false;
                return;
            }
        }
Example #11
0
        /// <summary>
        /// Starts a new soft collision session given some collider data.
        /// </summary>
        /// <param name="other">The collider data.</param>
        void StartSoftCollision(ref Collider other)
        {
            ulong collisionHandle = MagicLeapInternal.MagicLeapNativeBindings.InvalidHandle;

            Vector3 thisCenter       = objectCollider.bounds.center;
            Vector3 otherCenter      = other.bounds.center;
            float   maxDistance      = Vector3.Distance(thisCenter, otherCenter);
            float   closesetDistance = maxDistance * (other.gameObject.GetComponent <MLMovementCollider>().MaxDepth / 100.0f);

            MLResult result = MLMovement.StartSoftCollision(sessionHandle, otherCenter, closesetDistance, maxDistance, out collisionHandle);

            if (!result.IsOk)
            {
                Debug.LogErrorFormat("MLMovementBehavior.StartSoftCollision failed to start a soft collision, disabling script. Reason: {0}", result);
                enabled = false;
                return;
            }

            softCollisionMap.Add(other.gameObject.GetInstanceID(), collisionHandle);
        }
        /// <summary>
        /// Start up
        /// Note: This requires the privilege to be granted prior to Start()
        /// </summary>
        void Start()
        {
            MLResult result = MLPersistentStore.Start();

            if (!result.IsOk)
            {
                Debug.LogErrorFormat("MLPersistentBehavior failed starting MLPersistentStore, disabling script. Reason: {0}", result);
                enabled = false;
                return;
            }

            result = MLPersistentCoordinateFrames.Start();
            if (!result.IsOk)
            {
                MLPersistentStore.Stop();
                Debug.LogErrorFormat("MLPersistentBehavior failed starting MLPersistentCoordinateFrames, disabling script. Reason: {0}", result);
                enabled = false;
                return;
            }

            if (string.IsNullOrEmpty(UniqueId))
            {
                Debug.LogWarning("Unique Id is empty will try to use game object's name. It's good to provide a unique id for virtual objects to avoid weird behavior.");
                if (string.IsNullOrEmpty(gameObject.name))
                {
                    Debug.LogError("Either UniqueId or name should be non empty. Disabling component");
                    enabled = false;
                    return;
                }
                UniqueId = gameObject.name;
            }

            if (MLPersistentCoordinateFrames.IsReady)
            {
                CreateOrRestoreBinding();
            }
            else
            {
                MLPersistentCoordinateFrames.OnInitialized += HandleInitialized;
            }
        }
Example #13
0
        /// <summary>
        /// Request the specified privileges. This may solicit consent from the end-user.
        /// Note: The asynchronous callback occurs within the main thread.
        /// </summary>
        /// <param name="privilegeId">The privilege to request.</param>
        /// <param name="callback">Callback to be executed when the privilege request has completed.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the privilege request is in progress.
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if the callback is null.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started.
        /// Callback MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted.
        /// Callback MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied.
        /// </returns>
        public static MLResult RequestPrivilegeAsync(MLPrivileges.Id privilegeId, CallbackDelegate callback)
        {
            try
            {
                if (MLPrivileges.IsValidInstance())
                {
                    if (callback == null)
                    {
                        return(MLResult.Create(MLResult.Code.InvalidParam, "MLPrivileges.RequestPrivilegeAsync failed. Reason: Must send a valid callback."));
                    }

                    if (!_instance.currentRequests.ContainsKey(privilegeId))
                    {
                        IntPtr newRequest = IntPtr.Zero;

                        MLResult.Code resultCode = NativeBindings.MLPrivilegesRequestPrivilegeAsync(privilegeId, ref newRequest);
                        if (resultCode == MLResult.Code.Ok)
                        {
                            RequestPrivilegeQuery newQuery = new RequestPrivilegeQuery(callback, newRequest, privilegeId);
                            _instance.currentRequests.Add(privilegeId, newQuery);
                        }

                        return(MLResult.Create(resultCode));
                    }
                    else
                    {
                        return(MLResult.Create(MLResult.Code.Ok));
                    }
                }
                else
                {
                    MLPluginLog.ErrorFormat("MLPrivileges.RequestPrivilegeAsync failed. Reason: No Instance for MLPrivileges.");
                    return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilegeAsync failed. Reason: No Instance for MLPrivileges."));
                }
            }
            catch (System.EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLPrivileges.RequestPrivilegeAsync failed. Reason: API symbols not found");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.RequestPrivilegeAsync failed. Reason: API symbols not found."));
            }
        }
Example #14
0
        /// <summary>
        /// Retrieves the type of the PCF associated with the given CFUID.
        /// </summary>
        /// <param name="cfuid">The CFUID to look up the PCF type with.</param>
        /// <param name="type">Stores the type of PCF associated with the given CFUID.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if a valid PCF was found.
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to an invalid input parameter.
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if necessary privilege is missing.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to other internal error.
        /// MLResult.Result will be <c>MLResult.Code.PassableWorldLowMapQuality</c> if map quality is too low for content persistence. Continue building the map.
        /// MLResult.Result will be <c>MLResult.Code.PassableWorldNotFound</c> if the passed CFUID is not available.
        /// MLResult.Result will be <c>MLResult.Code.PassableWorldUnableToLocalize</c> if currently unable to localize into any map. Continue building the map.
        /// </returns>
        public static MLResult GetPCFTypeByCFUID(MagicLeapNativeBindings.MLCoordinateFrameUID cfuid, out PCF.Types type)
        {
            type = 0;

            if (MLPersistentCoordinateFrames.IsValidInstance())
            {
                try
                {
                    NativeBindings.FrameStateNative nativeState = NativeBindings.FrameStateNative.Create();
                    MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFramesGetFrameState(_instance.nativeTracker, in cfuid, ref nativeState);
                    if (!MLResult.IsOK(resultCode))
                    {
                        if (resultCode == MLResult.Code.PassableWorldLowMapQuality || resultCode == MLResult.Code.PassableWorldUnableToLocalize)
                        {
                            MLPluginLog.WarningFormat("Map quality not sufficient enough for MLPersistentCoordinateFrames.GetPCFTypeByCFUID. Reason: {0}", MLResult.CodeToString(resultCode));
                        }
                        else
                        {
                            MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: {0}", MLResult.CodeToString(resultCode));
                        }

                        return(MLResult.Create(resultCode, string.Format("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: {0}", MLResult.CodeToString(resultCode))));
                    }
                    else
                    {
                        type = nativeState.Type;
                        return(MLResult.Create(resultCode));
                    }
                }
                catch (EntryPointNotFoundException)
                {
                    MLPluginLog.Error("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: API symbols not found.");
                    return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: API symbols not found."));
                }
            }
            else
            {
                MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: No Instance for MLPersistentCoordinateFrames.");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPersistentCoordinateFrames.GetPCFTypeByCFUID failed. Reason: No Instance for MLPersistentCoordinateFrames."));
            }
        }
        /// <summary>
        /// Process pending requests and call the callback specified in the startup config.
        /// </summary>
        private void ProcessPendingQueries()
        {
            try
            {
                foreach (var pending in this.currentRequests.OrderByDescending(x => x.Key))
                {
                    MLResult.Code result = NativeBindings.MLPrivilegesRequestPrivilegeTryGet(pending.Value.Request);
                    if (result != MLResult.Code.Pending)
                    {
                        pending.Value.Result = MLResult.Create(result);
                        pending.Value.Callback(pending.Value.Result, pending.Key);

                        this.currentRequests.Remove(pending.Key);
                    }
                }
            }
            catch (System.EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLPrivileges.ProcessPendingQueries failed. Reason: API symbols not found");
            }
        }
        /// <summary>
        /// Initializes the image tracker.
        /// </summary>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error.
        /// </returns>
        protected override MLResult StartAPI()
        {
            this.handle = MagicLeapNativeBindings.InvalidHandle;
            MLResult.Code resultCode = NativeBindings.MLImageTrackerCreate(ref this.trackerSettings, ref this.handle);
            MLResult      result     = MLResult.Create(resultCode);

            if (result.IsOk)
            {
                bool success = MagicLeapNativeBindings.MLHandleIsValid(this.handle);
                if (!success)
                {
                    MLPluginLog.Error("MLImageTracker.StartApi failed. Reason: Invalid image tracker this.handle.");
                }
            }
            else
            {
                MLPluginLog.ErrorFormat("MLImageTracker.StartApi failed to create image tracker this.handle. Reason: {0}", result);
            }

            return(result);
        }
        /// <summary>
        /// Sets the Image Tracker's settings to match the provided settings.
        /// </summary>
        /// <param name="customSettings">The new MLImageTracker.Settings wanted.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successfully updated the image tracker settings.
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed to update the settings due to invalid input parameter.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if failed due to internal error.
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if failed to update the settings due to lack of privilege(s).
        /// </returns>
        public static MLResult UpdateTrackerSettings(MLImageTracker.Settings customSettings)
        {
            var currentSettings = GetCurrentTrackerSettings();

            if (currentSettings == customSettings)
            {
                return(MLResult.Create(MLResult.Code.Ok, "No change needed"));
            }

            Instance.trackerSettings = new NativeBindings.MLImageTrackerSettingsNative(customSettings);

            MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateSettings(Instance.handle, ref Instance.trackerSettings);
            MLResult      result     = MLResult.Create(resultCode);

            if (!result.IsOk)
            {
                Instance.trackerSettings = new NativeBindings.MLImageTrackerSettingsNative(currentSettings);
            }

            return(result);
        }
Example #18
0
        /// <summary>
        /// Starts the MLInput, initializes the first controller, and registers the connection handlers
        /// </summary>
        void Awake()
        {
            if (!MLInput.IsStarted)
            {
                MLInputConfiguration config = new MLInputConfiguration(MLInputConfiguration.DEFAULT_TRIGGER_DOWN_THRESHOLD,
                                                                       MLInputConfiguration.DEFAULT_TRIGGER_UP_THRESHOLD,
                                                                       true);
                MLResult result = MLInput.Start(config);
                if (!result.IsOk)
                {
                    Debug.LogErrorFormat("Error: ControllerConnectionHandler failed starting MLInput, disabling script. Reason: {0}", result);
                    enabled = false;
                    return;
                }
            }

            MLInput.OnControllerConnected    += HandleOnControllerConnected;
            MLInput.OnControllerDisconnected += HandleOnControllerDisconnected;

            GetAllowedInput();
        }
            /// <summary>
            /// Destroys the video sink.
            /// </summary>
            /// <returns>
            /// MLResult.Result will be <c>MLResult.Code.Ok</c> if destroying all handles was successful.
            /// MLResult.Result will be <c>MLResult.Code.WebRTCResultInstanceNotCreated</c> if MLWebRTC instance was not created.
            /// MLResult.Result will be <c>MLResult.Code.WebRTCResultMismatchingHandle</c> if an incorrect handle was sent.
            /// </returns>
            public override MLResult Destroy()
            {
#if PLATFORM_LUMIN
                if (!MagicLeapNativeBindings.MLHandleIsValid(this.Handle))
                {
                    return(MLResult.Create(MLResult.Code.InvalidParam, "Handle is invalid."));
                }

                updateVideoEvent.WaitOne(250);
                this.SetStream(null);

                MLResult.Code resultCode = NativeBindings.MLWebRTCVideoSinkDestroy(this.Handle);
                DidNativeCallSucceed(resultCode, "MLWebRTCVideoSinkDestroy()");
                this.InvalidateHandle();
                MLWebRTC.Instance.sinks.Remove(this);

                return(MLResult.Create(resultCode));
#else
                return(new MLResult());
#endif
            }
Example #20
0
        /// <summary>
        /// Requests for the hand mesh and executes the callback when the request is done.
        /// </summary>
        /// <param name="callback">Callback to execute when the request is done.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if successful.
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if failed due to internal invalid input parameter.
        /// </returns>
        public static MLResult RequestHandMesh(RequestHandMeshCallback callback)
        {
            if (callback == null)
            {
                MLPluginLog.ErrorFormat("MLHandMeshing.RequestHandMesh failed. Reason: Passed input callback is null");
                return(MLResult.Create(MLResult.Code.InvalidParam));
            }

            ulong requestHandle = MagicLeapNativeBindings.InvalidHandle;

            MLResult.Code resultCode = NativeBindings.MLHandMeshingRequestMesh(Instance.nativeTracker, ref requestHandle);
            if (resultCode != MLResult.Code.Ok)
            {
                MLPluginLog.ErrorFormat("MLHandMeshing.RequestHandMesh failed to request hand mesh. Reason: {0}", resultCode);
                return(MLResult.Create(resultCode));
            }

            Instance.pendingQueries.Add(new Query(requestHandle, callback));

            return(MLResult.Create(resultCode));
        }
        /// <summary>
        /// Internal call used to set the status of the Image Tracker.
        /// </summary>
        /// <param name="enabled">Used to enabled or disable Image Tracker to be enabled or disabled.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if there were invalid trackerSettings when setting the Image Tracker status.
        /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the Image Tracker status was updated successfully or if no change was needed.
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privileges.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an internal error.
        /// </returns>
        private MLResult SetTrackerStatusInternal(bool enabled)
        {
            if (this.trackerSettings.EnableTracker == enabled)
            {
                return(MLResult.Create(MLResult.Code.Ok, "No change needed"));
            }

            bool prevStatus = this.trackerSettings.EnableTracker;

            this.trackerSettings.EnableTracker = enabled;

            MLResult.Code resultCode = NativeBindings.MLImageTrackerUpdateSettings(this.handle, ref this.trackerSettings);
            MLResult      result     = MLResult.Create(resultCode);

            if (!result.IsOk)
            {
                this.trackerSettings.EnableTracker = prevStatus;
            }

            return(result);
        }
Example #22
0
 /// <summary>
 /// Checks whether the application has the specified privileges.
 /// This does not solicit consent from the end-user.
 /// </summary>
 /// <param name="privilegeId">The privilege to check for access.</param>
 /// <returns>
 /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted.
 /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied.
 /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started.
 /// </returns>
 public static MLResult CheckPrivilege(MLPrivileges.Id privilegeId)
 {
     try
     {
         if (MLPrivileges.IsValidInstance())
         {
             MLResult.Code checkPrivilegeResult = NativeBindings.MLPrivilegesCheckPrivilege(privilegeId);
             return((checkPrivilegeResult == MLResult.Code.PrivilegeNotGranted) ? MLResult.Create(checkPrivilegeResult, "Privilege Denied or Not Yet Requested.") : MLResult.Create(checkPrivilegeResult));
         }
         else
         {
             MLPluginLog.ErrorFormat("MLPrivileges.CheckPrivilege failed. Reason: No Instance for MLPrivileges.");
             return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.CheckPrivilege failed. Reason: No Instance for MLPrivileges."));
         }
     }
     catch (System.EntryPointNotFoundException)
     {
         MLPluginLog.Error("MLPrivileges.CheckPrivilege failed. Reason: API symbols not found");
         return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLPrivileges.CheckPrivilege failed. Reason: API symbols not found."));
     }
 }
        /// <summary>
        /// Start this instance.
        /// </summary>
        void Start()
        {
            MLResult result = MLPersistentStore.Start();

            if (!result.IsOk)
            {
                SetError("Failed to start persistent store. Disabling component");
                enabled = false;
                return;
            }
            result = MLPersistentCoordinateFrames.Start();
            if (!result.IsOk)
            {
                MLPersistentStore.Stop();
                SetError("Failed to start coordinate frames system. disabling component");
                enabled = false;
                return;
            }

            if (_representativePrefab == null)
            {
                SetError("Error: _representativePrefab must be set");
                enabled = false;
                return;
            }

            List <MLPCF> pcfList;

            result = MLPersistentCoordinateFrames.GetAllPCFs(out pcfList, int.MaxValue);
            if (!result.IsOk)
            {
                MLPersistentStore.Stop();
                MLPersistentCoordinateFrames.Stop();
                SetError(result.ToString());
                enabled = false;
                return;
            }

            TryShowingAllPCFs(pcfList);
        }
                /// <summary>
                /// Destroys the Track and its associated media source.
                /// </summary>
                /// <returns>
                /// MLResult.Result will be <c>MLResult.Code.Ok</c> if destroying all handles was successful.
                /// MLResult.Result will be <c>MLResult.Code.WebRTCResultInstanceNotCreated</c> if MLWebRTC instance was not created.
                /// MLResult.Result will be <c>MLResult.Code.WebRTCResultMismatchingHandle</c> if an incorrect handle was sent.
                /// </returns>
                public virtual MLResult DestroyLocal()
                {
#if PLATFORM_LUMIN
                    if (!this.IsLocal)
                    {
                        return(MLResult.Create(MLResult.Code.InvalidParam, "Souce is not local."));
                    }

                    if (!MagicLeapNativeBindings.MLHandleIsValid(this.Handle))
                    {
                        return(MLResult.Create(MLResult.Code.InvalidParam, "Source handle is invalid."));
                    }

                    this.Cleanup();

                    MLResult.Code resultCode = MLResult.Code.Ok;

                    // If this is a local source then we need to explicitly remove it from it's associated connections.
                    foreach (MLWebRTC.PeerConnection connection in Instance.connections)
                    {
                        if (connection == this.ParentConnection)
                        {
                            connection.RemoveLocalTrack(this);
                            break;
                        }
                    }

                    MLWebRTC.Instance.localTracks.Remove(this);

                    resultCode = Source.NativeBindings.MLWebRTCSourceDestroy(this.Handle);
                    DidNativeCallSucceed(resultCode, "MLWebRTCSourceDestroy()");
                    this.Handle           = MagicLeapNativeBindings.InvalidHandle;
                    this.ParentConnection = null;

                    return(MLResult.Create(resultCode));
#else
                    return(new MLResult());
#endif
                }
Example #25
0
        /// <summary>
        /// Cleans up unmanaged memory.
        /// </summary>
        /// <param name="isSafeToAccessManagedObjects">Determines if the pendingPCFPoseQueries list should be cleared.</param>
        protected override void CleanupAPI(bool isSafeToAccessManagedObjects)
        {
            if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.nativeTracker))
            {
                return;
            }

            try
            {
                MLResult.Code resultCode = NativeBindings.MLPersistentCoordinateFrameTrackerDestroy(_instance.nativeTracker);
                if (!MLResult.IsOK(resultCode))
                {
                    MLPluginLog.ErrorFormat("MLPersistentCoordinateFrames.CleanupAPI failed to destroy PersistentCoordinateFrame tracker. Reason: {0}", MLResult.CodeToString(resultCode));
                }

                _instance.nativeTracker = MagicLeapNativeBindings.InvalidHandle;
            }
            catch (EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLPersistentCoordinateFrames.CleanupAPI failed. Reason: API symbols not found.");
            }
        }
Example #26
0
            /// <summary>
            /// Call for querying the last known coarse/fine location.
            /// The accuracy field of the MLLocation.Location provides the estimate accuracy radius in meters.
            /// Returns the last known data on success and returns the last queried location data on failure. Latitude and Longitude of
            /// 0 should be assumed an Invalid Location.
            /// </summary>
            /// <param name="outLocation">Where to store the last known fine location. Only updates when getting the location succeeds. Latitude and Longitude of 0 should be assumed an Invalid Location.</param>
            /// <param name="isFine">Determines whether to query for fine location or coarse location.</param>
            /// <returns>
            /// MLResult.Result will be <c>MLResult.Code.Ok</c> if the location was queried successfully.
            /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if there was an internal error.
            /// MLResult.Result will be <c>MLResult.Code.InvalidParam</c> if there was an invalid location.
            /// MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if there was a lack of privilege(s).
            /// MLResult.Result will be <c>MLResult.Code.LocationProviderNotFound</c> if there was no provider or an invalid request was made.
            /// MLResult.Result will be <c>MLResult.Code.LocationNetworkConnection</c> if there was no internet connection.
            /// MLResult.Result will be <c>MLResult.Code.LocationNoLocation</c> if the location could not be found.
            /// </returns>
            public static MLResult MLLocationGetLastLocation(out MLLocation.Location outLocation, bool isFine)
            {
                // The automatic marshaling was not working properly for this structure. TimeStamp was always 0. To solve this
                // we use an IntPtr that has the proper default values set.
                NativeBindings.LocationNative location = NativeBindings.LocationNative.Create();
                MLResult.Code resultCode;

                IntPtr myPointer = Marshal.AllocHGlobal(Marshal.SizeOf(location));

                Marshal.StructureToPtr(location, myPointer, false);

                try
                {
                    resultCode = isFine ? NativeBindings.MLLocationGetLastFineLocation(myPointer) : NativeBindings.MLLocationGetLastCoarseLocation(myPointer);

                    if (resultCode != MLResult.Code.Ok)
                    {
                        MLPluginLog.ErrorFormat("MLLocation.NativeBindings.MLLocationGetLastLocation failed to get location. Reason: {0}", resultCode);
                    }
                }
                catch (EntryPointNotFoundException)
                {
                    MLResult result = MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLLocation API symbols not found.");
                    MLPluginLog.ErrorFormat("MLLocation.NativeBindings.MLLocationGetLastLocation failed to get location. Reason: {0}", result);
                    outLocation = new MLLocation.Location();
                    Marshal.FreeHGlobal(myPointer);
                    return(result);
                }

                location = (NativeBindings.LocationNative)Marshal.PtrToStructure(myPointer, typeof(NativeBindings.LocationNative));

                Marshal.FreeHGlobal(myPointer);

                MLResult finalResult = MLResult.Create(resultCode);

                outLocation = location.Data;

                return(finalResult);
            }
        /// <summary>
        /// Request a subset of connections as manually selected by the user. The results are delivered via a callback
        /// </summary>
        /// <param name="maxSelectionAmount">Max number of connections to be selected. Min limit is 1.</param>
        /// <param name="userPrompt">Text prompt to be displayed to the user with selection dialog. The max length for the prompt is 40 characters.</param>
        /// <param name="defaultFilter">Type of filter applied by default to MLConnections list in selection dialog.</param>
        /// <returns>
        /// <para>MLResult.Result will be <c>MLResult.Code.Ok</c> if successfully submitted.</para>
        /// <para>MLResult.Result will be <c>MLResult.Code.PrivilegeDenied</c> if permissions haven't been granted to make this call.</para>
        /// </returns>
        public static MLResult GetSelection(uint maxSelectionAmount, string userPrompt, SelectionFilter defaultFilter)
        {
            if (MLConnections.IsValidInstance())
            {
                NativeBindings.SelectionArgs argsToSend = NativeBindings.SelectionArgs.Create(maxSelectionAmount, userPrompt, defaultFilter);

                MLResult.Code resultCode = NativeBindings.MLConnectionsRequestSelection(ref argsToSend, ref _instance.selectionHandle);
                MLResult      result     = MLResult.Create(resultCode);

                if (!result.IsOk)
                {
                    MLPluginLog.ErrorFormat("MLConnections.GetSelection failed to request a selection. Reason: {0}", result);
                }

                return(result);
            }
            else
            {
                MLPluginLog.ErrorFormat("MLConnections.GetSelection failed. Reason: No Instance for MLConnections");
                return(MLResult.Create(MLResult.Code.UnspecifiedFailure, "MLConnections.GetSelection failed. Reason: No Instance for MLConnections"));
            }
        }
        /// <summary>
        /// Requests the specified privileges. This may possibly solicit consent from the end-user.
        /// </summary>
        /// <param name="privilegeIds">The privileges to request.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted.
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started.
        /// </returns>
        public static MLResult RequestPrivileges(params MLPrivileges.Id[] privilegeIds)
        {
#if PLATFORM_LUMIN
            MLResult result = new MLResult();

            foreach (MLPrivileges.Id privilegeId in privilegeIds)
            {
                result = CheckPrivilege(privilegeId);
                if (result.Result == MLResult.Code.PrivilegeGranted)
                {
                    continue;
                }

                result = RequestPrivilege(privilegeId);
                if (result.Result != MLResult.Code.PrivilegeGranted)
                {
                    return(result);
                }
            }
#endif
            return(result);
        }
        /// <summary>
        /// Request the specified privilege asynchronously. This may solicit consent from the end-user.
        /// This async override uses Tasks instead of a callback.
        /// </summary>
        /// <param name="privilegeId">The privilege to request.</param>
        /// <returns>
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeGranted</c> if the privilege is granted.
        /// MLResult.Result will be <c>MLResult.Code.PrivilegeNotGranted</c> if the privilege is denied.
        /// MLResult.Result will be <c>MLResult.Code.UnspecifiedFailure</c> if the privilege system was not started.
        /// </returns>
        private async Task <MLResult> RequestPrivilegeAsyncInternal(MLPrivileges.Id privilegeId)
        {
            var taskCompletionSource = new TaskCompletionSource <MLResult>();

            if (this.currentRequests.ContainsKey(privilegeId))
            {
                return(MLResult.Create(MLResult.Code.Ok));
            }

            IntPtr newRequest = IntPtr.Zero;

            MLResult.Code resultCode = NativeBindings.MLPrivilegesRequestPrivilegeAsync(privilegeId, ref newRequest);
            if (!MLResult.IsOK(resultCode))
            {
                return(MLResult.Create(resultCode));
            }

            RequestPrivilegeQuery newQuery = new RequestPrivilegeQuery((result, id) => taskCompletionSource.SetResult(result), newRequest, privilegeId);

            this.currentRequests.Add(privilegeId, newQuery);
            return(await taskCompletionSource.Task);
        }
        /// <summary>
        /// Destroy the found object native tracker.
        /// </summary>
        private void DestroyNativeTracker()
        {
            try
            {
                if (!MagicLeapNativeBindings.MLHandleIsValid(_instance.handle))
                {
                    return;
                }

                MLResult.Code resultCode = NativeBindings.MLFoundObjectTrackerDestroy(_instance.handle);
                if (!MLResult.IsOK(resultCode))
                {
                    MLPluginLog.ErrorFormat("MLFoundObjects.DestroyNativeTracker failed to destroy found object tracker. Reason: {0}", MLResult.CodeToString(resultCode));
                }

                _instance.handle = MagicLeapNativeBindings.InvalidHandle;
            }
            catch (System.EntryPointNotFoundException)
            {
                MLPluginLog.Error("MLFoundObjects.DestroyNativeTracker failed. Reason: API symbols not found");
            }
        }