private IEnumerator _AttemptRecoverIfInvalidState() { const string ANDROID_CAMERA_PERMISSION_NAME = "android.permission.CAMERA"; const int MAX_RECOVERY_ATTEMPTS = 10; var permissionsArray = new string[] { ANDROID_CAMERA_PERMISSION_NAME }; while (true) { if (TangoClientApi.CallsToConnectWithoutMatchingDisconnect()) { Debug.LogWarning("Recovery daemon detected ARCore connection problem. Cycling pause resume."); // Asking for the camera permission we already have forces a Pause/Resume "kick". AndroidPermissionsManager.RequestPermission(permissionsArray); // This avoids thrashing on recovery attempts. if (++m_numberOfRecoveryAttempts >= MAX_RECOVERY_ATTEMPTS) { yield break; } } yield return(null); } }
/// <summary> /// Connects an ARSession. Note that if user permissions are needed they will be requested and thus this is an /// asynchronous method. /// </summary> /// <param name="sessionConfig">The session configuration.</param> /// <returns>An <c>AsyncTask</c> that completes when the connection has been made or failed. </returns> public AsyncTask <SessionConnectionState> Connect(SessionConfig sessionConfig) { const string ANDROID_CAMERA_PERMISSION_NAME = "android.permission.CAMERA"; if (sessionConfig == null) { ARDebug.LogError("Unable to connect ARSession session due to missing ARSessionConfig."); SessionManager.ConnectionState = SessionConnectionState.MissingConfiguration; return(new AsyncTask <SessionConnectionState>(SessionManager.ConnectionState)); } bool isSupported; ApiServiceErrorStatus status = TangoClientApi.TangoService_IsSupported(out isSupported); if (status.IsTangoFailure()) { ARDebug.LogError("There was an error accessing the ARCore API."); SessionManager.ConnectionState = SessionConnectionState.ConnectToServiceFailed; return(new AsyncTask <SessionConnectionState>(SessionManager.ConnectionState)); } if (!isSupported) { ARDebug.LogError("Device does not support ARCore."); SessionManager.ConnectionState = SessionConnectionState.DeviceNotSupported; return(new AsyncTask <SessionConnectionState>(SessionManager.ConnectionState)); } // We have already connected at least once. if (SessionManager.ConnectionState != SessionConnectionState.Uninitialized) { ARDebug.LogError("Multiple attempts to connect to the ARSession. Note that the ARSession connection " + "spans the lifetime of the application and cannot be reconfigured. This will change in future " + "versions of ARCore."); return(new AsyncTask <SessionConnectionState>(SessionManager.ConnectionState)); } // Create an asynchronous task for the potential permissions flow and service connection. Action <SessionConnectionState> onTaskComplete; var returnTask = new AsyncTask <SessionConnectionState>(out onTaskComplete); // Attempt service connection immediately if permissions are granted. if (AndroidPermissionsManager.IsPermissionGranted(ANDROID_CAMERA_PERMISSION_NAME)) { _ConnectToService(sessionConfig, onTaskComplete); return(returnTask); } // Request needed permissions and attempt service connection if granted. var permissionsArray = new string[] { ANDROID_CAMERA_PERMISSION_NAME }; AndroidPermissionsManager.RequestPermission(permissionsArray).ThenAction((requestResult) => { if (requestResult.IsAllGranted) { _ConnectToService(sessionConfig, onTaskComplete); } else { ARDebug.LogError("ARCore connection failed because a needed permission was rejected."); SessionManager.ConnectionState = SessionConnectionState.UserRejectedNeededPermission; onTaskComplete(SessionManager.ConnectionState); } }); return(returnTask); }