This repository has been archived by the owner on Jun 20, 2023. It is now read-only.
/
TimeVariables.kt
240 lines (207 loc) · 8.34 KB
/
TimeVariables.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
package de.rki.coronawarnapp.risk
import com.google.android.gms.common.api.ApiException
import de.rki.coronawarnapp.BuildConfig
import de.rki.coronawarnapp.CoronaWarnApplication
import de.rki.coronawarnapp.exception.ExceptionCategory
import de.rki.coronawarnapp.exception.reporting.report
import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient
import de.rki.coronawarnapp.storage.LocalData
import de.rki.coronawarnapp.storage.tracing.TracingIntervalRepository
import de.rki.coronawarnapp.util.TimeAndDateExtensions.daysToMilliseconds
import java.util.concurrent.TimeUnit
object TimeVariables {
/****************************************************
* CONSTANTS
****************************************************/
/**
* Deactivation threshold time range
* In seconds
*/
private const val DEACTIVATION_TRACING_MEASURE_THRESHOLD_TIMERANGE = 60L
/**
* Getter function for [DEACTIVATION_TRACING_MEASURE_THRESHOLD_TIMERANGE]
*
* @return number of seconds
*/
fun getDeactivationTracingMeasureThresholdTimeRange(): Long =
DEACTIVATION_TRACING_MEASURE_THRESHOLD_TIMERANGE
/**
* The maximal runtime of a transaction
* In milliseconds
*/
private const val TRANSACTION_TIMEOUT = 60000L
/**
* Getter function for [TRANSACTION_TIMEOUT]
*
* @return timeout in milliseconds
*/
fun getTransactionTimeout(): Long = TRANSACTION_TIMEOUT
/**
* The max timeRange for the exposure risk calculation.
* In days.
*/
private const val DEFAULT_RETENTION_PERIOD = 14
/**
* Getter function for [DEFAULT_RETENTION_PERIOD]
*
* @return max calculation range in days
*/
fun getDefaultRetentionPeriodInDays() = DEFAULT_RETENTION_PERIOD
/**
* Getter function for [DEFAULT_RETENTION_PERIOD]
*
* @return max calculation range in ms
*/
fun getDefaultRetentionPeriodInMS() =
getDefaultRetentionPeriodInDays().toLong().daysToMilliseconds()
/**
* The time that the tracing has to be active to show the low risk level
* In hours.
*/
private const val MIN_ACTIVATED_TRACING_TIME = 24
/**
* Getter function for [MIN_ACTIVATED_TRACING_TIME]
*
* @return minimum required hours of active tracing
*/
fun getMinActivatedTracingTime(): Int = MIN_ACTIVATED_TRACING_TIME
/**
* The timeRange until the calculated exposure figures are rated as stale.
* In hours.
*/
private const val MAX_STALE_EXPOSURE_RISK_RANGE = 48
/**
* Getter function for [MAX_STALE_EXPOSURE_RISK_RANGE]
*
* @return stale threshold in hours
*/
fun getMaxStaleExposureRiskRange(): Int = MAX_STALE_EXPOSURE_RISK_RANGE
private const val MILISECONDS_IN_A_SECOND = 1000
private const val SECONDS_IN_A_MINUTES = 60
private const val MINUTES_IN_AN_HOUR = 60
private const val HOURS_IN_AN_DAY = 24
/**
* Delay in milliseconds for manual key retrieval process
* Value for testing: 1 min = 1000 * 60 * 1
* Value: 24 hours = 1000 * 60 * 60 * 24 milliseconds
*/
private val MANUAL_KEY_RETRIEVAL_DELAY =
if (BuildConfig.FLAVOR == "deviceForTesters") {
MILISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES
} else {
MILISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTES * MINUTES_IN_AN_HOUR * HOURS_IN_AN_DAY
}
/**
* Getter function for [MANUAL_KEY_RETRIEVAL_DELAY]
*
* @return delay of key retrieval in milliseconds
*/
fun getManualKeyRetrievalDelay() = MANUAL_KEY_RETRIEVAL_DELAY
/**
* This is the maximum attenuation duration value for the risk level calculation
* in minutes
*/
private const val MAX_ATTENUATION_DURATION = 30
/**
* Getter function for [MAX_ATTENUATION_DURATION]
*
* @return max attenuation duration in minutes
*/
fun getMaxAttenuationDuration() = MAX_ATTENUATION_DURATION
/****************************************************
* STORED DATA
****************************************************/
/**
* timestamp when the tracing was activated by the user read from the mobile device storage.
* The parameter is only filled once the tracing was activated and
* not if the user activated or deactivates the tracing.
*
* It will change when you reinstall your app and activate tracing again.
*
* @return time in milliseconds when tracing was initially activated
*/
fun getInitialExposureTracingActivationTimestamp(): Long? =
LocalData.initialTracingActivationTimestamp()
/**
* timestamp when the last successful exposureRisk calculation happened read from the mobile device storage.
* Last time when the transaction was successfully executed
*
* @return last time in milliseconds [de.rki.coronawarnapp.transaction.RetrieveDiagnosisKeysTransaction]
* was run successfully
*/
// because we have risk level calculation and key retrieval calculation
fun getLastTimeDiagnosisKeysFromServerFetch(): Long? =
LocalData.lastTimeDiagnosisKeysFromServerFetch()?.time
/****************************************************
* CALCULATED TIME VARIABLES
****************************************************/
/**
* The time since the last successful exposure calculation ran in foreground or background.
* In milliseconds
*
* @return time in milliseconds since the exposure calculation was run successfully
*/
fun getTimeSinceLastDiagnosisKeyFetchFromServer(): Long? {
val lastTimeDiagnosisKeysFromServerFetch =
getLastTimeDiagnosisKeysFromServerFetch() ?: return null
return System.currentTimeMillis() - lastTimeDiagnosisKeysFromServerFetch
}
/**
* The time the tracing is active.
*
* @return in milliseconds
*/
fun getTimeActiveTracingDuration(): Long = System.currentTimeMillis() -
(getInitialExposureTracingActivationTimestamp() ?: 0L) -
LocalData.totalNonActiveTracing()
suspend fun getActiveTracingDaysInRetentionPeriod(): Long {
// the active tracing time during the retention period - all non active tracing times
val tracingActiveMS = getTimeRangeFromRetentionPeriod()
val inactiveTracingIntervals = TracingIntervalRepository
.getDateRepository(CoronaWarnApplication.getAppContext())
.getIntervals()
.toMutableList()
// by default the tracing is deactivated
// if the API is reachable we set the value accordingly
var enIsEnabled = false
try {
enIsEnabled = !InternalExposureNotificationClient.asyncIsEnabled()
} catch (e: ApiException) {
e.report(ExceptionCategory.EXPOSURENOTIFICATION)
}
if (enIsEnabled) {
val current = System.currentTimeMillis()
var lastTimeTracingWasNotActivated =
LocalData.lastNonActiveTracingTimestamp() ?: current
if (lastTimeTracingWasNotActivated < (current - getTimeRangeFromRetentionPeriod())) {
lastTimeTracingWasNotActivated = current - getTimeRangeFromRetentionPeriod()
}
inactiveTracingIntervals.add(Pair(lastTimeTracingWasNotActivated, current))
}
val finalTracingMS = tracingActiveMS - inactiveTracingIntervals
.map { it.second - it.first }
.sum()
return TimeUnit.MILLISECONDS.toDays(finalTracingMS)
}
/****************************************************
* HELPER FUNCTIONS
****************************************************/
/**
* Return the maximum time of the time range that is used as retention time range.
* The retention time range will be corrected to the initial exposure activation timestamp
* (e.g. when we reset our data or start tracing for the first time after a fresh install)
*
* @return max number of days the server should fetch
*/
private fun getTimeRangeFromRetentionPeriod(): Long {
val activeTracingTimeInMS =
getInitialExposureTracingActivationTimestamp()?.let {
System.currentTimeMillis().minus(it)
} ?: return 0
return if (activeTracingTimeInMS > getDefaultRetentionPeriodInMS()) {
getDefaultRetentionPeriodInMS()
} else {
activeTracingTimeInMS
}
}
}