Skip to content

Commit

Permalink
[i18n] Replaces fuchsia.deprecatedtimezone
Browse files Browse the repository at this point in the history
The FIDL library fuchsia.deprecatedtimezone is going away.  There are
different and better ways to obtain the same functionality.

Fixes flutter#39650

Change-Id: If4e4234568c276d3cd2be34863f00165b6e97e0e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/129005
Commit-Queue: Filip Filmar <fmil@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
  • Loading branch information
filmil authored and commit-bot@chromium.org committed Jan 17, 2020
1 parent 9c6e548 commit c063f5d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
6 changes: 2 additions & 4 deletions runtime/vm/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,14 @@ library_for_all_configs("libdart_vm") {
if (is_fuchsia) {
if (using_fuchsia_sdk) {
extra_deps += [
"$fuchsia_sdk_root/fidl:fuchsia.deprecatedtimezone",
"$fuchsia_sdk_root/fidl:fuchsia.intl",
"$fuchsia_sdk_root/pkg:sys_cpp",
"$fuchsia_sdk_root/pkg:trace-engine",
]
} else {
extra_deps += [
# TODO(US-399): Remove time_service specific code when it is no longer
# necessary.
"//sdk/fidl/fuchsia.intl",
"//sdk/lib/sys/cpp",
"//sdk/fidl/fuchsia.deprecatedtimezone",

"//zircon/public/lib/fbl",
"//zircon/public/lib/trace-engine",
Expand Down
59 changes: 47 additions & 12 deletions runtime/vm/os_fuchsia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@
#include <fcntl.h>
#include <stdint.h>

#include <fuchsia/deprecatedtimezone/cpp/fidl.h>
#include <fuchsia/intl/cpp/fidl.h>
#include <lib/sys/cpp/service_directory.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
#include <zircon/types.h>

#include "third_party/icu/source/common/unicode/errorcode.h"
#include "third_party/icu/source/i18n/unicode/timezone.h"

#include "platform/assert.h"
#include "vm/zone.h"

Expand Down Expand Up @@ -61,33 +64,65 @@ intptr_t OS::ProcessId() {
return static_cast<intptr_t>(getpid());
}

// This is the default timezone returned if it could not be obtained. For
// Fuchsia, the default device timezone is always UTC.
static const char[] kDefaultTimezone = "UTC";

// TODO(FL-98): Change this to talk to fuchsia.dart to get timezone service to
// directly get timezone.
//
// Putting this hack right now due to CP-120 as I need to remove
// component:ConnectToEnvironmentServices and this is the only thing that is
// blocking it and FL-98 will take time.
static fuchsia::deprecatedtimezone::TimezoneSyncPtr tz;
static fuchsia::intl::PropertyProviderSyncPtr property_provider;

// 1000 milliseconds do one second make.
static const int32_t kMSPerSec = 1000;

static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
int32_t* local_offset,
int32_t* dst_offset) {
zx_status_t status = tz->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000,
local_offset, dst_offset);
if (status != ZX_OK) {
return status;
const char* timezone_id = GetTimeZoneName(seconds_since_epoch);
std::unique_ptr<icu::TimeZone> timezone(
icu::TimeZone::createTimeZone(timezone_id));
UErrorCode error = U_ZERO_ERROR;
const auto ms_since_epoch =
static_cast<UDate>(kMSPerSec * seconds_since_epoch);
// The units of time that local_offset and dst_offset are returned from this
// function is, usefully, not documented, but it seems that the units are
// milliseconds. Add these variables here for clarity.
int32_t local_offset_ms = 0;
int32_t dst_offset_ms = 0;
timezone->getOffset(ms_since_epoch, /*local_time=*/false, local_offset_ms,
dst_offset_ms, error);
if (error != U_ZERO_ERROR) {
icu::ErrorCode icu_error;
icu_error.set(error);
// Sadly there is no way to report the actual error. Next best thing is to
// log. On the upside, a direct call to timezone->getOffset should fail
// rarely, so this should not amount to log spam.
LOG(ERROR) << "could not get DST offset: " << icu_error.errorName();
return ZX_ERR_INTERNAL;
}
*local_offset *= 60;
*dst_offset *= 60;
// We must return offset in seconds, so convert.
*local_offset = local_offset_ms / kMSPerSec;
*dst_offset = dst_offset_ms / kMSPerSec;
return ZX_OK;
}

const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
// TODO(abarth): Handle time zone changes.
static const auto* tz_name = new std::string([] {
std::string result;
tz->GetTimezoneId(&result);
return result;
fuchsia::intl::Profile profile;
zx_status_t status = property_provider->GetProfile(&profile);
if (status != ZX_OK) {
return kDefaultTimezone;
}
const std::vector<fuchsia::intl::TimeZoneId>& tzs = profile.time_zones();
if (tzs.empty()) {
return kDefaultTimezone;
}
return tzs[0].id;
}());
return tz_name->c_str();
}
Expand Down Expand Up @@ -265,7 +300,7 @@ void OS::PrintErr(const char* format, ...) {
void OS::Init() {
InitializeTZData();
auto services = sys::ServiceDirectory::CreateFromNamespace();
services->Connect(tz.NewRequest());
services->Connect(property_provider.NewRequest());
}

void OS::Cleanup() {}
Expand Down

0 comments on commit c063f5d

Please sign in to comment.