Esempio n. 1
0
            public static void Enqueue(
                Context context,
                JobSetting jobSetting
                )
            {
                JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(
                    JOB_ID,
                    new ComponentName(context, Java.Lang.Class.FromType(typeof(ExposureNotDetectedJob))))
                                                 .SetOverrideDeadline(0);

                if (jobSetting != null)
                {
                    jobSetting.Apply(jobInfoBuilder);
                }

                JobInfo jobInfo = jobInfoBuilder.Build();

                JobScheduler jobScheduler = (JobScheduler)context.GetSystemService(JobSchedulerService);
                int          result       = jobScheduler.Schedule(jobInfo);

                if (result == JobScheduler.ResultSuccess)
                {
                    Logger.D("ExposureNotDetectedJob scheduled");
                }
                else if (result == JobScheduler.ResultFailure)
                {
                    Logger.D("ExposureNotDetectedJob schedule failed");
                }
            }
Esempio n. 2
0
        private async Task <IList <TemporaryExposureKey> > GetReleasedTemporaryExposureKeys(
            ExposureNotificationClient enClient,
            Context appContext
            )
        {
            TaskCompletionSource <Intent> taskCompletionSource = new TaskCompletionSource <Intent>(TaskCreationOptions.RunContinuationsAsynchronously);
            BroadcastReceiver             receiver             = new PreAuthorizeReleasePhoneUnlockedBroadcastReceiver(taskCompletionSource);

            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(API_TIMEOUT_MILLIS);

            using (cancellationTokenSource.Token.Register(() =>
            {
                Logger.D("cancellationTokenSource canceled.");
                taskCompletionSource.TrySetCanceled();
                appContext.UnregisterReceiver(receiver);
            }))
            {
                appContext.RegisterReceiver(
                    receiver,
                    INTENT_FILTER_PRE_AUTHORIZE_RELEASE_PHONE_UNLOCKED
                    );

                await enClient.RequestPreAuthorizedTemporaryExposureKeyReleaseAsync();

                Intent intent = await taskCompletionSource.Task;

                IList <TemporaryExposureKey> temporaryExposureKeys = intent.GetParcelableArrayListExtra(EXTRA_TEMPORARY_EXPOSURE_KEY_LIST)
                                                                     .Cast <AndroidTemporaryExposureKey>()
                                                                     .Select(tek => (TemporaryExposureKey) new PlatformTemporaryExposureKey(tek))
                                                                     .ToList();

                return(temporaryExposureKeys);
            }
        }
Esempio n. 3
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);
            }
Esempio n. 4
0
            public static void Enqueue(
                Context context, string token,
                JobSetting jobSetting
                )
            {
                PersistableBundle bundle = new PersistableBundle();

                bundle.PutString(EXTRA_TOKEN, token);

                JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(
                    JOB_ID,
                    new ComponentName(context, Java.Lang.Class.FromType(typeof(ExposureDetectedV1Job))))
                                                 .SetExtras(bundle)
                                                 .SetOverrideDeadline(0);

                if (jobSetting != null)
                {
                    jobSetting.Apply(jobInfoBuilder);
                }

                JobInfo jobInfo = jobInfoBuilder.Build();

                JobScheduler jobScheduler = (JobScheduler)context.GetSystemService(JobSchedulerService);
                int          result       = jobScheduler.Schedule(jobInfo);

                if (result == JobScheduler.ResultSuccess)
                {
                    Logger.D("ExposureDetectedV1Job scheduled");
                }
                else if (result == JobScheduler.ResultFailure)
                {
                    Logger.D("ExposureDetectedV1Job schedule failed");
                }
            }
Esempio n. 5
0
        private IExposureNotificationClient GetEnClient()
        {
            if (EnClient is null)
            {
                Logger.E("Init method must be called first.");
                throw new UnInitializedException("Init method must be called first.");
            }

            return(EnClient);
        }
Esempio n. 6
0
        public override async Task RequestPreAuthorizedTemporaryExposureKeyReleaseAsync()
        {
            Logger.D("RequestPreAuthorizedTemporaryExposureKeyReleaseAsync");

            IExposureNotificationHandler?handler  = null;
            ExposureNotificationClient?  enClient = null;

            if (_appContext is null)
            {
                throw new IllegalStateException("IExposureNotificationHandler is not set.");
            }

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

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

            try
            {
                IList <TemporaryExposureKey> temporaryExposureKeys = await GetReleasedTemporaryExposureKeys(enClient, _appContext);

                await handler.TemporaryExposureKeyReleasedAsync(temporaryExposureKeys);
            }
            catch (JavaTimeoutException exception)
            {
                // Wrap exception
                throw new TimeoutException(exception.Message);
            }
            catch (ApiException exception)
            {
                if (exception.IsENException())
                {
                    throw exception.ToENException();
                }
                throw;
            }
            finally
            {
            }
        }
