11
11
#include < fcntl.h>
12
12
#include < stdint.h>
13
13
14
- #include < fuchsia/intl /cpp/fidl.h>
14
+ #include < fuchsia/deprecatedtimezone /cpp/fidl.h>
15
15
#include < lib/async/default.h>
16
16
#include < lib/async-loop/loop.h>
17
17
#include < lib/async-loop/default.h>
24
24
#include < zircon/syscalls/object.h>
25
25
#include < zircon/types.h>
26
26
27
- #include " third_party/icu/source/common/unicode/errorcode.h"
28
- #include " third_party/icu/source/i18n/unicode/timezone.h"
29
-
30
27
#include " platform/assert.h"
31
- #include " platform/syslog.h"
32
28
#include " platform/utils.h"
33
29
#include " vm/zone.h"
34
30
35
31
namespace {
36
32
37
- static constexpr int32_t kMsPerSec = 1000 ;
38
-
39
33
// The data directory containing ICU timezone data files.
40
34
static constexpr char kICUTZDataDir [] = " /config/data/tzdata/icu/44/le" ;
41
35
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
-
49
36
// The status codes for tzdata file open and read.
50
37
enum class TZDataStatus {
51
- // The operation completed without error.
52
38
OK = 0 ,
53
39
// The open call for the tzdata file did not succeed.
54
40
COULD_NOT_OPEN = -1 ,
@@ -58,23 +44,16 @@ enum class TZDataStatus {
58
44
59
45
// Adds a facility for introspecting timezone data errors. Allows insight into
60
46
// the internal state of the VM even if error reporting facilities fail.
61
- //
62
- // Under normal operation, all metric values below should be zero.
63
47
class InspectMetrics {
64
48
public:
65
49
// Does not take ownership of inspector.
66
50
explicit InspectMetrics (inspect::Inspector* inspector)
67
51
: inspector_(inspector),
68
52
root_(inspector_->GetRoot ()),
69
53
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 )) {}
78
57
79
58
// Sets the last status code for DST offset calls.
80
59
void SetDSTOffsetStatus (zx_status_t status) {
@@ -88,17 +67,6 @@ class InspectMetrics {
88
67
tz_data_close_status_.Set (status);
89
68
}
90
69
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
-
102
70
private:
103
71
// The inspector that all metrics are being reported into.
104
72
inspect::Inspector* inspector_;
@@ -117,15 +85,6 @@ class InspectMetrics {
117
85
118
86
// The return code for the close() call for tzdata files.
119
87
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_;
129
88
};
130
89
131
90
// Initialized on OS:Init(), deinitialized on OS::Cleanup.
@@ -177,85 +136,50 @@ intptr_t OS::ProcessId() {
177
136
return static_cast <intptr_t >(getpid ());
178
137
}
179
138
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
-
184
139
// TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
185
140
// directly get timezone.
186
141
//
187
142
// Putting this hack right now due to CP-120 as I need to remove
188
143
// component:ConnectToEnvironmentServices and this is the only thing that is
189
144
// blocking it and FL-98 will take time.
190
- static fuchsia::intl::PropertyProviderSyncPtr property_provider ;
145
+ static fuchsia::deprecatedtimezone::TimezoneSyncPtr tz ;
191
146
192
147
static zx_status_t GetLocalAndDstOffsetInSeconds (int64_t seconds_since_epoch,
193
148
int32_t * local_offset,
194
149
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;
214
155
}
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 ;
218
158
return ZX_OK;
219
159
}
220
160
221
161
const char * OS::GetTimeZoneName (int64_t seconds_since_epoch) {
222
162
// 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
+ }());
242
168
return tz_name->c_str ();
243
169
}
244
170
245
171
int 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 (
249
174
seconds_since_epoch, &local_offset, &dst_offset);
250
175
return status == ZX_OK ? local_offset + dst_offset : 0 ;
251
176
}
252
177
253
178
int OS::GetLocalTimeZoneAdjustmentInSeconds () {
179
+ int32_t local_offset, dst_offset;
254
180
zx_time_t now = 0 ;
255
181
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 (
259
183
now / ZX_SEC (1 ), &local_offset, &dst_offset);
260
184
return status == ZX_OK ? local_offset : 0 ;
261
185
}
@@ -279,7 +203,7 @@ int64_t OS::GetCurrentMonotonicFrequency() {
279
203
}
280
204
281
205
int64_t OS::GetCurrentMonotonicMicros () {
282
- const int64_t ticks = GetCurrentMonotonicTicks ();
206
+ int64_t ticks = GetCurrentMonotonicTicks ();
283
207
ASSERT (GetCurrentMonotonicFrequency () == kNanosecondsPerSecond );
284
208
return ticks / kNanosecondsPerMicrosecond ;
285
209
}
@@ -433,8 +357,7 @@ void OS::Init() {
433
357
metrics = std::make_unique<InspectMetrics>(component_inspector->inspector ());
434
358
435
359
InitializeTZData ();
436
- auto services = sys::ServiceDirectory::CreateFromNamespace ();
437
- services->Connect (property_provider.NewRequest ());
360
+ context->svc ()->Connect (tz.NewRequest ());
438
361
}
439
362
440
363
void OS::Cleanup () {
0 commit comments