// Tells the local API when new diagnosis keys have been obtained from the server static async Task <(ExposureDetectionSummary, IEnumerable <ExposureInfo>)> PlatformDetectExposuresAsync(IEnumerable <string> keyFiles) { // Submit to the API var c = await GetConfigurationAsync(); var m = await GetManagerAsync(); var detectionSummary = await m.DetectExposuresAsync( c, keyFiles.Select(k => new NSUrl(k, false)).ToArray()); var summary = new ExposureDetectionSummary( (int)detectionSummary.DaysSinceLastExposure, detectionSummary.MatchedKeyCount, detectionSummary.MaximumRiskScore); // Get the info IEnumerable <ExposureInfo> info = Array.Empty <ExposureInfo>(); if (summary?.MatchedKeyCount > 0) { var exposures = await m.GetExposureInfoAsync(detectionSummary, Handler.UserExplanation); info = exposures.Select(i => new ExposureInfo( ((DateTime)i.Date).ToLocalTime(), TimeSpan.FromMinutes(i.Duration), i.AttenuationValue, i.TotalRiskScore, i.TransmissionRiskLevel.FromNative())); } // Return everything return(summary, info); }
// Tells the local API when new diagnosis keys have been obtained from the server static async Task <(ExposureDetectionSummary, Func <Task <IEnumerable <ExposureInfo> > >)> PlatformDetectExposuresAsync(IEnumerable <string> keyFiles, CancellationToken cancellationToken) { // Submit to the API var c = await GetConfigurationAsync(); var m = await GetManagerAsync(); // Extract all the files from the zips var allFiles = new List <string>(); foreach (var file in keyFiles) { using var stream = File.OpenRead(file); using var archive = new ZipArchive(stream, ZipArchiveMode.Read); // .bin var binTmp = Path.Combine(FileSystem.CacheDirectory, Guid.NewGuid().ToString() + ".bin"); using (var binWrite = File.Create(binTmp)) { var bin = archive.GetEntry("export.bin"); using var binRead = bin.Open(); await binRead.CopyToAsync(binWrite); } allFiles.Add(binTmp); // .sig var sigTmp = Path.ChangeExtension(binTmp, ".sig"); using (var sigWrite = File.Create(sigTmp)) { var sig = archive.GetEntry("export.sig"); using var sigRead = sig.Open(); await sigRead.CopyToAsync(sigWrite); } allFiles.Add(sigTmp); } // Start the detection var detectionSummaryTask = m.DetectExposuresAsync( c, allFiles.Select(k => new NSUrl(k, false)).ToArray(), out var detectProgress); cancellationToken.Register(detectProgress.Cancel); var detectionSummary = await detectionSummaryTask; // Delete all the extracted files foreach (var file in allFiles) { try { File.Delete(file); } catch { // no-op } } var attDurTs = new List <TimeSpan>(); var dictKey = new NSString("attenuationDurations"); if (detectionSummary.Metadata.ContainsKey(dictKey)) { var attDur = detectionSummary.Metadata.ObjectForKey(dictKey) as NSArray; for (nuint i = 0; i < attDur.Count; i++) { attDurTs.Add(TimeSpan.FromSeconds(attDur.GetItem <NSNumber>(i).Int32Value)); } } var sumRisk = 0; dictKey = new NSString("riskScoreSumFullRange"); if (detectionSummary.Metadata.ContainsKey(dictKey)) { var sro = detectionSummary.Metadata.ObjectForKey(dictKey); if (sro is NSNumber sron) { sumRisk = sron.Int32Value; } } var maxRisk = 0; dictKey = new NSString("maximumRiskScoreFullRange"); if (detectionSummary.Metadata.ContainsKey(dictKey)) { var sro = detectionSummary.Metadata.ObjectForKey(dictKey); if (sro is NSNumber sron) { maxRisk = sron.Int32Value; } } else { maxRisk = detectionSummary.MaximumRiskScore; } var summary = new ExposureDetectionSummary( (int)detectionSummary.DaysSinceLastExposure, detectionSummary.MatchedKeyCount, maxRisk, attDurTs.ToArray(), sumRisk); async Task <IEnumerable <ExposureInfo> > GetInfo() { // Get the info IEnumerable <ExposureInfo> info = Array.Empty <ExposureInfo>(); if (summary?.MatchedKeyCount > 0) { var exposures = await m.GetExposureInfoAsync(detectionSummary, Handler.UserExplanation, out var exposuresProgress); cancellationToken.Register(exposuresProgress.Cancel); info = exposures.Select(i => { var totalRisk = 0; var dictKey = new NSString("totalRiskScoreFullRange"); if (i.Metadata.ContainsKey(dictKey)) { var sro = i.Metadata.ObjectForKey(dictKey); if (sro is NSNumber sron) { totalRisk = sron.Int32Value; } } else { totalRisk = i.TotalRiskScore; } return(new ExposureInfo( (DateTime)i.Date, TimeSpan.FromMinutes(i.Duration), i.AttenuationValue, totalRisk, i.TransmissionRiskLevel.FromNative())); }); } return(info); } // Return everything return(summary, GetInfo); }