Esempio n. 7
0
        private static ENManager CreateEnManager() => new ENManager()
        {
            DiagnosisKeysAvailableHandler = new ENDiagnosisKeysAvailableHandler(async teks =>
            {
                if (Handler is null)
                {
                    Logger.E("ENDiagnosisKeysAvailableHandler is called but ENDiagnosisKeysAvailableHandler is not set.");
                    return;
                }

                IList <TemporaryExposureKey> temporaryExposureKeys = teks.Select(tek => (TemporaryExposureKey) new PlatformTemporaryExposureKey(tek)).ToList();
                await Handler.TemporaryExposureKeyReleasedAsync(temporaryExposureKeys);
            })
        };
Esempio n. 8
0
            private async Task <(ExposureSummary, IList <ExposureInformation> exposureInformations)> GetExposureV1Async(
                ExposureNotificationClient enClient,
                string token
                )
            {
                Logger.D($"GetExposureV1Async");

                AndroidExposureSummary exposureSummary = await enClient.EnClient.GetExposureSummaryAsync(token);

                IList <AndroidExposureInformation> eis = await enClient.EnClient.GetExposureInformationAsync(token);

                IList <ExposureInformation> exposureInformations = eis.Select(ei => (ExposureInformation) new PlatformExposureInformation(ei)).ToList();

                return(new PlatformExposureSummary(exposureSummary), exposureInformations);
            }
Esempio n. 9
0
            private async Task <(List <DailySummary> dailySummaries, List <ExposureWindow> exposureWindows)> GetExposureV2Async(
                ExposureNotificationClient enClient,
                ExposureConfiguration exposureConfiguration
                )
            {
                Logger.D($"GetExposureV2Async");


                IList <AndroidDailySummary> dss = await enClient.EnClient.GetDailySummariesAsync(
                    exposureConfiguration.GoogleDailySummariesConfig.ToAndroidDailySummariesConfig()
                    );

                List <DailySummary> dailySummaries = dss.Select(ds => (DailySummary) new PlatformDailySummary(ds)).ToList();

                IList <AndroidExposureWindow> ews = await enClient.EnClient.GetExposureWindowsAsync();

                List <ExposureWindow> exposureWindows = ews.Select(ew => (ExposureWindow) new PlatformExposureWindow(ew)).ToList();

                return(dailySummaries, exposureWindows);
            }
Esempio n. 10
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.ExposureNotDetectedAsync(exposureConfiguration);
                    }
                    finally
                    {
                        JobFinished(@params, false);
                    }
                });

                return(true);
            }
Esempio n. 11
0
 public override void OnReceive(Context context, Intent intent)
 {
     Logger.D($"ACTION_PRE_AUTHORIZE_RELEASE_PHONE_UNLOCKED");
     context.UnregisterReceiver(this);
     _taskCompletionSource.SetResult(intent);
 }
