diff --git a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj
index 2cba60edc..b3094171c 100644
--- a/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj
+++ b/Covid19Radar/Covid19Radar.Android/Covid19Radar.Android.csproj
@@ -175,7 +175,6 @@
-
@@ -192,6 +191,7 @@
+
@@ -601,7 +601,6 @@
-
diff --git a/Covid19Radar/Covid19Radar.Android/MainApplication.cs b/Covid19Radar/Covid19Radar.Android/MainApplication.cs
index 016bfe599..ddbbd0e7b 100644
--- a/Covid19Radar/Covid19Radar.Android/MainApplication.cs
+++ b/Covid19Radar/Covid19Radar.Android/MainApplication.cs
@@ -54,6 +54,9 @@ private Lazy _loggerService
private Lazy _exposureConfigurationRepository
= new Lazy(() => ContainerLocator.Current.Resolve());
+ private Lazy _dataMaintainanceService
+ = new Lazy(() => ContainerLocator.Current.Resolve());
+
public MainApplication(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
{
}
@@ -95,6 +98,7 @@ private void ScheduleBackgroundTasks()
{
_loggerService.Value.Exception("Failed to schedule ExposureDetectionBackgroundService", exception);
}
+
try
{
_eventLogSubmissionBackgroundService.Value.Schedule();
@@ -103,6 +107,15 @@ private void ScheduleBackgroundTasks()
{
_loggerService.Value.Exception("Failed to schedule EventLogSubmissionBackgroundService", exception);
}
+
+ try
+ {
+ _dataMaintainanceService.Value.Schedule();
+ }
+ catch (Exception exception)
+ {
+ _loggerService.Value.Exception("Failed to schedule DataMaintainanceBackgroundService", exception);
+ }
}
private void SetupENClient(ExposureNotificationClient client)
@@ -118,7 +131,7 @@ private void RegisterPlatformTypes(IContainer container)
// Services
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
- container.Register(Reuse.Singleton);
+ container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
diff --git a/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs
new file mode 100644
index 000000000..9be4e2586
--- /dev/null
+++ b/Covid19Radar/Covid19Radar.Android/Services/DataMaintainanceBackgroundService.cs
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+using System;
+using Android.Content;
+using Android.Runtime;
+using AndroidX.Work;
+using Covid19Radar.Services;
+using Covid19Radar.Services.Logs;
+using Java.Util.Concurrent;
+using Prism.Ioc;
+using Xamarin.Essentials;
+
+namespace Covid19Radar.Droid.Services.Logs
+{
+ public class DataMaintainanceBackgroundService : AbsDataMaintainanceBackgroundService
+ {
+ private const string CURRENT_WORK_NAME = "data_maintainance_worker_20220628";
+
+ private static readonly long INTERVAL_IN_HOURS = 24;
+ private static readonly long BACKOFF_DELAY_IN_MINUTES = 60;
+
+ public DataMaintainanceBackgroundService(
+ ILogFileService logFileService,
+ ILoggerService loggerService
+ ) : base(logFileService, loggerService)
+ {
+ // do nothing
+ }
+
+ public override void Schedule()
+ {
+ loggerService.StartMethod();
+
+ WorkManager workManager = WorkManager.GetInstance(Platform.AppContext);
+
+ PeriodicWorkRequest periodicWorkRequest = CreatePeriodicWorkRequest();
+ workManager.EnqueueUniquePeriodicWork(
+ CURRENT_WORK_NAME,
+ ExistingPeriodicWorkPolicy.Keep,
+ periodicWorkRequest
+ );
+
+ loggerService.EndMethod();
+ }
+
+ private PeriodicWorkRequest CreatePeriodicWorkRequest()
+ {
+ var workRequestBuilder = new PeriodicWorkRequest.Builder(
+ typeof(BackgroundWorker),
+ INTERVAL_IN_HOURS, TimeUnit.Hours
+ )
+ .SetConstraints(new Constraints.Builder()
+ .SetRequiresBatteryNotLow(true)
+ .Build())
+ .SetBackoffCriteria(BackoffPolicy.Linear, BACKOFF_DELAY_IN_MINUTES, TimeUnit.Minutes);
+ return workRequestBuilder.Build();
+ }
+ }
+
+ [Preserve]
+ public class BackgroundWorker : Worker
+ {
+ private Lazy _dataMaintainanceBackgroundService
+ => new Lazy(() => ContainerLocator.Current.Resolve());
+ private Lazy _loggerService => new Lazy(() => ContainerLocator.Current.Resolve());
+
+ public BackgroundWorker(Context context, WorkerParameters workerParameters)
+ : base(context, workerParameters)
+ {
+ // do nothing
+ }
+
+ public override Result DoWork()
+ {
+ var dataMaintainanceBackgroundService = _dataMaintainanceBackgroundService.Value;
+ var loggerService = _loggerService.Value;
+
+ loggerService.StartMethod();
+
+ try
+ {
+ dataMaintainanceBackgroundService.ExecuteAsync().GetAwaiter().GetResult();
+ return Result.InvokeSuccess();
+ }
+ catch (Exception exception)
+ {
+ loggerService.Exception("Exception", exception);
+ return Result.InvokeFailure();
+ }
+ finally
+ {
+ loggerService.EndMethod();
+ }
+ }
+
+ public override void OnStopped()
+ {
+ base.OnStopped();
+
+ _loggerService.Value.Warning("OnStopped");
+ }
+
+ }
+}
diff --git a/Covid19Radar/Covid19Radar.Android/Services/EventLogSubmissionBackgroundService.cs b/Covid19Radar/Covid19Radar.Android/Services/EventLogSubmissionBackgroundService.cs
index 11daf9f39..c5701b866 100644
--- a/Covid19Radar/Covid19Radar.Android/Services/EventLogSubmissionBackgroundService.cs
+++ b/Covid19Radar/Covid19Radar.Android/Services/EventLogSubmissionBackgroundService.cs
@@ -17,7 +17,7 @@ namespace Covid19Radar.Droid.Services
{
public class EventLogSubmissionBackgroundService : AbsEventLogSubmissionBackgroundService
{
- private const string CURRENT_WORK_NAME = "eventlog_submission_worker_20220112";
+ private const string CURRENT_WORK_NAME = "eventlog_submission_worker_20220628";
private const long INTERVAL_IN_HOURS = 24;
private const long BACKOFF_DELAY_IN_MINUTES = 60;
@@ -40,14 +40,14 @@ public override void Schedule()
PeriodicWorkRequest periodicWorkRequest = CreatePeriodicWorkRequest();
workManager.EnqueueUniquePeriodicWork(
CURRENT_WORK_NAME,
- ExistingPeriodicWorkPolicy.Replace,
+ ExistingPeriodicWorkPolicy.Keep,
periodicWorkRequest
);
_loggerService.EndMethod();
}
- private static PeriodicWorkRequest CreatePeriodicWorkRequest()
+ private PeriodicWorkRequest CreatePeriodicWorkRequest()
{
var workRequestBuilder = new PeriodicWorkRequest.Builder(
typeof(BackgroundWorker),
diff --git a/Covid19Radar/Covid19Radar.Android/Services/Logs/LogPeriodicDeleteService.cs b/Covid19Radar/Covid19Radar.Android/Services/Logs/LogPeriodicDeleteService.cs
deleted file mode 100644
index d88497c70..000000000
--- a/Covid19Radar/Covid19Radar.Android/Services/Logs/LogPeriodicDeleteService.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-using System;
-using Android.App;
-using Android.Content;
-using Covid19Radar.Services.Logs;
-using Prism.Ioc;
-using Xamarin.Essentials;
-
-namespace Covid19Radar.Droid.Services.Logs
-{
- public class LogPeriodicDeleteService : ILogPeriodicDeleteService
- {
- private static readonly int requestCode = 1000;
- private static readonly long executionIntervalMillis = 60 * 60 * 24 * 1000; // 24hours
-
- private readonly ILoggerService loggerService;
-
- public LogPeriodicDeleteService(
- ILoggerService loggerService
- )
- {
- this.loggerService = loggerService;
- }
-
- public void Init()
- {
- var nextScheduledTime = SetNextSchedule();
- loggerService.Info($"Next scheduled time: {DateTimeOffset.FromUnixTimeMilliseconds(nextScheduledTime).ToOffset(new TimeSpan(9, 0, 0))}");
- }
-
- public static long SetNextSchedule()
- {
- var nextScheduledTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + executionIntervalMillis;
-
- var context = Platform.AppContext;
- var intent = new Intent(context, typeof(LogPeriodicDeleteReceiver));
- var pendingIntent = PendingIntent.GetBroadcast(context, requestCode, intent, PendingIntentFlags.CancelCurrent);
-
- var alermService = context.GetSystemService(Context.AlarmService) as AlarmManager;
- if (alermService != null)
- {
- alermService.SetExactAndAllowWhileIdle(AlarmType.RtcWakeup, nextScheduledTime, pendingIntent);
- }
-
- return nextScheduledTime;
- }
- }
-
- [BroadcastReceiver]
- [IntentFilter(new[] { Intent.ActionBootCompleted })]
- public class LogPeriodicDeleteReceiver : BroadcastReceiver
- {
- private ILoggerService loggerService => ContainerLocator.Current.Resolve();
- private ILogFileService logFileService => ContainerLocator.Current.Resolve();
-
- public LogPeriodicDeleteReceiver()
- {
- // do nothing
- }
-
- public override void OnReceive(Context context, Intent intent)
- {
- try
- {
- loggerService.Info($"Action: {intent.Action}");
- logFileService.Rotate();
- loggerService.Info("Periodic deletion of old logs.");
- var nextScheduledTime = LogPeriodicDeleteService.SetNextSchedule();
- loggerService.Info($"Next scheduled time: {DateTimeOffset.FromUnixTimeMilliseconds(nextScheduledTime).ToOffset(new TimeSpan(9, 0, 0))}");
- }
- catch
- {
- // do nothing
- }
- }
- }
-}
diff --git a/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs b/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs
index 9ee3dbbbb..e771af87b 100644
--- a/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs
+++ b/Covid19Radar/Covid19Radar.Android/Services/Migration/MigrationProcessService.cs
@@ -69,14 +69,20 @@ public override Result DoWork()
public class MigrationProccessService : IMigrationProcessService
{
private readonly AbsExposureDetectionBackgroundService _exposureDetectionBackgroundService;
+ private readonly AbsDataMaintainanceBackgroundService _dataMaintainanceBackgroundService;
+ private readonly AbsEventLogSubmissionBackgroundService _eventLogSubmissionBackgroundService;
private readonly ILoggerService _loggerService;
public MigrationProccessService(
AbsExposureDetectionBackgroundService exposureDetectionBackgroundService,
+ AbsDataMaintainanceBackgroundService dataMaintainanceBackgroundService,
+ AbsEventLogSubmissionBackgroundService eventLogSubmissionBackgroundService,
ILoggerService loggerService
)
{
_exposureDetectionBackgroundService = exposureDetectionBackgroundService;
+ _dataMaintainanceBackgroundService = dataMaintainanceBackgroundService;
+ _eventLogSubmissionBackgroundService = eventLogSubmissionBackgroundService;
_loggerService = loggerService;
}
@@ -86,6 +92,8 @@ public async Task SetupAsync()
await new WorkManagerMigrator(
_exposureDetectionBackgroundService,
+ _dataMaintainanceBackgroundService,
+ _eventLogSubmissionBackgroundService,
_loggerService
).ExecuteAsync();
diff --git a/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs b/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs
index c0e02ee8a..c40b7b290 100644
--- a/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs
+++ b/Covid19Radar/Covid19Radar.Android/Services/Migration/WorkManagerMigrator.cs
@@ -19,14 +19,21 @@ internal class WorkManagerMigrator
};
private readonly AbsExposureDetectionBackgroundService _exposureDetectionBackgroundService;
+ private readonly AbsDataMaintainanceBackgroundService _dataMaintainanceBackgroundService;
+ private readonly AbsEventLogSubmissionBackgroundService _eventLogSubmissionBackgroundService;
+
private readonly ILoggerService _loggerService;
public WorkManagerMigrator(
AbsExposureDetectionBackgroundService exposureDetectionBackgroundService,
+ AbsDataMaintainanceBackgroundService dataMaintainanceBackgroundService,
+ AbsEventLogSubmissionBackgroundService eventLogSubmissionBackgroundService,
ILoggerService loggerService
)
{
_exposureDetectionBackgroundService = exposureDetectionBackgroundService;
+ _dataMaintainanceBackgroundService = dataMaintainanceBackgroundService;
+ _eventLogSubmissionBackgroundService = eventLogSubmissionBackgroundService;
_loggerService = loggerService;
}
@@ -38,6 +45,8 @@ internal Task ExecuteAsync()
CancelOldWorks(workManager, OldWorkNames, _loggerService);
_exposureDetectionBackgroundService.Schedule();
+ _dataMaintainanceBackgroundService.Schedule();
+ _eventLogSubmissionBackgroundService.Schedule();
_loggerService.EndMethod();
diff --git a/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs b/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs
index 6c491c375..87f3fdc79 100644
--- a/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs
+++ b/Covid19Radar/Covid19Radar.iOS/AppDelegate.cs
@@ -53,6 +53,9 @@ private Lazy _loggerService
private Lazy _exposureConfigurationRepository
= new Lazy(() => ContainerLocator.Current.Resolve());
+ private Lazy _dataMaintainanceBackgroundService
+ = new Lazy(() => ContainerLocator.Current.Resolve());
+
private App? AppInstance
{
get
@@ -112,12 +115,12 @@ public override bool FinishedLaunching(UIApplication app, NSDictionary launchOpt
UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(UIApplication.BackgroundFetchIntervalMinimum);
- ScheduleBackgroundTask();
+ ScheduleBackgroundTasks();
return base.FinishedLaunching(app, launchOptions);
}
- private void ScheduleBackgroundTask()
+ private void ScheduleBackgroundTasks()
{
try
{
@@ -127,6 +130,7 @@ private void ScheduleBackgroundTask()
{
_loggerService.Value.Exception("Failed to schedule ExposureDetectionBackgroundService", exception);
}
+
try
{
_eventLogSubmissionBackgroundService.Value.Schedule();
@@ -135,6 +139,15 @@ private void ScheduleBackgroundTask()
{
_loggerService.Value.Exception("Failed to schedule EventLogSubmissionBackgroundService", exception);
}
+
+ try
+ {
+ _dataMaintainanceBackgroundService.Value.Schedule();
+ }
+ catch (Exception exception)
+ {
+ _loggerService.Value.Exception("Failed to schedule DataMaintainanceBackgroundService", exception);
+ }
}
private bool IsUniversalLinks(NSDictionary launchOptions)
@@ -256,7 +269,7 @@ private void RegisterPlatformTypes(IContainer container)
// Services
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
- container.Register(Reuse.Singleton);
+ container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
container.Register(Reuse.Singleton);
diff --git a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj
index 013036399..6cecd9df3 100644
--- a/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj
+++ b/Covid19Radar/Covid19Radar.iOS/Covid19Radar.iOS.csproj
@@ -256,7 +256,6 @@
-
@@ -271,6 +270,7 @@
+
@@ -548,7 +548,6 @@
-
diff --git a/Covid19Radar/Covid19Radar.iOS/Info.plist b/Covid19Radar/Covid19Radar.iOS/Info.plist
index 751350d06..a88e10d47 100644
--- a/Covid19Radar/Covid19Radar.iOS/Info.plist
+++ b/Covid19Radar/Covid19Radar.iOS/Info.plist
@@ -54,8 +54,8 @@
BGTaskSchedulerPermittedIdentifiers
APP_PACKAGE_NAME.exposure-notification
- APP_PACKAGE_NAME.delete-old-logs
APP_PACKAGE_NAME.eventlog-submission
+ APP_PACKAGE_NAME.data-maintainance
UIAppFonts
@@ -68,7 +68,6 @@
LaunchScreen
UIBackgroundModes
- fetch
processing
UIUserInterfaceStyle
diff --git a/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs
new file mode 100644
index 000000000..61fd5a28f
--- /dev/null
+++ b/Covid19Radar/Covid19Radar.iOS/Services/DataMaintainanceBackgroundService.cs
@@ -0,0 +1,136 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using BackgroundTasks;
+using Covid19Radar.Common;
+using Covid19Radar.Services;
+using Covid19Radar.Services.Logs;
+using Foundation;
+using Xamarin.Essentials;
+
+namespace Covid19Radar.iOS.Services.Logs
+{
+ public class DataMaintainanceBackgroundService : AbsDataMaintainanceBackgroundService
+ {
+ #region Constants
+
+ private const int TASK_INTERVAL_IN_DAYS = 1;
+
+ #endregion
+
+ #region Static Fields
+
+ private static readonly string BGTASK_IDENTIFIER = AppInfo.PackageName + ".data-maintainance";
+
+ #endregion
+
+ #region Instance Fields
+
+ private readonly IDateTimeUtility _dateTimeUtility;
+
+ #endregion
+
+ #region Constructors
+
+ public DataMaintainanceBackgroundService(
+ ILoggerService loggerService,
+ ILogFileService logFileService,
+ IDateTimeUtility dateTimeUtility
+ ) : base(logFileService, loggerService)
+ {
+ _dateTimeUtility = dateTimeUtility;
+ }
+
+ #endregion
+
+ #region ILogPeriodicDeleteService Methods
+
+ public override void Schedule()
+ {
+ loggerService.StartMethod();
+
+ var result = BGTaskScheduler.Shared.Register(BGTASK_IDENTIFIER, null, task =>
+ {
+ loggerService.Info("Background task has been started.");
+
+ DateTime nextDateTime = _dateTimeUtility.UtcNow.Date.AddDays(TASK_INTERVAL_IN_DAYS);
+ ScheduleBgTask(nextDateTime);
+
+ var cancellationTokenSource = new CancellationTokenSource();
+ task.ExpirationHandler = cancellationTokenSource.Cancel;
+
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ await ExecuteAsync();
+ task.SetTaskCompleted(true);
+ }
+ catch (OperationCanceledException exception)
+ {
+ loggerService.Exception($"Background task canceled.", exception);
+ task.SetTaskCompleted(false);
+ }
+ catch (Exception exception)
+ {
+ loggerService.Exception($"Exception", exception);
+ task.SetTaskCompleted(false);
+ }
+ finally
+ {
+ cancellationTokenSource.Dispose();
+ }
+ }, cancellationTokenSource.Token);
+ });
+
+ if (result)
+ {
+ loggerService.Debug("BGTaskScheduler.Shared.Register succeeded.");
+ }
+ else
+ {
+ loggerService.Info("BGTaskScheduler.Shared.Register failed.");
+ }
+
+ ScheduleBgTask(_dateTimeUtility.UtcNow);
+
+ loggerService.EndMethod();
+ }
+
+ #endregion
+
+ #region Other Private Methods
+
+ private void ScheduleBgTask(DateTime nextDateTime)
+ {
+ loggerService.StartMethod();
+
+ try
+ {
+ BGProcessingTaskRequest bgTaskRequest = new BGProcessingTaskRequest(BGTASK_IDENTIFIER)
+ {
+ EarliestBeginDate = NSDate.FromTimeIntervalSince1970(nextDateTime.ToUnixEpoch())
+ };
+
+ BGTaskScheduler.Shared.Submit(bgTaskRequest, out var error);
+ if (error != null)
+ {
+ NSErrorException exception = new NSErrorException(error);
+ loggerService.Exception("BGTaskScheduler submit failed.", exception);
+ throw exception;
+ }
+ }
+ finally
+ {
+ loggerService.EndMethod();
+ }
+ }
+
+ #endregion
+ }
+
+}
diff --git a/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs b/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs
index eb6b65720..4d1516b41 100644
--- a/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs
+++ b/Covid19Radar/Covid19Radar.iOS/Services/EventLogSubmissionBackgroundService.cs
@@ -16,97 +16,103 @@ namespace Covid19Radar.iOS.Services
{
public class EventLogSubmissionBackgroundService : AbsEventLogSubmissionBackgroundService
{
- private static readonly string IDENTIFIER = AppInfo.PackageName + ".eventlog-submission";
+ private const int TASK_INTERVAL_IN_DAYS = 1;
- private const double ONE_DAY_IN_SECONDS = 1 * 24 * 60 * 60;
+ private static readonly string BGTASK_IDENTIFIER = AppInfo.PackageName + ".eventlog-submission";
private readonly IEventLogService _eventLogService;
private readonly ILoggerService _loggerService;
+ private readonly IDateTimeUtility _dateTimeUtility;
public EventLogSubmissionBackgroundService(
IEventLogService eventLogService,
- ILoggerService loggerService
+ ILoggerService loggerService,
+ IDateTimeUtility dateTimeUtility
) : base()
{
_eventLogService = eventLogService;
_loggerService = loggerService;
+ _dateTimeUtility = dateTimeUtility;
}
public override void Schedule()
{
_loggerService.StartMethod();
- _ = BGTaskScheduler.Shared.Register(IDENTIFIER, null, task =>
+ var result = BGTaskScheduler.Shared.Register(BGTASK_IDENTIFIER, null, task =>
{
- HandleSendLogAsync((BGAppRefreshTask)task);
- });
-
- ScheduleSendEventLog();
-
- _loggerService.EndMethod();
- }
-
- private void HandleSendLogAsync(BGAppRefreshTask task)
- {
- _loggerService.StartMethod();
+ _loggerService.Info("Background task has been started.");
- ScheduleSendEventLog();
+ DateTime nextDateTime = _dateTimeUtility.UtcNow.Date.AddDays(TASK_INTERVAL_IN_DAYS);
+ ScheduleBgTask(nextDateTime);
- var cancellationTokenSource = new CancellationTokenSource();
- task.ExpirationHandler = cancellationTokenSource.Cancel;
+ var cancellationTokenSource = new CancellationTokenSource();
+ task.ExpirationHandler = cancellationTokenSource.Cancel;
- _ = Task.Run(async () =>
- {
- _loggerService.Info("HandleSendLogAsync() Task.Run() start");
- try
- {
- await _eventLogService.SendAllAsync(
- AppConstants.EventLogMaxRequestSizeInBytes,
- AppConstants.EventLogMaxRetry);
- task.SetTaskCompleted(true);
- }
- catch (OperationCanceledException exception)
- {
- _loggerService.Exception($"Background task canceled.", exception);
- task.SetTaskCompleted(false);
- }
- catch (Exception exception)
- {
- _loggerService.Exception($"Exception", exception);
- task.SetTaskCompleted(false);
- }
- finally
+ _ = Task.Run(async () =>
{
- cancellationTokenSource.Dispose();
- _loggerService.Info("HandleSendLogAsync() Task.Run() end");
- }
+ try
+ {
+ await _eventLogService.SendAllAsync(
+ AppConstants.EventLogMaxRequestSizeInBytes,
+ AppConstants.EventLogMaxRetry);
+ task.SetTaskCompleted(true);
+ }
+ catch (OperationCanceledException exception)
+ {
+ _loggerService.Exception($"Background task canceled.", exception);
+ task.SetTaskCompleted(false);
+ }
+ catch (Exception exception)
+ {
+ _loggerService.Exception($"Exception", exception);
+ task.SetTaskCompleted(false);
+ }
+ finally
+ {
+ cancellationTokenSource.Dispose();
+ }
+ }, cancellationTokenSource.Token);
});
+ if (result)
+ {
+ _loggerService.Debug("BGTaskScheduler.Shared.Register succeeded.");
+ }
+ else
+ {
+ _loggerService.Info("BGTaskScheduler.Shared.Register failed.");
+ }
+
+ ScheduleBgTask(_dateTimeUtility.UtcNow);
+
_loggerService.EndMethod();
}
- private void ScheduleSendEventLog()
+ private void ScheduleBgTask(DateTime nextDateTime)
{
_loggerService.StartMethod();
- var bgTaskRequest = new BGProcessingTaskRequest(IDENTIFIER)
+ try
{
- EarliestBeginDate = NSDate.FromTimeIntervalSinceNow(ONE_DAY_IN_SECONDS),
- RequiresNetworkConnectivity = true
- };
-
- _loggerService.Info($"request.EarliestBeginDate: {bgTaskRequest.EarliestBeginDate}");
+ BGProcessingTaskRequest bgTaskRequest = new BGProcessingTaskRequest(BGTASK_IDENTIFIER)
+ {
+ RequiresNetworkConnectivity = true,
+ EarliestBeginDate = NSDate.FromTimeIntervalSince1970(nextDateTime.ToUnixEpoch())
+ };
- _ = BGTaskScheduler.Shared.Submit(bgTaskRequest, out var error);
- if (error != null)
+ BGTaskScheduler.Shared.Submit(bgTaskRequest, out var error);
+ if (error != null)
+ {
+ NSErrorException exception = new NSErrorException(error);
+ _loggerService.Exception("BGTaskScheduler submit failed.", exception);
+ throw exception;
+ }
+ }
+ finally
{
- NSErrorException exception = new NSErrorException(error);
- _loggerService.Exception("BGTaskScheduler submit failed.", exception);
- throw exception;
+ _loggerService.EndMethod();
}
-
- _loggerService.EndMethod();
}
}
}
-
diff --git a/Covid19Radar/Covid19Radar.iOS/Services/Logs/LogPeriodicDeleteService.cs b/Covid19Radar/Covid19Radar.iOS/Services/Logs/LogPeriodicDeleteService.cs
deleted file mode 100644
index 8f3955de2..000000000
--- a/Covid19Radar/Covid19Radar.iOS/Services/Logs/LogPeriodicDeleteService.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-using BackgroundTasks;
-using Covid19Radar.Services.Logs;
-using Foundation;
-using Xamarin.Essentials;
-
-namespace Covid19Radar.iOS.Services.Logs
-{
- public class LogPeriodicDeleteService : ILogPeriodicDeleteService
- {
- #region Static Fields
-
- private static readonly string identifier = AppInfo.PackageName + ".delete-old-logs";
-
- #endregion
-
- #region Instance Fields
-
- private readonly ILoggerService loggerService;
- private readonly ILogFileService logFileService;
-
- #endregion
-
- #region Constructors
-
- public LogPeriodicDeleteService(
- ILoggerService loggerService,
- ILogFileService logFileService
- )
- {
- this.loggerService = loggerService;
- this.logFileService = logFileService;
- }
-
- #endregion
-
- #region ILogPeriodicDeleteService Methods
-
- public void Init()
- {
- loggerService.StartMethod();
-
- _ = BGTaskScheduler.Shared.Register(identifier, null, task =>
- {
- HandleAppRefresh((BGAppRefreshTask)task);
- });
-
- ScheduleAppRefresh();
-
- loggerService.EndMethod();
- }
-
- #endregion
-
- #region Other Private Methods
-
- private void HandleAppRefresh(BGAppRefreshTask task)
- {
- try
- {
- loggerService.StartMethod();
-
- ScheduleAppRefresh();
-
- var queue = new NSOperationQueue();
- queue.MaxConcurrentOperationCount = 1;
-
- task.ExpirationHandler = () =>
- {
- loggerService.Info("Task expired.");
- queue.CancelAllOperations();
- };
-
- var operation = new DeleteOldLogsOperation(loggerService, logFileService);
- operation.CompletionBlock = () =>
- {
- loggerService.Info($"Operation completed. operation.IsCancelled: {operation.IsCancelled}");
- task.SetTaskCompleted(!operation.IsCancelled);
- };
-
- queue.AddOperation(operation);
-
- loggerService.EndMethod();
- }
- catch
- {
- // do nothing
- }
- }
-
- private void ScheduleAppRefresh()
- {
- loggerService.StartMethod();
-
- var oneDay = 1 * 24 * 60 * 60;
- var request = new BGAppRefreshTaskRequest(identifier);
- request.EarliestBeginDate = NSDate.FromTimeIntervalSinceNow(oneDay); // Fetch no earlier than 1 day from now
-
- loggerService.Info($"request.EarliestBeginDate: {request.EarliestBeginDate}");
-
- _ = BGTaskScheduler.Shared.Submit(request, out var error);
-
- if (error != null)
- {
- loggerService.Error($"Could not schedule app refresh. Error: {error}");
- }
-
- loggerService.EndMethod();
- }
-
- #endregion
- }
-
- class DeleteOldLogsOperation : NSOperation
- {
- #region Instance Fields
-
- private readonly ILoggerService loggerService;
- private readonly ILogFileService logFileService;
-
- #endregion
-
- #region Constructors
-
- public DeleteOldLogsOperation(ILoggerService loggerService, ILogFileService logFileService)
- {
- this.loggerService = loggerService;
- this.logFileService = logFileService;
- }
-
- #endregion
-
- #region NSOperation Methods
-
- public override void Main()
- {
- base.Main();
-
- try
- {
- loggerService.StartMethod();
-
- logFileService.Rotate();
-
- loggerService.Info("Periodic deletion of old logs.");
- loggerService.EndMethod();
- }
- catch
- {
- // do nothing
- }
- }
-
- #endregion
- }
-}
diff --git a/Covid19Radar/Covid19Radar/App.xaml.cs b/Covid19Radar/Covid19Radar/App.xaml.cs
index 5653063f3..0296db4f3 100644
--- a/Covid19Radar/Covid19Radar/App.xaml.cs
+++ b/Covid19Radar/Covid19Radar/App.xaml.cs
@@ -229,21 +229,6 @@ private static void RegisterCommonTypes(IContainer container)
container.Register(Reuse.Singleton);
}
- protected override void OnStart()
- {
- // Initialize periodic log delete service
- var logPeriodicDeleteService = Container.Resolve();
- logPeriodicDeleteService.Init();
-
- LogFileService.Rotate();
- }
-
- protected override void OnResume()
- {
- base.OnResume();
- LogFileService.Rotate();
- }
-
protected override void OnSleep()
{
base.OnSleep();
diff --git a/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs b/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs
new file mode 100644
index 000000000..2198801a4
--- /dev/null
+++ b/Covid19Radar/Covid19Radar/Services/AbsDataMaintainanceBackgroundService.cs
@@ -0,0 +1,40 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+using System.Threading.Tasks;
+using Covid19Radar.Services.Logs;
+
+namespace Covid19Radar.Services
+{
+ public abstract class AbsDataMaintainanceBackgroundService : IBackgroundService
+ {
+ protected readonly ILoggerService loggerService;
+
+ private readonly ILogFileService _logFileService;
+
+ public AbsDataMaintainanceBackgroundService(
+ ILogFileService logFileService,
+ ILoggerService loggerService
+ )
+ {
+ _logFileService = logFileService;
+ this.loggerService = loggerService;
+ }
+
+ public abstract void Schedule();
+
+ public async Task ExecuteAsync()
+ {
+ loggerService.StartMethod();
+
+ try
+ {
+ _logFileService.Rotate();
+ }
+ finally
+ {
+ loggerService.EndMethod();
+ }
+ }
+ }
+}
diff --git a/Covid19Radar/Covid19Radar/Services/Logs/LogPeriodicDeleteService.cs b/Covid19Radar/Covid19Radar/Services/Logs/LogPeriodicDeleteService.cs
deleted file mode 100644
index 0a9711e44..000000000
--- a/Covid19Radar/Covid19Radar/Services/Logs/LogPeriodicDeleteService.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-namespace Covid19Radar.Services.Logs
-{
- public interface ILogPeriodicDeleteService
- {
- void Init();
- }
-}
diff --git a/Covid19Radar/Covid19Radar/ViewModels/HomePage/SplashPageViewModel.cs b/Covid19Radar/Covid19Radar/ViewModels/HomePage/SplashPageViewModel.cs
index cbc5ea5c6..8d9d77f72 100644
--- a/Covid19Radar/Covid19Radar/ViewModels/HomePage/SplashPageViewModel.cs
+++ b/Covid19Radar/Covid19Radar/ViewModels/HomePage/SplashPageViewModel.cs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+using System.Threading.Tasks;
using Covid19Radar.Model;
using Covid19Radar.Repository;
using Covid19Radar.Services;
@@ -19,6 +20,7 @@ public class SplashPageViewModel : ViewModelBase
private readonly IUserDataService _userDataService;
private readonly IMigrationService _migrationService;
private readonly IUserDataRepository _userDataRepository;
+ private readonly ILogFileService _logFileService;
public SplashPageViewModel(
INavigationService navigationService,
@@ -26,7 +28,8 @@ public SplashPageViewModel(
ILoggerService loggerService,
IUserDataRepository userDataRepository,
IUserDataService userDataService,
- IMigrationService migrationService
+ IMigrationService migrationService,
+ ILogFileService logFileService
) : base(navigationService)
{
_termsUpdateService = termsUpdateService;
@@ -34,6 +37,7 @@ IMigrationService migrationService
_userDataRepository = userDataRepository;
_userDataService = userDataService;
_migrationService = migrationService;
+ _logFileService = logFileService;
}
public override async void OnNavigatedTo(INavigationParameters parameters)
@@ -44,6 +48,10 @@ public override async void OnNavigatedTo(INavigationParameters parameters)
await _migrationService.MigrateAsync();
+ await Task.Run(() => {
+ _logFileService.Rotate();
+ });
+
var destination = Destination.HomePage;
if (parameters.ContainsKey(SplashPage.DestinationKey))
{