Example #1
0
        public async Task ExposureNotDetectedAsync(ExposureConfiguration exposureConfiguration, long enVersion)
        {
            _loggerService.Info("ExposureNotDetected");

            var enVersionStr = enVersion.ToString();

            try
            {
                await _exposureDataCollectServer.UploadExposureDataAsync(
                    exposureConfiguration,
                    _deviceInfoUtility.Model,
                    enVersionStr
                    );
            }
            catch (Exception e)
            {
                _loggerService.Exception("UploadExposureDataAsync", e);
            }

            string idempotencyKey = Guid.NewGuid().ToString();

            try
            {
                await _eventLogService.SendExposureDataAsync(
                    idempotencyKey,
                    exposureConfiguration,
                    _deviceInfoUtility.Model,
                    enVersionStr
                    );
            }
            catch (Exception e)
            {
                _loggerService.Exception("SendExposureDataAsync", e);
            }
        }
Example #2
0
            public override bool OnStartJob(JobParameters @params)
            {
                IExposureNotificationHandler?handler  = null;
                ExposureNotificationClient?  enClient = null;

                if (ApplicationContext is IExposureNotificationHandler exposureNotificationHandler)
                {
                    handler  = exposureNotificationHandler;
                    enClient = (ExposureNotificationClient)exposureNotificationHandler.GetEnClient();
                }

                if (enClient is null)
                {
                    Logger.E("ExposureDetectedV2Job: enClient is null.");
                    return(false);
                }
                if (handler is null)
                {
                    Logger.E("ExposureDetectedV2Job: handler is null.");
                    return(false);
                }

                _ = Task.Run(async() =>
                {
                    try
                    {
                        ExposureConfiguration exposureConfiguration = await handler.GetExposureConfigurationAsync();
                        if (exposureConfiguration is null)
                        {
                            throw new IllegalStateException("ExposureConfiguration is null.");
                        }

                        await handler.PreExposureDetectedAsync(exposureConfiguration);

                        var(dailySummaries, exposureWindows) = await GetExposureV2Async(enClient, exposureConfiguration);

                        await handler.ExposureDetectedAsync(dailySummaries, exposureWindows, exposureConfiguration);
                    }
                    catch (ApiException exception)
                    {
                        if (exception.IsENException())
                        {
                            var enException = exception.ToENException();
                            await handler.ExceptionOccurredAsync(enException);
                            throw enException;
                        }
                        else
                        {
                            await handler.ExceptionOccurredAsync(exception);
                            throw;
                        }
                    }
                    finally
                    {
                        JobFinished(@params, false);
                    }
                });

                return(true);
            }
Example #3
0
        public async Task ExposureNotDetectedAsync(ExposureConfiguration exposureConfiguration)
        {
            Logger.D($"ExposureNotDetected: {DateTime.UtcNow}");

            var enVersion = (await EnClient.GetVersionAsync()).ToString();

            var exposureResult = new ExposureResult(
                exposureConfiguration,
                DateTime.Now
                )
            {
                Device    = DeviceInfo.Model,
                EnVersion = enVersion
            };
            var filePath = await SaveExposureResult(exposureResult);

            var exposureDataServerConfiguration = await LoadExposureDataServerConfiguration();

            var exposureDataResponse = await new ExposureDataServer(exposureDataServerConfiguration).UploadExposureDataAsync(
                exposureConfiguration,
                DeviceInfo.Model,
                enVersion
                );

            if (exposureDataResponse != null)
            {
                await SaveExposureResult(exposureDataResponse);

                File.Delete(filePath);
            }
        }
Example #4
0
        public async Task ExposureDetectedAsync(ExposureConfiguration exposureConfiguration, long enVersion, ExposureSummary exposureSummary, IList <ExposureInformation> exposureInformations)
        {
            _loggerService.Info("ExposureDetected: Legacy-V1");

            ExposureConfiguration.GoogleExposureConfiguration configurationV1 = exposureConfiguration.GoogleExposureConfig;

            bool isNewExposureDetected = _exposureDataRepository.AppendExposureData(
                exposureSummary,
                exposureInformations.ToList(),
                configurationV1.MinimumRiskScore
                );

            if (isNewExposureDetected)
            {
                _ = _localNotificationService.ShowExposureNotificationAsync();

                bool enableSendEventExposureNotificationNotified = _sendEventLogStateRepository
                                                                   .GetSendEventLogState(EventType.ExposureNotified) == SendEventLogState.Enable;

                if (enableSendEventExposureNotificationNotified)
                {
                    await _eventLogRepository.AddEventNotifiedAsync();
                }
            }
            else
            {
                _loggerService.Info($"MatchedKeyCount: {exposureSummary.MatchedKeyCount}, but no new exposure detected");
            }
        }
