public static void CreateAsync(string name, Action <Protocol> callback) { new Thread(() => { Probe.GetAllAsync(probes => { Protocol protocol = new Protocol(name); foreach (Probe probe in probes) { protocol.AddProbe(probe); } callback(protocol); }); }).Start(); }
/// <summary> /// Converts JSON to a Protocol object. Private because Protocols should always be serialized as encrypted binary codes, and this function works with unencrypted strings (it's called in service of the former). /// </summary> /// <param name="json">JSON to deserialize.</param> private static void DisplayFromJsonAsync(string json) { new Thread(() => { try { #region allow protocols to be opened across platforms by manually editing the namespaces in the JSON string newJSON; switch (SensusServiceHelper.Get().GetType().Name) { case "AndroidSensusServiceHelper": newJSON = json.Replace(".iOS", ".Android").Replace(".WinPhone", ".Android"); break; case "iOSSensusServiceHelper": newJSON = json.Replace(".Android", ".iOS").Replace(".WinPhone", ".iOS"); break; case "WinPhone": newJSON = json.Replace(".Android", ".WinPhone").Replace(".iOS", ".WinPhone"); break; default: throw new SensusException("Attempted to deserialize JSON into unknown service helper type: " + SensusServiceHelper.Get().GetType().FullName); } if (newJSON == json) { SensusServiceHelper.Get().Logger.Log("No cross-platform conversion required for service helper JSON.", LoggingLevel.Normal, typeof(Protocol)); } else { SensusServiceHelper.Get().Logger.Log("Performed cross-platform conversion of service helper JSON.", LoggingLevel.Normal, typeof(Protocol)); json = newJSON; } #endregion Protocol protocol = null; ManualResetEvent protocolWait = new ManualResetEvent(false); // always deserialize protocols on the main thread (e.g., since a looper might be required for android) Device.BeginInvokeOnMainThread(() => { try { protocol = JsonConvert.DeserializeObject <Protocol>(json, SensusServiceHelper.JSON_SERIALIZER_SETTINGS); } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Error while deserializing protocol: " + ex.Message, LoggingLevel.Normal, typeof(Protocol)); } finally { protocolWait.Set(); } }); protocolWait.WaitOne(); if (protocol == null) { SensusServiceHelper.Get().Logger.Log("Failed to deserialize protocol.", LoggingLevel.Normal, typeof(Protocol)); SensusServiceHelper.Get().FlashNotificationAsync("Failed to deserialize protocol."); return; } else { Action <Protocol> StartProtocol = p => { Device.BeginInvokeOnMainThread(async() => { if (!(App.Current.MainPage.Navigation.NavigationStack.Last() is ProtocolsPage)) { await App.Current.MainPage.Navigation.PushAsync(new ProtocolsPage()); } p.StartWithUserAgreement("You just opened a protocol named \"" + p.Name + "\" within Sensus." + (string.IsNullOrWhiteSpace(p.StartupAgreement) ? "" : " Please read the following terms and conditions.")); }); }; Protocol existingProtocol = SensusServiceHelper.Get().RegisteredProtocols.FirstOrDefault(p => p.Id == protocol.Id); if (existingProtocol == null) { Probe.GetAllAsync(probes => { // add any probes for the current platform that didn't come through when deserializing. for example, android has a listening WLAN probe, but iOS has a polling WLAN probe. neither will come through on the other platform when deserializing, since the types are not defined. List <Type> deserializedProbeTypes = protocol.Probes.Select(p => p.GetType()).ToList(); foreach (Probe probe in probes) { if (!deserializedProbeTypes.Contains(probe.GetType())) { SensusServiceHelper.Get().Logger.Log("Adding missing probe to protocol: " + probe.GetType().FullName, LoggingLevel.Normal, typeof(Protocol)); protocol.AddProbe(probe); } } // reset the random time anchor -- we shouldn't use the same one that someone else used protocol.ResetRandomTimeAnchor(); // reset the storage directory protocol.StorageDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), protocol.Id); if (!Directory.Exists(protocol.StorageDirectory)) { Directory.CreateDirectory(protocol.StorageDirectory); } SensusServiceHelper.Get().RegisterProtocol(protocol); StartProtocol(protocol); }); } else if (existingProtocol.Running) { SensusServiceHelper.Get().FlashNotificationAsync("Protocol \"" + existingProtocol.Name + "\" is already running."); } else { StartProtocol(existingProtocol); } } } catch (Exception ex) { SensusServiceHelper.Get().Logger.Log("Failed to deserialize/display protocol from JSON: " + ex.Message, LoggingLevel.Normal, typeof(Protocol)); SensusServiceHelper.Get().FlashNotificationAsync("Failed to deserialize and/or display protocol."); } }).Start(); }