1111#include < fcntl.h>
1212#include < stdint.h>
1313
14- #include < fuchsia/intl /cpp/fidl.h>
14+ #include < fuchsia/deprecatedtimezone /cpp/fidl.h>
1515#include < lib/async/default.h>
1616#include < lib/async-loop/loop.h>
1717#include < lib/async-loop/default.h>
2424#include < zircon/syscalls/object.h>
2525#include < zircon/types.h>
2626
27- #include " third_party/icu/source/common/unicode/errorcode.h"
28- #include " third_party/icu/source/i18n/unicode/timezone.h"
29-
3027#include " platform/assert.h"
31- #include " platform/syslog.h"
3228#include " platform/utils.h"
3329#include " vm/zone.h"
3430
3531namespace {
3632
37- static constexpr int32_t kMsPerSec = 1000 ;
38-
3933// The data directory containing ICU timezone data files.
4034static constexpr char kICUTZDataDir [] = " /config/data/tzdata/icu/44/le" ;
4135
42- // This is the general OK status.
43- static constexpr int32_t kOk = 0 ;
44-
45- // This status means that the error code is not initialized yet ("set" was not
46- // yet called). Error codes are usually either 0 (kOk), or negative.
47- static constexpr int32_t kUninitialized = 1 ;
48-
4936// The status codes for tzdata file open and read.
5037enum class TZDataStatus {
51- // The operation completed without error.
5238 OK = 0 ,
5339 // The open call for the tzdata file did not succeed.
5440 COULD_NOT_OPEN = -1 ,
@@ -58,23 +44,16 @@ enum class TZDataStatus {
5844
5945// Adds a facility for introspecting timezone data errors. Allows insight into
6046// the internal state of the VM even if error reporting facilities fail.
61- //
62- // Under normal operation, all metric values below should be zero.
6347class InspectMetrics {
6448 public:
6549 // Does not take ownership of inspector.
6650 explicit InspectMetrics (inspect::Inspector* inspector)
6751 : inspector_(inspector),
6852 root_(inspector_->GetRoot ()),
6953 metrics_(root_.CreateChild(" os" )),
70- dst_status_(metrics_.CreateInt(" dst_status" , kUninitialized )),
71- tz_data_status_(metrics_.CreateInt(" tz_data_status" , kUninitialized )),
72- tz_data_close_status_(
73- metrics_.CreateInt(" tz_data_close_status" , kUninitialized )),
74- get_profile_status_(
75- metrics_.CreateInt(" get_profile_status" , kUninitialized )),
76- profiles_timezone_content_status_(
77- metrics_.CreateInt(" timezone_content_status" , kOk )) {}
54+ dst_status_(metrics_.CreateInt(" dst_status" , 0 )),
55+ tz_data_status_(metrics_.CreateInt(" tz_data_status" , 0 )),
56+ tz_data_close_status_(metrics_.CreateInt(" tz_data_close_status" , 0 )) {}
7857
7958 // Sets the last status code for DST offset calls.
8059 void SetDSTOffsetStatus (zx_status_t status) {
@@ -88,17 +67,6 @@ class InspectMetrics {
8867 tz_data_close_status_.Set (status);
8968 }
9069
91- // Sets the last status code for the call to PropertyProvider::GetProfile.
92- void SetProfileStatus (zx_status_t status) {
93- get_profile_status_.Set (static_cast <int32_t >(status));
94- }
95-
96- // Sets the last status seen while examining timezones returned from
97- // PropertyProvider::GetProfile.
98- void SetTimeZoneContentStatus (zx_status_t status) {
99- profiles_timezone_content_status_.Set (static_cast <int32_t >(status));
100- }
101-
10270 private:
10371 // The inspector that all metrics are being reported into.
10472 inspect::Inspector* inspector_;
@@ -117,15 +85,6 @@ class InspectMetrics {
11785
11886 // The return code for the close() call for tzdata files.
11987 inspect::IntProperty tz_data_close_status_;
120-
121- // The return code of the GetProfile call in GetTimeZoneName. If this is
122- // nonzero, then os_fuchsia.cc reported a default timezone as a fallback.
123- inspect::IntProperty get_profile_status_;
124-
125- // U_ILLEGAL_ARGUMENT_ERROR(=1) if timezones read from ProfileProvider were
126- // incorrect. Otherwise 0. If this metric reports U_ILLEGAL_ARGUMENT_ERROR,
127- // the os_fuchsia.cc module reported a default timezone as a fallback.
128- inspect::IntProperty profiles_timezone_content_status_;
12988};
13089
13190// Initialized on OS:Init(), deinitialized on OS::Cleanup.
@@ -177,85 +136,50 @@ intptr_t OS::ProcessId() {
177136 return static_cast <intptr_t >(getpid ());
178137}
179138
180- // This is the default timezone returned if it could not be obtained. For
181- // Fuchsia, the default device timezone is always UTC.
182- static const char kDefaultTimezone [] = " UTC" ;
183-
184139// TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
185140// directly get timezone.
186141//
187142// Putting this hack right now due to CP-120 as I need to remove
188143// component:ConnectToEnvironmentServices and this is the only thing that is
189144// blocking it and FL-98 will take time.
190- static fuchsia::intl::PropertyProviderSyncPtr property_provider ;
145+ static fuchsia::deprecatedtimezone::TimezoneSyncPtr tz ;
191146
192147static zx_status_t GetLocalAndDstOffsetInSeconds (int64_t seconds_since_epoch,
193148 int32_t * local_offset,
194149 int32_t * dst_offset) {
195- const char * timezone_id = OS::GetTimeZoneName (seconds_since_epoch);
196- std::unique_ptr<icu::TimeZone> timezone (
197- icu::TimeZone::createTimeZone (timezone_id));
198- UErrorCode error = U_ZERO_ERROR;
199- const auto ms_since_epoch =
200- static_cast <UDate>(kMsPerSec * seconds_since_epoch);
201- // The units of time that local_offset and dst_offset are returned from this
202- // function is, usefully, not documented, but it seems that the units are
203- // milliseconds. Add these variables here for clarity.
204- int32_t local_offset_ms = 0 ;
205- int32_t dst_offset_ms = 0 ;
206- timezone->getOffset (ms_since_epoch, /* local_time=*/ false , local_offset_ms,
207- dst_offset_ms, error);
208- metrics->SetDSTOffsetStatus (error);
209- if (error != U_ZERO_ERROR) {
210- icu::ErrorCode icu_error;
211- icu_error.set (error);
212- Syslog::PrintErr (" could not get DST offset: %s\n " , icu_error.errorName ());
213- return ZX_ERR_INTERNAL;
150+ zx_status_t status = tz->GetTimezoneOffsetMinutes (seconds_since_epoch * 1000 ,
151+ local_offset, dst_offset);
152+ metrics->SetDSTOffsetStatus (status);
153+ if (status != ZX_OK) {
154+ return status;
214155 }
215- // We must return offset in seconds, so convert.
216- *local_offset = local_offset_ms / kMsPerSec ;
217- *dst_offset = dst_offset_ms / kMsPerSec ;
156+ *local_offset *= 60 ;
157+ *dst_offset *= 60 ;
218158 return ZX_OK;
219159}
220160
221161const char * OS::GetTimeZoneName (int64_t seconds_since_epoch) {
222162 // TODO(abarth): Handle time zone changes.
223- static const std::unique_ptr<std::string> tz_name =
224- std::make_unique<std::string>([]() -> std::string {
225- fuchsia::intl::Profile profile;
226- const zx_status_t status = property_provider->GetProfile (&profile);
227- metrics->SetProfileStatus (status);
228- if (status != ZX_OK) {
229- return kDefaultTimezone ;
230- }
231- const std::vector<fuchsia::intl::TimeZoneId>& timezones =
232- profile.time_zones ();
233- if (timezones.empty ()) {
234- metrics->SetTimeZoneContentStatus (U_ILLEGAL_ARGUMENT_ERROR);
235- // Empty timezone array is not up to fuchsia::intl spec. The serving
236- // endpoint is broken and should be fixed.
237- Syslog::PrintErr (" got empty timezone value\n " );
238- return kDefaultTimezone ;
239- }
240- return timezones[0 ].id ;
241- }());
163+ static const auto * tz_name = new std::string ([] {
164+ std::string result;
165+ tz->GetTimezoneId (&result);
166+ return result;
167+ }());
242168 return tz_name->c_str ();
243169}
244170
245171int OS::GetTimeZoneOffsetInSeconds (int64_t seconds_since_epoch) {
246- int32_t local_offset = 0 ;
247- int32_t dst_offset = 0 ;
248- const zx_status_t status = GetLocalAndDstOffsetInSeconds (
172+ int32_t local_offset, dst_offset;
173+ zx_status_t status = GetLocalAndDstOffsetInSeconds (
249174 seconds_since_epoch, &local_offset, &dst_offset);
250175 return status == ZX_OK ? local_offset + dst_offset : 0 ;
251176}
252177
253178int OS::GetLocalTimeZoneAdjustmentInSeconds () {
179+ int32_t local_offset, dst_offset;
254180 zx_time_t now = 0 ;
255181 zx_clock_get (ZX_CLOCK_UTC, &now);
256- int32_t local_offset = 0 ;
257- int32_t dst_offset = 0 ;
258- const zx_status_t status = GetLocalAndDstOffsetInSeconds (
182+ zx_status_t status = GetLocalAndDstOffsetInSeconds (
259183 now / ZX_SEC (1 ), &local_offset, &dst_offset);
260184 return status == ZX_OK ? local_offset : 0 ;
261185}
@@ -279,7 +203,7 @@ int64_t OS::GetCurrentMonotonicFrequency() {
279203}
280204
281205int64_t OS::GetCurrentMonotonicMicros () {
282- const int64_t ticks = GetCurrentMonotonicTicks ();
206+ int64_t ticks = GetCurrentMonotonicTicks ();
283207 ASSERT (GetCurrentMonotonicFrequency () == kNanosecondsPerSecond );
284208 return ticks / kNanosecondsPerMicrosecond ;
285209}
@@ -433,8 +357,7 @@ void OS::Init() {
433357 metrics = std::make_unique<InspectMetrics>(component_inspector->inspector ());
434358
435359 InitializeTZData ();
436- auto services = sys::ServiceDirectory::CreateFromNamespace ();
437- services->Connect (property_provider.NewRequest ());
360+ context->svc ()->Connect (tz.NewRequest ());
438361}
439362
440363void OS::Cleanup () {
0 commit comments