Example #5
0
        public void TestDeserializeFromJson()
        {
            var expected = new ExposureConfiguration();
            var exposureConfiguration = Utils.ReadObjectFromJsonPath <ExposureConfiguration>(PATH_JSON);

            Assert.True(expected.Equals(exposureConfiguration));
        }
 public Task UploadExposureDataAsync(
     ExposureConfiguration exposureConfiguration,
     string deviceModel,
     string enVersion,
     ExposureSummary exposureSummary,
     IList <ExposureInformation> exposureInformation
     )
 => Task.CompletedTask;
 public Task UploadExposureDataAsync(
     ExposureConfiguration exposureConfiguration,
     string deviceModel,
     string enVersion,
     IList <DailySummary> dailySummaries,
     IList <ExposureWindow> exposureWindows
     )
 => Task.CompletedTask;
        public async void ExposureDetected_ExposureInformationHighRiskExposureDetected()
        {
            // Test Data
            var exposureConfiguration = new ExposureConfiguration()
            {
                GoogleExposureConfig = new ExposureConfiguration.GoogleExposureConfiguration()
                {
                    MinimumRiskScore = 0
                }
            };
            var exposureSummary = new ExposureSummary()
            {
                MaximumRiskScore = 1
            };
            var exposureInformantion = new ExposureInformation()
            {
                AttenuationDurationsInMillis = new int[] { 0 },
                AttenuationValue             = 0,
                DateMillisSinceEpoch         = 0,
                DurationInMillis             = 0,
                TotalRiskScore        = 2,
                TransmissionRiskLevel = RiskLevel.High
            };
            var exposureInformationList = new List <ExposureInformation>()
            {
                exposureInformantion
            };
            var enVersion = 2;

            // Mock Setup
            exposureDataCollectServer
            .Setup(x => x.UploadExposureDataAsync(
                       It.IsAny <ExposureConfiguration>(),
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <ExposureSummary>(),
                       It.IsAny <List <ExposureInformation> >()));
            deviceInfoUtility.Setup(x => x.Model).Returns("UnitTest");

            exposureRiskCalculationService
            .Setup(x => x.CalcRiskLevel(It.IsAny <DailySummary>(), It.IsAny <List <ExposureWindow> >(), It.IsAny <V1ExposureRiskCalculationConfiguration>()))
            .Returns(RiskLevel.High);


            // Test Case
            var unitUnderTest = CreateService();
            await unitUnderTest.ExposureDetectedAsync(exposureConfiguration, enVersion, exposureSummary, exposureInformationList);


            // Assert
            localNotificationService
            .Verify(x => x.ShowExposureNotificationAsync(), Times.Once);

            var expectedSerializedData = JsonConvert.SerializeObject(exposureInformationList.Select(x => new UserExposureInfo(x)));

            secureStorageService
            .Verify(x => x.SetValue <string>("ExposureInformation", It.Is <string>(x => x == expectedSerializedData)), Times.Once);
        }
Example #9
0
        public void PreExposureDetected(ExposureConfiguration exposureConfiguration, long enVersion)
        {
            _loggerService.Debug("PreExposureDetected");

            if (exposureConfiguration == null)
            {
                _loggerService.Error("PreExposureDetected is called but exposureConfiguration is null.");
            }
        }
Example #10
0
 public Task SendExposureDataAsync(
     string idempotencyKey,
     ExposureConfiguration exposureConfiguration,
     string deviceModel, string enVersion,
     IList <DailySummary> dailySummaries, IList <ExposureWindow> exposureWindows
     )
 {
     // do nothing
     return(Task.CompletedTask);
 }
