/// <summary> /// A method that lets the VoIP background process know that the UI process is connected to it. /// Call this method at the beginning of the Launching and Activated event handlers. /// </summary> public void ConnectUi() { if (this.isConnected) { // Nothing more to be done return; } // Start the VoIP background agent host process, if it is not started already int backgroundProcessId; try { VoipBackgroundProcess.Launch(out backgroundProcessId); } catch (Exception err) { Debug.WriteLine("[App] Error launching VoIP background process. UI may no longer be in the foreground. Exception: " + err.Message); throw; } // Wait for the background process to become ready string backgroundProcessReadyEventName = Globals.GetBackgroundProcessReadyEventName((uint)backgroundProcessId); using (EventWaitHandle backgroundProcessReadyEvent = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset, name: backgroundProcessReadyEventName)) { TimeSpan timeout = Debugger.IsAttached ? BackgroundProcessController.indefiniteWait : BackgroundProcessController.fifteenSeconds; if (!backgroundProcessReadyEvent.WaitOne(timeout)) { // We timed out - something is wrong throw new InvalidOperationException(string.Format("The background process did not become ready in {0} milliseconds", timeout.Milliseconds)); } else { Debug.WriteLine("[App] Background process {0} is ready", backgroundProcessId); } } // The background process is now ready. // It is possible that the background process now becomes "not ready" again, but the chances of this happening are slim, // and in that case, the following statement would fail - so, at this point, we don't explicitly guard against this condition. // Create an instance of the server in the background process. this.server = (Server)WindowsRuntimeMarshal.GetActivationFactory(typeof(Server)).ActivateInstance(); // Un-set an event that indicates that the UI process is disconnected from the background process. // The VoIP background process waits for this event to get set before shutting down. // This ensures that the VoIP background agent host process doesn't shut down while the UI process is connected to it. string uiDisconnectedEventName = Globals.GetUiDisconnectedEventName((uint)backgroundProcessId); this.uiDisconnectedEvent = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset, name: uiDisconnectedEventName); this.uiDisconnectedEvent.Reset(); // The UI process is now connected to the background process this.isConnected = true; }
// Constructor public MainPage() { InitializeComponent(); var stopwatch = new Stopwatch(); stopwatch.Start(); try { VoipBackgroundProcess.Launch(); } catch (InvalidCastException err) { Debug.WriteLine("[App] Error launching VoIP background process. UI may no longer be in the foreground. Exception: " + err.Message); throw; } long elapsed_time = stopwatch.ElapsedMilliseconds; Debug.WriteLine(elapsed_time); //Task.Run(() => { VoipBackgroundProcess.Launch(); } // ); #if TA Loaded += MainPage_Loaded; #endif }
/// <summary> /// Starts and connects the UI to the background process. /// </summary> public void ConnectBackgroundProcessToInterface() { TileManager.Instance.RemoveCountOnTile(); if (BackgroundProcessConnected) { Debug.WriteLine("[LinphoneManager] Background process already connected to interface"); return; } int backgroundProcessID; try { VoipBackgroundProcess.Launch(out backgroundProcessID); } catch (Exception e) { Debug.WriteLine("[LinphoneManager] Error launching VoIP background process. Exception: " + e.Message); throw; } try { server = BackgroundManager.Instance.OopServer; } catch (Exception) { // Wait for the background process to become ready string backgroundProcessReadyEventName = Globals.GetBackgroundProcessReadyEventName((uint)backgroundProcessID); using (EventWaitHandle backgroundProcessReadyEvent = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset, name: backgroundProcessReadyEventName)) { TimeSpan timeout = twoSecs; if (!backgroundProcessReadyEvent.WaitOne(timeout)) { // We timed out - something is wrong throw new InvalidOperationException(string.Format("The background process ({0}) did not become ready in {1} seconds", backgroundProcessID, timeout.Seconds)); } else { Debug.WriteLine("[LinphoneManager] Background process {0} is ready", backgroundProcessID); } } // The background process is now ready. // It is possible that the background process now becomes "not ready" again, but the chances of this happening are slim, // and in that case, the following statement would fail - so, at this point, we don't explicitly guard against this condition. server = BackgroundManager.Instance.OopServer; } // Un-set an event that indicates that the UI process is disconnected from the background process. // The background process waits for this event to get set before shutting down. // This ensures that the background agent host process doesn't shut down while the UI process is connected to it. string uiDisconnectedEventName = Globals.GetUiDisconnectedEventName((uint)backgroundProcessID); uiDisconnectedEvent = new EventWaitHandle(initialState: false, mode: EventResetMode.ManualReset, name: uiDisconnectedEventName); uiDisconnectedEvent.Reset(); BackgroundProcessConnected = true; Debug.WriteLine("[LinphoneManager] Background process connected to interface"); // Create LinphoneCore if not created yet, otherwise do nothing InitLinphoneCore(); }