Esempio n. 12
0
        public override async Task <ProvideDiagnosisKeysResult> ProvideDiagnosisKeysAsync(
            List <string> keyFiles,
            string token,
            CancellationTokenSource?cancellationTokenSource = null
            )
        {
            var enClient = GetEnClient();

            Logger.D($"DiagnosisKey {keyFiles.Count}");

            if (keyFiles.Count == 0)
            {
                Logger.D($"No DiagnosisKey found.");
                return(ProvideDiagnosisKeysResult.NoDiagnosisKeyFound);
            }

            if (Handler is null)
            {
                throw new IllegalStateException("IExposureNotificationHandler is not set.");
            }

            ExposureConfiguration configuration = await Handler.GetExposureConfigurationAsync();

            if (configuration is null)
            {
                throw new IllegalStateException("ExposureConfiguration is null.");
            }

            TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            // Check and add taskCompletionSource for prevent multiple starts.
            lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
            {
                Logger.D($"ExposureStateBroadcastReceiveTaskCompletionSourceDict count {ExposureStateBroadcastReceiveTaskCompletionSourceDict.Count}");
                if (ExposureStateBroadcastReceiveTaskCompletionSourceDict.ContainsKey(token))
                {
                    Logger.E($"Task ProvideDiagnosisKeysAsync(Legacy-V1 mode) token {token} is already started.");
                    return(ProvideDiagnosisKeysResult.Completed);
                }

                ExposureStateBroadcastReceiveTaskCompletionSourceDict.Add(token, taskCompletionSource);
            }

            cancellationTokenSource ??= new CancellationTokenSource(API_PROVIDE_DIAGNOSIS_KEYS_TIMEOUT_MILLIS);

            var files = keyFiles.Select(f => new File(f)).ToList();

            try
            {
                using (cancellationTokenSource.Token.Register(() =>
                {
                    Logger.D("ProvideDiagnosisKeysAsync cancellationTokenSource canceled.");
                    taskCompletionSource?.TrySetException(
                        new TimeoutException($"ExposureStateBroadcastReceiver was not called in {API_PROVIDE_DIAGNOSIS_KEYS_TIMEOUT_MILLIS} millis.")
                        );
                    lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
                    {
                        ExposureStateBroadcastReceiveTaskCompletionSourceDict.Remove(token);
                    }
                }))
                {
                    await enClient.ProvideDiagnosisKeysAsync(files, configuration.ToAndroidExposureConfiguration(), token);

                    _ = await taskCompletionSource.Task;

                    lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
                    {
                        ExposureStateBroadcastReceiveTaskCompletionSourceDict.Remove(token);
                    }
                }

                Logger.D("ExposureStateBroadcastReceiveTaskCompletionSource is completed.");
                return(ProvideDiagnosisKeysResult.Completed);
            }
            catch (JavaTimeoutException exception)
            {
                // Wrap exception
                throw new TimeoutException(exception.Message);
            }
            catch (ApiException exception)
            {
                if (exception.IsENException())
                {
                    throw exception.ToENException();
                }
                throw;
            }
        }
Esempio n. 13
0
        public override async Task <ProvideDiagnosisKeysResult> ProvideDiagnosisKeysAsync(
            List <string> keyFiles,
            CancellationTokenSource?cancellationTokenSource = null
            )
        {
            var enClient = GetEnClient();

            Logger.D($"DiagnosisKey {keyFiles.Count}");

            if (keyFiles.Count == 0)
            {
                Logger.D($"No DiagnosisKey found.");
                return(ProvideDiagnosisKeysResult.NoDiagnosisKeyFound);
            }

            if (Handler is null)
            {
                throw new IllegalStateException("IExposureNotificationHandler is not set.");
            }

            ExposureConfiguration configuration = await Handler.GetExposureConfigurationAsync();

            if (configuration is null)
            {
                throw new IllegalStateException("ExposureConfiguration is null.");
            }

            string token = Guid.NewGuid().ToString();
            TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously);

            // Check and add taskCompletionSource for prevent multiple starts.
            lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
            {
                Logger.D($"ExposureStateBroadcastReceiveTaskCompletionSourceDict count {ExposureStateBroadcastReceiveTaskCompletionSourceDict.Count}");
                if (ExposureStateBroadcastReceiveTaskCompletionSourceDict.Count > 0)
                {
                    Logger.E($"Task ProvideDiagnosisKeysAsync(ExposureWindow mode) is already started.");
                    return(ProvideDiagnosisKeysResult.Completed);
                }

                ExposureStateBroadcastReceiveTaskCompletionSourceDict.Add(token, taskCompletionSource);
            }

            cancellationTokenSource ??= new CancellationTokenSource(API_PROVIDE_DIAGNOSIS_KEYS_TIMEOUT_MILLIS);

            DiagnosisKeysDataMapping diagnosisKeysDataMapping = configuration.GoogleDiagnosisKeysDataMappingConfig.ToDiagnosisKeysDataMapping();

            try
            {
                DiagnosisKeysDataMapping currentDiagnosisKeysDataMapping = await enClient.GetDiagnosisKeysDataMappingAsync();

                // https://github.com/google/exposure-notifications-internals/blob/aaada6ce5cad0ea1493930591557f8053ef4f113/exposurenotification/src/main/java/com/google/samples/exposurenotification/nearby/DiagnosisKeysDataMapping.java#L113
                if (!diagnosisKeysDataMapping.Equals(currentDiagnosisKeysDataMapping))
                {
                    await enClient.SetDiagnosisKeysDataMappingAsync(diagnosisKeysDataMapping);

                    await Handler.DiagnosisKeysDataMappingAppliedAsync();

                    Logger.I("DiagnosisKeysDataMapping have been updated.");
                }
                else
                {
                    Logger.D("DiagnosisKeysDataMapping is not updated.");
                }

                var files = keyFiles.Select(f => new File(f)).ToList();
                DiagnosisKeyFileProvider diagnosisKeyFileProvider = new DiagnosisKeyFileProvider(files);

                using (cancellationTokenSource.Token.Register(() =>
                {
                    Logger.D("ProvideDiagnosisKeysAsync cancellationTokenSource canceled.");
                    taskCompletionSource?.TrySetException(
                        new TimeoutException($"ExposureStateBroadcastReceiver was not called in {API_PROVIDE_DIAGNOSIS_KEYS_TIMEOUT_MILLIS} millis.")
                        );
                    lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
                    {
                        ExposureStateBroadcastReceiveTaskCompletionSourceDict.Remove(token);
                    }
                }))
                {
                    await enClient.ProvideDiagnosisKeysAsync(diagnosisKeyFileProvider);

                    _ = await taskCompletionSource.Task;
                }

                Logger.D("ExposureStateBroadcastReceiveTaskCompletionSource is completed.");
                return(ProvideDiagnosisKeysResult.Completed);
            }
            catch (JavaTimeoutException exception)
            {
                // Wrap exception
                throw new TimeoutException(exception.Message);
            }
            catch (ApiException exception)
            {
                if (exception.IsENException())
                {
                    throw exception.ToENException();
                }
                throw;
            }
            finally
            {
                lock (ExposureStateBroadcastReceiveTaskCompletionSourceDict)
                {
                    ExposureStateBroadcastReceiveTaskCompletionSourceDict.Remove(token);
                }
            }
        }