Example #11
0
 public ExposureData(ExposureConfiguration exposureConfiguration,
                     ExposureSummary?exposureSummary, IList <ExposureInformation>?exposureInformations,
                     IList <DailySummary>?dailySummaries, IList <ExposureWindow>?exposureWindows)
 {
     this.exposureConfiguration = exposureConfiguration;
     this.exposureSummary       = exposureSummary;
     this.exposureInformations  = exposureInformations;
     this.dailySummaries        = dailySummaries;
     this.exposureWindows       = exposureWindows;
 }
Example #12
0
 public Task SendExposureDataAsync(
     string idempotencyKey,
     ExposureConfiguration exposureConfiguration,
     string deviceModel,
     string enVersion
     )
 {
     // do nothing
     return(Task.CompletedTask);
 }
Example #13
0
        public void TestNotEquals()
        {
            var expected = new ExposureConfiguration();

            expected.GoogleExposureConfig.MinimumRiskScore = 1;

            var exposureConfiguration = Utils.ReadObjectFromJsonPath <ExposureConfiguration>(PATH_JSON);

            Assert.False(expected.Equals(exposureConfiguration));
        }
        private bool IsUpdatedDiagnosisKeysDataMapping(
            ExposureConfiguration exposureConfiguration1,
            ExposureConfiguration exposureConfiguration2
            )
        {
            var googleDiagnosisKeysDataMappingConfigUpdated    = !exposureConfiguration1.GoogleDiagnosisKeysDataMappingConfig.Equals(exposureConfiguration2.GoogleDiagnosisKeysDataMappingConfig);
            var appleInfectiousnessForDaysSinceOnsetOfSymptoms = !exposureConfiguration1.AppleExposureConfigV2.InfectiousnessForDaysSinceOnsetOfSymptoms
                                                                 .SequenceEqual(exposureConfiguration2.AppleExposureConfigV2.InfectiousnessForDaysSinceOnsetOfSymptoms);

            return(googleDiagnosisKeysDataMappingConfigUpdated || appleInfectiousnessForDaysSinceOnsetOfSymptoms);
        }
 public override async Task ProvideDiagnosisKeysAsync(List <string> keyFiles, ExposureConfiguration configuration, string token)
 {
     try
     {
         await Client.ProvideDiagnosisKeysAsync(keyFiles, configuration, token);
     }
     catch (ApiException apiException)
     {
         Debug.Print($"ApiException StatusCode {apiException.StatusCode}");
     }
 }
