Esempio n. 1
0
        // this will be called when they keys need to be collected from the server
        public async Task FetchExposureKeysFromServerAsync(ITemporaryExposureKeyBatches batches)
        {
            // This is "default" by default
            var region = LocalStateManager.Instance.Region ?? DefaultRegion;

            var checkForMore = true;

            do
            {
                try
                {
                    // Find next batch number
                    var batchNumber = LocalStateManager.Instance.ServerBatchNumber + 1;

                    // Build the blob storage url for the given batch file we are on next
                    var url = $"{apiUrlBlobStorageBase}/{blobStorageContainerNamePrefix}{region}/{batchNumber}.dat";

                    var response = await http.GetAsync(url);

                    // If we get a 404, there are no newer batch files available to download
                    if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        checkForMore = false;
                        break;
                    }

                    response.EnsureSuccessStatusCode();

                    // Skip batch files which are older than 14 days
                    if (response.Content.Headers.LastModified.HasValue)
                    {
                        if (response.Content.Headers.LastModified < DateTimeOffset.UtcNow.AddDays(-14))
                        {
                            LocalStateManager.Instance.ServerBatchNumber = batchNumber;
                            LocalStateManager.Save();
                            checkForMore = true;
                            continue;
                        }
                    }

                    // Read the batch file stream
                    using var responseStream = await response.Content.ReadAsStreamAsync();

                    // Parse into a Proto.File
                    var batchFile = TemporaryExposureKeyBatch.Parser.ParseFrom(responseStream);

                    // Submit to the batch processor
                    await batches.AddBatchAsync(batchFile);

                    // Update the number we are on
                    LocalStateManager.Instance.ServerBatchNumber = batchNumber;
                    LocalStateManager.Save();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    checkForMore = false;
                }
            } while (checkForMore);
        }
Esempio n. 2
0
        // this will be called when the user is submitting a diagnosis and the local keys need to go to the server
        public async Task UploadSelfExposureKeysToServerAsync(IEnumerable <TemporaryExposureKey> temporaryExposureKeys)
        {
            var pendingDiagnosis = LocalStateManager.Instance.PendingDiagnosis;

            if (pendingDiagnosis == null || string.IsNullOrEmpty(pendingDiagnosis.DiagnosisUid))
            {
                throw new InvalidOperationException();
            }

            try
            {
                var url = $"{apiUrlBase.TrimEnd('/')}/selfdiagnosis";

                var json = JsonConvert.SerializeObject(new SelfDiagnosisSubmissionRequest
                {
                    DiagnosisUid = pendingDiagnosis.DiagnosisUid,
                    TestDate     = pendingDiagnosis.DiagnosisDate.ToUnixTimeMilliseconds(),
                    Keys         = temporaryExposureKeys
                });

                var http     = new HttpClient();
                var response = await http.PutAsync(url, new StringContent(json));

                response.EnsureSuccessStatusCode();

                // Update pending status
                pendingDiagnosis.Shared = true;
                LocalStateManager.Save();
            }
            catch
            {
                throw;
            }
        }
Esempio n. 3
0
        public async Task UploadSelfExposureKeysToServer(IEnumerable <TemporaryExposureKey> temporaryExposureKeys)
        {
            var diagnosisUid = LocalStateManager.Instance.LatestDiagnosis.DiagnosisUid;

            if (string.IsNullOrEmpty(diagnosisUid))
            {
                throw new InvalidOperationException();
            }

            try
            {
                var url = $"{apiUrlBase.TrimEnd('/')}/selfdiagnosis";

                var json = JsonConvert.SerializeObject(new SelfDiagnosisSubmissionRequest
                {
                    DiagnosisUid = diagnosisUid,
                    Keys         = temporaryExposureKeys
                });

                var http     = new HttpClient();
                var response = await http.PutAsync(url, new StringContent(json));

                response.EnsureSuccessStatusCode();

                LocalStateManager.Instance.LatestDiagnosis.Shared = true;
                LocalStateManager.Save();
            }
            catch
            {
                throw;
            }
        }
Esempio n. 4
0
        public async Task FetchExposureKeysFromServer(Func <IEnumerable <TemporaryExposureKey>, Task> addKeys)
        {
            var latestKeysResponseIndex = LocalStateManager.Instance.LatestKeysResponseIndex;

            var take = 1024;
            var skip = 0;

            var checkForMore = false;

            do
            {
                // Get the newest date we have keys from and request since then
                // or if no date stored, only return as much as the past 14 days of keys
                var url = $"{apiUrlBase.TrimEnd('/')}/keys?since={latestKeysResponseIndex}&skip={skip}&take={take}";

                var response = await http.GetAsync(url);

                response.EnsureSuccessStatusCode();

                var responseData = await response.Content.ReadAsStringAsync();

                if (string.IsNullOrEmpty(responseData))
                {
                    break;
                }

                // Response contains the timestamp in seconds since epoch, and the list of keys
                var keys = JsonConvert.DeserializeObject <KeysResponse>(responseData);

                var numKeys = keys?.Keys?.Count() ?? 0;

                // See if keys were returned on this call
                if (numKeys > 0)
                {
                    // Call the callback with the batch of keys to add
                    await addKeys(keys.Keys);

                    var newLatestKeysResponseIndex = keys.Latest;

                    if (newLatestKeysResponseIndex > LocalStateManager.Instance.LatestKeysResponseIndex)
                    {
                        LocalStateManager.Instance.LatestKeysResponseIndex = newLatestKeysResponseIndex;
                        LocalStateManager.Save();
                    }

                    // Increment our skip starting point for the next batch
                    skip += take;
                }

                // If we got back more or the same amount of our requested take, there may be
                // more left on the server to request again
                checkForMore = numKeys >= take;
            } while (checkForMore);
        }
Esempio n. 5
0
        public async Task ExposureDetected(ExposureDetectionSummary summary, Func <Task <IEnumerable <ExposureInfo> > > getDetailsFunc)
        {
            LocalStateManager.Instance.ExposureSummary = summary;

            var details = await getDetailsFunc();

            LocalStateManager.Instance.ExposureInformation.AddRange(details);

            LocalStateManager.Save();

            MessagingCenter.Instance.Send(this, "exposure_info_changed");

            // TODO: Save this info and alert the user
            // Pop up a local notification
        }
Esempio n. 6
0
        // this will be called when a potential exposure has been detected
        public async Task ExposureDetectedAsync(ExposureDetectionSummary summary, IEnumerable <ExposureInfo> exposureInfo)
        {
            LocalStateManager.Instance.ExposureSummary = summary;

            // Add these on main thread in case the UI is visible so it can update
            await Device.InvokeOnMainThreadAsync(() =>
            {
                foreach (var i in exposureInfo)
                {
                    LocalStateManager.Instance.ExposureInformation.Add(i);
                }
            });

            LocalStateManager.Save();

            var notification = new NotificationRequest
            {
                NotificationId = 100,
                Title          = "Possible COVID-19 Exposure",
                Description    = "It is possible you have been exposed to someone who was a confirmed diagnosis of COVID-19.  Tap for more details."
            };

            NotificationCenter.Current.Show(notification);
        }