-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
integrate kronos-android ntp clock library into project #150
base: develop
Are you sure you want to change the base?
Conversation
add Kronos ntp clock lib change DiagnosisKeysToken to use ntp time
make app context injectable, make NTPTime use it removed app context access hack from BaseCovidWatchApplicaiton
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's nice start but according to README from https://github.com/lyft/Kronos-Android
we need to init this lib in the onCreate
of the Application
class. So when the wrappers is done we would need to inject it in the Application
class to call syncInBackground
method.
Also, to fix the problem we need to limit the date pickers on the verification screen to real dates.
So we would to rework it here:
Lines 122 to 128 in 21cb2a7
val twoWeeksAgo = LocalDate.now().plusDays(-14).toInstant() | |
.toEpochMilli() | |
// Day in the past or 14 days back | |
val fromWhen = dayInPast ?: twoWeeksAgo | |
val untilNow = LocalDate.now().toInstant().toEpochMilli() |
import org.koin.core.KoinComponent | ||
import org.koin.core.inject | ||
|
||
class NTPTime { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A separate wrapper is nice but having a static reference to a context is a bad thing that leads to memory leaks.
In Koin
there is androidApplication()
that returns applicationContext
, have a look at any wrapper that use androidApplication()
in appModule
. For example Notifications
-- we need something like that and then we will be injecting NtpTime
anywhere we need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, to make it clear -- I suggest to rename this class to NtpTime
because of the guidelines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed static reference to context, changed so it's passed into the constructor and never stored
renamed file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made NtpClock injectable. Injected into BaseCovidWatchApplication and started properly from onCreate()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
modified VerifyPositiveDiagnosisFragment to use NtpTime for date pickers
import org.covidwatch.android.data.converter.ExposureConfigurationConverter | ||
|
||
@Entity(tableName = "diagnosis_keys_token") | ||
@TypeConverters(ExposureConfigurationConverter::class) | ||
data class DiagnosisKeysToken( | ||
@PrimaryKey val token: String, | ||
val exposureConfiguration: CovidExposureConfiguration, | ||
val providedTime: Long = System.currentTimeMillis(), | ||
val providedTime: Long = NTPTime.currentTimeMillis(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would to remove default value for this property and use injected NtpTime
to use a proper time. But having here a proper world time is not critical, it's not even used anywhere for now.
So we could leave the System
time here because this class might be deleted in the near future when we update EN version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change reverted back to System call
import android.content.ContextWrapper | ||
|
||
// exists solely to make the Android applicationContext injectable | ||
class AppContext(context : Context) : ContextWrapper(context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove it please since we won't use the implementation of NTPTime
with companion object
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
file removed
…ment to use NtpTime for date pickers refactor so NtpTime is injectable, change VerifyPositiveDiagnosisFragment to use NtpTime for date pickers remove AppContext class properly start ntpTime in Application onCreate()
remove unused function from NtpTime
remove unused import
removed trailing newline (the only change to this file) to remove from this commit
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like the github editor enforces the final newline haha
remove DiagnonsisKeysToken.kt from commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for changes now it's better but still some issues need to be resolved.
I double checked the library and it's quite old but the version of it still still super alpha which suggest Lyft doesn't really support it. There are a few issues in their repo but we don't really need a high accuracy from the lib -- we need good enough to sync the days not minutes.
Another old lib that I remember is https://github.com/instacart/truetime-android
but it looks even more abandoned so no big difference I guess.
Also, I realized that introducing NTP time, in the ideal case, would need more changes than here...
We probably need to change most of Instant.now()
or any now()
requests but this is too big changes that would need to replace all java.Time
API. We need to think on this before changing everything.
app/build.gradle
Outdated
@@ -288,6 +288,10 @@ dependencies { | |||
testImplementation "io.mockk:mockk:1.10.0" | |||
// Koin | |||
testImplementation "org.koin:koin-test:$koin_version" | |||
|
|||
// Kronos ntp clock | |||
def kronos_latest_version = "0.0.1-alpha09" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last dependencies are preserved for the test flavored so let's move this before the test dependencies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dependency line moved
fun syncInBackground() = kronosClock.syncInBackground() | ||
|
||
fun nowAsLocalDate() : LocalDate = | ||
Instant.ofEpochMilli(currentTimeMillis()).atZone(ZoneId.systemDefault()).toLocalDate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ZoneId.systemDefault()
introduces the same problem that we tried to eliminate -- it tights the time of the app to the users' settings. I was able to reproduce a one day shift with a timezone that have the next day relatively to mine. It's not that big as before but still a problem.
One way to resolve is just to remove atZone(ZoneId.systemDefault())
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed notion of LocalDate from NtpTime to avoid confusion / simplify the code. Sticking to returning Instants instead
@@ -119,13 +121,13 @@ class VerifyPositiveDiagnosisFragment : | |||
val builder = MaterialDatePicker.Builder.datePicker() | |||
val constraints = CalendarConstraints.Builder() | |||
|
|||
val twoWeeksAgo = LocalDate.now().plusDays(-14).toInstant() | |||
val twoWeeksAgo = ntpTime.nowAsLocalDate().plusDays(-14).toInstant() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a problem with this solution.
Even if the dates that can be selected are correct the date picker shows the current month from the device's settings.
I tried to use selection to current day when we open the dialog but it doesn't help.
@rasprague Could you try to investigate if that somehow possible to fix with MaterialDatePicker
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
adding a setOpenAt() to the date picker constraints fixes this
…nstant removed "LocalTime" from NtpTime add plus/minus days extenstion to Instant
force date picker to open on today's month
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost done, just a few suggestions. But the concern about this PR is still valid -- should we use this NTP adjusted time across the whole app or only in the date pickers.
app/build.gradle
Outdated
apply plugin: 'com.google.gms.google-services' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the same formatter from AS in the future to avoid this kind of changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
|
||
import java.time.Instant | ||
|
||
// 1d * (24h/d) * (60m/h) * (60s/m) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating extensions is nice but why then don't use existing API inside of them?
Like this:
minus(15, ChronoUnit.DAYS)
add(Duration.ofDays(15))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed
constraints.setValidator(BaseDateValidator { it in fromWhen..untilNow }) | ||
constraints | ||
.setValidator(BaseDateValidator { it in fromWhen..untilNow }) | ||
.setOpenAt(untilNow) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
|
||
// Day in the past or 14 days back | ||
val fromWhen = dayInPast ?: twoWeeksAgo | ||
|
||
val untilNow = LocalDate.now().toInstant().toEpochMilli() | ||
val untilNow = ntpTime.nowAsInstant().toEpochMilli() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the conversion is redundant because we use the milliseconds anyway. We could make NtpTime.currentTimeMillis
public and use it directly here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calling currentTimeMillis() directly
minor changes / cleanup
integrate ntp clock library into app, make "Share a Positive Diagnosis" date picker use ntp time