Example #16
0
        public async Task ExposureDetectedAsync(ExposureConfiguration exposureConfiguration, long enVersion, ExposureSummary exposureSummary, IList <ExposureInformation> exposureInformations)
        {
            _loggerService.Info("ExposureDetected: Legacy-V1");

            var enVersionStr = enVersion.ToString();

            ExposureConfiguration.GoogleExposureConfiguration configurationV1 = exposureConfiguration.GoogleExposureConfig;

            bool isNewExposureDetected = _exposureDataRepository.AppendExposureData(
                exposureSummary,
                exposureInformations.ToList(),
                configurationV1.MinimumRiskScore
                );

            if (isNewExposureDetected)
            {
                _ = _localNotificationService.ShowExposureNotificationAsync();
            }
            else
            {
                _loggerService.Info($"MatchedKeyCount: {exposureSummary.MatchedKeyCount}, but no new exposure detected");
            }

            try
            {
                await _exposureDataCollectServer.UploadExposureDataAsync(
                    exposureConfiguration,
                    _deviceInfoUtility.Model,
                    enVersionStr,
                    exposureSummary, exposureInformations
                    );
            }
            catch (Exception e)
            {
                _loggerService.Exception("UploadExposureDataAsync", e);
            }

            string idempotencyKey = Guid.NewGuid().ToString();

            try
            {
                await _eventLogService.SendExposureDataAsync(
                    idempotencyKey,
                    exposureConfiguration,
                    _deviceInfoUtility.Model,
                    enVersionStr,
                    exposureSummary, exposureInformations
                    );
            }
            catch (Exception e)
            {
                _loggerService.Exception("SendExposureDataAsync", e);
            }
        }
        public ExposureConfigurationService(IConfiguration configuration)
        {
            _exposureConfiguration = RetrieveExposureConfigurationFromConfig(configuration.GetSection("ExposureConfig"));
            ModelValidator.ValidateContract(_exposureConfiguration);

            _exposureConfigurationV1_2 = new ExposureConfigurationV1_2()
            {
                Configuration            = RetrieveExposureConfigurationFromConfig(configuration.GetSection("ExposureConfigV1_2")),
                AttenuationBucketsParams = RetrieveAttentuationBucketsParametersFromConfig(configuration.GetSection("AttenuationBucketsParams"))
            };
            ModelValidator.ValidateContract(_exposureConfigurationV1_2);
        }
        public async void ExposureDetected_ExposureInformationHighRiskExposureNotDetected()
        {
            // Test Data
            var exposureConfiguration = new ExposureConfiguration()
            {
                GoogleExposureConfig = new ExposureConfiguration.GoogleExposureConfiguration()
                {
                    MinimumRiskScore = 3
                }
            };
            var exposureSummary = new ExposureSummary()
            {
                MaximumRiskScore = 1
            };
            var exposureInformantion = new ExposureInformation()
            {
                AttenuationDurationsInMillis = new int[] { 0 },
                AttenuationValue             = 0,
                DateMillisSinceEpoch         = 0,
                DurationInMillis             = 0,
                TotalRiskScore        = 2,
                TransmissionRiskLevel = RiskLevel.High
            };
            var exposureInformationList = new List <ExposureInformation>()
            {
                exposureInformantion
            };
            var enVersion = 2;

            // Mock Setup
            exposureDataCollectServer
            .Setup(x => x.UploadExposureDataAsync(
                       It.IsAny <ExposureConfiguration>(),
                       It.IsAny <string>(),
                       It.IsAny <string>(),
                       It.IsAny <ExposureSummary>(),
                       It.IsAny <List <ExposureInformation> >()));
            deviceInfoUtility.Setup(x => x.Model).Returns("UnitTest");


            // Test Case
            var unitUnderTest = CreateService();
            await unitUnderTest.ExposureDetectedAsync(exposureConfiguration, enVersion, exposureSummary, exposureInformationList);


            // Assert
            localNotificationService
            .Verify(x => x.ShowExposureNotificationAsync(), Times.Never);
            secureStorageService
            .Verify(x => x.SetStringValue("ExposureInformation", It.IsAny <string>()), Times.Never);
        }
