Closed Bug 714357 Opened 13 years ago Closed 7 years ago

API to enumerate available timezones and set timezone

Categories

(Core :: DOM: Device Interfaces, defect, P1)

ARM
Gonk (Firefox OS)
defect

Tracking

()

RESOLVED WONTFIX
blocking-kilimanjaro ?
blocking-basecamp -

People

(Reporter: cjones, Unassigned)

References

Details

The initial implementation of this is only going to be used on gonk, and these three APIs are pretty closely related, so putting them in one work item.

Here's a strawman for the settings

  settings.time.useNetworkTime --- Boolean.  If true, use NITZ, NTP or other network-provided timezone/datetime info.  If true, the "timezone" and "datetime" settings below become read-only, but are updated as network time updates are received.

  settings.time.timezone --- String representing a timezone in one of the formats allowable for the TZ environment variable used by POSIX tzset().

  settings.time.msSinceEpoch --- Datetime as a number of milliseconds since the POSIX Epoch (i.e., 00:00:00 UTC on 1 January 1970).

It's less clear where enumerating preconfigured timezones should live.  This probably needs to be a privileged API since it adds fingerprinting bits.  But, a purely enumeration API isn't all that's needed to implement a settings application, because the timezone names would want to be localized.  So maybe it's just best to hard-code them for now.
(In reply to Chris Jones [:cjones] [:warhammer] from comment #0)
>   settings.time.msSinceEpoch --- Datetime as a number of milliseconds since
> the POSIX Epoch (i.e., 00:00:00 UTC on 1 January 1970).

I don't really like having this as a setting because it will be a constantly moving value and I don't think we should have such kind of settings. I would prefer an API that allows setting the current time instead and getting it with a Date object. If we have such API, we could allow setting the timezone trough it.

> It's less clear where enumerating preconfigured timezones should live.  This
> probably needs to be a privileged API since it adds fingerprinting bits. 

If the preconfigured TZ live in Gecko, it will be the same for all Gecko users so fingerprinting wouldn't be an issue.
(In reply to Mounir Lamouri (:volkmar) (:mounir) from comment #1)
> (In reply to Chris Jones [:cjones] [:warhammer] from comment #0)
> >   settings.time.msSinceEpoch --- Datetime as a number of milliseconds since
> > the POSIX Epoch (i.e., 00:00:00 UTC on 1 January 1970).
> 
> I don't really like having this as a setting because it will be a constantly
> moving value and I don't think we should have such kind of settings. I would
> prefer an API that allows setting the current time instead and getting it
> with a Date object. If we have such API, we could allow setting the timezone
> trough it.
> 

I don't understand how that's different.  It sounds like you're exchanging milliseconds for Date objects.

Date doesn't know about DST etc. AFAICT so I don't think that's a good interface for setting the timezone.  The timezone configuration is surprisingly complicated, see man 2 tzset.

> > It's less clear where enumerating preconfigured timezones should live.  This
> > probably needs to be a privileged API since it adds fingerprinting bits. 
> 
> If the preconfigured TZ live in Gecko, it will be the same for all Gecko
> users so fingerprinting wouldn't be an issue.

In Gonk they live in the low-level android system data.  That data might be different on different OS's.  But your argument may be sound.  However, I don't know of any use cases for enumerating available timezones other than to implement UI to set it, so keeping this privileged seems reasonable to start with.  My recommendation is to hard-code this in gaia anyway, for the sake of l10n.
(In reply to Chris Jones [:cjones] [:warhammer] from comment #2)
> (In reply to Mounir Lamouri (:volkmar) (:mounir) from comment #1)
> > (In reply to Chris Jones [:cjones] [:warhammer] from comment #0)
> > >   settings.time.msSinceEpoch --- Datetime as a number of milliseconds since
> > > the POSIX Epoch (i.e., 00:00:00 UTC on 1 January 1970).
> > 
> > I don't really like having this as a setting because it will be a constantly
> > moving value and I don't think we should have such kind of settings. I would
> > prefer an API that allows setting the current time instead and getting it
> > with a Date object. If we have such API, we could allow setting the timezone
> > trough it.
> > 
> 
> I don't understand how that's different.  It sounds like you're exchanging
> milliseconds for Date objects.

What I meant is that settings should be fixed values and "time.msSinceEpoch" is going to be a constantly moving value. I really don't think we should do that. Instead, we should have an API that allows setting the system time and getting the time could be done trough the Date object.

> Date doesn't know about DST etc. AFAICT so I don't think that's a good
> interface for setting the timezone.  The timezone configuration is
> surprisingly complicated, see man 2 tzset.

TZ could be a setting, sure. But if we have msSinceEpoch in an API we could also just use that API for TZ. I'm not sure what you meant by "that" in "I don't think that's a good interface".
(In reply to Mounir Lamouri (:volkmar) (:mounir) from comment #3)
> (In reply to Chris Jones [:cjones] [:warhammer] from comment #2)
> > (In reply to Mounir Lamouri (:volkmar) (:mounir) from comment #1)
> > > (In reply to Chris Jones [:cjones] [:warhammer] from comment #0)
> > > >   settings.time.msSinceEpoch --- Datetime as a number of milliseconds since
> > > > the POSIX Epoch (i.e., 00:00:00 UTC on 1 January 1970).
> > > 
> > > I don't really like having this as a setting because it will be a constantly
> > > moving value and I don't think we should have such kind of settings. I would
> > > prefer an API that allows setting the current time instead and getting it
> > > with a Date object. If we have such API, we could allow setting the timezone
> > > trough it.
> > > 
> > 
> > I don't understand how that's different.  It sounds like you're exchanging
> > milliseconds for Date objects.
> 
> What I meant is that settings should be fixed values and "time.msSinceEpoch"
> is going to be a constantly moving value. I really don't think we should do
> that. Instead, we should have an API that allows setting the system time and
> getting the time could be done trough the Date object.
> 

Date is unprivileged, but setting the datetime and timezone needs to be privilege.

I don't fully understand the objection to changing settings values.  Can you elaborate?

> > Date doesn't know about DST etc. AFAICT so I don't think that's a good
> > interface for setting the timezone.  The timezone configuration is
> > surprisingly complicated, see man 2 tzset.
> 
> TZ could be a setting, sure. But if we have msSinceEpoch in an API we could
> also just use that API for TZ. I'm not sure what you meant by "that" in "I
> don't think that's a good interface".

I thought you were proposing to change msSinceEpoch to an interface that set the timezone using a new Date object, which is what I was objecting to.  It seems natural to me to have these configuration values live in settings (although the system-clock setting will be implemented by the system HW clock, instead of the settings DB), so I'd like to understand your objection to that better.
(In reply to Chris Jones [:cjones] [:warhammer] from comment #4)
> I don't fully understand the objection to changing settings values.  Can you
> elaborate?
> 

Sorry, "changing" here was ambiguous.  I meant it in the sense of "varying".
Indeed, I wasn't proposing to use a new Date object to set those values but to get them (at least for the current time).

The reason why I don't want to have the current time in a setting is because the current time is not a setting. A setting is whether I'm using a NTP server to sync my clock and what is the server URL; it's my timezone; it's whether I have wifi disabled. Only static values. Values that could be stored in a database and an application would have to set them to change them.
With a dynamic setting we are breaking those implicit rules IMO. The value is no longer static and if it is, it will be set every ms which is insane. That means no change event will be fired but the setting will actually change.

IMO, the natural way to do that is to have an API that let changing the system time. We don't need anything for getting the time because |Date| is here for that. We could use that API to get the 'timechange' event.
(In reply to Mounir Lamouri (:volkmar) (:mounir) from comment #6)
> The reason why I don't want to have the current time in a setting is because
> the current time is not a setting. A setting is whether I'm using a NTP
> server to sync my clock and what is the server URL; it's my timezone; it's
> whether I have wifi disabled. Only static values. Values that could be
> stored in a database and an application would have to set them to change
> them.
> With a dynamic setting we are breaking those implicit rules IMO. The value
> is no longer static and if it is, it will be set every ms which is insane.
> That means no change event will be fired but the setting will actually
> change.
> 

The concrete argument I see here is that with a varying system-clock setting, we wouldn't want to fire a "settings value" changed event on every clock tick.  OK, that's a good argument.

> IMO, the natural way to do that is to have an API that let changing the
> system time.

A new API for setting time is fine by me, just more overhead.  Let's bikeshed this away.  Strawman

  navigator.setSystemClockMs(ms)

> We don't need anything for getting the time because |Date| is
> here for that. We could use that API to get the 'timechange' event.

AFAIK, no one proposed adding new APIs specifically for getting the current time.  So I agree with you.
(In reply to Chris Jones [:cjones] [:warhammer] from comment #7)
> > IMO, the natural way to do that is to have an API that let changing the
> > system time.
> 
> A new API for setting time is fine by me, just more overhead.  Let's
> bikeshed this away.  Strawman
> 
>   navigator.setSystemClockMs(ms)

I would prefer setSystemClock(Date) or maybe allowing |Date| or |ms|.
I'm not sure if having this is |navigator| makes a lot of sense but I don't see what we could do. Also, if we want a 'timechange' event, should it be fired on |window|, |navigator| or another object? I would tend to say |window|.
We need to be very careful about allowing Date, because the system-clock setting is number of milliseconds since Epoch in UTC.  We can define things so that that works though, if it seems helpful to others.  (I'm ambivalent.)
(In reply to Chris Jones [:cjones] [:warhammer] from comment #9)
> We need to be very careful about allowing Date, because the system-clock
> setting is number of milliseconds since Epoch in UTC.  We can define things
> so that that works though, if it seems helpful to others.  (I'm ambivalent.)

I don't really like the idea of re-inveting the wheel because someone might mis-use a tool that already exist. We can get ms since epoch in the current TZ with Date with a simple computation so it doesn't sound a blocker to me.
A better API here would be adjustSystemClock(dtMs), where |dtMs| is the change in number of milliseconds.  That avoids clock skew from the UI choosing a date, and the platform actually setting it (which could be pretty much an arbitrary time in the future).
(In reply to Chris Jones [:cjones] [:warhammer] from comment #11)
> That avoids clock skew from the UI
> choosing a date, and the platform actually setting it (which could be pretty
> much an arbitrary time in the future).

I didn't really understood that. Could you rephrase it?
A clock-setting application will do something like the following
 1. have UI for the user to choose the "current time"
 2. have a "Set" button, or something along those lines
 3. when the user clicks "Set", parse the time and convert it to a Date or milliseconds-since-Epoch value
 4. call navigator.set/adjustSystemClock()
 5. gecko calls clock_settime() (on POSIX)

The problem is, there's a theoretically arbitrarily long delay between (3) and (5).  Each millisecond that elapses between (3) and (5) is another millisecond the clock is off the value the user wanted.

Whereas with adjustSystemClock(), the client specifies an offset from the *current* time in (3).  That offset is still the same no matter how much time elapses between (3) and (5).  So step (5) would be, "call clock_gettime(), apply the offset, then call clock_settime()".

Does that make sense?
Asking for the delta seems a pretty hard API.
Wouldn't that be easier if the Web facing API was requesting for a Date and we would convert this to a delta in the Gecko implementation so we would reduce as much as possible the difference when calling clock_settime(). The only delay would be between creating the Date object in the caller side and us doing the delta computation. Seems like we could make this insignificant, right?
Arggghh, was looking over https://docs.google.com/spreadsheet/ccc?key=0Akyz_Bqjgf5pdENVekxYRjBTX0dCXzItMnRyUU1RQ0E#gid=0 and at the HAL implementation, and noticed we don't have this hooked up anywhere :(.

clee, is setting system time + timezone part of the v1 UI spec?  I sort of assume so, but not sure.  If so we need this API.

It looks like bug 714352 didn't actually hook up NITZ to the system-clock HAL, so we have no way at all to update the system clock.  The internal clock on phones is not reliable so this is actually a relatively bad problem.  The system time might drift up to the order of hours over a few months of use :/.

Another option is to implement a poor-man's SNTP with XHR and then use this API to update the time.  The problem with that approach is it hard-codes the timezone.

Either this bug or a followup to bug 714352 should block.  I don't have the powers to set flags ...
blocking-basecamp: --- → ?
blocking-kilimanjaro: --- → ?
I thought the idea was to set the timezone using the settings API. But we definitely need an API for setting the current time.
blocking-basecamp: ? → +
Bug 714358 is going to handle the time changes notifications and setting the time.
As Jonas, I thought setting the timezone would be done with the Settings API. I'm not sure what else should be needed for v1. Can't we just have available tz built in Gaia?
Depends on: 714358
Summary: API to enumerate available timezones, set datetime, and set timezone → API to enumerate available timezones and set timezone
Timezone via settings sounds great, but
 - we have to recognize when that changes and poke hal::SetTimezone
 - we have to connect NITZ up to that setting

(In reply to Mounir Lamouri (:mounir) (on VACATION until August 5th) from comment #17)
> Can't we just have available tz built in Gaia?

I don't know what you mean by this.
Oh, I think you mean for enumerating.  Yes, that's not great but OK.
Guys, do we still need this bug?
Priority: -- → P1
(In reply to Chris Jones [:cjones] [:warhammer] from comment #18)
> Timezone via settings sounds great, but
>  - we have to recognize when that changes and poke hal::SetTimezone
>  - we have to connect NITZ up to that setting

Are these bug 714359 (or bug 714358) and bug 714352?
No, those are different things.
Minusing this since we don't need an API for enumerating available timezones in v1. We're filing a separate bug on specifically making it possible to set the timezone.
(In reply to Jonas Sicking (:sicking) from comment #23)
> Minusing this since we don't need an API for enumerating available timezones
> in v1. We're filing a separate bug on specifically making it possible to set
> the timezone.

Filed bug 783021.
No longer depends on: 791962
In 'First Time Usage' App we need to enumerate the list of 'timezones' available, and info related as:
GMT +2 Cairo, Bucharest... Also this info should be in Settings, Do we need a common way of retrieving this info? Probably if is not in API, some 'json' with this info in shared?

On the other hand we should rename this bug due to 'setTimezone' was in other specific bug.
blocking-basecamp: - → ?
Borja, as said in comment 17 and in comment 23, we don't need this for v1. Gaia can have its hard coded available timezones for the moment.
For sure, we could create a 'timezones.json' in '/shared' for having the same set in Settings and FTU, what do you think?
I don't know how Gaia is working so I can't really give any opinion. You should probably open a bug for Gaia and ask Gaia peers their opinions.
(In reply to Mounir Lamouri (:mounir) from comment #28)
> I don't know how Gaia is working so I can't really give any opinion. You
> should probably open a bug for Gaia and ask Gaia peers their opinions.

The timezone json is currently stored in Settings app and <select> is created live according to it.

I will against moving this to b+; there are already Gaia feature done without this.
Not blocking because we have a Gaia workaround.
blocking-basecamp: ? → -
When you enable the API in bug 866301, you can possibly retrieve the timezones by fixing bug 837961 and/or bug 895737.
Closing as WONTFIX since FxOS is no more. As per comment 31 JavaScript has some APIs for this now too.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.