Esempio n. 14
0
 public static void LogD(this NSErrorException nsErrorException)
 {
     Logger.D($"Error occurred {nsErrorException.Code} - {nsErrorException.Domain} - {nsErrorException.Message}");
 }
Esempio n. 15
0
 public override bool OnStopJob(JobParameters @params)
 {
     Logger.E("ExposureNotDetectedJob stopped.");
     return(false);
 }
Esempio n. 16
0
        public override void OnReceive(Context context, Intent intent)
        {
            var action = intent.Action;

            Logger.D($"Intent Action {action}");

            ExposureNotificationClient?enClient = null;

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

            if (enClient is null)
            {
                Logger.E("ExposureStateBroadcastReceiver: enClient is null.");
                return;
            }

            try
            {
                switch (action)
                {
                case ACTION_EXPOSURE_STATE_UPDATED:
                    Logger.D($"ACTION_EXPOSURE_STATE_UPDATED");
                    bool v1 = intent.HasExtra(EXTRA_EXPOSURE_SUMMARY);

                    string varsionStr = v1 ? "1" : "2";
                    Logger.D($"EN version {varsionStr}");

                    if (v1)
                    {
                        string token = intent.GetStringExtra(EXTRA_TOKEN);
                        ExposureDetectedV1Job.Enqueue(
                            context,
                            token,
                            enClient.ExposureDetectedV1JobSetting
                            );
                    }
                    else
                    {
                        ExposureDetectedV2Job.Enqueue(
                            context,
                            enClient.ExposureDetectedV2JobSetting
                            );
                    }
                    break;

                case ACTION_EXPOSURE_NOT_FOUND:
                    Logger.D($"ACTION_EXPOSURE_NOT_FOUND");
                    ExposureNotDetectedJob.Enqueue(
                        context,
                        enClient.ExposureNotDetectedJobSetting
                        );
                    break;
                }
            }
            catch (Exception e)
            {
                Logger.E($"Exception occurred: {e}");
            }
            finally
            {
                var exposureStateBroadcastReceiveTaskCompletionSourceDict = enClient.ExposureStateBroadcastReceiveTaskCompletionSourceDict;

                lock (exposureStateBroadcastReceiveTaskCompletionSourceDict)
                {
                    foreach (var key in exposureStateBroadcastReceiveTaskCompletionSourceDict.Keys)
                    {
                        exposureStateBroadcastReceiveTaskCompletionSourceDict.TryGetValue(key, out var value);
                        value?.TrySetResult(true);
                    }
                }
            }
        }