Example #19
0
        public void TestSerializeToJson()
        {
            var exposureConfiguration = new ExposureConfiguration();
            var jsonStr = JsonConvert.SerializeObject(exposureConfiguration, Formatting.Indented);

            //Logger.D(jsonStr);

            using (var sr = new StreamReader(File.OpenRead(Utils.GetFullPath(PATH_JSON))))
            {
                var expected = sr.ReadToEnd();

                Assert.AreEqual(expected, jsonStr);
            }
        }
        public async Task ExposureDetectionAsync_ListFileNotFound()
        {
            ExposureConfiguration   exposureConfiguration   = new ExposureConfiguration();
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

            // Mock Setup
            mockLocalPathService
            .Setup(x => x.CacheDirectory)
            .Returns(Path.GetTempPath());

            // Setup ExposureNotification API
            mockExposureNotificationApiService.Setup(x => x.IsEnabledAsync())
            .ReturnsAsync(true);
            mockExposureNotificationApiService.Setup(x => x.GetStatusCodesAsync())
            .ReturnsAsync(new List <int>()
            {
                ExposureNotificationStatus.Code_Android.ACTIVATED,
            });

            mockDiagnosisKeyRepository
            .Setup(x => x.GetDiagnosisKeysListAsync(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .ReturnsAsync((HttpStatusCode.NotFound, new List <DiagnosisKeyEntry>()));

            mockServerConfigurationRepository
            .Setup(x => x.Regions)
            .Returns(new string[] { "440" });
            mockServerConfigurationRepository
            .Setup(x => x.GetDiagnosisKeyListProvideServerUrl(It.IsAny <string>()))
            .Returns("https://example.com");

            mockExposureConfigurationRepository
            .Setup(x => x.GetExposureConfigurationAsync())
            .ReturnsAsync(exposureConfiguration);

            mockUserDataRepository
            .Setup(x => x.GetLastProcessDiagnosisKeyTimestampAsync(It.IsAny <string>()))
            .ReturnsAsync(0L);


            // Test Case
            var unitUnderTest = CreateService();
            await unitUnderTest.ExposureDetectionAsync(cancellationTokenSource);


            // Assert
            mockDiagnosisKeyRepository.Verify(x => x.GetDiagnosisKeysListAsync(It.IsAny <string>(), It.IsAny <CancellationToken>()), Times.Once);
            mockDiagnosisKeyRepository.Verify(x => x.DownloadDiagnosisKeysAsync(It.IsAny <DiagnosisKeyEntry>(), It.IsAny <string>(), It.IsAny <CancellationToken>()), Times.Never);
            mockUserDataRepository.Verify(x => x.SetCanConfirmExposure(false), Times.Once());
            mockUserDataRepository.Verify(x => x.SetIsMaxPerDayExposureDetectionAPILimitReached(false), Times.Once());
        }
Example #21
0
        public ExposureResult(ExposureConfiguration exposureConfiguration,
                              DateTime generatedAt,
                              ExposureSummary exposureSummary, IList <ExposureInformation> exposureInformations,
                              IList <DailySummary> dailySummaries, IList <ExposureWindow> exposureWindows)
        {
            this.exposureConfiguration = exposureConfiguration;

            // to ISO 8601
            this.generatedAt = generatedAt.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");

            this.exposureSummary      = exposureSummary;
            this.exposureInformations = exposureInformations;
            this.dailySummaries       = dailySummaries;
            this.exposureWindows      = exposureWindows;
        }
        public async Task UploadExposureDataAsync(
            ExposureConfiguration exposureConfiguration,
            string deviceModel,
            string enVersion
            )
        {
            var exposureResult = new ExposureRequest(
                exposureConfiguration
                )
            {
                Device    = deviceModel,
                EnVersion = enVersion,
            };

            await UploadExposureDataAsync(exposureResult);
        }
Example #23
0
        public async Task SendExposureDataAsync(
            string idempotencyKey,
            ExposureConfiguration exposureConfiguration,
            string deviceModel,
            string enVersion
            )
        {
            var data = new ExposureData(
                exposureConfiguration
                )
            {
                Device    = deviceModel,
                EnVersion = enVersion,
            };

            await SendExposureDataAsync(idempotencyKey, data);
        }
Example #24
0
 public async Task <ExposureDataResponse?> UploadExposureDataAsync(
     ExposureConfiguration exposureConfiguration,
     string deviceModel,
     string enVersion,
     IList <DailySummary> dailySummaries,
     IList <ExposureWindow> exposureWindows
     )
 {
     return(await UploadExposureDataAsync(
                exposureConfiguration,
                deviceModel,
                enVersion,
                null,
                dailySummaries,
                exposureWindows
                ));
 }
Example #25
0
        private async Task <ExposureConfiguration> LoadExposureConfigurationAsync()
        {
            var exposureConfigurationPath = Path.Combine(_configurationDir, Constants.EXPOSURE_CONFIGURATION_FILENAME);

            if (File.Exists(exposureConfigurationPath))
            {
                return(JsonConvert.DeserializeObject <ExposureConfiguration>(
                           await File.ReadAllTextAsync(exposureConfigurationPath)
                           ));
            }

            var exposureConfiguration = new ExposureConfiguration();
            var json = JsonConvert.SerializeObject(exposureConfiguration, Formatting.Indented);
            await File.WriteAllTextAsync(exposureConfigurationPath, json);

            return(_exposureConfiguration);
        }
Example #26
0
        public async Task ExposureDetectedAsync(ExposureConfiguration exposureConfiguration, long enVersion, IList <DailySummary> dailySummaries, IList <ExposureWindow> exposureWindows)
        {
            _loggerService.Debug("ExposureDetected: ExposureWindows");

            var(newDailySummaries, newExposureWindows) = await _exposureDataRepository.SetExposureDataAsync(
                dailySummaries.ToList(),
                exposureWindows.ToList()
                );

            var exposureRiskCalculationConfiguration = await _exposureRiskCalculationConfigurationRepository
                                                       .GetExposureRiskCalculationConfigurationAsync(preferCache : false);

            _loggerService.Info(exposureRiskCalculationConfiguration.ToString());

            long expectOldestDateMillisSinceEpoch
                = _dateTimeUtility.UtcNow
                  .AddDays(AppConstants.TermOfExposureRecordValidityInDays)
                  .ToUnixEpochMillis();

            bool isHighRiskExposureDetected = newDailySummaries
                                              .Where(ds => ds.DateMillisSinceEpoch >= expectOldestDateMillisSinceEpoch)
                                              .Select(ds => _exposureRiskCalculationService.CalcRiskLevel(
                                                          ds,
                                                          newExposureWindows.Where(ew => ew.DateMillisSinceEpoch == ds.DateMillisSinceEpoch).ToList(),
                                                          exposureRiskCalculationConfiguration
                                                          )
                                                      )
                                              .Any(riskLevel => riskLevel >= RiskLevel.High);

            if (isHighRiskExposureDetected)
            {
                _ = _localNotificationService.ShowExposureNotificationAsync();

                bool enableSendEventExposureNotificationNotified = _sendEventLogStateRepository
                                                                   .GetSendEventLogState(EventType.ExposureNotified) == SendEventLogState.Enable;

                if (enableSendEventExposureNotificationNotified)
                {
                    await _eventLogRepository.AddEventNotifiedAsync();
                }
            }
            else
            {
                _loggerService.Info($"DailySummary: {dailySummaries.Count}, but no high-risk exposure detected");
            }
        }
Example #27
0
        private async Task <ExposureConfiguration> LoadExposureConfigurationAsync()
        {
            var exposureConfigurationPath = new AndroidFile(_configurationDir, Constants.EXPOSURE_CONFIGURATION_FILENAME);

            if (exposureConfigurationPath.Exists())
            {
                string content = await File.ReadAllTextAsync(exposureConfigurationPath.AbsolutePath);

                return(JsonConvert.DeserializeObject <ExposureConfiguration>(content));
            }

            var exposureConfiguration = new ExposureConfiguration();
            var json = JsonConvert.SerializeObject(exposureConfiguration, Formatting.Indented);
            await File.WriteAllTextAsync(exposureConfigurationPath.AbsolutePath, json);

            return(exposureConfiguration);
        }
        public async Task UploadExposureDataAsync(
            ExposureConfiguration exposureConfiguration,
            string deviceModel,
            string enVersion,
            IList <DailySummary> dailySummaries,
            IList <ExposureWindow> exposureWindows
            )
        {
            var exposureResult = new ExposureRequest(exposureConfiguration,
                                                     dailySummaries, exposureWindows
                                                     )
            {
                Device    = deviceModel,
                EnVersion = enVersion,
            };

            await UploadExposureDataAsync(exposureResult);
        }
Example #29
0
        private async Task InitializeExposureConfiguration()
        {
            var appDir = FileSystem.AppDataDirectory;
            var exposureConfigurationPath = Path.Combine(appDir, EXPOSURE_CONFIGURATION_FILENAME);

            if (File.Exists(exposureConfigurationPath))
            {
                using StreamReader sr = File.OpenText(exposureConfigurationPath);
                string config = await sr.ReadToEndAsync();

                _exposureConfiguration = JsonConvert.DeserializeObject <ExposureConfiguration>(config);
                return;
            }

            _exposureConfiguration = new ExposureConfiguration();
            var configJson = JsonConvert.SerializeObject(_exposureConfiguration, Formatting.Indented);
            await File.WriteAllTextAsync(exposureConfigurationPath, configJson);
        }
        public async Task UploadExposureDataAsync(
            ExposureConfiguration exposureConfiguration,
            string deviceModel,
            string enVersion,
            ExposureSummary exposureSummary,
            IList <ExposureInformation> exposureInformation
            )
        {
            var exposureResult = new ExposureRequest(exposureConfiguration,
                                                     exposureSummary, exposureInformation
                                                     )
            {
                Device    = deviceModel,
                EnVersion = enVersion,
            };

            await UploadExposureDataAsync(exposureResult);
        }